mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 00:07:43 +00:00
Kernel: Comment the living daylights out of signal trampoline/sigreturn
Mere mortals like myself cannot understand more than two lines of assembly without a million comments explaining what's happening, so do that and make sure no one has to go on a wild stack state chase when hacking on these.
This commit is contained in:
parent
7238c946f0
commit
585054d68b
2 changed files with 40 additions and 12 deletions
|
@ -297,16 +297,25 @@ void signal_trampoline_dummy()
|
||||||
".intel_syntax noprefix\n"
|
".intel_syntax noprefix\n"
|
||||||
".globl asm_signal_trampoline\n"
|
".globl asm_signal_trampoline\n"
|
||||||
"asm_signal_trampoline:\n"
|
"asm_signal_trampoline:\n"
|
||||||
|
// stack state: ret flags, ret ip, register dump, signal mask, signal, handler (alignment = 16), 0
|
||||||
|
|
||||||
|
// save ebp
|
||||||
"push ebp\n"
|
"push ebp\n"
|
||||||
"mov ebp, esp\n"
|
"mov ebp, esp\n"
|
||||||
"push eax\n" // we have to store eax 'cause it might be the return value from a syscall
|
// we have to save eax 'cause it might be the return value from a syscall
|
||||||
"sub esp, 4\n" // align the stack to 16 bytes
|
|
||||||
"mov eax, [ebp+12]\n" // push the signal code
|
|
||||||
"push eax\n"
|
"push eax\n"
|
||||||
"call [ebp+8]\n" // call the signal handler
|
// align the stack to 16 bytes (as our current offset is 12 from the fake return addr, saved ebp and saved eax)
|
||||||
|
"sub esp, 4\n"
|
||||||
|
// push the signal code
|
||||||
|
"mov eax, [ebp+12]\n"
|
||||||
|
"push eax\n"
|
||||||
|
// call the signal handler
|
||||||
|
"call [ebp+8]\n"
|
||||||
|
// Unroll stack back to the saved eax
|
||||||
"add esp, 8\n"
|
"add esp, 8\n"
|
||||||
|
// syscall SC_sigreturn
|
||||||
"mov eax, %P0\n"
|
"mov eax, %P0\n"
|
||||||
"int 0x82\n" // sigreturn syscall
|
"int 0x82\n"
|
||||||
".globl asm_signal_trampoline_end\n"
|
".globl asm_signal_trampoline_end\n"
|
||||||
"asm_signal_trampoline_end:\n"
|
"asm_signal_trampoline_end:\n"
|
||||||
".att_syntax" ::"i"(Syscall::SC_sigreturn));
|
".att_syntax" ::"i"(Syscall::SC_sigreturn));
|
||||||
|
@ -320,15 +329,24 @@ void signal_trampoline_dummy()
|
||||||
".intel_syntax noprefix\n"
|
".intel_syntax noprefix\n"
|
||||||
".globl asm_signal_trampoline\n"
|
".globl asm_signal_trampoline\n"
|
||||||
"asm_signal_trampoline:\n"
|
"asm_signal_trampoline:\n"
|
||||||
|
// stack state: ret flags, ret ip, register dump, signal mask, signal, handler (alignment = 16), 0
|
||||||
|
|
||||||
|
// save rbp
|
||||||
"push rbp\n"
|
"push rbp\n"
|
||||||
"mov rbp, rsp\n"
|
"mov rbp, rsp\n"
|
||||||
"push rax\n" // we have to store rax 'cause it might be the return value from a syscall
|
// we have to save rax 'cause it might be the return value from a syscall
|
||||||
"sub rsp, 8\n" // align the stack to 16 bytes
|
"push rax\n"
|
||||||
"mov rdi, [rbp+24]\n" // push the signal code
|
// align the stack to 16 bytes (our offset is 24 bytes from the fake return addr, saved rbp and saved rax).
|
||||||
"call [rbp+16]\n" // call the signal handler
|
"sub rsp, 8\n"
|
||||||
|
// push the signal code
|
||||||
|
"mov rdi, [rbp+24]\n"
|
||||||
|
// call the signal handler
|
||||||
|
"call [rbp+16]\n"
|
||||||
|
// unroll stack back to the saved rax
|
||||||
"add rsp, 8\n"
|
"add rsp, 8\n"
|
||||||
|
// syscall SC_sigreturn
|
||||||
"mov rax, %P0\n"
|
"mov rax, %P0\n"
|
||||||
"int 0x82\n" // sigreturn syscall
|
"int 0x82\n"
|
||||||
".globl asm_signal_trampoline_end\n"
|
".globl asm_signal_trampoline_end\n"
|
||||||
"asm_signal_trampoline_end:\n"
|
"asm_signal_trampoline_end:\n"
|
||||||
".att_syntax" ::"i"(Syscall::SC_sigreturn));
|
".att_syntax" ::"i"(Syscall::SC_sigreturn));
|
||||||
|
|
|
@ -84,9 +84,14 @@ ErrorOr<FlatPtr> Process::sys$sigreturn([[maybe_unused]] RegisterState& register
|
||||||
SmapDisabler disabler;
|
SmapDisabler disabler;
|
||||||
|
|
||||||
#if ARCH(I386)
|
#if ARCH(I386)
|
||||||
|
// Stack state (created by the signal trampoline):
|
||||||
|
// ret flags, ret ip, register dump,
|
||||||
|
// signal mask, signal, handler (alignment = 16),
|
||||||
|
// 0, ebp, eax
|
||||||
|
|
||||||
// Here, we restore the state pushed by dispatch signal and asm_signal_trampoline.
|
// Here, we restore the state pushed by dispatch signal and asm_signal_trampoline.
|
||||||
u32* stack_ptr = (u32*)registers.userspace_esp;
|
FlatPtr* stack_ptr = bit_cast<FlatPtr*>(registers.userspace_esp);
|
||||||
u32 smuggled_eax = *stack_ptr;
|
FlatPtr smuggled_eax = *stack_ptr;
|
||||||
|
|
||||||
// pop the stored eax, ebp, return address, handler and signal code
|
// pop the stored eax, ebp, return address, handler and signal code
|
||||||
stack_ptr += 5;
|
stack_ptr += 5;
|
||||||
|
@ -107,6 +112,11 @@ ErrorOr<FlatPtr> Process::sys$sigreturn([[maybe_unused]] RegisterState& register
|
||||||
registers.userspace_esp = registers.esp;
|
registers.userspace_esp = registers.esp;
|
||||||
return smuggled_eax;
|
return smuggled_eax;
|
||||||
#else
|
#else
|
||||||
|
// Stack state (created by the signal trampoline):
|
||||||
|
// ret flags, ret ip, register dump,
|
||||||
|
// signal mask, signal, handler (alignment = 16),
|
||||||
|
// 0, ebp, eax
|
||||||
|
|
||||||
// Here, we restore the state pushed by dispatch signal and asm_signal_trampoline.
|
// Here, we restore the state pushed by dispatch signal and asm_signal_trampoline.
|
||||||
FlatPtr* stack_ptr = (FlatPtr*)registers.userspace_rsp;
|
FlatPtr* stack_ptr = (FlatPtr*)registers.userspace_rsp;
|
||||||
FlatPtr smuggled_rax = *stack_ptr;
|
FlatPtr smuggled_rax = *stack_ptr;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue