https://git.reactos.org/?p=reactos.git;a=commitdiff;h=0d3825862f596b05d2a944...
commit 0d3825862f596b05d2a944f5000813e574302d8f Author: Jérôme Gardou jerome.gardou@reactos.org AuthorDate: Tue Apr 6 10:53:35 2021 +0200 Commit: Jérôme Gardou zefklop@users.noreply.github.com CommitDate: Tue Apr 6 17:57:18 2021 +0200
[NTOS:KE] Rewrite KiSystemCallTrampoline in assembly
Instead of making assumptions about what the compiler does with forced-inline functions --- ntoskrnl/include/internal/i386/ke.h | 68 +++---------------------------------- ntoskrnl/ke/i386/trap.s | 34 +++++++++++++++++++ 2 files changed, 38 insertions(+), 64 deletions(-)
diff --git a/ntoskrnl/include/internal/i386/ke.h b/ntoskrnl/include/internal/i386/ke.h index e7152395c92..e91b8d6ad16 100644 --- a/ntoskrnl/include/internal/i386/ke.h +++ b/ntoskrnl/include/internal/i386/ke.h @@ -684,71 +684,11 @@ KiDispatchException2Args(IN NTSTATUS Code, // // Performs a system call // - - /* - * This sequence does a RtlCopyMemory(Stack - StackBytes, Arguments, StackBytes) - * and then calls the function associated with the system call. - * - * It's done in assembly for two reasons: we need to muck with the stack, - * and the call itself restores the stack back for us. The only way to do - * this in C is to do manual C handlers for every possible number of args on - * the stack, and then have the handler issue a call by pointer. This is - * wasteful since it'll basically push the values twice and require another - * level of call indirection. - * - * The ARM kernel currently does this, but it should probably be changed - * later to function like this as well. - * - */ -#ifdef __GNUC__ -FORCEINLINE -NTSTATUS -KiSystemCallTrampoline(IN PVOID Handler, - IN PVOID Arguments, - IN ULONG StackBytes) -{ - NTSTATUS Result; - - __asm__ __volatile__ - ( - "subl %1, %%esp\n\t" - "movl %%esp, %%edi\n\t" - "movl %2, %%esi\n\t" - "shrl $2, %1\n\t" - "rep movsd\n\t" - "call *%3\n\t" - "movl %%eax, %0" - : "=r"(Result) - : "c"(StackBytes), - "d"(Arguments), - "r"(Handler) - : "%esp", "%esi", "%edi" - ); - return Result; -} -#elif defined(_MSC_VER) -FORCEINLINE NTSTATUS -KiSystemCallTrampoline(IN PVOID Handler, - IN PVOID Arguments, - IN ULONG StackBytes) -{ - __asm - { - mov ecx, StackBytes - mov esi, Arguments - mov eax, Handler - sub esp, ecx - mov edi, esp - shr ecx, 2 - rep movsd - call eax - } - /* Return with result in EAX */ -} -#else -#error Unknown Compiler -#endif +NTAPI +KiSystemCallTrampoline(_In_ PVOID Handler, + _In_ PVOID Arguments, + _In_ ULONG StackBytes);
// diff --git a/ntoskrnl/ke/i386/trap.s b/ntoskrnl/ke/i386/trap.s index c4b2e168c54..24dfc1a58aa 100644 --- a/ntoskrnl/ke/i386/trap.s +++ b/ntoskrnl/ke/i386/trap.s @@ -220,4 +220,38 @@ _KiConvertToGuiThread@0: /* return to the caller */ ret
+/* +NTSTATUS +NTAPI +KiSystemCallTrampoline(IN PVOID Handler, + IN PVOID Arguments, + IN ULONG StackBytes); +*/ +PUBLIC _KiSystemCallTrampoline@12 +_KiSystemCallTrampoline@12: + push ebp + mov ebp, esp + push esi + push edi + + /* Get handler */ + mov eax, [ebp + 8] + /* Get arguments */ + mov esi, [ebp + 12] + /* Get stack bytes */ + mov ecx, [ebp + 16] + + /* Copy args to the stack */ + sub esp, ecx + mov edi, esp + shr ecx, 2 + rep movsd + + call eax + + pop edi + pop esi + leave + + ret 12 END