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 "signal_user.h"
14 #include "sigcontext.h"
15 #include "registers.h"
18 #ifdef CONFIG_MODE_SKAS
22 static int copy_sc_from_user_skas(struct pt_regs
*regs
,
23 struct sigcontext
*from
)
26 unsigned long fpregs
[HOST_FP_SIZE
];
29 err
= copy_from_user(&sc
, from
, sizeof(sc
));
30 err
|= copy_from_user(fpregs
, sc
.fpstate
, sizeof(fpregs
));
34 REGS_GS(regs
->regs
.skas
.regs
) = sc
.gs
;
35 REGS_FS(regs
->regs
.skas
.regs
) = sc
.fs
;
36 REGS_ES(regs
->regs
.skas
.regs
) = sc
.es
;
37 REGS_DS(regs
->regs
.skas
.regs
) = sc
.ds
;
38 REGS_EDI(regs
->regs
.skas
.regs
) = sc
.edi
;
39 REGS_ESI(regs
->regs
.skas
.regs
) = sc
.esi
;
40 REGS_EBP(regs
->regs
.skas
.regs
) = sc
.ebp
;
41 REGS_SP(regs
->regs
.skas
.regs
) = sc
.esp
;
42 REGS_EBX(regs
->regs
.skas
.regs
) = sc
.ebx
;
43 REGS_EDX(regs
->regs
.skas
.regs
) = sc
.edx
;
44 REGS_ECX(regs
->regs
.skas
.regs
) = sc
.ecx
;
45 REGS_EAX(regs
->regs
.skas
.regs
) = sc
.eax
;
46 REGS_IP(regs
->regs
.skas
.regs
) = sc
.eip
;
47 REGS_CS(regs
->regs
.skas
.regs
) = sc
.cs
;
48 REGS_EFLAGS(regs
->regs
.skas
.regs
) = sc
.eflags
;
49 REGS_SS(regs
->regs
.skas
.regs
) = sc
.ss
;
51 err
= restore_fp_registers(userspace_pid
[0], fpregs
);
53 printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, "
61 int copy_sc_to_user_skas(struct sigcontext
*to
, struct _fpstate
*to_fp
,
65 unsigned long fpregs
[HOST_FP_SIZE
];
66 struct faultinfo
* fi
= ¤t
->thread
.arch
.faultinfo
;
69 sc
.gs
= REGS_GS(regs
->regs
.skas
.regs
);
70 sc
.fs
= REGS_FS(regs
->regs
.skas
.regs
);
71 sc
.es
= REGS_ES(regs
->regs
.skas
.regs
);
72 sc
.ds
= REGS_DS(regs
->regs
.skas
.regs
);
73 sc
.edi
= REGS_EDI(regs
->regs
.skas
.regs
);
74 sc
.esi
= REGS_ESI(regs
->regs
.skas
.regs
);
75 sc
.ebp
= REGS_EBP(regs
->regs
.skas
.regs
);
76 sc
.esp
= REGS_SP(regs
->regs
.skas
.regs
);
77 sc
.ebx
= REGS_EBX(regs
->regs
.skas
.regs
);
78 sc
.edx
= REGS_EDX(regs
->regs
.skas
.regs
);
79 sc
.ecx
= REGS_ECX(regs
->regs
.skas
.regs
);
80 sc
.eax
= REGS_EAX(regs
->regs
.skas
.regs
);
81 sc
.eip
= REGS_IP(regs
->regs
.skas
.regs
);
82 sc
.cs
= REGS_CS(regs
->regs
.skas
.regs
);
83 sc
.eflags
= REGS_EFLAGS(regs
->regs
.skas
.regs
);
84 sc
.esp_at_signal
= regs
->regs
.skas
.regs
[UESP
];
85 sc
.ss
= regs
->regs
.skas
.regs
[SS
];
87 sc
.err
= fi
->error_code
;
88 sc
.trapno
= fi
->trap_no
;
90 err
= save_fp_registers(userspace_pid
[0], fpregs
);
92 printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
96 to_fp
= (to_fp
? to_fp
: (struct _fpstate
*) (to
+ 1));
102 return(copy_to_user(to
, &sc
, sizeof(sc
)) ||
103 copy_to_user(to_fp
, fpregs
, sizeof(fpregs
)));
107 #ifdef CONFIG_MODE_TT
109 /* These copy a sigcontext to/from userspace. They copy the fpstate pointer,
110 * blowing away the old, good one. So, that value is saved, and then restored
111 * after the sigcontext copy. In copy_from, the variable holding the saved
112 * fpstate pointer, and the sigcontext that it should be restored to are both
113 * in the kernel, so we can just restore using an assignment. In copy_to, the
114 * saved pointer is in the kernel, but the sigcontext is in userspace, so we
117 int copy_sc_from_user_tt(struct sigcontext
*to
, struct sigcontext
*from
,
120 struct _fpstate
*to_fp
, *from_fp
;
125 from_fp
= from
->fpstate
;
127 err
= copy_from_user(to
, from
, sizeof(*to
));
131 err
|= copy_from_user(to_fp
, from_fp
, fpsize
);
135 int copy_sc_to_user_tt(struct sigcontext
*to
, struct _fpstate
*fp
,
136 struct sigcontext
*from
, int fpsize
)
138 struct _fpstate
*to_fp
, *from_fp
;
141 to_fp
= (fp
? fp
: (struct _fpstate
*) (to
+ 1));
142 from_fp
= from
->fpstate
;
143 err
= copy_to_user(to
, from
, sizeof(*to
));
145 err
|= copy_to_user(&to
->fpstate
, &to_fp
, sizeof(to
->fpstate
));
146 err
|= copy_to_user(to_fp
, from_fp
, fpsize
);
152 static int copy_sc_from_user(struct pt_regs
*to
, void __user
*from
)
156 ret
= CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to
->regs
), from
,
157 sizeof(struct _fpstate
)),
158 copy_sc_from_user_skas(to
, from
));
162 static int copy_sc_to_user(struct sigcontext
*to
, struct _fpstate
*fp
,
163 struct pt_regs
*from
)
165 return(CHOOSE_MODE(copy_sc_to_user_tt(to
, fp
, UPT_SC(&from
->regs
),
167 copy_sc_to_user_skas(to
, fp
, from
)));
170 static int copy_ucontext_to_user(struct ucontext
*uc
, struct _fpstate
*fp
,
171 sigset_t
*set
, unsigned long sp
)
175 err
|= put_user(current
->sas_ss_sp
, &uc
->uc_stack
.ss_sp
);
176 err
|= put_user(sas_ss_flags(sp
), &uc
->uc_stack
.ss_flags
);
177 err
|= put_user(current
->sas_ss_size
, &uc
->uc_stack
.ss_size
);
178 err
|= copy_sc_to_user(&uc
->uc_mcontext
, fp
, ¤t
->thread
.regs
);
179 err
|= copy_to_user(&uc
->uc_sigmask
, set
, sizeof(*set
));
187 struct sigcontext sc
;
188 struct _fpstate fpstate
;
189 unsigned long extramask
[_NSIG_WORDS
-1];
197 struct siginfo
*pinfo
;
201 struct _fpstate fpstate
;
205 int setup_signal_stack_sc(unsigned long stack_top
, int sig
,
206 struct k_sigaction
*ka
, struct pt_regs
*regs
,
209 struct sigframe __user
*frame
;
214 frame
= (struct sigframe
*) stack_top
- 1;
215 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
218 restorer
= (void *) frame
->retcode
;
219 if(ka
->sa
.sa_flags
& SA_RESTORER
)
220 restorer
= ka
->sa
.sa_restorer
;
222 err
|= __put_user(restorer
, &frame
->pretcode
);
223 err
|= __put_user(sig
, &frame
->sig
);
224 err
|= copy_sc_to_user(&frame
->sc
, NULL
, regs
);
225 err
|= __put_user(mask
->sig
[0], &frame
->sc
.oldmask
);
227 err
|= __copy_to_user(&frame
->extramask
, &mask
->sig
[1],
228 sizeof(frame
->extramask
));
231 * This is popl %eax ; movl $,%eax ; int $0x80
233 * WE DO NOT USE IT ANY MORE! It's only left here for historical
234 * reasons and because gdb uses it as a signature to notice
235 * signal handler stack frames.
237 err
|= __put_user(0xb858, (short __user
*)(frame
->retcode
+0));
238 err
|= __put_user(__NR_sigreturn
, (int __user
*)(frame
->retcode
+2));
239 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+6));
244 PT_REGS_SP(regs
) = (unsigned long) frame
;
245 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
246 PT_REGS_EAX(regs
) = (unsigned long) sig
;
247 PT_REGS_EDX(regs
) = (unsigned long) 0;
248 PT_REGS_ECX(regs
) = (unsigned long) 0;
250 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
251 ptrace_notify(SIGTRAP
);
255 int setup_signal_stack_si(unsigned long stack_top
, int sig
,
256 struct k_sigaction
*ka
, struct pt_regs
*regs
,
257 siginfo_t
*info
, sigset_t
*mask
)
259 struct rt_sigframe __user
*frame
;
264 frame
= (struct rt_sigframe
*) stack_top
- 1;
265 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
268 restorer
= (void *) frame
->retcode
;
269 if(ka
->sa
.sa_flags
& SA_RESTORER
)
270 restorer
= ka
->sa
.sa_restorer
;
272 err
|= __put_user(restorer
, &frame
->pretcode
);
273 err
|= __put_user(sig
, &frame
->sig
);
274 err
|= __put_user(&frame
->info
, &frame
->pinfo
);
275 err
|= __put_user(&frame
->uc
, &frame
->puc
);
276 err
|= copy_siginfo_to_user(&frame
->info
, info
);
277 err
|= copy_ucontext_to_user(&frame
->uc
, &frame
->fpstate
, mask
,
281 * This is movl $,%eax ; int $0x80
283 * WE DO NOT USE IT ANY MORE! It's only left here for historical
284 * reasons and because gdb uses it as a signature to notice
285 * signal handler stack frames.
287 err
|= __put_user(0xb8, (char __user
*)(frame
->retcode
+0));
288 err
|= __put_user(__NR_rt_sigreturn
, (int __user
*)(frame
->retcode
+1));
289 err
|= __put_user(0x80cd, (short __user
*)(frame
->retcode
+5));
294 PT_REGS_SP(regs
) = (unsigned long) frame
;
295 PT_REGS_IP(regs
) = (unsigned long) ka
->sa
.sa_handler
;
296 PT_REGS_EAX(regs
) = (unsigned long) sig
;
297 PT_REGS_EDX(regs
) = (unsigned long) &frame
->info
;
298 PT_REGS_ECX(regs
) = (unsigned long) &frame
->uc
;
300 if ((current
->ptrace
& PT_DTRACE
) && (current
->ptrace
& PT_PTRACED
))
301 ptrace_notify(SIGTRAP
);
305 long sys_sigreturn(struct pt_regs regs
)
307 unsigned long sp
= PT_REGS_SP(¤t
->thread
.regs
);
308 struct sigframe __user
*frame
= (struct sigframe
*)(sp
- 8);
310 struct sigcontext __user
*sc
= &frame
->sc
;
311 unsigned long __user
*oldmask
= &sc
->oldmask
;
312 unsigned long __user
*extramask
= frame
->extramask
;
313 int sig_size
= (_NSIG_WORDS
- 1) * sizeof(unsigned long);
315 if(copy_from_user(&set
.sig
[0], oldmask
, sizeof(&set
.sig
[0])) ||
316 copy_from_user(&set
.sig
[1], extramask
, sig_size
))
319 sigdelsetmask(&set
, ~_BLOCKABLE
);
321 spin_lock_irq(¤t
->sighand
->siglock
);
322 current
->blocked
= set
;
324 spin_unlock_irq(¤t
->sighand
->siglock
);
326 if(copy_sc_from_user(¤t
->thread
.regs
, sc
))
329 /* Avoid ERESTART handling */
330 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
331 return(PT_REGS_SYSCALL_RET(¤t
->thread
.regs
));
334 force_sig(SIGSEGV
, current
);
338 long sys_rt_sigreturn(struct pt_regs regs
)
340 unsigned long __user sp
= PT_REGS_SP(¤t
->thread
.regs
);
341 struct rt_sigframe __user
*frame
= (struct rt_sigframe
*) (sp
- 4);
343 struct ucontext __user
*uc
= &frame
->uc
;
344 int sig_size
= _NSIG_WORDS
* sizeof(unsigned long);
346 if(copy_from_user(&set
, &uc
->uc_sigmask
, sig_size
))
349 sigdelsetmask(&set
, ~_BLOCKABLE
);
351 spin_lock_irq(¤t
->sighand
->siglock
);
352 current
->blocked
= set
;
354 spin_unlock_irq(¤t
->sighand
->siglock
);
356 if(copy_sc_from_user(¤t
->thread
.regs
, &uc
->uc_mcontext
))
359 /* Avoid ERESTART handling */
360 PT_REGS_SYSCALL_NR(¤t
->thread
.regs
) = -1;
361 return(PT_REGS_SYSCALL_RET(¤t
->thread
.regs
));
364 force_sig(SIGSEGV
, current
);
369 * Overrides for Emacs so that we follow Linus's tabbing style.
370 * Emacs will notice this stuff at the end of the file and automatically
371 * adjust the settings for this buffer only. This must remain at the end
373 * ---------------------------------------------------------------------------
375 * c-file-style: "linux"