summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCristian-Bogdan SIRB <cbsirb@gmail.com>2020-02-27 11:36:53 +0200
committerAndreas Kling <kling@serenityos.org>2020-02-27 10:58:43 +0100
commit5aa5ce53bcb23e1c31362bae317725ea0cce175a (patch)
tree16e61f4934a35111e091599202660a471ba5fae6
parent0c1497846e78fdf82ad70c2b49b3d8c981eb960f (diff)
downloadserenity-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.cpp7
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.