summaryrefslogtreecommitdiff
path: root/utils/libmach/5db.c
diff options
context:
space:
mode:
authorforsyth <forsyth@vitanuova.com>2010-04-27 12:51:13 +0100
committerforsyth <forsyth@vitanuova.com>2010-04-27 12:51:13 +0100
commitd67b7dad77bb8aa973dad1f7c3ab0c309b114278 (patch)
tree6794120fb327d6de19cf05eed53f80d877781a3e /utils/libmach/5db.c
parent09da2e137d5eb0c940df35d989e4c31ec0654fc4 (diff)
20100427-1251
Diffstat (limited to 'utils/libmach/5db.c')
-rw-r--r--utils/libmach/5db.c153
1 files changed, 84 insertions, 69 deletions
diff --git a/utils/libmach/5db.c b/utils/libmach/5db.c
index 8312487c..535739e8 100644
--- a/utils/libmach/5db.c
+++ b/utils/libmach/5db.c
@@ -17,7 +17,7 @@ struct Instr
{
Map *map;
ulong w;
- ulong addr;
+ uvlong addr;
uchar op; /* super opcode */
uchar cond; /* bits 28-31 */
@@ -38,7 +38,7 @@ struct Opcode
{
char* o;
void (*fmt)(Opcode*, Instr*);
- ulong (*foll)(Map*, Rgetter, Instr*, ulong);
+ uvlong (*foll)(Map*, Rgetter, Instr*, uvlong);
char* a;
};
@@ -49,11 +49,11 @@ static char FRAMENAME[] = ".frame";
* Arm-specific debugger interface
*/
-extern char *armexcep(Map*, Rgetter);
-static int armfoll(Map*, ulong, Rgetter, ulong*);
-static int arminst(Map*, ulong, char, char*, int);
-static int armdas(Map*, ulong, char*, int);
-static int arminstlen(Map*, ulong);
+static char *armexcep(Map*, Rgetter);
+static int armfoll(Map*, uvlong, Rgetter, uvlong*);
+static int arminst(Map*, uvlong, char, char*, int);
+static int armdas(Map*, uvlong, char*, int);
+static int arminstlen(Map*, uvlong);
/*
* Debugger interface
@@ -78,13 +78,13 @@ Machdata armmach =
arminstlen, /* instruction size */
};
-char*
+static char*
armexcep(Map *map, Rgetter rget)
{
- long c;
+ uvlong c;
c = (*rget)(map, "TYPE");
- switch (c&0x1f) {
+ switch ((int)c&0x1f) {
case 0x11:
return "Fiq interrupt";
case 0x12:
@@ -148,11 +148,16 @@ armclass(long w)
op++; /* swap */
break;
}
+ if(w & (1<<23)) { /* mullu */
+ op = (48+24+4+4+2+2+4);
+ if(w & (1<<22)) /* mull */
+ op += 2;
+ }
if(w & (1<<21))
op++; /* mla */
break;
}
- if ((op & 0x9) == 0x9) /* ld/st byte/half s/u */
+ if((op & 0x9) == 0x9) /* ld/st byte/half s/u */
{
op = (48+16+4) + ((w >> 22) & 0x1) + ((w >> 19) & 0x2);
break;
@@ -161,7 +166,7 @@ armclass(long w)
if(w & (1<<4))
op += 32;
else
- if(w & (31<<7))
+ if((w & (31<<7)) || (w & (1<<5)))
op += 16;
break;
case 1: /* data processing i,r,r */
@@ -183,16 +188,16 @@ armclass(long w)
op = (48+24+4+4+2+2) + ((w >> 3) & 0x2) + ((w >> 20) & 0x1);
break;
default:
- op = (48+24+4+4+2+2+4);
+ op = (48+24+4+4+2+2+4+4);
break;
}
return op;
}
static int
-decode(Map *map, ulong pc, Instr *i)
+decode(Map *map, uvlong pc, Instr *i)
{
- long w;
+ ulong w;
if(get4(map, pc, &w) < 0) {
werrstr("can't read instruction: %r");
@@ -206,6 +211,8 @@ decode(Map *map, ulong pc, Instr *i)
return 1;
}
+#pragma varargck argpos bprint 2
+
static void
bprint(Instr *i, char *fmt, ...)
{
@@ -226,7 +233,7 @@ plocal(Instr *i)
int offset;
if(!findsym(i->addr, CTEXT, &s)) {
- if(debug)fprint(2,"fn not found @%lux: %r\n", i->addr);
+ if(debug)fprint(2,"fn not found @%llux: %r\n", i->addr);
return 0;
}
fn = s.name;
@@ -248,14 +255,14 @@ plocal(Instr *i)
class == CAUTO ? " auto" : "param", offset);
return 0;
}
- bprint(i, "%s%c%d%s", s.name, class == CPARAM ? '+' : '-', s.value, reg);
+ bprint(i, "%s%c%lld%s", s.name, class == CPARAM ? '+' : '-', s.value, reg);
return 1;
}
/*
* Print value v as name[+offset]
*/
-int
+static int
gsymoff(char *buf, int n, long v, int space)
{
Symbol s;
@@ -277,7 +284,7 @@ gsymoff(char *buf, int n, long v, int space)
if (!delta)
return snprint(buf, n, "%s", s.name);
if (s.type != 't' && s.type != 'T')
- return snprint(buf, n, "%s+%lux", s.name, v-s.value);
+ return snprint(buf, n, "%s+%llux", s.name, v-s.value);
else
return snprint(buf, n, "#%lux", v);
}
@@ -454,7 +461,7 @@ armco(Opcode *o, Instr *i) /* coprocessor instructions */
static int
armcondpass(Map *map, Rgetter rget, uchar cond)
{
- ulong psr;
+ uvlong psr;
uchar n;
uchar z;
uchar c;
@@ -467,24 +474,24 @@ armcondpass(Map *map, Rgetter rget, uchar cond)
v = (psr >> 28) & 1;
switch(cond) {
- case 0: return z;
- case 1: return !z;
- case 2: return c;
- case 3: return !c;
- case 4: return n;
- case 5: return !n;
- case 6: return v;
- case 7: return !v;
- case 8: return c && !z;
- case 9: return !c || z;
- case 10: return n == v;
- case 11: return n != v;
- case 12: return !z && (n == v);
- case 13: return z && (n != v);
- case 14: return 1;
- case 15: return 0;
+ default:
+ case 0: return z;
+ case 1: return !z;
+ case 2: return c;
+ case 3: return !c;
+ case 4: return n;
+ case 5: return !n;
+ case 6: return v;
+ case 7: return !v;
+ case 8: return c && !z;
+ case 9: return !c || z;
+ case 10: return n == v;
+ case 11: return n != v;
+ case 12: return !z && (n == v);
+ case 13: return z && (n != v);
+ case 14: return 1;
+ case 15: return 0;
}
- return 0;
}
static ulong
@@ -503,6 +510,7 @@ armshiftval(Map *map, Rgetter rget, Instr *i)
v = rget(map, buf);
switch((i->w & BITS(4, 6)) >> 4) {
+ default:
case 0: /* LSLIMM */
return v << s;
case 1: /* LSLREG */
@@ -548,7 +556,6 @@ armshiftval(Map *map, Rgetter rget, Instr *i)
return ROR(v, s & 0xF);
}
}
- return 0;
}
static int
@@ -580,15 +587,15 @@ armmaddr(Map *map, Rgetter rget, Instr *i)
nb = nbits(i->w & ((1 << 15) - 1));
switch((i->w >> 23) & 3) {
- case 0: return (v - (nb*4)) + 4;
- case 1: return v;
- case 2: return v - (nb*4);
- case 3: return v + 4;
+ default:
+ case 0: return (v - (nb*4)) + 4;
+ case 1: return v;
+ case 2: return v - (nb*4);
+ case 3: return v + 4;
}
- return 0;
}
-static ulong
+static uvlong
armaddr(Map *map, Rgetter rget, Instr *i)
{
char buf[8];
@@ -634,8 +641,8 @@ armaddr(Map *map, Rgetter rget, Instr *i)
}
}
-static ulong
-armfadd(Map *map, Rgetter rget, Instr *i, ulong pc)
+static uvlong
+armfadd(Map *map, Rgetter rget, Instr *i, uvlong pc)
{
char buf[8];
int r;
@@ -650,8 +657,8 @@ armfadd(Map *map, Rgetter rget, Instr *i, ulong pc)
return rget(map, buf) + armshiftval(map, rget, i);
}
-static ulong
-armfmovm(Map *map, Rgetter rget, Instr *i, ulong pc)
+static uvlong
+armfmovm(Map *map, Rgetter rget, Instr *i, uvlong pc)
{
ulong v;
ulong addr;
@@ -661,15 +668,15 @@ armfmovm(Map *map, Rgetter rget, Instr *i, ulong pc)
return pc+4;
addr = armmaddr(map, rget, i) + nbits(i->w & BITS(0,15));
- if(get4(map, addr, (long*)&v) < 0) {
+ if(get4(map, addr, &v) < 0) {
werrstr("can't read addr: %r");
return -1;
}
return v;
}
-static ulong
-armfbranch(Map *map, Rgetter rget, Instr *i, ulong pc)
+static uvlong
+armfbranch(Map *map, Rgetter rget, Instr *i, uvlong pc)
{
if(!armcondpass(map, rget, (i->w >> 28) & 0xf))
return pc+4;
@@ -677,11 +684,10 @@ armfbranch(Map *map, Rgetter rget, Instr *i, ulong pc)
return pc + (((signed long)i->w << 8) >> 6) + 8;
}
-static ulong
-armfmov(Map *map, Rgetter rget, Instr *i, ulong pc)
+static uvlong
+armfmov(Map *map, Rgetter rget, Instr *i, uvlong pc)
{
- ulong rd;
- ulong v;
+ ulong rd, v;
rd = (i->w >> 12) & 0xf;
if(rd != 15 || !armcondpass(map, rget, (i->w>>28)&0xf))
@@ -690,7 +696,7 @@ armfmov(Map *map, Rgetter rget, Instr *i, ulong pc)
/* LDR */
/* BUG: Needs LDH/B, too */
if(((i->w>>26)&0x3) == 1) {
- if(get4(map, armaddr(map, rget, i), (long*)&v) < 0) {
+ if(get4(map, armaddr(map, rget, i), &v) < 0) {
werrstr("can't read instruction: %r");
return pc+4;
}
@@ -698,7 +704,9 @@ armfmov(Map *map, Rgetter rget, Instr *i, ulong pc)
}
/* MOV */
- return armshiftval(map, rget, i);
+ v = armshiftval(map, rget, i);
+
+ return v;
}
static Opcode opcodes[] =
@@ -775,8 +783,8 @@ static Opcode opcodes[] =
"MVN%C%S", armdpi, 0, "$#%i,R%d",
/* 48+16 */
- "MUL%C%S", armdpi, 0, "R%s,R%M,R%n",
- "MULA%C%S", armdpi, 0, "R%s,R%M,R%n,R%d",
+ "MUL%C%S", armdpi, 0, "R%M,R%s,R%n",
+ "MULA%C%S", armdpi, 0, "R%M,R%s,R%n,R%d",
"SWPW", armdpi, 0, "R%s,(R%n),R%d",
"SWPB", armdpi, 0, "R%s,(R%n),R%d",
@@ -808,6 +816,13 @@ static Opcode opcodes[] =
"MCR%C", armco, 0, "",
"MRC%C", armco, 0, "",
+/* 48+24+4+4+2+2+4 */
+ "MULLU%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",
+ "MULALU%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",
+ "MULL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",
+ "MULAL%C%S", armdpi, 0, "R%M,R%s,(R%n,R%d)",
+
+/* 48+24+4+4+2+2+4+4 */
"UNK", armunk, 0, "",
};
@@ -874,11 +889,11 @@ format(char *mnemonic, Instr *i, char *f)
break;
case 'M':
- bprint(i, "%d", (i->w>>8) & 0xf);
+ bprint(i, "%lud", (i->w>>8) & 0xf);
break;
case 'm':
- bprint(i, "%d", (i->w>>7) & 0x1f);
+ bprint(i, "%lud", (i->w>>7) & 0x1f);
break;
case 'h':
@@ -898,7 +913,7 @@ format(char *mnemonic, Instr *i, char *f)
fmt = "#%lx(R%d)";
if (i->rn == 15) {
/* convert load of offset(PC) to a load immediate */
- if (get4(i->map, i->addr+i->imm+8, &i->imm) > 0)
+ if (get4(i->map, i->addr+i->imm+8, (ulong*)&i->imm) > 0)
{
g = 1;
fmt = "";
@@ -909,7 +924,7 @@ format(char *mnemonic, Instr *i, char *f)
if (i->rd == 11) {
ulong nxti;
- if (get4(i->map, i->addr+4, (long*)&nxti) > 0) {
+ if (get4(i->map, i->addr+4, &nxti) > 0) {
if ((nxti & 0x0e0f0fff) == 0x060c000b) {
i->imm += mach->sb;
g = 1;
@@ -995,7 +1010,7 @@ format(char *mnemonic, Instr *i, char *f)
}
static int
-printins(Map *map, ulong pc, char *buf, int n)
+printins(Map *map, uvlong pc, char *buf, int n)
{
Instr i;
@@ -1009,14 +1024,14 @@ printins(Map *map, ulong pc, char *buf, int n)
}
static int
-arminst(Map *map, ulong pc, char modifier, char *buf, int n)
+arminst(Map *map, uvlong pc, char modifier, char *buf, int n)
{
USED(modifier);
return printins(map, pc, buf, n);
}
static int
-armdas(Map *map, ulong pc, char *buf, int n)
+armdas(Map *map, uvlong pc, char *buf, int n)
{
Instr i;
@@ -1031,7 +1046,7 @@ armdas(Map *map, ulong pc, char *buf, int n)
}
static int
-arminstlen(Map *map, ulong pc)
+arminstlen(Map *map, uvlong pc)
{
Instr i;
@@ -1041,9 +1056,9 @@ arminstlen(Map *map, ulong pc)
}
static int
-armfoll(Map *map, ulong pc, Rgetter rget, ulong *foll)
+armfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
{
- ulong d;
+ uvlong d;
Instr i;
if(decode(map, pc, &i) < 0)