g_return_val_if_reached(FALSE);
}
+static void instruction_fail(const guint8 *instr_base,gint offset_last,const gchar *location)
+{
+char instr_buf[4*3+1],*s;
+
+ g_return_if_fail(offset_last<=(gint)((sizeof(instr_buf)-1)/3));
+
+ s=instr_buf;
+ while (offset_last-->=0)
+ s+=sprintf(s," %02X",*instr_base++);
+ g_error("instruction_length(): Unhandled at %s:%s",location,instr_buf);
+ /* NOTREACHED */
+}
static gsize instruction_length(const guint8 *instr)
{
+#define INSTRUCTION_FAIL(offset_last) instruction_fail(instr,(offset_last),G_STRLOC)
+
if ((instr[0] & 0xF8)==0x50) /* push %regular-register */
return 1;
if ((instr[0] & 0xF8)==0x58) /* pop %regular-register */
return 1+1+4+1; /* 80 3D immediate-quad-indirect byte */
case 0x7C: /* cmpb $byte,#immediate(%reg,1) */
return 1+1+1+1+1; /* 80 7C address-mode immediate byte */
- default: g_assert_not_reached();
+ default: INSTRUCTION_FAIL(1);
}
case 0x83:
switch (instr[1]) {
return 1+1+4+1; /* 83 3D immediate-quad-indirect byte */
case 0x7C: /* cmpl $byte,#immediate(%reg,1) */
return 1+1+1+1+1; /* 80 7C address-mode immediate byte */
- default: g_assert_not_reached();
+ default: INSTRUCTION_FAIL(1);
}
case 0x8A: /* mov ??,?? */
case 0x8B: /* mov Gb,Eb */
case 0x4C: /* mov #offset(%reg,#mult),%reg */
case 0x54: /* mov #offset(%reg,#mult),%reg */
return 1+1+1+1; /* 8B 44 address-mode offset */
- default: g_assert_not_reached();
+ case 0xC0: /* mov %eax,%eax */
+ return 2;
+ case 0xFF: /* mov %edi,%edi */
+ return 2;
+ default: INSTRUCTION_FAIL(1);
}
case 0x8D: /* lea Gb,M */
switch (instr[1]) {
case 0x44: /* mov #offset(%reg,%reg,#mult),%reg */
return 4; /* 8B 44 address-mode offset */
- default: g_assert_not_reached();
+ default: INSTRUCTION_FAIL(1);
}
case 0x8F: /* lea Gb,M */
switch (instr[1]) {
switch (instr[2]) {
case 0x24: /* popl (%esp,1) */
return 3;
- default: g_assert_not_reached();
+ default: INSTRUCTION_FAIL(2);
}
- default: g_assert_not_reached();
+ default: INSTRUCTION_FAIL(1);
}
case 0x9C: /* pushf */
return 1;
return 1;
case 0xFF: /* inc/dec Ev */
return 2;
- default: g_assert_not_reached();
+ default: INSTRUCTION_FAIL(0);
}
g_assert_not_reached(); /* TODO:fill the table */
/* NOTREACHED */
return 0;
+
+#undef INSTRUCTION_FAIL
}