Commit | Line | Data |
---|---|---|
ea2ba7dc | 1 | /* |
1da177e4 LT |
2 | * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) |
3 | * Licensed under the GPL | |
4 | */ | |
5 | ||
6 | #include <signal.h> | |
7 | #include <errno.h> | |
1da177e4 | 8 | #include "kern_util.h" |
4ff83ce1 | 9 | #include "as-layout.h" |
1da177e4 LT |
10 | #include "task.h" |
11 | #include "sigcontext.h" | |
c578455a BS |
12 | #include "skas.h" |
13 | #include "ptrace_user.h" | |
14 | #include "sysdep/ptrace.h" | |
15 | #include "sysdep/ptrace_user.h" | |
0805d89c | 16 | #include "os.h" |
1da177e4 | 17 | |
377fad3a JD |
18 | static union uml_pt_regs ksig_regs[UM_NR_CPUS]; |
19 | ||
1da177e4 LT |
20 | void sig_handler_common_skas(int sig, void *sc_ptr) |
21 | { | |
22 | struct sigcontext *sc = sc_ptr; | |
5d86456d | 23 | union uml_pt_regs *r; |
ea2ba7dc | 24 | void (*handler)(int, union uml_pt_regs *); |
5d86456d | 25 | int save_user, save_errno = errno; |
1da177e4 LT |
26 | |
27 | /* This is done because to allow SIGSEGV to be delivered inside a SEGV | |
28 | * handler. This can happen in copy_user, and if SEGV is disabled, | |
29 | * the process will die. | |
30 | * XXX Figure out why this is better than SA_NODEFER | |
31 | */ | |
377fad3a | 32 | if(sig == SIGSEGV) { |
1da177e4 | 33 | change_sig(SIGSEGV, 1); |
377fad3a JD |
34 | /* For segfaults, we want the data from the |
35 | * sigcontext. In this case, we don't want to mangle | |
36 | * the process registers, so use a static set of | |
37 | * registers. For other signals, the process | |
38 | * registers are OK. | |
39 | */ | |
40 | r = &ksig_regs[cpu()]; | |
41 | copy_sc(r, sc_ptr); | |
42 | } | |
43 | else r = TASK_REGS(get_current()); | |
1da177e4 | 44 | |
5d86456d JD |
45 | save_user = r->skas.is_user; |
46 | r->skas.is_user = 0; | |
c0a689d0 JD |
47 | if ( sig == SIGFPE || sig == SIGSEGV || |
48 | sig == SIGBUS || sig == SIGILL || | |
49 | sig == SIGTRAP ) { | |
5d86456d | 50 | GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc); |
c0a689d0 | 51 | } |
1da177e4 LT |
52 | |
53 | change_sig(SIGUSR1, 1); | |
1da177e4 | 54 | |
ea2ba7dc GS |
55 | handler = sig_info[sig]; |
56 | ||
57 | /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */ | |
58 | if (sig != SIGIO && sig != SIGWINCH && | |
59 | sig != SIGVTALRM && sig != SIGALRM) | |
60 | unblock_signals(); | |
61 | ||
5d86456d | 62 | handler(sig, r); |
1da177e4 LT |
63 | |
64 | errno = save_errno; | |
5d86456d | 65 | r->skas.is_user = save_user; |
1da177e4 | 66 | } |