=?UTF-8?Q?Andr=C3=A9=20Hentschel=20?=: winedbg: Complete the Thumb disassembler.

Alexandre Julliard julliard at winehq.org
Wed May 2 14:30:01 CDT 2012


Module: wine
Branch: master
Commit: f86ea4cbe9fb81c3c8edc583214f8149d6df2fcc
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=f86ea4cbe9fb81c3c8edc583214f8149d6df2fcc

Author: André Hentschel <nerv at dawncrow.de>
Date:   Tue May  1 19:45:45 2012 +0200

winedbg: Complete the Thumb disassembler.

---

 programs/winedbg/be_arm.c |   77 +++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 71 insertions(+), 6 deletions(-)

diff --git a/programs/winedbg/be_arm.c b/programs/winedbg/be_arm.c
index 7da28b6..8ceb14c 100644
--- a/programs/winedbg/be_arm.c
+++ b/programs/winedbg/be_arm.c
@@ -67,7 +67,7 @@ static char const tbl_shifts[][4] = {
 };
 
 static char const tbl_hiops_t[][4] = {
-"add", "cmp", "mov", "bx"
+    "add", "cmp", "mov", "bx"
 };
 
 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] = {
-"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)
@@ -368,7 +372,7 @@ static WORD thumb_disasm_aluop(WORD inst, ADDRESS64 *addr)
     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 load = (inst >> 11) & 0x01;
@@ -388,7 +392,30 @@ static WORD thumb_disasm_blocktrans(WORD inst, ADDRESS64 *addr)
             else dbg_printf("%s, ", tbl_regs[i]);
         }
     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("}");
     return 0;
@@ -417,6 +444,18 @@ static WORD thumb_disasm_condbranch(WORD inst, ADDRESS64 *addr)
     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)
 {
     WORD src = (inst >> 11) & 0x01;
@@ -471,6 +510,28 @@ static WORD thumb_disasm_ldrimm(WORD inst, ADDRESS64 *addr)
     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)
 {
     WORD op = (inst >> 11) & 0x03;
@@ -531,16 +592,20 @@ struct inst_thumb16
 static const struct inst_thumb16 tbl_thumb16[] = {
     { 0xfc00, 0x4400, thumb_disasm_hireg },
     { 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 },
     { 0xf000, 0xd000, thumb_disasm_condbranch },
+    { 0xf800, 0xe000, thumb_disasm_uncondbranch },
     { 0xf000, 0xa000, thumb_disasm_loadadr },
     { 0xf800, 0x4800, thumb_disasm_ldrpcrel },
     { 0xf000, 0x9000, thumb_disasm_ldrsprel },
     { 0xff00, 0xb000, thumb_disasm_addsprel },
     { 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 },
-    { 0xf000, 0xd000, thumb_disasm_condbranch },
     { 0xff00, 0xdf00, thumb_disasm_swi },
     { 0xff00, 0xbf00, thumb_disasm_nop },
     { 0xf800, 0x1800, thumb_disasm_addsub },




More information about the wine-cvs mailing list