linux(4): Rework signal trampoline on Aarch64

To avoid clobbering of any registers by the trampoline code use Linux
way to call signal handlers. I.e., we are out from the kernel right into
the signal handler, put return address from the signal handler into the
link register.
The mysterious NOP is required for some unwinders (e.g. libc++) that
unconditionally subtract one from the result of _Unwind_GetIP() in order
to identify the calling function.

MFC after:		1 week
This commit is contained in:
Dmitry Chagin 2023-05-15 00:27:31 +03:00
parent 5f19e18b64
commit d957343f87
3 changed files with 7 additions and 5 deletions

View File

@ -45,10 +45,11 @@ linux_platform:
.text
nop /* This is what Linux calls a "Mysterious NOP". */
EENTRY(__kernel_rt_sigreturn)
blr x8
nop /* This is what Linux calls a "Mysterious NOP". */
.globl __user_rt_sigreturn
__user_rt_sigreturn:
mov x8, #LINUX_SYS_linux_rt_sigreturn
svc #0
EEND(__kernel_rt_sigreturn)

View File

@ -118,7 +118,7 @@ LIN_SDT_PROBE_DEFINE0(sysvec, linux_exec_setregs, todo);
LINUX_VDSO_SYM_CHAR(linux_platform);
LINUX_VDSO_SYM_INTPTR(kern_timekeep_base);
LINUX_VDSO_SYM_INTPTR(__kernel_rt_sigreturn);
LINUX_VDSO_SYM_INTPTR(__user_rt_sigreturn);
static int
linux_fetch_syscall_args(struct thread *td)
@ -353,9 +353,9 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask)
tf->tf_x[2] = 0;
}
tf->tf_x[29] = (register_t)&fp->fp;
tf->tf_x[8] = (register_t)catcher;
tf->tf_elr = (register_t)catcher;
tf->tf_sp = (register_t)fp;
tf->tf_elr = (register_t)__kernel_rt_sigreturn;
tf->tf_lr = (register_t)__user_rt_sigreturn;
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_elr,
tf->tf_sp);

View File

@ -70,6 +70,7 @@ VERSION
global:
linux_platform;
kern_timekeep_base;
__user_rt_sigreturn;
local: *;
};
}