diff options
author | marcel <marcel@FreeBSD.org> | 2004-07-08 16:30:42 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2004-07-08 16:30:42 +0000 |
commit | deb9f179ef07d77226390fb40676a146506e0cb0 (patch) | |
tree | 3297aaa3679ec2723da06341fcbd90ab5378c752 /sys/ia64 | |
parent | 042d10f8ef48e69d0af980b7709a295d34a9d987 (diff) | |
download | FreeBSD-src-deb9f179ef07d77226390fb40676a146506e0cb0.zip FreeBSD-src-deb9f179ef07d77226390fb40676a146506e0cb0.tar.gz |
Better handle the break instruction trap. The runtime specification
has outlined which break numbers are software interrupts, debugger
breakpoints and ABI specific breaks. We mostly treated all break
numbers we didn't care about as debugger breakpoints.
Diffstat (limited to 'sys/ia64')
-rw-r--r-- | sys/ia64/ia64/trap.c | 53 |
1 files changed, 46 insertions, 7 deletions
diff --git a/sys/ia64/ia64/trap.c b/sys/ia64/ia64/trap.c index 83946b1..5b00494 100644 --- a/sys/ia64/ia64/trap.c +++ b/sys/ia64/ia64/trap.c @@ -440,10 +440,51 @@ trap(int vector, struct trapframe *tf) case IA64_VEC_BREAK: if (user) { - if (tf->tf_special.ifa == 0x100000) { + /* XXX we don't decode break.b */ + ucode = (int)tf->tf_special.ifa & 0x1FFFFF; + if (ucode < 0x80000) { + /* Software interrupts. */ + switch (ucode) { + case 0: /* Unknown error. */ + sig = SIGILL; + break; + case 1: /* Integer divide by zero. */ + sig = SIGFPE; + ucode = FPE_INTDIV; + break; + case 2: /* Integer overflow. */ + sig = SIGFPE; + ucode = FPE_INTOVF; + break; + case 3: /* Range check/bounds check. */ + sig = SIGFPE; + ucode = FPE_FLTSUB; + break; + case 6: /* Decimal overflow. */ + case 7: /* Decimal divide by zero. */ + case 8: /* Packed decimal error. */ + case 9: /* Invalid ASCII digit. */ + case 10: /* Invalid decimal digit. */ + sig = SIGFPE; + ucode = FPE_FLTINV; + break; + case 4: /* Null pointer dereference. */ + case 5: /* Misaligned data. */ + case 11: /* Paragraph stack overflow. */ + sig = SIGSEGV; + break; + default: + sig = SIGILL; + break; + } + } else if (ucode < 0x100000) { + /* Debugger breakpoint. */ + tf->tf_special.psr &= ~IA64_PSR_SS; + sig = SIGTRAP; + } else if (ucode == 0x100000) { break_syscall(tf); return; /* do_ast() already called. */ - } else if (tf->tf_special.ifa == 0x180000) { + } else if (ucode == 0x180000) { mcontext_t mc; error = copyin((void*)tf->tf_scratch.gr8, @@ -452,12 +493,10 @@ trap(int vector, struct trapframe *tf) set_mcontext(td, &mc); return; /* Don't call do_ast()!!! */ } - ucode = tf->tf_scratch.gr8; sig = SIGSEGV; - } else { - tf->tf_special.psr &= ~IA64_PSR_SS; - sig = SIGTRAP; - } + ucode = tf->tf_scratch.gr8; + } else + sig = SIGILL; } else { #ifdef DDB if (kdb_trap(vector, tf)) |