2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
6 #include "linux/signal.h"
7 #include "linux/ptrace.h"
8 #include "asm/current.h"
9 #include "asm/ucontext.h"
10 #include "asm/uaccess.h"
11 #include "asm/unistd.h"
12 #include "frame_kern.h"
13 #include "sigcontext.h"
14 #include "registers.h"
17 #ifdef CONFIG_MODE_SKAS
21 void copy_sc(union uml_pt_regs
*regs
, void *from
)
23 struct sigcontext
*sc
= from
;
25 REGS_GS(regs
->skas
.regs
) = sc
->gs
;
26 REGS_FS(regs
->skas
.regs
) = sc
->fs
;
27 REGS_ES(regs
->skas
.regs
) = sc
->es
;
28 REGS_DS(regs
->skas
.regs
) = sc
->ds
;
29 REGS_EDI(regs
->skas
.regs
) = sc
->edi
;
30 REGS_ESI(regs
->skas
.regs
) = sc
->esi
;
31 REGS_EBP(regs
->skas
.regs
) = sc
->ebp
;
32 REGS_SP(regs
->skas
.regs
) = sc
->esp
;
33 REGS_EBX(regs
->skas
.regs
) = sc
->ebx
;
34 REGS_EDX(regs
->skas
.regs
) = sc
->edx
;
35 REGS_ECX(regs
->skas
.regs
) = sc
->ecx
;
36 REGS_EAX(regs
->skas
.regs
) = sc
->eax
;
37 REGS_IP(regs
->skas
.regs
) = sc
->eip
;
38 REGS_CS(regs
->skas
.regs
) = sc
->cs
;
39 REGS_EFLAGS(regs
->skas
.regs
) = sc
->eflags
;
40 REGS_SS(regs
->skas
.regs
) = sc
->ss
;
43 static int copy_sc_from_user_skas(struct pt_regs
*regs
,
44 struct sigcontext __user
*from
)
47 unsigned long fpregs
[HOST_FP_SIZE
];
50 err
= copy_from_user(&sc
, from
, sizeof(sc
));
51 err
|= copy_from_user(fpregs
, sc
.fpstate
, sizeof(fpregs
));
55 copy_sc(®s
->regs
, &sc
);
57 err
= restore_fp_registers(userspace_pid
[0], fpregs
);
59 printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
60 "errno = %d\n", -err
);
67 int copy_sc_to_user_skas(struct sigcontext __user
*to
, struct _fpstate __user
*to_fp
,
68 struct pt_regs
*regs
, unsigned long sp
)
71 unsigned long fpregs
[HOST_FP_SIZE
];
72 struct faultinfo
* fi
= ¤t
->thread
.arch
.faultinfo
;
75 sc
.gs
= REGS_GS(regs
->regs
.skas
.regs
);
76 sc
.fs
= REGS_FS(regs
->regs
.skas
.regs
);
77 sc
.es
= REGS_ES(regs
->regs
.skas
.regs
);
78 sc
.ds
= REGS_DS(regs
->regs
.skas
.regs
);
79 sc
.edi
= REGS_EDI(regs
->regs
.skas
.regs
);
80 sc
.esi
= REGS_ESI(regs
->regs
.skas
.regs
);
81 sc
.ebp
= REGS_EBP(regs
->regs
.skas
.regs
);
83 sc
.ebx
= REGS_EBX(regs
->regs
.skas
.regs
);
84 sc
.edx
= REGS_EDX(regs
->regs
.skas
.regs
);
85 sc
.ecx
= REGS_ECX(regs
->regs
.skas
.regs
);
86 sc
.eax
= REGS_EAX(regs
->regs
.skas
.regs
);
87 sc
.eip
= REGS_IP(regs
->regs
.skas
.regs
);
88 sc
.cs
= REGS_CS(regs
->regs
.skas
.regs
);
89 sc
.eflags
= REGS_EFLAGS(regs
->regs
.skas
.regs
);
90 sc
.esp_at_signal
= regs
->regs
.skas
.regs
[UESP
];
91 sc
.ss
= regs
->regs
.skas
.regs
[SS
];
93 sc
.err
= fi
->error_code
;
94 sc
.trapno
= fi
->trap_no
;
96 err
= save_fp_registers(userspace_pid
[0], fpregs
);
98 printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
102 to_fp
= (to_fp
? to_fp
: (struct _fpstate __user
*) (to
+ 1));
108 return copy_to_user(to
, &sc
, sizeof(sc
)) ||
109 copy_to_user(to_fp
, fpregs
, sizeof(fpregs
));
113 #ifdef CONFIG_MODE_TT
115 /* These copy a sigcontext to/from userspace. They copy the fpstate pointer,
116 * blowing away the old, good one. So, that value is saved, and then restored
117 * after the sigcontext copy. In copy_from, the variable holding the saved
118 * fpstate pointer, and the sigcontext that it should be restored to are both
119 * in the kernel, so we can just restore using an assignment. In copy_to, the
120 * saved pointer is in the kernel, but the sigcontext is in userspace, so we
123 int copy_sc_from_user_tt(struct sigcontext
*to
, struct sigcontext __user
*from
,
126 struct _fpstate
*to_fp
;
127 struct _fpstate __user
*from_fp
;
133 err
= copy_from_user(to
, from
, sizeof(*to
));
134 from_fp
= to
->fpstate
;
138 err
|= copy_from_user(to_fp
, from_fp
, fpsize
);
142 int copy_sc_to_user_tt(struct sigcontext __user
*to
, struct _fpstate __user
*fp
,
143 struct sigcontext
*from
, int fpsize
, unsigned long sp
)
145 struct _fpstate __user
*to_fp
;
146 struct _fpstate
*from_fp
;
149 to_fp
= (fp
? fp
: (struct _fpstate __user
*) (to
+ 1));
150 from_fp
= from
->fpstate
;
151 err
= copy_to_user(to
, from
, sizeof(*to
));
153 /* The SP in the sigcontext is the updated one for the signal
154 * delivery. The sp passed in is the original, and this needs
155 * to be restored, so we stick it in separately.
157 err
|= copy_to_user(&SC_SP(to
), &sp
, sizeof(sp
));
160 err
|= copy_to_user(&to
->fpstate
, &to_fp
, sizeof(to
->fpstate
));
161 err
|= copy_to_user(to_fp
, from_fp
, fpsize
);
167 static int copy_sc_from_user(struct pt_regs
*to
, void __user
*from
)
171 ret
= CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to
->regs
), from
,
172 sizeof(struct _fpstate
)),
173 copy_sc_from_user_skas(to
, from
));
177 static int copy_sc_to_user(struct sigcontext __user
*to
, struct _fpstate __user
*fp
,
178 struct pt_regs
*from
, unsigned long sp
)
180 return CHOOSE_MODE(copy_sc_to_user_tt(to
, fp
, UPT_SC(&from
->regs
),
182 copy_sc_to_user_skas(to
, fp
, from
, sp
));
185 static int copy_ucontext_to_user(struct ucontext __user
*uc
, struct _fpstate __user
*fp
,
186 sigset_t
*set
, unsigned long sp
)
190 err
|= put_user(current
->sas_ss_sp
, &uc
->uc_stack
.ss_sp
);
191 err
|= put_user(sas_ss_flags(sp
), &uc
->uc_stack
.ss_flags
);
192 err
|= put_user(current
->sas_ss_size
, &uc
->uc_stack
.ss_size
);
193 err
|= copy_sc_to_user(&uc
->uc_mcontext
, fp
, ¤t
->thread
.regs
, sp
);
194 err
|= copy_to_user(&uc
->uc_sigmask
, set
, sizeof(*set
));
200 char __user
*pretcode
;
202 struct sigcontext sc
;
203 struct _fpstate fpstate
;
204 unsigned long extramask
[_NSIG_WORDS
-1];
210 char __user
*pretcode
;
212 struct siginfo __user
*pinfo
;
216 struct _fpstate fpstate
;
220 int setup_signal_stack_sc(unsigned long stack_top
, int sig
,
221 struct k_sigaction
*ka
, struct pt_regs
*regs
,
224 struct sigframe __user
*frame
;
225 void __user
*restorer
;
226 unsigned long save_sp
= PT_REGS_SP(regs
);
229 /* This is the same calculation as i386 - ((sp + 4) & 15) == 0 */
230 stack_top
= ((stack_top
+ 4) & -16UL) - 4;
231 frame
= (struct sigframe __user
*) stack_top
- 1;
232 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
235 restorer
= frame
->retcode
;
236 if(ka
->sa
.sa_flags
& SA_RESTORER
)
237 restorer
= ka
->sa
.sa_restorer
;
239 /* Update SP now because the page fault handler refuses to extend
240 * the stack if the faulting address is too far below the current
241 * SP, which frame now certainly is. If there's an error, the original
242 * value is restored on the way out.
243 * When writing the sigcontext to the stack, we have to write the
244 * original value, so that's passed to copy_sc_to_user, which does
245 * the right thing with it.
247 PT_REGS_SP(regs
) = (unsigned long) frame
;
249 err
|= __put_user(restorer
, &frame
->pretcode
);
250 err
|= __put_user(sig
, &frame
->sig
);
251 err
|= copy_sc_to_user(&frame
->sc
, NULL
, regs
, save_sp
);
252 err
|= __put_user(mask
->sig
[0], &frame
->sc
.oldmask
);
254 err
|= __copy_to_user(&frame
->extramask
, &mask
->sig
[1],
255 sizeof(frame
->extramask
));
258 * This is popl %eax ; movl $,%eax ; int $0x80
260 * WE DO NOT USE IT ANY MORE! It's only left here for historical
261 * reasons and because gdb uses it as a signature to notice
262 * signal handler stack frames.
264 err
|= __put_user(0xb858, (short __user
*)(frame
->retcode
+0));
265 err
|= __put_user(__NR_sigreturn
, (int __user
*)(frame
->retcode
+2));
266 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+6));
271 PT_REGS_SP(regs
) = (unsigned long) frame
;
272 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
273 PT_REGS_EAX(regs
) = (unsigned long) sig
;
274 PT_REGS_EDX(regs
) = (unsigned long) 0;
275 PT_REGS_ECX(regs
) = (unsigned long) 0;
277 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
278 ptrace_notify(SIGTRAP
);
282 PT_REGS_SP(regs
) = save_sp
;
286 int setup_signal_stack_si(unsigned long stack_top
, int sig
,
287 struct k_sigaction
*ka
, struct pt_regs
*regs
,
288 siginfo_t
*info
, sigset_t
*mask
)
290 struct rt_sigframe __user
*frame
;
291 void __user
*restorer
;
292 unsigned long save_sp
= PT_REGS_SP(regs
);
296 frame
= (struct rt_sigframe __user
*) stack_top
- 1;
297 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
300 restorer
= frame
->retcode
;
301 if(ka
->sa
.sa_flags
& SA_RESTORER
)
302 restorer
= ka
->sa
.sa_restorer
;
304 /* See comment above about why this is here */
305 PT_REGS_SP(regs
) = (unsigned long) frame
;
307 err
|= __put_user(restorer
, &frame
->pretcode
);
308 err
|= __put_user(sig
, &frame
->sig
);
309 err
|= __put_user(&frame
->info
, &frame
->pinfo
);
310 err
|= __put_user(&frame
->uc
, &frame
->puc
);
311 err
|= copy_siginfo_to_user(&frame
->info
, info
);
312 err
|= copy_ucontext_to_user(&frame
->uc
, &frame
->fpstate
, mask
,
316 * This is movl $,%eax ; int $0x80
318 * WE DO NOT USE IT ANY MORE! It's only left here for historical
319 * reasons and because gdb uses it as a signature to notice
320 * signal handler stack frames.
322 err
|= __put_user(0xb8, (char __user
*)(frame
->retcode
+0));
323 err
|= __put_user(__NR_rt_sigreturn
, (int __user
*)(frame
->retcode
+1));
324 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+5));
329 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
330 PT_REGS_EAX(regs
) = (unsigned long) sig
;
331 PT_REGS_EDX(regs
) = (unsigned long) &frame
->info
;
332 PT_REGS_ECX(regs
) = (unsigned long) &frame
->uc
;
334 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
335 ptrace_notify(SIGTRAP
);
339 PT_REGS_SP(regs
) = save_sp
;
343 long sys_sigreturn(struct pt_regs regs
)
345 unsigned long sp
= PT_REGS_SP(¤t
->thread
.regs
);
346 struct sigframe __user
*frame
= (struct sigframe __user
*)(sp
- 8);
348 struct sigcontext __user
*sc
= &frame
->sc
;
349 unsigned long __user
*oldmask
= &sc
->oldmask
;
350 unsigned long __user
*extramask
= frame
->extramask
;
351 int sig_size
= (_NSIG_WORDS
- 1) * sizeof(unsigned long);
353 if(copy_from_user(&set
.sig
[0], oldmask
, sizeof(set
.sig
[0])) ||
354 copy_from_user(&set
.sig
[1], extramask
, sig_size
))
357 sigdelsetmask(&set
, ~_BLOCKABLE
);
359 spin_lock_irq(¤t
->sighand
->siglock
);
360 current
->blocked
= set
;
362 spin_unlock_irq(¤t
->sighand
->siglock
);
364 if(copy_sc_from_user(¤t
->thread
.regs
, sc
))
367 /* Avoid ERESTART handling */
368 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
369 return PT_REGS_SYSCALL_RET(¤t
->thread
.regs
);
372 force_sig(SIGSEGV
, current
);
376 long sys_rt_sigreturn(struct pt_regs regs
)
378 unsigned long sp
= PT_REGS_SP(¤t
->thread
.regs
);
379 struct rt_sigframe __user
*frame
= (struct rt_sigframe __user
*) (sp
- 4);
381 struct ucontext __user
*uc
= &frame
->uc
;
382 int sig_size
= _NSIG_WORDS
* sizeof(unsigned long);
384 if(copy_from_user(&set
, &uc
->uc_sigmask
, sig_size
))
387 sigdelsetmask(&set
, ~_BLOCKABLE
);
389 spin_lock_irq(¤t
->sighand
->siglock
);
390 current
->blocked
= set
;
392 spin_unlock_irq(¤t
->sighand
->siglock
);
394 if(copy_sc_from_user(¤t
->thread
.regs
, &uc
->uc_mcontext
))
397 /* Avoid ERESTART handling */
398 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
399 return PT_REGS_SYSCALL_RET(¤t
->thread
.regs
);
402 force_sig(SIGSEGV
, current
);