static int
setup_return(struct pt_regs *regs, struct k_sigaction *ka,
unsigned long __user *rc, void __user *frame, int usig)
{
unsigned long handler = (unsigned long)ka->sa.sa_handler;
unsigned long retcode;
int thumb = 0;
unsigned long cpsr = regs->ARM_cpsr & ~PSR_f;
/*
* Maybe we need to deliver a 32-bit signal to a 26-bit task.
*/
if (ka->sa.sa_flags & SA_THIRTYTWO)
cpsr = (cpsr & ~MODE_MASK) | USR_MODE;
#ifdef CONFIG_ARM_THUMB
if (elf_hwcap & HWCAP_THUMB) {
/*
* The LSB of the handler determines if we're going to
* be using THUMB or ARM mode for this signal handler.
*/
thumb = handler & 1;
if (thumb)
cpsr |= PSR_T_BIT;
else
cpsr &= ~PSR_T_BIT;
}
#endif
//这里的retcode就是保存手工构造的sigreturn()代码
if (ka->sa.sa_flags & SA_RESTORER) {
retcode = (unsigned long)ka->sa.sa_restorer;
} else {
unsigned int idx = thumb;
if (ka->sa.sa_flags & SA_SIGINFO)
idx += 2;
if (__put_user(sigreturn_codes[idx], rc))
return 1;
if (cpsr & MODE32_BIT) {
/*
* 32-bit code can use the new high-page
* signal return code support.
*/
retcode = KERN_SIGRETURN_CODE + (idx << 2) + thumb;
} else {
/*
* Ensure that the instruction cache sees
* the return code written onto the stack.
*/
flush_icache_range((unsigned long)rc,
(unsigned long)(rc + 1));
retcode = ((unsigned long)rc) + thumb;
}
}
regs->ARM_r0 = usig;
regs->ARM_sp = (unsigned long)frame;//堆栈
regs->ARM_lr = retcode;//返回地址,当用户态信号处理函数结束时,就会把这个地址作为返回地址
regs->ARM_pc = handler;//信号处理函数
regs->ARM_cpsr = cpsr;
return 0;
}