undefined.c (e6e746bfb086d563bf0ad454a33ecbcab8836dbf) | undefined.c (ae4fa2223a960ae069fb91224700fe94e94cb2b9) |
---|---|
1/* $NetBSD: undefined.c,v 1.22 2003/11/29 22:21:29 bjh21 Exp $ */ 2 3/*- 4 * Copyright (c) 2001 Ben Harris. 5 * Copyright (c) 1995 Mark Brinicombe. 6 * Copyright (c) 1995 Brini. 7 * All rights reserved. 8 * --- 72 unchanged lines hidden (view full) --- 81#ifdef DDB 82#include <ddb/db_output.h> 83#endif 84 85#ifdef KDB 86#include <machine/db_machdep.h> 87#endif 88 | 1/* $NetBSD: undefined.c,v 1.22 2003/11/29 22:21:29 bjh21 Exp $ */ 2 3/*- 4 * Copyright (c) 2001 Ben Harris. 5 * Copyright (c) 1995 Mark Brinicombe. 6 * Copyright (c) 1995 Brini. 7 * All rights reserved. 8 * --- 72 unchanged lines hidden (view full) --- 81#ifdef DDB 82#include <ddb/db_output.h> 83#endif 84 85#ifdef KDB 86#include <machine/db_machdep.h> 87#endif 88 |
89#define ARM_COPROC_INSN(insn) (((insn) & (1 << 27)) != 0) 90#define ARM_VFP_INSN(insn) ((((insn) & 0xfe000000) == 0xf2000000) || \ 91 (((insn) & 0xff100000) == 0xf4000000)) 92#define ARM_COPROC(insn) (((insn) >> 8) & 0xf) 93 94#define THUMB_32BIT_INSN(insn) ((insn) >= 0xe800) 95#define THUMB_COPROC_INSN(insn) (((insn) & (3 << 26)) == (3 << 26)) 96#define THUMB_COPROC_UNDEFINED(insn) (((insn) & 0x3e << 20) == 0) 97#define THUMB_VFP_INSN(insn) (((insn) & (3 << 24)) == (3 << 24)) 98#define THUMB_COPROC(insn) (((insn) >> 8) & 0xf) 99 100#define COPROC_VFP 10 101 |
|
89#ifdef KDTRACE_HOOKS 90int (*dtrace_invop_jump_addr)(struct trapframe *); 91#endif 92 93static int gdb_trapper(u_int, u_int, struct trapframe *, int); 94 95LIST_HEAD(, undefined_handler) undefined_handlers[MAX_COPROCS]; 96 --- 77 unchanged lines hidden (view full) --- 174undefinedinstruction(struct trapframe *frame) 175{ 176 struct thread *td; 177 u_int fault_pc; 178 int fault_instruction; 179 int fault_code; 180 int coprocessor; 181 struct undefined_handler *uh; | 102#ifdef KDTRACE_HOOKS 103int (*dtrace_invop_jump_addr)(struct trapframe *); 104#endif 105 106static int gdb_trapper(u_int, u_int, struct trapframe *, int); 107 108LIST_HEAD(, undefined_handler) undefined_handlers[MAX_COPROCS]; 109 --- 77 unchanged lines hidden (view full) --- 187undefinedinstruction(struct trapframe *frame) 188{ 189 struct thread *td; 190 u_int fault_pc; 191 int fault_instruction; 192 int fault_code; 193 int coprocessor; 194 struct undefined_handler *uh; |
195 int error; |
|
182#ifdef VERBOSE_ARM32 183 int s; 184#endif 185 ksiginfo_t ksi; 186 187 /* Enable interrupts if they were enabled before the exception. */ 188 if (__predict_true(frame->tf_spsr & PSR_I) == 0) 189 enable_interrupts(PSR_I); 190 if (__predict_true(frame->tf_spsr & PSR_F) == 0) 191 enable_interrupts(PSR_F); 192 193 PCPU_INC(cnt.v_trap); 194 | 196#ifdef VERBOSE_ARM32 197 int s; 198#endif 199 ksiginfo_t ksi; 200 201 /* Enable interrupts if they were enabled before the exception. */ 202 if (__predict_true(frame->tf_spsr & PSR_I) == 0) 203 enable_interrupts(PSR_I); 204 if (__predict_true(frame->tf_spsr & PSR_F) == 0) 205 enable_interrupts(PSR_F); 206 207 PCPU_INC(cnt.v_trap); 208 |
209#if __ARM_ARCH >= 7 210 if ((frame->tf_spsr & PSR_T) != 0) 211 frame->tf_pc -= THUMB_INSN_SIZE; 212 else 213#endif 214 frame->tf_pc -= INSN_SIZE; |
|
195 fault_pc = frame->tf_pc; 196 197 /* 198 * Get the current thread/proc structure or thread0/proc0 if there is 199 * none. 200 */ 201 td = curthread == NULL ? &thread0 : curthread; 202 | 215 fault_pc = frame->tf_pc; 216 217 /* 218 * Get the current thread/proc structure or thread0/proc0 if there is 219 * none. 220 */ 221 td = curthread == NULL ? &thread0 : curthread; 222 |
203 /* 204 * Make sure the program counter is correctly aligned so we 205 * don't take an alignment fault trying to read the opcode. 206 */ 207 if (__predict_false((fault_pc & 3) != 0)) { | 223 coprocessor = 0; 224 if ((frame->tf_spsr & PSR_T) == 0) { 225 /* 226 * Make sure the program counter is correctly aligned so we 227 * don't take an alignment fault trying to read the opcode. 228 */ 229 if (__predict_false((fault_pc & 3) != 0)) { 230 ksiginfo_init_trap(&ksi); 231 ksi.ksi_signo = SIGILL; 232 ksi.ksi_code = ILL_ILLADR; 233 ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc; 234 trapsignal(td, &ksi); 235 userret(td, frame); 236 return; 237 } 238 239 /* 240 * Should use fuword() here .. but in the interests of 241 * squeezing every bit of speed we will just use ReadWord(). 242 * We know the instruction can be read as was just executed 243 * so this will never fail unless the kernel is screwed up 244 * in which case it does not really matter does it ? 245 */ 246 247 fault_instruction = *(u_int32_t *)fault_pc; 248 249 /* Check for coprocessor instruction */ 250 251 /* 252 * According to the datasheets you only need to look at bit 253 * 27 of the instruction to tell the difference between and 254 * undefined instruction and a coprocessor instruction 255 * following an undefined instruction trap. 256 */ 257 258 if (ARM_COPROC_INSN(fault_instruction)) 259 coprocessor = ARM_COPROC(fault_instruction); 260 else { /* check for special instructions */ 261 if (ARM_VFP_INSN(fault_instruction)) 262 coprocessor = COPROC_VFP; /* vfp / simd */ 263 } 264 } else { 265#if __ARM_ARCH >= 7 266 fault_instruction = *(uint16_t *)fault_pc; 267 if (THUMB_32BIT_INSN(fault_instruction)) { 268 fault_instruction <<= 16; 269 fault_instruction |= *(uint16_t *)(fault_pc + 2); 270 271 /* 272 * Is it a Coprocessor, Advanced SIMD, or 273 * Floating-point instruction. 274 */ 275 if (THUMB_COPROC_INSN(fault_instruction)) { 276 if (THUMB_COPROC_UNDEFINED(fault_instruction)) { 277 /* undefined insn */ 278 } else if (THUMB_VFP_INSN(fault_instruction)) 279 coprocessor = COPROC_VFP; 280 else 281 coprocessor = 282 THUMB_COPROC(fault_instruction); 283 } 284 } 285#else 286 /* 287 * No support for Thumb-2 on this cpu 288 */ |
208 ksiginfo_init_trap(&ksi); 209 ksi.ksi_signo = SIGILL; 210 ksi.ksi_code = ILL_ILLADR; 211 ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc; 212 trapsignal(td, &ksi); 213 userret(td, frame); 214 return; | 289 ksiginfo_init_trap(&ksi); 290 ksi.ksi_signo = SIGILL; 291 ksi.ksi_code = ILL_ILLADR; 292 ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc; 293 trapsignal(td, &ksi); 294 userret(td, frame); 295 return; |
215 } 216 217 /* 218 * Should use fuword() here .. but in the interests of squeezing every 219 * bit of speed we will just use ReadWord(). We know the instruction 220 * can be read as was just executed so this will never fail unless the 221 * kernel is screwed up in which case it does not really matter does 222 * it ? 223 */ 224 225 fault_instruction = *(u_int32_t *)fault_pc; 226 227 /* Update vmmeter statistics */ 228#if 0 229 uvmexp.traps++; | |
230#endif | 296#endif |
231 /* Check for coprocessor instruction */ 232 233 /* 234 * According to the datasheets you only need to look at bit 27 of the 235 * instruction to tell the difference between and undefined 236 * instruction and a coprocessor instruction following an undefined 237 * instruction trap. 238 */ 239 240 coprocessor = 0; 241 if ((fault_instruction & (1 << 27)) != 0) 242 coprocessor = (fault_instruction >> 8) & 0x0f; 243#ifdef VFP 244 else { /* check for special instructions */ 245 if (((fault_instruction & 0xfe000000) == 0xf2000000) || 246 ((fault_instruction & 0xff100000) == 0xf4000000)) 247 coprocessor = 10; /* vfp / simd */ | |
248 } | 297 } |
249#endif /* VFP */ | |
250 251 if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) { 252 /* 253 * Modify the fault_code to reflect the USR/SVC state at 254 * time of fault. 255 */ 256 fault_code = FAULT_USER; 257 td->td_frame = frame; 258 } else 259 fault_code = 0; 260 261 /* OK this is were we do something about the instruction. */ 262 LIST_FOREACH(uh, &undefined_handlers[coprocessor], uh_link) 263 if (uh->uh_handler(fault_pc, fault_instruction, frame, 264 fault_code) == 0) 265 break; 266 | 298 299 if ((frame->tf_spsr & PSR_MODE) == PSR_USR32_MODE) { 300 /* 301 * Modify the fault_code to reflect the USR/SVC state at 302 * time of fault. 303 */ 304 fault_code = FAULT_USER; 305 td->td_frame = frame; 306 } else 307 fault_code = 0; 308 309 /* OK this is were we do something about the instruction. */ 310 LIST_FOREACH(uh, &undefined_handlers[coprocessor], uh_link) 311 if (uh->uh_handler(fault_pc, fault_instruction, frame, 312 fault_code) == 0) 313 break; 314 |
267 if (fault_code & FAULT_USER && fault_instruction == PTRACE_BREAKPOINT) { 268 PROC_LOCK(td->td_proc); 269 _PHOLD(td->td_proc); 270 ptrace_clear_single_step(td); 271 _PRELE(td->td_proc); 272 PROC_UNLOCK(td->td_proc); 273 return; | 315 if (fault_code & FAULT_USER) { 316 /* TODO: No support for ptrace from Thumb-2 */ 317 if ((frame->tf_spsr & PSR_T) == 0 && 318 fault_instruction == PTRACE_BREAKPOINT) { 319 PROC_LOCK(td->td_proc); 320 _PHOLD(td->td_proc); 321 error = ptrace_clear_single_step(td); 322 _PRELE(td->td_proc); 323 PROC_UNLOCK(td->td_proc); 324 if (error != 0) { 325 ksiginfo_init_trap(&ksi); 326 ksi.ksi_signo = SIGILL; 327 ksi.ksi_code = ILL_ILLOPC; 328 ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc; 329 trapsignal(td, &ksi); 330 } 331 return; 332 } |
274 } 275 276 if (uh == NULL && (fault_code & FAULT_USER)) { 277 /* Fault has not been handled */ 278 ksiginfo_init_trap(&ksi); 279 ksi.ksi_signo = SIGILL; 280 ksi.ksi_code = ILL_ILLOPC; 281 ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc; --- 24 unchanged lines hidden --- | 333 } 334 335 if (uh == NULL && (fault_code & FAULT_USER)) { 336 /* Fault has not been handled */ 337 ksiginfo_init_trap(&ksi); 338 ksi.ksi_signo = SIGILL; 339 ksi.ksi_code = ILL_ILLOPC; 340 ksi.ksi_addr = (u_int32_t *)(intptr_t) fault_pc; --- 24 unchanged lines hidden --- |