- ucontext_t *_uc;
- mcontext_t *_mc;
- u1 *pv;
- u1 *sp;
- u1 *ra;
- u1 *xpc;
- u1 opc;
- u1 mod;
- u1 rm;
- s4 d;
- s4 disp;
- ptrint val;
- s4 type;
- void *p;
-
- _uc = (ucontext_t *) _p;
- _mc = &_uc->uc_mcontext;
-
- pv = NULL; /* is resolved during stackframeinfo creation */
- sp = (u1 *) _mc->gregs[ESP];
- xpc = (u1 *) _mc->gregs[EIP];
- ra = xpc; /* return address is equal to XPC */
-
- /* get exception-throwing instruction */
-
- opc = M_ALD_MEM_GET_OPC(xpc);
- mod = M_ALD_MEM_GET_MOD(xpc);
- rm = M_ALD_MEM_GET_RM(xpc);
-
- /* for values see emit_mov_mem_reg and emit_mem */
-
- if ((opc == 0x8b) && (mod == 0) && (rm == 5)) {
- /* this was a hardware-exception */
-
- d = M_ALD_MEM_GET_REG(xpc);
- disp = M_ALD_MEM_GET_DISP(xpc);
-
- /* we use the exception type as load displacement */
-
- type = disp;
-
- /* ATTENTION: The _mc->gregs layout is completely crazy! The
- registers are reversed starting with number 4 for REG_EDI
- (see /usr/include/sys/ucontext.h). We have to convert that
- here. */
-
- val = _mc->gregs[EAX - d];
-
- if (type == TRAP_COMPILER) {
- /* The PV from the compiler stub is equal to the XPC. */
-
- pv = xpc;
-
- /* We use a framesize of zero here because the call pushed
- the return addres onto the stack. */
-
- ra = md_stacktrace_get_returnaddress(sp, 0);
-
- /* Skip the RA on the stack. */
-
- sp = sp + 1 * SIZEOF_VOID_P;
-
- /* The XPC is the RA minus 2, because the RA points to the
- instruction after the call. */
-
- xpc = ra - 2;
- }
- }
- else {
- /* this was a normal NPE */