Fixes PR85 for powerpc.
authorChristian Thalinger <twisti@complang.tuwien.ac.at>
Sat, 13 Sep 2008 11:57:20 +0000 (13:57 +0200)
committerChristian Thalinger <twisti@complang.tuwien.ac.at>
Sat, 13 Sep 2008 11:57:20 +0000 (13:57 +0200)
* src/vm/jit/powerpc/linux/md-os.c (md_signal_handler_sigill): Check
if the trap instruction has been patched on the way to the signal
handler.
* src/vm/jit/powerpc/patcher.c (patcher_is_valid_trap_instruction_at):
New function.

src/vm/jit/powerpc/linux/md-os.c
src/vm/jit/powerpc/patcher.c

index db748db3f87c27c425ccb8e867c60c3f88b362cc..edfc86d203085a4752ccbbdf3b399a56b9d04795 100644 (file)
@@ -2,6 +2,7 @@
 
    Copyright (C) 1996-2005, 2006, 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2008 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
 #include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
+#include "vm/jit/disass.h"
 #include "vm/jit/executionstate.h"
 
 #if defined(ENABLE_PROFILING)
 # include "vm/jit/optimizing/profile.h"
 #endif
 
+#include "vm/jit/patcher-common.hpp"
 #include "vm/jit/trap.h"
 
 
@@ -182,6 +185,25 @@ void md_signal_handler_sigill(int sig, siginfo_t* siginfo, void* _p)
        void* ra = (void*) _gregs[PT_LNK]; // The RA is correct for leag methods.
        void* xpc =(void*) _gregs[PT_NIP];
 
+       // Get the illegal-instruction.
+       uint32_t mcode = *((uint32_t*) xpc);
+
+       // Check if the trap instruction is valid.
+       // TODO Move this into patcher_handler.
+       if (patcher_is_valid_trap_instruction_at(xpc) == false) {
+               // Check if the PC has been patched during our way to this
+               // signal handler (see PR85).
+               if (patcher_is_patched_at(xpc) == true)
+                       return;
+
+               // We have a problem...
+               log_println("md_signal_handler_sigill: Unknown illegal instruction 0x%x at 0x%lx", mcode, xpc);
+#if defined(ENABLE_DISASSEMBLER)
+               (void) disassinstr(xpc);
+#endif
+               vm_abort("Aborting...");
+       }
+
        // This signal is always a patcher.
        int      type = TRAP_PATCHER;
        intptr_t val  = 0;
index 051a186e616fe6fc582bdfbd10d73ceb48dee222..0dc24cadd927788661a136b216916118a60a106c 100644 (file)
@@ -2,6 +2,7 @@
 
    Copyright (C) 1996-2005, 2006, 2007, 2008
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+   Copyright (C) 2008 Theobroma Systems Ltd.
 
    This file is part of CACAO.
 
@@ -65,6 +66,22 @@ void patcher_patch_code(patchref_t *pr)
 }
 
 
+/**
+ * Check if the trap instruction at the given PC is valid.
+ *
+ * @param pc Program counter.
+ *
+ * @return true if valid, false otherwise.
+ */
+bool patcher_is_valid_trap_instruction_at(void* pc)
+{
+       uint32_t mcode = *((uint32_t*) pc);
+
+       // Check for the undefined instruction we use.
+       return (mcode == 0x00000000);
+}
+
+
 /* patcher_resolve_classref_to_classinfo ***************************************
 
    ACONST: