diff --git a/kernel/arch/earm/arch_system.c b/kernel/arch/earm/arch_system.c index 4db5fdbe3..7d8357361 100644 --- a/kernel/arch/earm/arch_system.c +++ b/kernel/arch/earm/arch_system.c @@ -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) diff --git a/kernel/system/do_sigsend.c b/kernel/system/do_sigsend.c index bbf21149d..ddb8db93c 100644 --- a/kernel/system/do_sigsend.c +++ b/kernel/system/do_sigsend.c @@ -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, diff --git a/lib/libc/arch/arm/sys-minix/__sigreturn.S b/lib/libc/arch/arm/sys-minix/__sigreturn.S index 9d3f26170..9eee41635 100644 --- a/lib/libc/arch/arm/sys-minix/__sigreturn.S +++ b/lib/libc/arch/arm/sys-minix/__sigreturn.S @@ -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) */