PR85 for x86_64.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Sat, 20 Dec 2008 14:25:49 +0000 (15:25 +0100)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Sat, 20 Dec 2008 14:25:49 +0000 (15:25 +0100)
* src/vm/jit/patcher-common.cpp (patcher_is_patched): Also support 16 bit
instructions.
* src/vm/jit/x86_64/linux/md-os.c: Check for already patched instructions.
* src/vm/jit/x86_64/patcher.c (patcher_is_valid_trap_instruction_at):
Implemented.

src/vm/jit/patcher-common.cpp
src/vm/jit/x86_64/linux/md-os.c
src/vm/jit/x86_64/patcher.c

index b4386ada1df60a584030777d65b829f9de6520fa..146e52834fd672135a7f368b5f892f7c155368f9 100644 (file)
@@ -247,7 +247,13 @@ bool patcher_is_patched(patchref_t* pr)
        // instruction as the patcher structure contains.
        uint32_t mcode = *((uint32_t*) pr->mpc);
 
+#if PATCHER_CALL_SIZE == 4
        if (mcode != pr->mcode) {
+#elif PATCHER_CALL_SIZE == 2
+       if ((uint16_t) mcode != (uint16_t) pr->mcode) {
+#else
+#error Unknown PATCHER_CALL_SIZE
+#endif
                // The code differs.
                return false;
        }
index 78ff29675028ceb08ab71c3d2b1f07e0b177ff23..1c30b8bbf94fac72d746b7f3256e047461f258f6 100644 (file)
@@ -260,6 +260,22 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
        xpc = (u1 *) _mc->gregs[REG_RIP];
        ra  = xpc;                          /* return address is equal to 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 at 0x%lx", xpc);
+#if defined(ENABLE_DISASSEMBLER)
+               (void) disassinstr(xpc);
+#endif
+               vm_abort("Aborting...");
+       }
+
        /* This is a patcher. */
 
        type = TRAP_PATCHER;
index fa0c0b296d264b0bc990bf92bf4ed17bb3cf5197..ae4b7aa2131eb14c9949dca08ab808ba38f185ab 100644 (file)
@@ -59,6 +59,21 @@ void patcher_patch_code(patchref_t *pr)
        md_icacheflush((void*) pr->mpc, PATCHER_CALL_SIZE);
 }
 
+/**
+ * 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)
+{
+       uint16_t mcode = *((uint16_t*) pc);
+
+       // Check for the undefined instruction we use.
+       return (mcode == 0x0b0f);
+}
+
 
 /* patcher_resolve_classref_to_classinfo ***************************************