Various fixes:
- Remove an extra entry from the array for 0x0f prefixed instruction groups. This fixes decoding of instructions where the second opcode >= 0x80. - Add support for the 64-bit immediate mov instructions. - When short_addr is enabled, don't parse the modr/m byte for a 16-bit address, but as a 32-bit address. - Support %rip relative addressing. - Don't print a displacement of 0 if there is a base or index register. MFC after: 3 days
This commit is contained in:
parent
d77f5882e7
commit
818b0b4bdf
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=164263
@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$");
|
||||
#define Ib 21 /* byte immediate, unsigned */
|
||||
#define Ibs 22 /* byte immediate, signed */
|
||||
#define Iw 23 /* word immediate, unsigned */
|
||||
#define Ilq 24 /* long/quad immediate, unsigned */
|
||||
#define O 25 /* direct address */
|
||||
#define Db 26 /* byte displacement from EIP */
|
||||
#define Dl 27 /* long displacement from EIP */
|
||||
@ -351,7 +352,6 @@ static const struct inst * const db_inst_0f[] = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
db_inst_0f8x,
|
||||
db_inst_0f9x,
|
||||
db_inst_0fax,
|
||||
@ -752,14 +752,14 @@ static const struct inst db_inst_table[256] = {
|
||||
/*b6*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
|
||||
/*b7*/ { "mov", FALSE, BYTE, op2(I, Ri), 0 },
|
||||
|
||||
/*b8*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
|
||||
/*b9*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
|
||||
/*ba*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
|
||||
/*bb*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
|
||||
/*bc*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
|
||||
/*bd*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
|
||||
/*be*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
|
||||
/*bf*/ { "mov", FALSE, LONG, op2(I, Ri), 0 },
|
||||
/*b8*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
|
||||
/*b9*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
|
||||
/*ba*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
|
||||
/*bb*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
|
||||
/*bc*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
|
||||
/*bd*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
|
||||
/*be*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
|
||||
/*bf*/ { "mov", FALSE, LONG, op2(Ilq, Ri), 0 },
|
||||
|
||||
/*c0*/ { "", TRUE, BYTE, op2(Ib, E), db_Grp2 },
|
||||
/*c1*/ { "", TRUE, LONG, op2(Ib, E), db_Grp2 },
|
||||
@ -854,17 +854,6 @@ struct i_addr {
|
||||
int ss;
|
||||
};
|
||||
|
||||
static const char * const db_index_reg_16[8] = {
|
||||
"%bx,%si",
|
||||
"%bx,%di",
|
||||
"%bp,%si",
|
||||
"%bp,%di",
|
||||
"%si",
|
||||
"%di",
|
||||
"%bp",
|
||||
"%bx"
|
||||
};
|
||||
|
||||
static const char * const db_reg[2][4][16] = {
|
||||
|
||||
{{"%al", "%cl", "%dl", "%bl", "%ah", "%ch", "%dh", "%bh",
|
||||
@ -927,7 +916,7 @@ db_read_address(loc, short_addr, rex, regmodrm, addrp)
|
||||
int regmodrm;
|
||||
struct i_addr * addrp; /* out */
|
||||
{
|
||||
int mod, rm, sib, index, disp;
|
||||
int mod, rm, sib, index, disp, size, have_sib;
|
||||
|
||||
mod = f_mod(rex, regmodrm);
|
||||
rm = f_rm(rex, regmodrm);
|
||||
@ -940,68 +929,49 @@ db_read_address(loc, short_addr, rex, regmodrm, addrp)
|
||||
addrp->is_reg = FALSE;
|
||||
addrp->index = 0;
|
||||
|
||||
if (short_addr) {
|
||||
addrp->index = 0;
|
||||
addrp->ss = 0;
|
||||
switch (mod) {
|
||||
case 0:
|
||||
if (rm == 6) {
|
||||
get_value_inc(disp, loc, 2, FALSE);
|
||||
addrp->disp = disp;
|
||||
if (short_addr)
|
||||
size = LONG;
|
||||
else
|
||||
size = QUAD;
|
||||
|
||||
if ((rm & 0x7) == 4) {
|
||||
get_value_inc(sib, loc, 1, FALSE);
|
||||
rm = sib_base(rex, sib);
|
||||
index = sib_index(rex, sib);
|
||||
if (index != 4)
|
||||
addrp->index = db_reg[1][size][index];
|
||||
addrp->ss = sib_ss(rex, sib);
|
||||
have_sib = 1;
|
||||
} else
|
||||
have_sib = 0;
|
||||
|
||||
switch (mod) {
|
||||
case 0:
|
||||
if (rm == 5) {
|
||||
get_value_inc(addrp->disp, loc, 4, FALSE);
|
||||
if (have_sib)
|
||||
addrp->base = 0;
|
||||
}
|
||||
else {
|
||||
addrp->disp = 0;
|
||||
addrp->base = db_index_reg_16[rm];
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
get_value_inc(disp, loc, 1, TRUE);
|
||||
disp &= 0xFFFF;
|
||||
addrp->disp = disp;
|
||||
addrp->base = db_index_reg_16[rm];
|
||||
break;
|
||||
case 2:
|
||||
get_value_inc(disp, loc, 2, FALSE);
|
||||
addrp->disp = disp;
|
||||
addrp->base = db_index_reg_16[rm];
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (mod != 3 && rm == 4) {
|
||||
get_value_inc(sib, loc, 1, FALSE);
|
||||
rm = sib_base(rex, sib);
|
||||
index = sib_index(rex, sib);
|
||||
if (index != 4)
|
||||
addrp->index = db_reg[1][QUAD][index];
|
||||
addrp->ss = sib_ss(rex, sib);
|
||||
}
|
||||
else if (short_addr)
|
||||
addrp->base = "%eip";
|
||||
else
|
||||
addrp->base = "%rip";
|
||||
} else {
|
||||
addrp->disp = 0;
|
||||
addrp->base = db_reg[1][size][rm];
|
||||
}
|
||||
break;
|
||||
|
||||
switch (mod) {
|
||||
case 0:
|
||||
if (rm == 5) {
|
||||
get_value_inc(addrp->disp, loc, 4, FALSE);
|
||||
addrp->base = 0;
|
||||
}
|
||||
else {
|
||||
addrp->disp = 0;
|
||||
addrp->base = db_reg[1][QUAD][rm];
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
get_value_inc(disp, loc, 1, TRUE);
|
||||
addrp->disp = disp;
|
||||
addrp->base = db_reg[1][size][rm];
|
||||
break;
|
||||
|
||||
case 1:
|
||||
get_value_inc(disp, loc, 1, TRUE);
|
||||
addrp->disp = disp;
|
||||
addrp->base = db_reg[1][QUAD][rm];
|
||||
break;
|
||||
|
||||
case 2:
|
||||
get_value_inc(disp, loc, 4, FALSE);
|
||||
addrp->disp = disp;
|
||||
addrp->base = db_reg[1][QUAD][rm];
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
get_value_inc(disp, loc, 4, FALSE);
|
||||
addrp->disp = disp;
|
||||
addrp->base = db_reg[1][size][rm];
|
||||
break;
|
||||
}
|
||||
return (loc);
|
||||
}
|
||||
@ -1022,7 +992,8 @@ db_print_address(seg, size, rex, addrp)
|
||||
db_printf("%s:", seg);
|
||||
}
|
||||
|
||||
db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY);
|
||||
if (addrp->disp != 0 || (addrp->base == 0 && addrp->index == 0))
|
||||
db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY);
|
||||
if (addrp->base != 0 || addrp->index != 0) {
|
||||
db_printf("(");
|
||||
if (addrp->base)
|
||||
@ -1154,6 +1125,7 @@ db_disasm(loc, altfmt)
|
||||
int prefix;
|
||||
int imm;
|
||||
int imm2;
|
||||
long imm64;
|
||||
int len;
|
||||
struct i_addr address;
|
||||
|
||||
@ -1426,6 +1398,12 @@ db_disasm(loc, altfmt)
|
||||
db_printf("$%#r", imm);
|
||||
break;
|
||||
|
||||
case Ilq:
|
||||
len = db_lengths[rex & REX_W ? QUAD : LONG];
|
||||
get_value_inc(imm64, loc, len, FALSE);
|
||||
db_printf("$%#lr", imm64);
|
||||
break;
|
||||
|
||||
case O:
|
||||
len = (short_addr ? 2 : 4);
|
||||
get_value_inc(displ, loc, len, FALSE);
|
||||
|
Loading…
Reference in New Issue
Block a user