* src/vm/jit/mips/linux/md-os.c (md_signal_handler_sigsegv): Restored an
authorStefan Ring <stefan@complang.tuwien.ac.at>
Mon, 5 Oct 2009 22:32:10 +0000 (00:32 +0200)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Mon, 5 Oct 2009 22:32:10 +0000 (00:32 +0200)
ugly hack for finding the instruction pointer.
(md_signal_handler_sigill): Fixed, for the previous version was based on QEMU's
behavior which does not appear to be correct.

src/vm/jit/mips/linux/md-os.c

index 2fec3a5bf1b66c97d2a5236058f92b4eaedaf9fb..f48ca785803a4468b54bd94fa0db3976747b3174 100644 (file)
@@ -80,10 +80,41 @@ void md_init(void)
  */
 void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p)
 {
+       int disp = 0;
+       int cause;
        ucontext_t* _uc = (struct ucontext *) _p;
        mcontext_t* _mc = &_uc->uc_mcontext;
+       void *xpc;
 
-       void* xpc = (void*) (_mc->pc - 4);
+#if !defined(__UCLIBC__)
+# if ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 5))
+       /* NOTE: We only need this for pre glibc-2.5. */
+
+       /* get the cause of this exception */
+
+       cause = _mc->cause;
+
+       /* check the cause to find the faulting instruction */
+
+       /* TODO: use defines for that stuff */
+
+       switch (cause & 0x0000003c) {
+       case 0x00000008:
+               /* TLBL: XPC is ok */
+               break;
+
+       case 0x00000010:
+               /* AdEL: XPC is of the following instruction */
+               disp -= 4;
+               break;
+       }
+       xpc = (void*) (_mc->pc + disp);
+# else
+       xpc = (void*) _mc->pc;
+# endif
+#else
+       xpc = (void*) _gregs[CTX_EPC];
+#endif
 
        // Handle the trap.
        trap_handle(TRAP_SIGSEGV, xpc, _p);
@@ -98,7 +129,11 @@ void md_signal_handler_sigill(int sig, siginfo_t* siginfo, void* _p)
        ucontext_t* _uc = (struct ucontext *) _p;
        mcontext_t* _mc = &_uc->uc_mcontext;
 
-       void* xpc = (void*) (_mc->pc - 4);
+#if !defined(__UCLIBC__)
+       void* xpc = (void*) _mc->pc;
+#else
+       void* xpc = (void*) _gregs[CTX_EPC];
+#endif
 
        // Handle the trap.
        trap_handle(TRAP_SIGILL, xpc, _p);