+/**
+ * Decode the trap instruction at the given PC.
+ *
+ * @param trp information about trap to be filled
+ * @param sig signal number
+ * @param xpc exception PC
+ * @param es execution state of the machine
+ * @return true if trap was decoded successfully, false otherwise.
+ */
+bool md_trap_decode(trapinfo_t* trp, int sig, void* xpc, executionstate_t* es)
+{
+ // Get the throwing instruction.
+ uint32_t mcode = *((uint32_t*) xpc);
+
+ switch (sig) {
+ case TRAP_SIGILL:
+ // Check for valid trap instruction.
+ if (mcode == 0x00000000) {
+ trp->type = TRAP_PATCHER;
+ trp->value = 0;
+ return true;
+ }
+ return false;
+
+ case TRAP_SIGSEGV:
+ {
+ // Decode the throwing instruction.
+ int s1 = M_INSTR_OP2_IMM_A(mcode);
+ int16_t disp = M_INSTR_OP2_IMM_I(mcode);
+ int d = M_INSTR_OP2_IMM_D(mcode);
+
+ // We use the exception type as load displacement.
+ if (s1 == REG_ZERO) {
+ trp->type = disp;
+ trp->value = es->intregs[d];
+ return true;
+ }
+
+ // Default case is a normal NullPointerException.
+ if (es->intregs[s1] == 0) {
+ trp->type = TRAP_NullPointerException;
+ trp->value = 0;
+ return true;
+ }
+
+ return false;
+ }
+
+ default:
+ return false;
+ }
+}
+
+