Linux????е???????????????
???????????? ???????[ 2013/2/25 10:12:12 ] ????????
????get_sigframe()??????????????sp-sizeof(struct sigframe)???????????????????????洢???????????????????sp+sizeof(struct sigframe)?????
?????????????????????????do_signal()????????????????????????????do_signal()?????handle_signal()??handle_signal()??????setup_frame()????setup_rt_frame()????????????????????????setup_frame()??????н?????????
static int
setup_frame(int usig?? struct k_sigaction *ka?? sigset_t *set?? struct pt_regs *regs)
{
//?????????????????sigframe??
struct sigframe __user *frame = get_sigframe(ka?? regs?? sizeof(*frame));
int err = 0;
if (!frame)
return 1;
//????????????????????????????sigframe????
err |= setup_sigcontext(&frame->sc?? &frame->aux?? regs?? set->sig[0]);
if (_NSIG_WORDS > 1) {
err |= __copy_to_user(frame->extramask?? &set->sig[1]??
sizeof(frame->extramask));
}
if (err == 0)
err = setup_return(regs?? ka?? &frame->retcode?? frame?? usig);
return err;
}
????setup_return()???÷??????????????£?
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
<SPAN style="WHITE-SPACE: pre"> </SPAN>//?????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;
}
??????setup_frame()?????????????????????????????????????????????????????????????????????????????????????retcode??ν????????????????????retcode????δ????????????????glibc(2.3.2)??
#include <sysdep.h>
/* If no SA_RESTORER function was specified by the application we use
one of these. This avoids the need for the kernel to synthesise a return
instruction on the stack?? which would involve expensive cache flushes. */
ENTRY(__default_sa_restorer)
swi SYS_ify(sigreturn)
#ifdef __NR_rt_sigreturn
ENTRY(__default_rt_sa_restorer)
swi SYS_ify(rt_sigreturn)
#define SYS_ify(syscall_name) (__NR_##syscall_name)
??????
???·???
??????????????????
2023/3/23 14:23:39???д?ò??????????
2023/3/22 16:17:39????????????????????Щ??
2022/6/14 16:14:27??????????????????????????
2021/10/18 15:37:44???????????????
2021/9/17 15:19:29???·???????·
2021/9/14 15:42:25?????????????
2021/5/28 17:25:47??????APP??????????
2021/5/8 17:01:11