1 /* The kernel call that is implemented in this file:
4 * The parameters for this kernel call are:
5 * m_sigcalls.endpt # process to call signal handler
6 * m_sigcalls.sigctx # pointer to sigcontext structure
10 #include "kernel/system.h"
16 /*===========================================================================*
18 *===========================================================================*/
19 int do_sigsend(struct proc
* caller
, message
* m_ptr
)
21 /* Handle sys_sigsend, POSIX-style signal handling. */
24 register struct proc
*rp
;
25 struct sigframe_sigcontext fr
, *frp
;
28 if (!isokendpt(m_ptr
->m_sigcalls
.endpt
, &proc_nr
)) return EINVAL
;
29 if (iskerneln(proc_nr
)) return EPERM
;
30 rp
= proc_addr(proc_nr
);
32 /* Get the sigmsg structure into our address space. */
33 if ((r
= data_copy_vmcheck(caller
, caller
->p_endpoint
,
34 (vir_bytes
)m_ptr
->m_sigcalls
.sigctx
, KERNEL
,
35 (vir_bytes
)&smsg
, (phys_bytes
) sizeof(struct sigmsg
))) != OK
)
38 /* Compute the user stack pointer where sigframe will start. */
39 smsg
.sm_stkptr
= arch_get_sp(rp
);
40 frp
= (struct sigframe_sigcontext
*) smsg
.sm_stkptr
- 1;
42 /* Copy the registers to the sigcontext structure. */
43 memset(&fr
, 0, sizeof(fr
));
44 fr
.sf_scp
= &frp
->sf_sc
;
47 fr
.sf_sc
.sc_gs
= rp
->p_reg
.gs
;
48 fr
.sf_sc
.sc_fs
= rp
->p_reg
.fs
;
49 fr
.sf_sc
.sc_es
= rp
->p_reg
.es
;
50 fr
.sf_sc
.sc_ds
= rp
->p_reg
.ds
;
51 fr
.sf_sc
.sc_edi
= rp
->p_reg
.di
;
52 fr
.sf_sc
.sc_esi
= rp
->p_reg
.si
;
53 fr
.sf_sc
.sc_ebp
= rp
->p_reg
.fp
;
54 fr
.sf_sc
.sc_ebx
= rp
->p_reg
.bx
;
55 fr
.sf_sc
.sc_edx
= rp
->p_reg
.dx
;
56 fr
.sf_sc
.sc_ecx
= rp
->p_reg
.cx
;
57 fr
.sf_sc
.sc_eax
= rp
->p_reg
.retreg
;
58 fr
.sf_sc
.sc_eip
= rp
->p_reg
.pc
;
59 fr
.sf_sc
.sc_cs
= rp
->p_reg
.cs
;
60 fr
.sf_sc
.sc_eflags
= rp
->p_reg
.psw
;
61 fr
.sf_sc
.sc_esp
= rp
->p_reg
.sp
;
62 fr
.sf_sc
.sc_ss
= rp
->p_reg
.ss
;
63 fr
.sf_fp
= rp
->p_reg
.fp
;
64 fr
.sf_signum
= smsg
.sm_signo
;
65 rp
->p_reg
.fp
= (reg_t
) &frp
->sf_fp
;
66 fr
.sf_scpcopy
= fr
.sf_scp
;
67 fr
.sf_ra_sigreturn
= smsg
.sm_sigreturn
;
68 fr
.sf_ra
= rp
->p_reg
.pc
;
70 fr
.sf_sc
.trap_style
= rp
->p_seg
.p_kern_trap_style
;
72 if (fr
.sf_sc
.trap_style
== KTS_NONE
) {
73 printf("do_sigsend: sigsend an unsaved process\n");
77 if (proc_used_fpu(rp
)) {
78 /* save the FPU context before saving it to the sig context */
80 memcpy(&fr
.sf_sc
.sc_fpu_state
, rp
->p_seg
.fpu_state
, FPU_XFP_SIZE
);
85 fr
.sf_sc
.sc_spsr
= rp
->p_reg
.psr
;
86 fr
.sf_sc
.sc_r0
= rp
->p_reg
.retreg
;
87 fr
.sf_sc
.sc_r1
= rp
->p_reg
.r1
;
88 fr
.sf_sc
.sc_r2
= rp
->p_reg
.r2
;
89 fr
.sf_sc
.sc_r3
= rp
->p_reg
.r3
;
90 fr
.sf_sc
.sc_r4
= rp
->p_reg
.r4
;
91 fr
.sf_sc
.sc_r5
= rp
->p_reg
.r5
;
92 fr
.sf_sc
.sc_r6
= rp
->p_reg
.r6
;
93 fr
.sf_sc
.sc_r7
= rp
->p_reg
.r7
;
94 fr
.sf_sc
.sc_r8
= rp
->p_reg
.r8
;
95 fr
.sf_sc
.sc_r9
= rp
->p_reg
.r9
;
96 fr
.sf_sc
.sc_r10
= rp
->p_reg
.r10
;
97 fr
.sf_sc
.sc_r11
= rp
->p_reg
.fp
;
98 fr
.sf_sc
.sc_r12
= rp
->p_reg
.r12
;
99 fr
.sf_sc
.sc_usr_sp
= rp
->p_reg
.sp
;
100 fr
.sf_sc
.sc_usr_lr
= rp
->p_reg
.lr
;
101 fr
.sf_sc
.sc_svc_lr
= 0; /* ? */
102 fr
.sf_sc
.sc_pc
= rp
->p_reg
.pc
; /* R15 */
105 /* Finish the sigcontext initialization. */
106 fr
.sf_sc
.sc_mask
= smsg
.sm_mask
;
107 fr
.sf_sc
.sc_flags
= rp
->p_misc_flags
& MF_FPU_INITIALIZED
;
108 fr
.sf_sc
.sc_magic
= SC_MAGIC
;
110 /* Initialize the sigframe structure. */
112 fpu_sigcontext(rp
, &fr
, &fr
.sf_sc
);
115 /* use the ARM link register to set the return address from the signal
118 rp
->p_reg
.lr
= (reg_t
) smsg
.sm_sigreturn
;
119 if(rp
->p_reg
.lr
& 1) { printf("sigsend: LSB LR makes no sense.\n"); }
121 /* pass signal handler parameters in registers */
122 rp
->p_reg
.retreg
= (reg_t
) smsg
.sm_signo
;
123 rp
->p_reg
.r1
= 0; /* sf_code */
124 rp
->p_reg
.r2
= (reg_t
) fr
.sf_scp
;
125 rp
->p_misc_flags
|= MF_CONTEXT_SET
;
128 /* Copy the sigframe structure to the user's stack. */
129 if ((r
= data_copy_vmcheck(caller
, KERNEL
, (vir_bytes
)&fr
,
130 m_ptr
->m_sigcalls
.endpt
, (vir_bytes
)frp
,
131 (vir_bytes
)sizeof(struct sigframe_sigcontext
))) != OK
)
134 /* Reset user registers to execute the signal handler. */
135 rp
->p_reg
.sp
= (reg_t
) frp
;
136 rp
->p_reg
.pc
= (reg_t
) smsg
.sm_sighandler
;
138 /* Signal handler should get clean FPU. */
139 rp
->p_misc_flags
&= ~MF_FPU_INITIALIZED
;
141 if(!RTS_ISSET(rp
, RTS_PROC_STOP
)) {
142 printf("system: warning: sigsend a running process\n");
143 printf("caller stack: ");
144 proc_stacktrace(caller
);
150 #endif /* USE_SIGSEND */