winedbg: Complete the Thumb disassembler.
This commit is contained in:
parent
93a0ca7c6c
commit
f86ea4cbe9
|
@ -67,7 +67,7 @@ static char const tbl_shifts[][4] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static char const tbl_hiops_t[][4] = {
|
static char const tbl_hiops_t[][4] = {
|
||||||
"add", "cmp", "mov", "bx"
|
"add", "cmp", "mov", "bx"
|
||||||
};
|
};
|
||||||
|
|
||||||
static char const tbl_aluops_t[][4] = {
|
static char const tbl_aluops_t[][4] = {
|
||||||
|
@ -76,7 +76,11 @@ static char const tbl_aluops_t[][4] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static char const tbl_immops_t[][4] = {
|
static char const tbl_immops_t[][4] = {
|
||||||
"mov", "cmp", "add", "sub"
|
"mov", "cmp", "add", "sub"
|
||||||
|
};
|
||||||
|
|
||||||
|
static char const tbl_sregops_t[][5] = {
|
||||||
|
"strh", "ldsb", "ldrh", "ldsh"
|
||||||
};
|
};
|
||||||
|
|
||||||
static UINT db_get_inst(void* addr, int size)
|
static UINT db_get_inst(void* addr, int size)
|
||||||
|
@ -368,7 +372,7 @@ static WORD thumb_disasm_aluop(WORD inst, ADDRESS64 *addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WORD thumb_disasm_blocktrans(WORD inst, ADDRESS64 *addr)
|
static WORD thumb_disasm_pushpop(WORD inst, ADDRESS64 *addr)
|
||||||
{
|
{
|
||||||
short lrpc = (inst >> 8) & 0x01;
|
short lrpc = (inst >> 8) & 0x01;
|
||||||
short load = (inst >> 11) & 0x01;
|
short load = (inst >> 11) & 0x01;
|
||||||
|
@ -388,7 +392,30 @@ static WORD thumb_disasm_blocktrans(WORD inst, ADDRESS64 *addr)
|
||||||
else dbg_printf("%s, ", tbl_regs[i]);
|
else dbg_printf("%s, ", tbl_regs[i]);
|
||||||
}
|
}
|
||||||
if (lrpc)
|
if (lrpc)
|
||||||
dbg_printf(", %s", load ? "pc" : "lr");
|
dbg_printf("%s%s", last ? ", " : "", load ? "pc" : "lr");
|
||||||
|
|
||||||
|
dbg_printf("}");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WORD thumb_disasm_blocktrans(WORD inst, ADDRESS64 *addr)
|
||||||
|
{
|
||||||
|
short load = (inst >> 11) & 0x01;
|
||||||
|
short i;
|
||||||
|
short last;
|
||||||
|
|
||||||
|
for (i=7;i>=0;i--)
|
||||||
|
if ((inst>>i) & 1) break;
|
||||||
|
last = i;
|
||||||
|
|
||||||
|
dbg_printf("\n\t%s\t%s!, {", load ? "ldmia" : "stmia", tbl_regs[(inst >> 8) & 0x07]);
|
||||||
|
|
||||||
|
for (i=0;i<=7;i++)
|
||||||
|
if ((inst>>i) & 1)
|
||||||
|
{
|
||||||
|
if (i == last) dbg_printf("%s", tbl_regs[i]);
|
||||||
|
else dbg_printf("%s, ", tbl_regs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
dbg_printf("}");
|
dbg_printf("}");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -417,6 +444,18 @@ static WORD thumb_disasm_condbranch(WORD inst, ADDRESS64 *addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WORD thumb_disasm_uncondbranch(WORD inst, ADDRESS64 *addr)
|
||||||
|
{
|
||||||
|
short offset = (inst & 0x07ff) << 1;
|
||||||
|
|
||||||
|
if (offset & 0x0800) offset |= 0xf000;
|
||||||
|
offset += 4;
|
||||||
|
|
||||||
|
dbg_printf("\n\tb\t");
|
||||||
|
db_printsym(addr->Offset + offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static WORD thumb_disasm_loadadr(WORD inst, ADDRESS64 *addr)
|
static WORD thumb_disasm_loadadr(WORD inst, ADDRESS64 *addr)
|
||||||
{
|
{
|
||||||
WORD src = (inst >> 11) & 0x01;
|
WORD src = (inst >> 11) & 0x01;
|
||||||
|
@ -471,6 +510,28 @@ static WORD thumb_disasm_ldrimm(WORD inst, ADDRESS64 *addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static WORD thumb_disasm_ldrhimm(WORD inst, ADDRESS64 *addr)
|
||||||
|
{
|
||||||
|
WORD offset = (inst & 0x07c0) >> 5;
|
||||||
|
dbg_printf("\n\t%s\t%s, [%s, #%u]", (inst & 0x0800)?"ldrh":"strh",
|
||||||
|
tbl_regs[inst & 0x07], tbl_regs[(inst >> 3) & 0x07], offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WORD thumb_disasm_ldrreg(WORD inst, ADDRESS64 *addr)
|
||||||
|
{
|
||||||
|
dbg_printf("\n\t%s%s\t%s, [%s, %s]", (inst & 0x0800)?"ldr":"str", (inst & 0x0400)?"b":"",
|
||||||
|
tbl_regs[inst & 0x07], tbl_regs[(inst >> 3) & 0x07], tbl_regs[(inst >> 6) & 0x07]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WORD thumb_disasm_ldrsreg(WORD inst, ADDRESS64 *addr)
|
||||||
|
{
|
||||||
|
dbg_printf("\n\t%s\t%s, [%s, %s]", tbl_sregops_t[(inst >> 10) & 0x03],
|
||||||
|
tbl_regs[inst & 0x07], tbl_regs[(inst >> 3) & 0x07], tbl_regs[(inst >> 6) & 0x07]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static WORD thumb_disasm_immop(WORD inst, ADDRESS64 *addr)
|
static WORD thumb_disasm_immop(WORD inst, ADDRESS64 *addr)
|
||||||
{
|
{
|
||||||
WORD op = (inst >> 11) & 0x03;
|
WORD op = (inst >> 11) & 0x03;
|
||||||
|
@ -531,16 +592,20 @@ struct inst_thumb16
|
||||||
static const struct inst_thumb16 tbl_thumb16[] = {
|
static const struct inst_thumb16 tbl_thumb16[] = {
|
||||||
{ 0xfc00, 0x4400, thumb_disasm_hireg },
|
{ 0xfc00, 0x4400, thumb_disasm_hireg },
|
||||||
{ 0xfc00, 0x4000, thumb_disasm_aluop },
|
{ 0xfc00, 0x4000, thumb_disasm_aluop },
|
||||||
{ 0xf600, 0xb400, thumb_disasm_blocktrans },
|
{ 0xf600, 0xb400, thumb_disasm_pushpop },
|
||||||
|
{ 0xf000, 0xc000, thumb_disasm_blocktrans },
|
||||||
{ 0xf800, 0xf000, thumb_disasm_longbl },
|
{ 0xf800, 0xf000, thumb_disasm_longbl },
|
||||||
{ 0xf000, 0xd000, thumb_disasm_condbranch },
|
{ 0xf000, 0xd000, thumb_disasm_condbranch },
|
||||||
|
{ 0xf800, 0xe000, thumb_disasm_uncondbranch },
|
||||||
{ 0xf000, 0xa000, thumb_disasm_loadadr },
|
{ 0xf000, 0xa000, thumb_disasm_loadadr },
|
||||||
{ 0xf800, 0x4800, thumb_disasm_ldrpcrel },
|
{ 0xf800, 0x4800, thumb_disasm_ldrpcrel },
|
||||||
{ 0xf000, 0x9000, thumb_disasm_ldrsprel },
|
{ 0xf000, 0x9000, thumb_disasm_ldrsprel },
|
||||||
{ 0xff00, 0xb000, thumb_disasm_addsprel },
|
{ 0xff00, 0xb000, thumb_disasm_addsprel },
|
||||||
{ 0xe000, 0x6000, thumb_disasm_ldrimm },
|
{ 0xe000, 0x6000, thumb_disasm_ldrimm },
|
||||||
|
{ 0xf000, 0x8000, thumb_disasm_ldrhimm },
|
||||||
|
{ 0xf200, 0x5000, thumb_disasm_ldrreg },
|
||||||
|
{ 0xf200, 0x5200, thumb_disasm_ldrsreg },
|
||||||
{ 0xe000, 0x2000, thumb_disasm_immop },
|
{ 0xe000, 0x2000, thumb_disasm_immop },
|
||||||
{ 0xf000, 0xd000, thumb_disasm_condbranch },
|
|
||||||
{ 0xff00, 0xdf00, thumb_disasm_swi },
|
{ 0xff00, 0xdf00, thumb_disasm_swi },
|
||||||
{ 0xff00, 0xbf00, thumb_disasm_nop },
|
{ 0xff00, 0xbf00, thumb_disasm_nop },
|
||||||
{ 0xf800, 0x1800, thumb_disasm_addsub },
|
{ 0xf800, 0x1800, thumb_disasm_addsub },
|
||||||
|
|
Loading…
Reference in New Issue