handle_rt_signal64主要负责信号处理栈处理分析,如下图所示
int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{
struct rt_sigframe __user *frame;
unsigned long newsp = 0;
unsigned long oldsp = 0;
long err = 0;
/* 从regs->gpr[1]读取当前栈指针,往下增长sizeof(*frame),0x960Byte */
frame = get_sigframe(ksig, get_tm_stackpointer(regs), sizeof(*frame), 0);
if (unlikely(frame == NULL))
goto badframe;
err |= __put_user(&frame->info, &frame->pinfo);
err |= __put_user(&frame->uc, &frame->puc);
err |= copy_siginfo_to_user(&frame->info, &ksig->info);
if (err)
goto badframe;
/* 个人增加的调试代码,纯粹打印 */
oldsp = regs->gpr[1];
/* Create the ucontext. */
err |= __put_user(0, &frame->uc.uc_flags);
/* 保存当前sp到用户栈,后续需要从这里恢复原来的内容 */
err |= __save_altstack(&frame->uc.uc_stack, regs->gpr[1]);
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
if (MSR_TM_ACTIVE(regs->msr)) {
/* The ucontext_t passed to userland points to the second
* ucontext_t (for transactional state) with its uc_link ptr.
*/
err |= __put_user(&frame->uc_transact, &frame->uc.uc_link);
err |= setup_tm_sigcontexts(&frame->uc.uc_mcontext,
&frame->uc_transact.uc_mcontext,
regs, ksig->sig,
NULL,
(unsigned long)ksig->ka.sa.sa_handler);
} else
#endif
{
err |= __put_user(0, &frame->uc.uc_link);
/* 保存当前信号上下文到用户栈空间,后续需要从这里恢复原来的内容 */
err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, ksig->sig,
NULL, (unsigned long)ksig->ka.sa.sa_handler,
1);
}
err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
if (err)
goto badframe;
/* Make sure signal handler doesn't get spurious FP exceptions */
current->thread.fp_state.fpscr = 0;
/* Set up to return from userspace. */
if (vdso64_rt_sigtramp && current->mm->context.vdso_base) {
/* link是函数返回地址LR,信号处理handle执行return后地址,此处使用VDSO */
regs->link = current->mm->context.vdso_base + vdso64_rt_sigtramp;
} else {
err |= setup_trampoline(__NR_rt_sigreturn, &frame->tramp[0]);
if (err)
goto badframe;
regs->link = (unsigned long) &frame->tramp[0];
}
/* Allocate a dummy caller frame for the signal handler. */
/* 在frame再往下构建一个128B的虚拟栈,个人认为是作为安全空隙,避免被踩?*/
newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
err |= put_user(regs->gpr[1], (unsigned long __user *)newsp);
/* Set up "regs" so we "return" to the signal handler. */
if (is_elf2_task()) {
regs->nip = (unsigned long) ksig->ka.sa.sa_handler;
regs->gpr[12] = regs->nip;
} else {
/* Handler is *really* a pointer to the function descriptor for
* the signal routine. The first entry in the function
* descriptor is the entry address of signal and the second
* entry is the TOC value we need to use.
*/
func_descr_t __user *funct_desc_ptr =
(func_descr_t __user *) ksig->ka.sa.sa_handler;
/* 设置regs->nip为用户信号处理函数地址,一旦从内核返回,直接执行 */
err |= get_user(regs->nip, &funct_desc_ptr->entry);
err |= get_user(regs->gpr[2], &funct_desc_ptr->toc);
}
/* enter the signal handler in native-endian mode */
regs->msr &= ~MSR_LE;
regs->msr |= (MSR_KERNEL & MSR_LE);
/* 设置用户信号处理函数的栈地址 */
regs->gpr[1] = newsp;
/* 信号处理函数的第一个入参,信号值 */
regs->gpr[3] = ksig->sig;
regs->result = 0;
if (ksig->ka.sa.sa_flags & SA_SIGINFO) {
/* 如果指定SA_SIGINFO,信号处理函数的第二个入参 */
err |= get_user(regs->gpr[4], (unsigned long __user *)&frame->pinfo);
/* 如果指定SA_SIGINFO,信号处理函数的第三个入参 */
err |= get_user(regs->gpr[5], (unsigned long __user *)&frame->puc);
regs->gpr[6] = (unsigned long) frame;
} else {
regs->gpr[4] = (unsigned long)&frame->uc.uc_mcontext;
}
if (err)
goto badframe;
/* 调试打印原来的oldsp,frame,newsp, 新的link,新的nip */
pr_info("oldsp=%#lx, oldsp=%#lx, frame=%#lx, newsp=%#lx, regs->link=%#lx,regs->nip=%#lx", oldsp, frame, newsp, regs->link,regs->nip);
return 0;
badframe:
if (show_unhandled_signals)
printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
current->comm, current->pid, "setup_rt_frame",
(long)frame, regs->nip, regs->link);
return 1;
}
在handle_rt_signal64增加了打印后,测试用例注册一个信号,信号处理函数使用嵌入汇编方式读取R1寄存器(当前SP),
从当前SP开始打印一堆数据,如下所示。当前SP地址是0x3ffffe75d1c0与newsp又相差144B,为什么呢?请继续往下看。
oldsp=0x3ffffe75dc30, frame=0x3ffffe75d2d0, newsp=0x3ffffe75d250, regs->link=0x3fff8a740478, regs->nip=0x10000964
add=0x3ffffe75d1c0, val=0x3ffffe75d250
add=0x3ffffe75d1c8, val=0x3d8
add=0x3ffffe75d1d0, val=0x100009e4
add=0x3ffffe75d1d8, val=0x400000010
add=0x3ffffe75d1e0, val=0x1474e5500
add=0x3ffffe75d1e8, val=0x100192d8
add=0x3ffffe75d1f0, val=0x600000020
add=0x3ffffe75d1f8, val=0x3ffffe75d1f0
add=0x3ffffe75d200, val=0x3ffffe75d1f0
add=0x3ffffe75d208, val=0x27
add=0x3ffffe75d210, val=0
add=0x3ffffe75d218, val=0x3ffffe75d210
add=0x3ffffe75d220, val=0x3ffffe75d210
add=0x3ffffe75d228, val=0x3ffffe75d1c0
add=0x3ffffe75d230, val=0xe01040200
add=0x3ffffe75d238, val=0x3ffffe75d1c0
add=0x3ffffe75d240, val=0x67406c2d820a1180
add=0x3ffffe75d248, val=0xffffffff
add=0x3ffffe75d250, val=0x3ffffe75dc30
add=0x3ffffe75d258, val=0x2200c081290a042
add=0x3ffffe75d260, val=0x3fff8a740478
add=0x3ffffe75d268, val=0xcc28013980000a0a
add=0x3ffffe75d270, val=0xc28081240818440
add=0x3ffffe75d278, val=0x8008518000000044
add=0x3ffffe75d280, val=0xcd042041d
add=0x3ffffe75d288, val=0x80003018b5000001
add=0x3ffffe75d290, val=0x1041090022100260
add=0x3ffffe75d298, val=0x4712a92850000501
add=0x3ffffe75d2a0, val=0x440980482000028
add=0x3ffffe75d2a8, val=0x240020054e01000
add=0x3ffffe75d2b0, val=0x80164430c11002
add=0x3ffffe75d2b8, val=0x1c00021004240000
add=0x3ffffe75d2c0, val=0x80018000f90a380
add=0x3ffffe75d2c8, val=0x4406280080012010
add=0x3ffffe75d2d0, val=0
add=0x3ffffe75d2d8, val=0
add=0x3ffffe75d2e0, val=0
add=0x3ffffe75d2e8, val=0x2fe75d9e8
add=0x3ffffe75d2f0, val=0
add=0x3ffffe75d2f8, val=0
add=0x3ffffe75d300, val=0
add=0x3ffffe75d308, val=0x3fff8a77ea10
add=0x3ffffe75d310, val=0x3ffffe75d7e0
add=0x3ffffe75d318, val=0x3fff8a534ec8
add=0x3ffffe75d320, val=0x5
add=0x3ffffe75d328, val=0x3ffffe75d7b0
add=0x3ffffe75d330, val=0x3ffffe75d9f8
add=0x3ffffe75d338, val=0x3fff8a77b4d8
add=0x3ffffe75d340, val=0x3ffffe75d810
add=0x3ffffe75d348, val=0x3fff8a55fe10
add=0x3ffffe75d350, val=0x1
add=0x3ffffe75d358, val=0x3fff8a5361fb
add=0x3ffffe75d360, val=0x10
add=0x3ffffe75d368, val=0x3ffffe75d9c0
add=0x3ffffe75d370, val=0x3ffffe75d3f0
add=0x3ffffe75d378, val=0x420042228a70de10
add=0x3ffffe75d380, val=0x3fff8a7592e0
add=0x3ffffe75d388, val=0x3fff8a57eae4
add=0x3ffffe75d390, val=0x18
add=0x3ffffe75d398, val=0xcfe75d9c0
add=0x3ffffe75d3a0, val=0x10011260
add=0x3ffffe75d3a8, val=0x480042228a73de00
add=0x3ffffe75d3b0, val=0x3ffffe75d3b8
add=0x3ffffe75d3b8, val=0xa2
add=0x3ffffe75d3c0, val=0x3ffffe75dc30
add=0x3ffffe75d3c8, val=0x3fff8a727c10
add=0x3ffffe75d3d0, val=0x4
add=0x3ffffe75d3d8, val=0x3ffffe75de38
add=0x3ffffe75d3e0, val=0x88000248
add=0x3ffffe75d3e8, val=0x4000
add=0x3ffffe75d3f0, val=0x3fff8a5c3ef8
add=0x3ffffe75d3f8, val=0x8202f000
add=0x3ffffe75d400, val=0
add=0x3ffffe75d408, val=0
add=0x3ffffe75d410, val=0
add=0x3ffffe75d418, val=0
add=0x3ffffe75d420, val=0x3fff8a780750
add=0x3ffffe75d428, val=0
add=0x3ffffe75d430, val=0
add=0x3ffffe75d438, val=0
add=0x3ffffe75d440, val=0
add=0x3ffffe75d448, val=0
add=0x3ffffe75d450, val=0
add=0x3ffffe75d458, val=0
add=0x3ffffe75d460, val=0
add=0x3ffffe75d468, val=0
add=0x3ffffe75d470, val=0
add=0x3ffffe75d478, val=0
add=0x3ffffe75d480, val=0
add=0x3ffffe75d488, val=0
add=0x3ffffe75d490, val=0x3fff8a77ee20
add=0x3ffffe75d498, val=0x3ffffe75dd38
add=0x3ffffe75d4a0, val=0x10000
add=0x3ffffe75d4a8, val=0x3ffffe75ddb8
add=0x3ffffe75d4b0, val=0xffffffff
add=0x3ffffe75d4b8, val=0x3fff8a648754
add=0x3ffffe75d4c0, val=0x8202d000
add=0x3ffffe75d4c8, val=0x3ffffe75de38
add=0x3ffffe75d4d0, val=0
add=0x3ffffe75d4d8, val=0x3fff8a64854c
add=0x3ffffe75d4e0, val=0
add=0x3ffffe75d4e8, val=0x98000248
add=0x3ffffe75d4f0, val=0x1
add=0x3ffffe75d4f8, val=0xc00
add=0x3ffffe75d500, val=0x3fff8a648440
add=0x3ffffe75d508, val=0
add=0x3ffffe75d510, val=0xfffffffffffffffc
add=0x3ffffe75d518, val=0x3fff8a781b10
add=0x3ffffe75d520, val=0
add=0x3ffffe75d528, val=0x3fff8a781ae8
add=0x3ffffe75d530, val=0x3ffffe75d6a0
add=0x3ffffe75d538, val=0
add=0x3ffffe75d540, val=0
add=0x3ffffe75d548, val=0
add=0x3ffffe75d550, val=0
add=0x3ffffe75d558, val=0
add=0x3ffffe75d560, val=0
add=0x3ffffe75d568, val=0
add=0x3ffffe75d570, val=0
add=0x3ffffe75d578, val=0
add=0x3ffffe75d580, val=0
add=0x3ffffe75d588, val=0
add=0x3ffffe75d590, val=0
add=0x3ffffe75d598, val=0
add=0x3ffffe75d5a0, val=0
add=0x3ffffe75d5a8, val=0
add=0x3ffffe75d5b0, val=0
add=0x3ffffe75d5b8, val=0
add=0x3ffffe75d5c0, val=0
add=0x3ffffe75d5c8, val=0
add=0x3ffffe75d5d0, val=0
add=0x3ffffe75d5d8, val=0
add=0x3ffffe75d5e0, val=0
add=0x3ffffe75d5e8, val=0
add=0x3ffffe75d5f0, val=0
add=0x3ffffe75d5f8, val=0
add=0x3ffffe75d600, val=0
add=0x3ffffe75d608, val=0
add=0x3ffffe75d610, val=0
add=0x3ffffe75d618, val=0
add=0x3ffffe75d620, val=0
add=0x3ffffe75d628, val=0
add=0x3ffffe75d630, val=0
add=0x3ffffe75d638, val=0xfff8000000000000
add=0x3ffffe75d640, val=0x3ffffe75d650
add=0x3ffffe75d648, val=0x3fff8a77b000
add=0x3ffffe75d650, val=0
add=0x3ffffe75d658, val=0
add=0x3ffffe75d660, val=0
add=0x3ffffe75d668, val=0
add=0x3ffffe75d670, val=0
add=0x3ffffe75d678, val=0
add=0x3ffffe75d680, val=0
add=0x3ffffe75d688, val=0
add=0x3ffffe75d690, val=0
add=0x3ffffe75d698, val=0
add=0x3ffffe75d6a0, val=0
add=0x3ffffe75d6a8, val=0
add=0x3ffffe75d6b0, val=0
add=0x3ffffe75d6b8, val=0
add=0x3ffffe75d6c0, val=0
add=0x3ffffe75d6c8, val=0
add=0x3ffffe75d6d0, val=0
add=0x3ffffe75d6d8, val=0
add=0x3ffffe75d6e0, val=0
add=0x3ffffe75d6e8, val=0
add=0x3ffffe75d6f0, val=0
add=0x3ffffe75d6f8, val=0
add=0x3ffffe75d700, val=0
add=0x3ffffe75d708, val=0
add=0x3ffffe75d710, val=0
add=0x3ffffe75d718, val=0
add=0x3ffffe75d720, val=0
add=0x3ffffe75d728, val=0
add=0x3ffffe75d730, val=0
add=0x3ffffe75d738, val=0
add=0x3ffffe75d740, val=0x404040404040404
add=0x3ffffe75d748, val=0x404040404040404
add=0x3ffffe75d750, val=0x1020304050607
add=0x3ffffe75d758, val=0x8090a0b0c0d0e0f
add=0x3ffffe75d760, val=0
add=0x3ffffe75d768, val=0x3fff8a77eea0
add=0x3ffffe75d770, val=0
add=0x3ffffe75d778, val=0
add=0x3ffffe75d780, val=0
add=0x3ffffe75d788, val=0
add=0x3ffffe75d790, val=0
add=0x3ffffe75d798, val=0
add=0x3ffffe75d7a0, val=0
add=0x3ffffe75d7a8, val=0
add=0x3ffffe75d7b0, val=0
add=0x3ffffe75d7b8, val=0
add=0x3ffffe75d7c0, val=0
add=0x3ffffe75d7c8, val=0
add=0x3ffffe75d7d0, val=0
add=0x3ffffe75d7d8, val=0
add=0x3ffffe75d7e0, val=0
add=0x3ffffe75d7e8, val=0
add=0x3ffffe75d7f0, val=0
add=0x3ffffe75d7f8, val=0
add=0x3ffffe75d800, val=0
add=0x3ffffe75d808, val=0
add=0x3ffffe75d810, val=0
add=0x3ffffe75d818, val=0
add=0x3ffffe75d820, val=0
add=0x3ffffe75d828, val=0
add=0x3ffffe75d830, val=0
add=0x3ffffe75d838, val=0
add=0x3ffffe75d840, val=0
add=0x3ffffe75d848, val=0
add=0x3ffffe75d850, val=0
add=0x3ffffe75d858, val=0x10000
add=0x3ffffe75d860, val=0xffffffff00000000
add=0x3ffffe75d868, val=0x3fff8a779000
add=0x3ffffe75d870, val=0x3fff8a779750
add=0x3ffffe75d878, val=0xf
add=0x3ffffe75d880, val=0x3ffffe75d920
add=0x3ffffe75d888, val=0x3ffffe75d940
add=0x3ffffe75d890, val=0x3fff8a747448
add=0x3ffffe75d898, val=0x3fff8a780d60
add=0x3ffffe75d8a0, val=0x3ffffe75d920
add=0x3ffffe75d8a8, val=0xffffffff
add=0x3ffffe75d8b0, val=0
add=0x3ffffe75d8b8, val=0
add=0x3ffffe75d8c0, val=0
add=0x3ffffe75d8c8, val=0
add=0x3ffffe75d8d0, val=0
add=0x3ffffe75d8d8, val=0
add=0x3ffffe75d8e0, val=0
add=0x3ffffe75d8e8, val=0
add=0x3ffffe75d8f0, val=0
add=0x3ffffe75d8f8, val=0
add=0x3ffffe75d900, val=0
add=0x3ffffe75d908, val=0
add=0x3ffffe75d910, val=0x3fff8a5a9e08
add=0x3ffffe75d918, val=0x1b9708
add=0x3ffffe75d920, val=0x3fff8a567000
add=0x3ffffe75d928, val=0x3fff8a720708
add=0x3ffffe75d930, val=0x3ffffe75dee8
add=0x3ffffe75d938, val=0x3fff8a77b000
add=0x3ffffe75d940, val=0x3ffffe75d9f0
add=0x3ffffe75d948, val=0x22000482fe75d950
add=0x3ffffe75d950, val=0x3fff8a75af4c
add=0x3ffffe75d958, val=0x420222448a77d718
add=0x3ffffe75d960, val=0x3fff8a756ffc
add=0x3ffffe75d968, val=0
add=0x3ffffe75d970, val=0x3ffffe75da10
add=0x3ffffe75d978, val=0x3fff8a788278
add=0x3ffffe75d980, val=0x3fff8a7803c8
add=0x3ffffe75d988, val=0x3fff8a788278
add=0x3ffffe75d990, val=0x3ffffe75da10
add=0x3ffffe75d998, val=0x3ffffe75d9a8
add=0x3ffffe75d9a0, val=0x3ffffe75d2d0
add=0x3ffffe75d9a8, val=0xc00000000
add=0x3ffffe75d9b0, val=0xfffffffe8a747448
add=0x3ffffe75d9b8, val=0
add=0x3ffffe75d9c0, val=0
add=0x3ffffe75d9c8, val=0x3ffffe75dbd0
add=0x3ffffe75d9d0, val=0x3fff8a780cd0
add=0x3ffffe75d9d8, val=0x3fff8a7803c8
add=0x3ffffe75d9e0, val=0x3ffffe75dee8
add=0x3ffffe75d9e8, val=0x105cf61e
add=0x3ffffe75d9f0, val=0x7aa
add=0x3ffffe75d9f8, val=0x3fff8a77ba70
add=0x3ffffe75da00, val=0x2
add=0x3ffffe75da08, val=0x3fff8a77b000
add=0x3ffffe75da10, val=0x3ffffe75db80
add=0x3ffffe75da18, val=0x10033000
add=0x3ffffe75da20, val=0x3fff8a754530
add=0x3ffffe75da28, val=0x3ffffe75db70
add=0x3ffffe75da30, val=0x3fff8a77da90
add=0x3ffffe75da38, val=0x1
add=0x3ffffe75da40, val=0x3ffffe75db88
add=0x3ffffe75da48, val=0x3fff8a77d718
add=0x3ffffe75da50, val=0x1
add=0x3ffffe75da58, val=0x3fff8a77bbf0
add=0x3ffffe75da60, val=0x3fff8a714900
add=0x3ffffe75da68, val=0x3ffffe75dbd0
add=0x3ffffe75da70, val=0x3ffffe75dbf0
add=0x3ffffe75da78, val=0x3ffffe75dbd0
add=0x3ffffe75da80, val=0x3ffffe75dc30
add=0x3ffffe75da88, val=0x3ffffe75daa0
add=0x3ffffe75da90, val=0x3ffffe75daa8
add=0x3ffffe75da98, val=0x3fff8a721728
add=0x3ffffe75daa0, val=0
add=0x3ffffe75daa8, val=0
add=0x3ffffe75dab0, val=0
add=0x3ffffe75dab8, val=0
add=0x3ffffe75dac0, val=0
add=0x3ffffe75dac8, val=0
add=0x3ffffe75dad0, val=0x3fff8a77ee20
add=0x3ffffe75dad8, val=0x3fff8a76a5d0
add=0x3ffffe75dae0, val=0x3fff8a56a8b4
add=0x3ffffe75dae8, val=0
add=0x3ffffe75daf0, val=0
add=0x3ffffe75daf8, val=0
add=0x3ffffe75db00, val=0
add=0x3ffffe75db08, val=0
add=0x3ffffe75db10, val=0x3fff8a7803c8
add=0x3ffffe75db18, val=0x3ffffe75dc60
add=0x3ffffe75db20, val=0x3fff8a7818c0
add=0x3ffffe75db28, val=0x1
add=0x3ffffe75db30, val=0x3ffffe75dc78
add=0x3ffffe75db38, val=0x3fff8a781548
add=0x3ffffe75db40, val=0x1
add=0x3ffffe75db48, val=0x3fff8a77bab8
add=0x3ffffe75db50, val=0x3ffffe75dd80
add=0x3ffffe75db58, val=0x10000447
add=0x3ffffe75db60, val=0
add=0x3ffffe75db68, val=0x3fff8a7818c0
add=0x3ffffe75db70, val=0x105cf61e
add=0x3ffffe75db78, val=0x3ffffe75db80
add=0x3ffffe75db80, val=0x3ffffe75dd10
add=0x3ffffe75db88, val=0x22042444ffffffff
add=0x3ffffe75db90, val=0x3fff8a754d7c
add=0x3ffffe75db98, val=0
add=0x3ffffe75dba0, val=0x30
add=0x3ffffe75dba8, val=0x5b
add=0x3ffffe75dbb0, val=0x6e
add=0x3ffffe75dbb8, val=0x77
add=0x3ffffe75dbc0, val=0x3ffffe75dc78
add=0x3ffffe75dbc8, val=0
add=0x3ffffe75dbd0, val=0x3ffffe75dc60
add=0x3ffffe75dbd8, val=0
add=0x3ffffe75dbe0, val=0
add=0x3ffffe75dbe8, val=0
add=0x3ffffe75dbf0, val=0
add=0x3ffffe75dbf8, val=0
add=0x3ffffe75dc00, val=0
add=0x3ffffe75dc08, val=0x3fff8a77ee20
add=0x3ffffe75dc10, val=0x3ffffe75dd38
add=0x3ffffe75dc18, val=0x10000
add=0x3ffffe75dc20, val=0x3ffffe75ddb8
add=0x3ffffe75dc28, val=0xffffffff
add=0x3ffffe75dc30, val=0x3ffffe75de70
add=0x3ffffe75dc38, val=0x3fff8a77ee20
add=0x3ffffe75dc40, val=0x3ffffe75dee0
add=0x3ffffe75dc48, val=0x8
add=0x3ffffe75dc50, val=0x3ffffe75dee8
add=0x3ffffe75dc58, val=0x3fff8a70e9c8
add=0x3ffffe75dc60, val=0x3fff8a576750
add=0x3ffffe75dc68, val=0x3fff8a77b000
add=0x3ffffe75dc70, val=0x3fff8a616b9c
add=0x3ffffe75dc78, val=0xffffffff
其中:oldspp与frame相差0x960B, frame与newsp=128B, regs->link=0x3fff8a740478, regs->nip=0x10000964,NIP指向信号处理函数地址(如下反汇编所示地址0x10000964)
回答上面的问题,当前SP地址是0x3ffffe75d1c0与newsp又相差144B,为什么呢?
看反汇编代码10000970: f8 21 ff 71 stdu r1,-144(r1),可以看到r1又往下增长了144B了(我们的打印在此行之后)。
0000000010000964 <.sig_handler>:
10000964: 7c 08 02 a6 mflr r0
10000968: f8 01 00 10 std r0,16(r1)
1000096c: fb e1 ff f8 std r31,-8(r1)
10000970: f8 21 ff 71 stdu r1,-144(r1)
10000974: 7c 3f 0b 78 mr r31,r1
10000978: 7c 69 1b 78 mr r9,r3
1000097c: 91 3f 00 c0 stw r9,192(r31)
10000980: 39 20 00 00 li r9,0
10000984: 91 3f 00 70 stw r9,112(r31)
10000988: 39 20 00 00 li r9,0
1000098c: f9 3f 00 78 std r9,120(r31)
10000990: 7c 29 0b 78 mr r9,r1
10000994: f9 3f 00 78 std r9,120(r31)
其中:regs->link=0x3fff8a740478用于使用VDSO机制,从本进程maps可以看出VDSO可以看出vdso64_rt_sigtramp的地址是0x0478;regs->nip=0x10000964指向TEXT段的信号处理函数。
root@xxxxx:/proc/2033# cat maps
10000000-10001000 r-xp 00000000 00:16 2291 /var/volatile/timer
10011000-10012000 rw-p 00001000 00:16 2291 /var/volatile/timer
10012000-10033000 rw-p 00000000 00:00 0 [heap]
3fff8a532000-3fff8a550000 r-xp 00000000 01:00 9891 /lib64/libpthread-2.20.so
3fff8a550000-3fff8a55f000 ---p 0001e000 01:00 9891 /lib64/libpthread-2.20.so
3fff8a55f000-3fff8a560000 r--p 0001d000 01:00 9891 /lib64/libpthread-2.20.so
3fff8a560000-3fff8a562000 rw-p 0001e000 01:00 9891 /lib64/libpthread-2.20.so
3fff8a562000-3fff8a567000 rw-p 00000000 00:00 0
3fff8a567000-3fff8a6fb000 r-xp 00000000 01:00 9909 /lib64/libc-2.20.so
3fff8a6fb000-3fff8a70a000 ---p 00194000 01:00 9909 /lib64/libc-2.20.so
3fff8a70a000-3fff8a70e000 r--p 00193000 01:00 9909 /lib64/libc-2.20.so
3fff8a70e000-3fff8a721000 rw-p 00197000 01:00 9909 /lib64/libc-2.20.so
3fff8a721000-3fff8a725000 rw-p 00000000 00:00 0
3fff8a725000-3fff8a72e000 r-xp 00000000 01:00 9906 /lib64/librt-2.20.so
3fff8a72e000-3fff8a73d000 ---p 00009000 01:00 9906 /lib64/librt-2.20.so
3fff8a73d000-3fff8a73e000 r--p 00008000 01:00 9906 /lib64/librt-2.20.so
3fff8a73e000-3fff8a73f000 rw-p 00009000 01:00 9906 /lib64/librt-2.20.so
3fff8a73f000-3fff8a740000 rw-p 00000000 00:00 0
3fff8a740000-3fff8a743000 r-xp 00000000 00:00 0 [vdso]
3fff8a747000-3fff8a76f000 r-xp 00000000 01:00 9930 /lib64/ld-2.20.so
3fff8a779000-3fff8a77d000 rw-p 00000000 00:00 0
3fff8a77d000-3fff8a77e000 rw-p 00000000 00:00 0
3fff8a77e000-3fff8a77f000 r--p 00027000 01:00 9930 /lib64/ld-2.20.so
3fff8a77f000-3fff8a782000 rw-p 00028000 01:00 9930 /lib64/ld-2.20.so
3ffffe73e000-3ffffe75f000 rw-p 00000000 00:00 0 [stack]
root@xxxxx:/proc/2033#
regs->link=0x3fff8a740478用于使用VDSO机制,究竟是执行什么代码呢?
原来是以下代码,从以下代码看出,addi r1, r1, __SIGNAL_FRAMESIZE又把newsp改为到frame。注意当前r1是由于信号处理函数结束blr返回后自动已经改为newsp(r1+144B)了。
V_FUNCTION_BEGIN(__kernel_sigtramp_rt64)
.Lsigrt_start = . - 4
addi r1, r1, __SIGNAL_FRAMESIZE
li r0,__NR_rt_sigreturn
sc
.Lsigrt_end:
V_FUNCTION_END(__kernel_sigtramp_rt64)
通过sc系统调用,执行以下代码
int sys_rt_sigreturn(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7, unsigned long r8,
struct pt_regs *regs)
{
/* 当前gpr[1]就是上次frame,frame结构体第一个元素就是uc,因此强转换没有问题 */
struct ucontext __user *uc = (struct ucontext __user *)regs->gpr[1];
sigset_t set;
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
unsigned long msr;
#endif
/* Always make any pending restarted system calls return -EINTR */
current->restart_block.fn = do_no_restart_syscall;
if (!access_ok(VERIFY_READ, uc, sizeof(*uc)))
goto badframe;
if (__copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
goto badframe;
set_current_blocked(&set);
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
if (__get_user(msr, &uc->uc_mcontext.gp_regs[PT_MSR]))
goto badframe;
if (MSR_TM_ACTIVE(msr)) {
/* We recheckpoint on return. */
struct ucontext __user *uc_transact;
if (__get_user(uc_transact, &uc->uc_link))
goto badframe;
if (restore_tm_sigcontexts(regs, &uc->uc_mcontext,
&uc_transact->uc_mcontext))
goto badframe;
}
else
/* Fall through, for non-TM restore */
#endif
/* 恢复信号上下文 */
if (restore_sigcontext(regs, NULL, 1, &uc->uc_mcontext))
goto badframe;
/* 恢复栈指针内容 */
if (restore_altstack(&uc->uc_stack))
goto badframe;
set_thread_flag(TIF_RESTOREALL);
return 0;
badframe:
if (show_unhandled_signals)
printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
current->comm, current->pid, "rt_sigreturn",
(long)uc, regs->nip, regs->link);
force_sig(SIGSEGV, current);
return 0;
}
总结:内核的信号处理机制效率并不高,因为__kernel_sigtramp_rt64返回再次进入内核时,内核从用户态栈空间还原出原始的pt_regs,准备返回用户态时,又重新检测有没有pending信号,一旦有,又得执行信号处理函数又需要构建frame,不停地循环,因此效率堪忧。
有空再补充一个栈变化图。