????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)