// 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;
}
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;
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 ***************************************