arm: make signal handlers work

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
This commit is contained in:
Ben Gras 2013-01-30 03:13:24 +01:00
parent b6d285faba
commit e3e5cf6d34
3 changed files with 23 additions and 2 deletions

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

View 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,

View 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) */