linux在构造信号处理过程中面临内核态触发用户态代码的问题。当信号到达内核,内核不可能直接执行用户态的代码。所以,内核利用的方式是将用户态进程的栈帧扩展,然后直接返回用户态,利用伪造的栈信息执行信号量。
这是内核给用户态的程序提供的一个接口。
arch/arm64/kernel/vdso/vdso.lds.S
ENTRY(__kernel_rt_sigreturn)
.cfi_startproc
.cfi_signal_frame
.cfi_def_cfa x29, 0
.cfi_offset x29, 0 * 8
.cfi_offset x30, 1 * 8
mov x8, #__NR_rt_sigreturn
svc #0
.cfi_endproc
ENDPROC(__kernel_rt_sigreturn)
__kernel_rt_sigreturn,做一个系统调用,查询系统调用表,对应的函数是sys_rt_sigreturn
arm下面利用vdso __kernel_rt_sigreturn恢复保存的用户态栈信息,
- [Depth] [Result] [VA] [RVA] [Sym] [Img]
0 80000003 7FA03F4F0C BFF0C <unknown> /lib/aarch64-linux-gnu/libc-2.23.so
1 80000003 7FA06C933C 533C <unknown> /usr/lib/aarch64-linux-gnu/libdrm.so.2.4.0
2 80000003 7FA06CFD8C BD8C <unknown> /usr/lib/aarch64-linux-gnu/libdrm.so.2.4.0
3 80000003 7F9FCD2A4C 50A4C <unknown> /usr/lib/xorg/modules/drivers/radeon_drv.so
4 80000003 5579F67138 CC138 <unknown> /usr/lib/xorg/Xorg
5 80000003 557A036C74 19BC74 <unknown> /usr/lib/xorg/Xorg
6 80000003 557A0378E0 19C8E0 <unknown> /usr/lib/xorg/Xorg
7 80000003 5579F06740 6B740 <unknown> /usr/lib/xorg/Xorg
8 80000003 5579F06D54 6BD54 <unknown> /usr/lib/xorg/Xorg
9 80000003 5579F08308 6D308 <unknown> /usr/lib/xorg/Xorg
10 80000003 5579F0873C 6D73C <unknown> /usr/lib/xorg/Xorg
11 80000003 7F9FC35178 6178 <unknown> /usr/lib/xorg/modules/input/evdev_drv.so
12 80000003 7F9FC35808 6808 <unknown> /usr/lib/xorg/modules/input/evdev_drv.so
13 80000003 5579F300D0 950D0 <unknown> /usr/lib/xorg/Xorg
14 80000003 5579F53E94 B8E94 <unknown> /usr/lib/xorg/Xorg
15 80000004 7FA089E6C0 6C0 <unknown> <unknown>
16 10000000 7FA03F56AC C06AC <unknown> /lib/aarch64-linux-gnu/libc-2.23.so
17 10000000 557A046098 1AB098 <unknown> /usr/lib/xorg/Xorg
18 10000000 5579EF00F4 550F4 <unknown> /usr/lib/xorg/Xorg
19 10000000 5579EF43EC 593EC <unknown> /usr/lib/xorg/Xorg
20 10000000 7FA0354920 1F920 <unknown> /lib/aarch64-linux-gnu/libc-2.23.so
21 10000000 5579EDDFF8 42FF8 <unknown> /usr/lib/xorg/Xorg
整个栈会在 va 6c0执行栈恢复,在网上的栈其实信号处理函数的栈。当返回va 6c0栈信息恢复到信号触发前,进程继续运行。