diff options
author | Cristian-Bogdan SIRB <cbsirb@gmail.com> | 2020-02-27 11:36:53 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-02-27 10:58:43 +0100 |
commit | 5aa5ce53bcb23e1c31362bae317725ea0cce175a (patch) | |
tree | 16e61f4934a35111e091599202660a471ba5fae6 | |
parent | 0c1497846e78fdf82ad70c2b49b3d8c981eb960f (diff) | |
download | serenity-5aa5ce53bcb23e1c31362bae317725ea0cce175a.zip |
Kernel: Fix the gettid syscall
syscall_handler was not actually updating the value in regs->eax, so the
gettid() was always returning 85: the value of regs->eax was not
actually updated, and it remained the one from Userland (the value of
SC_gettid).
The syscall_handler was modified to actually get a pointer to
RegisterState, so any changes to it will actually be saved.
NOTE: This was actually more of a compiler optimization:
On the SC_gettid flow, we saved in regs.eax the return value of
sys$gettid(), but the compiler discarded it, since it followed a return.
On a normal flow, the value of regs.eax was reused in
tracer->did_syscall, so the compiler actually updated the value.
-rw-r--r-- | Kernel/Syscall.cpp | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index f1f19617f4..e40af90bdc 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -33,7 +33,7 @@ namespace Kernel { -extern "C" void syscall_handler(RegisterState); +extern "C" void syscall_handler(RegisterState&); extern "C" void syscall_asm_entry(); asm( @@ -52,8 +52,9 @@ asm( " cld\n" " xor %esi, %esi\n" " xor %edi, %edi\n" + " push %esp\n" " call syscall_handler\n" - " add $0x4, %esp\n" + " add $0x8, %esp\n" " popl %gs\n" " popl %fs\n" " popl %es\n" @@ -121,7 +122,7 @@ int handle(RegisterState& regs, u32 function, u32 arg1, u32 arg2, u32 arg3) } -void syscall_handler(RegisterState regs) +void syscall_handler(RegisterState& regs) { // Special handling of the "gettid" syscall since it's extremely hot. // FIXME: Remove this hack once userspace locks stop calling it so damn much. |