]> Zhao Yanbai Git Server - minix.git/commitdiff
arm: make signal handlers work
authorBen Gras <ben@minix3.org>
Wed, 30 Jan 2013 02:13:24 +0000 (03:13 +0100)
committerBen Gras <ben@minix3.org>
Wed, 30 Jan 2013 04:10:12 +0000 (04:10 +0000)
A few kernel and calling convention adjustments to make sigsend and
sigreturn work for arm.

. provide a arch_proc_setcontext for earm in kernel
. set LR in context of signal handler to provide a proper
  return address (to __sigreturn)
. change __sigreturn to retrieve the sigcontext pointer
  from the sigframe struct and pass it to _sigreturn() in r0

Change-Id: Icd135a70595382c79d11d8dd9876f6a6f1df41f8

kernel/arch/earm/arch_system.c
kernel/system/do_sigsend.c
lib/libc/arch/arm/sys-minix/__sigreturn.S

index 4db5fdbe3ffff36b3752b95a9b204c171c1f3ce0..7d83573614e3782f8da575534565fa12a50a5e87 100644 (file)
@@ -52,6 +52,19 @@ void arch_proc_reset(struct proc *pr)
 void arch_proc_setcontext(struct proc *p, struct stackframe_s *state,
        int isuser, int trapstyle)
 {
+        assert(sizeof(p->p_reg) == sizeof(*state));
+        memcpy(&p->p_reg, state, sizeof(*state));
+
+        /* further code is instructed to not touch the context
+         * any more
+         */
+        p->p_misc_flags |= MF_CONTEXT_SET;
+
+        if(!(p->p_rts_flags)) {
+                printf("WARNINIG: setting full context of runnable process\n");
+                print_proc(p);
+                util_stacktrace();
+        }
 }
 
 void arch_set_secondary_ipc_return(struct proc *p, u32_t val)
index bbf21149de07645b62e30ea44f1c728f81884914..ddb8db93ca3936c5a107031061f6e8a3e989380f 100644 (file)
@@ -81,6 +81,13 @@ int do_sigsend(struct proc * caller, message * m_ptr)
   fr.sf_signo = smsg.sm_signo;
   fr.sf_retadr = (void (*)()) smsg.sm_sigreturn;
 
+#if defined(__arm__)
+  /* use the ARM link register to set the return address from the signal
+   * handler
+   */
+  rp->p_reg.lr = (reg_t) fr.sf_retadr;
+#endif
+
   /* Copy the sigframe structure to the user's stack. */
   if((r=data_copy_vmcheck(caller, KERNEL, (vir_bytes) &fr,
        m_ptr->SIG_ENDPT, (vir_bytes) frp, 
index 9d3f2617008c63b70b5e29fabe025073d4f1553e..9eee416358a8d363664e3c416a6a5b220c39921e 100644 (file)
@@ -5,5 +5,6 @@
 
 IMPORT(_sigreturn)
 ENTRY(__sigreturn)
-       add     sp, sp, #16
-       b       _C_LABEL(_sigreturn)
+       add     sp, sp, #24     /* make sp point to sigframe.sf_scpcopy */
+       pop     {r0}            /* load it into r0 as parameter */
+       b       _C_LABEL(_sigreturn)    /* _sigreturn(struct sigcontext *sf_scpcopy) */