42 lines
1.5 KiB
ArmAsm
42 lines
1.5 KiB
ArmAsm
#include "syscall.h"
|
|
|
|
/*
|
|
* Shared signal-delivery trampoline (see signal.h/signal.c). This is NOT
|
|
* entered like a normal function call from C -- signal.c's
|
|
* sigConsumePending rewrites a thread's own saved trapframe so that
|
|
* iretq lands ring 3 execution directly at sigTrampolineStart, with %rax
|
|
* already holding the handler's address and %rdi already holding the
|
|
* signal number (the handler's sole SysV argument), exactly as if the
|
|
* kernel itself had performed `call *%rax` with that argument set up.
|
|
*
|
|
* Position independent by construction: every instruction here is either
|
|
* PC-relative (the final backward jmp) or references no address at all
|
|
* (call through a register, an immediate syscall number, int $0x80) -- so
|
|
* sigInstallTrampoline can copy these bytes to any physical frame and map
|
|
* that frame at any virtual address (sigTrampolineVirtualAddr) and it
|
|
* still runs correctly, unlike this same code linked and executed in
|
|
* place inside the kernel's own (very different) virtual address range.
|
|
*/
|
|
.section .text
|
|
.code64
|
|
|
|
.global sigTrampolineStart
|
|
.global sigTrampolineEnd
|
|
|
|
sigTrampolineStart:
|
|
call *%rax
|
|
movl $sysSigReturn, %eax
|
|
int $0x80
|
|
|
|
/* Only reached if sysSigReturn somehow returned instead of restoring the
|
|
pre-signal context and resuming it (a kernel bug, not a state a correct
|
|
sysOnSigReturn can produce) -- park here rather than run off into
|
|
whatever garbage happens to follow this page. */
|
|
sigTrampolineHang:
|
|
hlt
|
|
jmp sigTrampolineHang
|
|
|
|
sigTrampolineEnd:
|
|
|
|
.section .note.GNU-stack, "", @progbits
|