This source file includes following definitions.
- die_if_kernel
- do_entArith
- do_entIF
- do_entUna
- do_entUnaUser
- do_entSys
- trap_init
1
2
3
4
5
6
7
8
9
10
11 #include <linux/sched.h>
12 #include <linux/tty.h>
13
14 #include <asm/unaligned.h>
15
16 void die_if_kernel(char * str, struct pt_regs * regs, long err)
17 {
18 long i;
19 unsigned long sp;
20 unsigned int * pc;
21
22 if (regs->ps & 8)
23 return;
24 printk("%s(%d): %s %ld\n", current->comm, current->pid, str, err);
25 sp = (unsigned long) (regs+1);
26 printk("pc = %lx ps = %04lx\n", regs->pc, regs->ps);
27 printk("rp = %lx sp = %lx\n", regs->r26, sp);
28 printk("r0=%lx r1=%lx r2=%lx r3=%lx\n",
29 regs->r0, regs->r1, regs->r2, regs->r3);
30 printk("r8=%lx\n", regs->r8);
31 printk("r16=%lx r17=%lx r18=%lx r19=%lx\n",
32 regs->r16, regs->r17, regs->r18, regs->r19);
33 printk("r20=%lx r21=%lx r22=%lx r23=%lx\n",
34 regs->r20, regs->r21, regs->r22, regs->r23);
35 printk("r24=%lx r25=%lx r26=%lx r27=%lx\n",
36 regs->r24, regs->r25, regs->r26, regs->r27);
37 printk("r28=%lx r29=%lx r30=%lx\n",
38 regs->r28, regs->gp, sp);
39 printk("Code:");
40 pc = (unsigned int *) regs->pc;
41 for (i = -3; i < 6; i++)
42 printk("%c%08x%c",i?' ':'<',pc[i],i?' ':'>');
43 printk("\n");
44 for (i = 0 ; i < 5000000000 ; i++)
45 ;
46 halt();
47 }
48
49 asmlinkage void do_entArith(unsigned long summary, unsigned long write_mask,
50 unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5,
51 struct pt_regs regs)
52 {
53 printk("Arithmetic trap: %02lx %016lx\n", summary, write_mask);
54 die_if_kernel("Arithmetic fault", ®s, 0);
55 send_sig(SIGFPE, current, 1);
56 }
57
58 asmlinkage void do_entIF(unsigned long type, unsigned long a1, unsigned long a2,
59 unsigned long a3, unsigned long a4, unsigned long a5,
60 struct pt_regs regs)
61 {
62 extern int ptrace_cancel_bpt (struct task_struct *who);
63
64 die_if_kernel("Instruction fault", ®s, type);
65 switch (type) {
66 case 0:
67 if (ptrace_cancel_bpt(current)) {
68 regs.pc -= 4;
69 }
70 send_sig(SIGTRAP, current, 1);
71 break;
72
73 case 1:
74 case 2:
75 case 3:
76 case 4:
77 send_sig(SIGILL, current, 1);
78 break;
79
80 default:
81 panic("do_entIF: unexpected instruction-fault type");
82 }
83 }
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98 struct allregs {
99 unsigned long regs[32];
100 unsigned long ps, pc, gp, a0, a1, a2;
101 };
102
103 struct unaligned_stat {
104 unsigned long count, va, pc;
105 } unaligned;
106
107 asmlinkage void do_entUna(void * va, unsigned long opcode, unsigned long reg,
108 unsigned long a3, unsigned long a4, unsigned long a5,
109 struct allregs regs)
110 {
111 static int cnt = 0;
112
113 if (++cnt < 5)
114 printk("Unaligned trap at %016lx: %p %lx %ld\n",
115 regs.pc, va, opcode, reg);
116
117 ++unaligned.count;
118 unaligned.va = (unsigned long) va - 4;
119 unaligned.pc = regs.pc;
120
121
122 if (reg >= 16 && reg <= 18)
123 reg += 19;
124 switch (opcode) {
125 case 0x28:
126 *(reg+regs.regs) = (int) ldl_u(va);
127 return;
128 case 0x29:
129 *(reg+regs.regs) = ldq_u(va);
130 return;
131 case 0x2c:
132 stl_u(*(reg+regs.regs), va);
133 return;
134 case 0x2d:
135 stq_u(*(reg+regs.regs), va);
136 return;
137 }
138 printk("Bad unaligned kernel access at %016lx: %p %lx %ld\n",
139 regs.pc, va, opcode, reg);
140 do_exit(SIGSEGV);
141 }
142
143
144
145
146
147
148
149
150
151 asmlinkage void do_entUnaUser(void *va, unsigned long opcode, unsigned long reg,
152 unsigned long a3, unsigned long a4, unsigned long a5,
153 struct pt_regs regs)
154 {
155 regs.pc -= 4;
156 send_sig(SIGSEGV, current, 1);
157 }
158
159
160
161
162
163
164
165
166
167
168
169
170 asmlinkage long do_entSys(unsigned long a0, unsigned long a1, unsigned long a2,
171 unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs)
172 {
173 if (regs.r0 != 112)
174 printk("<sc %ld(%lx,%lx,%lx)>", regs.r0, a0, a1, a2);
175 return -1;
176 }
177
178 extern asmlinkage void entMM(void);
179 extern asmlinkage void entIF(void);
180 extern asmlinkage void entArith(void);
181 extern asmlinkage void entUna(void);
182 extern asmlinkage void entSys(void);
183
184 void trap_init(void)
185 {
186 unsigned long gptr;
187
188
189
190
191 __asm__("br %0,___tmp\n"
192 "___tmp:\tldgp %0,0(%0)"
193 : "=r" (gptr));
194 wrkgp(gptr);
195
196 wrent(entArith, 1);
197 wrent(entMM, 2);
198 wrent(entIF, 3);
199 wrent(entUna, 4);
200 wrent(entSys, 5);
201 }