cae36a52 |
1 | #include <u.h> |
2 | #include <libc.h> |
3 | #include <ureg.h> |
4 | #include "dat.h" |
5 | #include "fns.h" |
6 | #include "linux.h" |
7 | |
8 | #pragma profile off |
9 | |
10 | void |
11 | retuser(void) |
12 | { |
13 | Uproc *p; |
14 | Ureg *u; |
15 | |
16 | p = current; |
17 | u = p->ureg; |
18 | p->ureg = nil; |
19 | if(p->innote == 0) |
20 | jumpureg(u); |
21 | p->innote = 0; |
22 | noted(NCONT); |
23 | } |
24 | |
25 | static void |
26 | handletrap(void *v, char *m) |
27 | { |
28 | Uproc *p; |
29 | Usiginfo si; |
30 | |
31 | p = current; |
32 | p->innote = 1; |
33 | p->ureg = v; |
34 | |
35 | if(strncmp(m, "interrupt", 9) == 0){ |
36 | if(p->notified){ |
37 | p->notified = 0; |
38 | } else { |
39 | memset(&si, 0, sizeof(si)); |
40 | si.signo = SIGINT; |
41 | sendsignal(p, &si, 0); |
42 | } |
43 | goto handled; |
44 | } |
45 | |
46 | if(p->traceproc) |
47 | goto traced; |
48 | |
49 | if(strncmp(m, "sys: trap: general protection violation", 39) == 0) |
50 | if(linuxcall() == 0) |
51 | goto handled; |
52 | |
53 | if(strncmp(m, "sys: write on closed pipe", 25) == 0) |
54 | goto handled; |
55 | |
56 | if(strncmp(m, "sys: trap: invalid opcode", 25) == 0){ |
57 | memset(&si, 0, sizeof(si)); |
58 | si.signo = SIGILL; |
59 | si.code = ILL_ILLOPC; |
60 | si.fault.addr = (void*)p->ureg->pc; |
61 | sendsignal(p, &si, 0); |
62 | goto handled; |
63 | } |
64 | |
65 | if(strncmp(m, "sys: trap: divide error", 23) == 0){ |
66 | memset(&si, 0, sizeof(si)); |
67 | si.signo = SIGFPE; |
68 | si.code = FPE_INTDIV; |
69 | si.fault.addr = (void*)p->ureg->pc; |
70 | sendsignal(p, &si, 0); |
71 | goto handled; |
72 | } |
73 | |
74 | if(strncmp(m, "sys: trap: overflow", 19) == 0){ |
75 | memset(&si, 0, sizeof(si)); |
76 | si.signo = SIGFPE; |
77 | si.code = FPE_INTOVF; |
78 | si.fault.addr = (void*)p->ureg->pc; |
79 | sendsignal(p, &si, 0); |
80 | goto handled; |
81 | } |
82 | |
83 | trace("handletrap: %s", m); |
84 | if(debug) |
85 | noted(NDFLT); |
86 | |
87 | exitproc(p, SIGKILL, 1); |
88 | |
89 | handled: |
90 | if(p->traceproc) |
91 | traced: p->traceproc(p->tracearg); |
92 | |
93 | handlesignals(); |
94 | retuser(); |
95 | } |
96 | |
97 | #pragma profile on |
98 | |
99 | |
100 | void inittrap(void) |
101 | { |
102 | ulong f; |
103 | |
104 | /* disable FPU faults */ |
105 | f = getfcr(); |
106 | f &= ~(FPINEX|FPOVFL|FPUNFL|FPZDIV|FPINVAL); |
107 | setfcr(f); |
108 | |
109 | notify(handletrap); |
110 | } |