summaryrefslogtreecommitdiff
path: root/utils/libmach
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
parent09da2e137d5eb0c940df35d989e4c31ec0654fc4 (diff)
20100427-1251
Diffstat (limited to 'utils/libmach')
-rw-r--r--utils/libmach/2.c5
-rw-r--r--utils/libmach/2db.c200
-rw-r--r--utils/libmach/2obj.c8
-rw-r--r--utils/libmach/5db.c153
-rw-r--r--utils/libmach/6.c97
-rw-r--r--utils/libmach/6obj.c8
-rw-r--r--utils/libmach/8db.c2123
-rw-r--r--utils/libmach/9.c120
-rw-r--r--utils/libmach/9obj.c155
-rw-r--r--utils/libmach/a.out.h9
-rw-r--r--utils/libmach/access.c134
-rw-r--r--utils/libmach/ar.h3
-rw-r--r--utils/libmach/bootexec.h40
-rw-r--r--utils/libmach/elf.h39
-rw-r--r--utils/libmach/executable.c625
-rw-r--r--utils/libmach/kdb.c493
-rw-r--r--utils/libmach/machdata.c68
-rw-r--r--utils/libmach/map.c60
-rw-r--r--utils/libmach/mkfile7
-rw-r--r--utils/libmach/obj.c47
-rw-r--r--utils/libmach/obj.h3
-rw-r--r--utils/libmach/q.c161
-rw-r--r--utils/libmach/qdb.c497
-rw-r--r--utils/libmach/qobj.c26
-rw-r--r--utils/libmach/swap.c34
-rw-r--r--utils/libmach/sym.c394
-rw-r--r--utils/libmach/t.c8
-rw-r--r--utils/libmach/tdb.c38
-rw-r--r--utils/libmach/ureg6.h58
-rw-r--r--utils/libmach/ureg9.h44
-rw-r--r--utils/libmach/uregq.h2
-rw-r--r--utils/libmach/uregt.h38
-rw-r--r--utils/libmach/vcodas.c10
-rw-r--r--utils/libmach/vdb.c111
34 files changed, 3414 insertions, 2404 deletions
diff --git a/utils/libmach/2.c b/utils/libmach/2.c
index 2b1010f4..9d58b00b 100644
--- a/utils/libmach/2.c
+++ b/utils/libmach/2.c
@@ -75,8 +75,9 @@ Mach m68020 =
"a6base", /* static base register name */
0, /* value */
0x2000, /* page size */
- 0x80000000, /* kernel base */
- 0, /* kernel text mask */
+ 0x80000000U, /* kernel base */
+ 0x80000000U, /* kernel text mask */
+ 0x7FFFFFFFU, /* user stack top */
2, /* quantization of pc */
4, /* szaddr */
4, /* szreg */
diff --git a/utils/libmach/2db.c b/utils/libmach/2db.c
index 5aa61fd3..284df3c5 100644
--- a/utils/libmach/2db.c
+++ b/utils/libmach/2db.c
@@ -1,6 +1,6 @@
#include <lib9.h>
#include <bio.h>
-#include "mach.h"
+#include <mach.h>
/*
* 68020-specific debugger interface
@@ -8,10 +8,10 @@
static char *m68020excep(Map*, Rgetter);
-static int m68020foll(Map*, ulong, Rgetter, ulong*);
-static int m68020inst(Map*, ulong, char, char*, int);
-static int m68020das(Map*, ulong, char*, int);
-static int m68020instlen(Map*, ulong);
+static int m68020foll(Map*, uvlong, Rgetter, uvlong*);
+static int m68020inst(Map*, uvlong, char, char*, int);
+static int m68020das(Map*, uvlong, char*, int);
+static int m68020instlen(Map*, uvlong);
Machdata m68020mach =
{
@@ -99,9 +99,10 @@ m68020ufix(Map *map)
{
struct ftype *ft;
int i, size, vec;
- ulong efl[2], stktop;
+ ulong efl[2];
uchar *ef=(uchar*)efl;
- long l;
+ ulong l;
+ uvlong stktop;
short fvo;
/* The kernel proc pointer on a 68020 is always
@@ -116,8 +117,8 @@ m68020ufix(Map *map)
if ((l&0xfc000000) == 0x04000000) /* if NeXT */
size = 30*2;
else
- size = 46*2; /* 68020 */
- USED(size); /* kept because it might be re-used later */
+ size = 46*2; /* 68020 */
+ USED(size);
stktop = mach->kbase+mach->pgsize;
for(i=3; i<100; i++){
@@ -150,7 +151,7 @@ m68020ufix(Map *map)
static char *
m68020excep(Map *map, Rgetter rget)
{
- ulong pc;
+ uvlong pc;
uchar buf[4];
if (m68020ufix(map) < 0)
@@ -373,20 +374,20 @@ struct operand
{
int eatype;
short ext;
- union {
+ /*union {*/
long immediate; /* sign-extended integer byte/word/long */
- struct { /* index mode displacements */
+ /*struct {*/ /* index mode displacements */
long disp;
long outer;
- } s0;
+ /*};*/
char floater[24]; /* floating point immediates */
- } u0;
+ /*};*/
};
struct inst
{
int n; /* # bytes in instruction */
- ulong addr; /* addr of start of instruction */
+ uvlong addr; /* addr of start of instruction */
ushort raw[4+12]; /* longest instruction: 24 byte packed immediate */
Operand and[2];
char *end; /* end of print buffer */
@@ -911,7 +912,7 @@ dumpinst(Inst *ip, char *buf, int n)
}
static int
-getword(Inst *ip, long offset)
+getword(Inst *ip, uvlong offset)
{
if (ip->n < nelem(ip->raw)) {
if (get2(mymap, offset, &ip->raw[ip->n++]) > 0)
@@ -978,56 +979,55 @@ getimm(Inst *ip, Operand *ap, int mode)
{
case EAM_B: /* byte */
case EAALL_B:
- return i8(ip, &ap->u0.immediate);
+ return i8(ip, &ap->immediate);
case EADI_W: /* word */
case EAALL_W:
- return i16(ip, &ap->u0.immediate);
+ return i16(ip, &ap->immediate);
case EADI_L: /* long */
case EAALL_L:
- return i32(ip, &ap->u0.immediate);
+ return i32(ip, &ap->immediate);
case EAFLT: /* floating point - size in bits 10-12 or word 1 */
switch((ip->raw[1]>>10)&0x07)
{
case 0: /* long integer */
- return i32(ip, &ap->u0.immediate);
+ return i32(ip, &ap->immediate);
case 1: /* single precision real */
ap->eatype = IREAL;
- return getshorts(ip, ap->u0.floater, 2);
+ return getshorts(ip, ap->floater, 2);
case 2: /* extended precision real - not supported */
ap->eatype = IEXT;
- return getshorts(ip, ap->u0.floater, 6);
+ return getshorts(ip, ap->floater, 6);
case 3: /* packed decimal real - not supported */
ap->eatype = IPACK;
- return getshorts(ip, ap->u0.floater, 12);
+ return getshorts(ip, ap->floater, 12);
case 4: /* integer word */
- return i16(ip, &ap->u0.immediate);
+ return i16(ip, &ap->immediate);
case 5: /* double precision real */
ap->eatype = IDBL;
- return getshorts(ip, ap->u0.floater, 4);
+ return getshorts(ip, ap->floater, 4);
case 6: /* integer byte */
- return i8(ip, &ap->u0.immediate);
+ return i8(ip, &ap->immediate);
default:
ip->errmsg = "bad immediate float data";
return -1;
}
- break;
+ /* not reached */
case IV: /* size encoded in bits 6&7 of opcode word */
default:
switch((ip->raw[0]>>6)&0x03)
{
case 0x00: /* integer byte */
- return i8(ip, &ap->u0.immediate);
+ return i8(ip, &ap->immediate);
case 0x01: /* integer word */
- return i16(ip, &ap->u0.immediate);
+ return i16(ip, &ap->immediate);
case 0x02: /* integer long */
- return i32(ip, &ap->u0.immediate);
+ return i32(ip, &ap->immediate);
default:
ip->errmsg = "bad immediate size";
return -1;
}
- break;
+ /* not reached */
}
- return 1;
}
static int
@@ -1040,9 +1040,9 @@ getdisp(Inst *ip, Operand *ap)
ext = ip->raw[ip->n-1];
ap->ext = ext;
if ((ext&0x100) == 0) { /* indexed with 7-bit displacement */
- ap->u0.s0.disp = ext&0x7f;
- if (ap->u0.s0.disp&0x40)
- ap->u0.s0.disp |= ~0x7f;
+ ap->disp = ext&0x7f;
+ if (ap->disp&0x40)
+ ap->disp |= ~0x7f;
return 1;
}
switch(ext&0x30) /* first (inner) displacement */
@@ -1050,11 +1050,11 @@ getdisp(Inst *ip, Operand *ap)
case 0x10:
break;
case 0x20:
- if (i16(ip, &ap->u0.s0.disp) < 0)
+ if (i16(ip, &ap->disp) < 0)
return -1;
break;
case 0x30:
- if (i32(ip, &ap->u0.s0.disp) < 0)
+ if (i32(ip, &ap->disp) < 0)
return -1;
break;
default:
@@ -1064,9 +1064,9 @@ getdisp(Inst *ip, Operand *ap)
switch (ext&0x03) /* outer displacement */
{
case 0x02: /* 16 bit displacement */
- return i16(ip, &ap->u0.s0.outer);
+ return i16(ip, &ap->outer);
case 0x03: /* 32 bit displacement */
- return i32(ip, &ap->u0.s0.outer);
+ return i32(ip, &ap->outer);
default:
break;
}
@@ -1105,7 +1105,7 @@ ea(Inst *ip, int ea, Operand *ap, int mode)
case 0x05:
ap->eatype = ADisp;
type = Bdisp;
- if (i16(ip, &ap->u0.s0.disp) < 0)
+ if (i16(ip, &ap->disp) < 0)
return -1;
break;
case 0x06:
@@ -1120,19 +1120,19 @@ ea(Inst *ip, int ea, Operand *ap, int mode)
case 0x00:
type = Abs;
ap->eatype = ABS;
- if (i16(ip, &ap->u0.immediate) < 0)
+ if (i16(ip, &ap->immediate) < 0)
return -1;
break;
case 0x01:
type = Abs;
ap->eatype = ABS;
- if (i32(ip, &ap->u0.immediate) < 0)
+ if (i32(ip, &ap->immediate) < 0)
return -1;
break;
case 0x02:
type = PCrel;
ap->eatype = PDisp;
- if (i16(ip, &ap->u0.s0.disp) < 0)
+ if (i16(ip, &ap->disp) < 0)
return -1;
break;
case 0x03:
@@ -1217,27 +1217,27 @@ decode(Inst *ip, Optable *op)
break;
case OP8: /* weird movq instruction */
ap->eatype = IMM;
- ap->u0.immediate = opcode&0xff;
+ ap->immediate = opcode&0xff;
if (opcode&0x80)
- ap->u0.immediate |= ~0xff;
+ ap->immediate |= ~0xff;
break;
case I8: /* must be two-word opcode */
ap->eatype = IMM;
- ap->u0.immediate = ip->raw[1]&0xff;
- if (ap->u0.immediate&0x80)
- ap->u0.immediate |= ~0xff;
+ ap->immediate = ip->raw[1]&0xff;
+ if (ap->immediate&0x80)
+ ap->immediate |= ~0xff;
break;
case I16: /* 16 bit immediate */
case BR16:
ap->eatype = IMM;
- if (i16(ip, &ap->u0.immediate) < 0)
+ if (i16(ip, &ap->immediate) < 0)
return -1;
break;
case C16: /* CAS2 16 bit immediate */
ap->eatype = IMM;
- if (i16(ip, &ap->u0.immediate) < 0)
+ if (i16(ip, &ap->immediate) < 0)
return -1;
- if (ap->u0.immediate & 0x0e38) {
+ if (ap->immediate & 0x0e38) {
ip->errmsg = "bad CAS2W operand";
return 0;
}
@@ -1245,7 +1245,7 @@ decode(Inst *ip, Optable *op)
case I32: /* 32 bit immediate */
case BR32:
ap->eatype = IMM;
- if (i32(ip, &ap->u0.immediate) < 0)
+ if (i32(ip, &ap->immediate) < 0)
return -1;
break;
case IV: /* immediate data depends on size field */
@@ -1254,15 +1254,15 @@ decode(Inst *ip, Optable *op)
break;
case BR8: /* branch displacement format */
ap->eatype = IMM;
- ap->u0.immediate = opcode&0xff;
- if (ap->u0.immediate == 0) {
- if (i16(ip, &ap->u0.immediate) < 0)
+ ap->immediate = opcode&0xff;
+ if (ap->immediate == 0) {
+ if (i16(ip, &ap->immediate) < 0)
return -1;
- } else if (ap->u0.immediate == 0xff) {
- if (i32(ip, &ap->u0.immediate) < 0)
+ } else if (ap->immediate == 0xff) {
+ if (i32(ip, &ap->immediate) < 0)
return -1;
- } else if (ap->u0.immediate & 0x80)
- ap->u0.immediate |= ~0xff;
+ } else if (ap->immediate & 0x80)
+ ap->immediate |= ~0xff;
break;
case STACK: /* Dummy operand type for Return instructions */
default:
@@ -1299,6 +1299,8 @@ instruction(Inst *ip)
return 0;
}
+#pragma varargck argpos bprint 2
+
static void
bprint(Inst *i, char *fmt, ...)
{
@@ -1318,11 +1320,12 @@ static char *regname[] =
static void
plocal(Inst *ip, Operand *ap)
{
- int ret, offset;
- long moved;
+ int ret;
+ long offset;
+ uvlong moved;
Symbol s;
- offset = ap->u0.s0.disp;
+ offset = ap->disp;
if (!findsym(ip->addr, CTEXT, &s))
goto none;
@@ -1338,7 +1341,7 @@ plocal(Inst *ip, Operand *ap)
if (ret)
bprint(ip, "%s+%lux", s.name, offset);
else
-none: bprint(ip, "%lux", ap->u0.s0.disp);
+none: bprint(ip, "%lux", ap->disp);
}
/*
@@ -1401,7 +1404,7 @@ prindex(Inst *ip, int reg, Operand *ap)
if (left <= 0)
return;
ext = ap->ext;
- disp = ap->u0.s0.disp;
+ disp = ap->disp;
/* look for static base register references */
if ((ext&0xa0) == 0x20 && reg == 14 && mach->sb && disp) {
reg = 17; /* "A6" -> "SB" */
@@ -1429,7 +1432,7 @@ prindex(Inst *ip, int reg, Operand *ap)
break;
case 0x12:
case 0x13:
- ip->curr += symoff(ip->curr, left, ap->u0.s0.outer, CANY);
+ ip->curr += symoff(ip->curr, left, ap->outer, CANY);
if (pidx(ip, ext, reg, "((%s)", "((%s)", 0))
bprint(ip, ")");
break;
@@ -1439,7 +1442,7 @@ prindex(Inst *ip, int reg, Operand *ap)
break;
case 0x16:
case 0x17:
- ip->curr += symoff(ip->curr, left, ap->u0.s0.outer, CANY);
+ ip->curr += symoff(ip->curr, left, ap->outer, CANY);
pidx(ip, ext, reg, "((%s))", "(%s)", 0);
break;
case 0x20:
@@ -1464,7 +1467,7 @@ prindex(Inst *ip, int reg, Operand *ap)
case 0x23:
case 0x32:
case 0x33:
- ip->curr += symoff(ip->curr, left, ap->u0.s0.outer, CANY);
+ ip->curr += symoff(ip->curr, left, ap->outer, CANY);
bprint(ip, "(");
if (reg == 15)
plocal(ip, ap);
@@ -1487,7 +1490,7 @@ prindex(Inst *ip, int reg, Operand *ap)
case 0x27:
case 0x36:
case 0x37:
- ip->curr += symoff(ip->curr, left, ap->u0.s0.outer, CANY);
+ ip->curr += symoff(ip->curr, left, ap->outer, CANY);
bprint(ip, "(");
if (reg == 15)
plocal(ip, ap);
@@ -1528,53 +1531,53 @@ pea(int reg, Inst *ip, Operand *ap)
bprint(ip, "-(A%d)", reg);
break;
case PDisp:
- ip->curr += symoff(ip->curr, left, ip->addr+2+ap->u0.s0.disp, CANY);
+ ip->curr += symoff(ip->curr, left, ip->addr+2+ap->disp, CANY);
break;
case PXD:
prindex(ip, 16, ap);
break;
case ADisp: /* references off the static base */
- if (reg == 6 && mach->sb && ap->u0.s0.disp) {
- ip->curr += symoff(ip->curr, left, ap->u0.s0.disp+mach->sb, CANY);
- bprint(ip, "(SB)", reg);
+ if (reg == 6 && mach->sb && ap->disp) {
+ ip->curr += symoff(ip->curr, left, ap->disp+mach->sb, CANY);
+ bprint(ip, "(SB)");
break;
}
/* reference autos and parameters off the stack */
if (reg == 7)
plocal(ip, ap);
else
- ip->curr += symoff(ip->curr, left, ap->u0.s0.disp, CANY);
+ ip->curr += symoff(ip->curr, left, ap->disp, CANY);
bprint(ip, "(A%d)", reg);
break;
case BXD:
prindex(ip, reg+8, ap);
break;
case ABS:
- ip->curr += symoff(ip->curr, left, ap->u0.immediate, CANY);
+ ip->curr += symoff(ip->curr, left, ap->immediate, CANY);
bprint(ip, "($0)");
break;
case IMM:
*ip->curr++ = '$';
- ip->curr += symoff(ip->curr, left-1, ap->u0.immediate, CANY);
+ ip->curr += symoff(ip->curr, left-1, ap->immediate, CANY);
break;
case IREAL:
*ip->curr++ = '$';
- ip->curr += beieeesftos(ip->curr, left-1, (void*) ap->u0.floater);
+ ip->curr += beieeesftos(ip->curr, left-1, (void*) ap->floater);
break;
case IDBL:
*ip->curr++ = '$';
- ip->curr += beieeedftos(ip->curr, left-1, (void*) ap->u0.floater);
+ ip->curr += beieeedftos(ip->curr, left-1, (void*) ap->floater);
break;
case IPACK:
bprint(ip, "$#");
for (i = 0; i < 24 && ip->curr < ip->end-1; i++) {
- _hexify(ip->curr, ap->u0.floater[i], 1);
+ _hexify(ip->curr, ap->floater[i], 1);
ip->curr += 2;
}
break;
case IEXT:
bprint(ip, "$#");
- ip->curr += beieee80ftos(ip->curr, left-2, (void*)ap->u0.floater);
+ ip->curr += beieee80ftos(ip->curr, left-2, (void*)ap->floater);
break;
default:
bprint(ip, "??%x??", ap->eatype);
@@ -1646,7 +1649,7 @@ formatins(char *fmt, Inst *ip)
break;
case 'i': /* immediate operand */
ip->curr += symoff(ip->curr, ip->end-ip->curr,
- ip->and[currand++].u0.immediate, CANY);
+ ip->and[currand++].immediate, CANY);
break;
case 'j': /* data registers; word 1: [0-2] & [12-14] */
r1 = w1&0x07;
@@ -1686,7 +1689,7 @@ formatins(char *fmt, Inst *ip)
break;
case 't': /* text offset */
ip->curr += symoff(ip->curr, ip->end-ip->curr,
- ip->and[currand++].u0.immediate+ip->addr+2, CTEXT);
+ ip->and[currand++].immediate+ip->addr+2, CTEXT);
break;
case 'u': /* register number; word 1: [6-8] */
*ip->curr++ = ((w1>>6)&0x07)+'0';
@@ -1817,7 +1820,6 @@ immsize(Inst *ip, int mode)
default:
return isize[(ip->raw[0]>>6)&0x03];
}
- return -1;
}
static int
@@ -1902,7 +1904,7 @@ instrsize(Inst *ip, Optable *op)
case BREAC: /* EAC JMP or CALL operand */
/* easy displacements for follow set */
if ((opcode&0x038) == 0x28 || (opcode&0x3f) == 0x3a) {
- if (i16(ip, &ip->and[i].u0.immediate) < 0)
+ if (i16(ip, &ip->and[i].immediate) < 0)
return -1;
} else {
t = easize(ip, opcode&0x3f, mode);
@@ -1916,11 +1918,11 @@ instrsize(Inst *ip, Optable *op)
ip->n++;
break;
case BR16: /* 16 bit branch displacement */
- if (i16(ip, &ip->and[i].u0.immediate) < 0)
+ if (i16(ip, &ip->and[i].immediate) < 0)
return -1;
break;
case BR32: /* 32 bit branch displacement */
- if (i32(ip, &ip->and[i].u0.immediate) < 0)
+ if (i32(ip, &ip->and[i].immediate) < 0)
return -1;
break;
case I32: /* 32 bit immediate */
@@ -1938,15 +1940,15 @@ instrsize(Inst *ip, Optable *op)
case BR8: /* loony branch displacement format */
t = opcode&0xff;
if (t == 0) {
- if (i16(ip, &ip->and[i].u0.immediate) < 0)
+ if (i16(ip, &ip->and[i].immediate) < 0)
return -1;
} else if (t == 0xff) {
- if (i32(ip, &ip->and[i].u0.immediate) < 0)
+ if (i32(ip, &ip->and[i].immediate) < 0)
return -1;
} else {
- ip->and[i].u0.immediate = t;
+ ip->and[i].immediate = t;
if (t & 0x80)
- ip->and[i].u0.immediate |= ~0xff;
+ ip->and[i].immediate |= ~0xff;
}
break;
case STACK: /* Dummy operand for Return instructions */
@@ -1972,19 +1974,19 @@ eaval(Inst *ip, Operand *ap, Rgetter rget)
sprint(buf, "A%d", reg);
return (*rget)(mymap, buf);
case PDisp:
- return ip->addr+2+ap->u0.s0.disp;
+ return ip->addr+2+ap->disp;
case ADisp:
sprint(buf, "A%d", reg);
- return ap->u0.s0.disp+(*rget)(mymap, buf);
+ return ap->disp+(*rget)(mymap, buf);
case ABS:
- return ap->u0.immediate;
+ return ap->immediate;
default:
return 0;
}
}
static int
-m68020instlen(Map *map, ulong pc)
+m68020instlen(Map *map, uvlong pc)
{
Inst i;
Optable *op;
@@ -1999,10 +2001,11 @@ m68020instlen(Map *map, ulong pc)
}
static int
-m68020foll(Map *map, ulong pc, Rgetter rget, ulong *foll)
+m68020foll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
{
int j;
Inst i;
+ ulong l;
Optable *op;
mymap = map;
@@ -2021,11 +2024,12 @@ m68020foll(Map *map, ulong pc, Rgetter rget, ulong *foll)
case BR16: /* FBcc, FDBcc, DBcc */
case BR32: /* FBcc */
foll[0] = pc+i.n*2;
- foll[1] = pc+2+i.and[j].u0.immediate;
+ foll[1] = pc+2+i.and[j].immediate;
return 2;
case STACK: /* RTR, RTS, RTD */
- if (get4(map, (*rget)(map, mach->sp), (long*) foll) < 0)
+ if (get4(map, (*rget)(map, mach->sp), &l) < 0)
return -1;
+ *foll = l;
return 1;
default:
break;
@@ -2036,7 +2040,7 @@ m68020foll(Map *map, ulong pc, Rgetter rget, ulong *foll)
}
static int
-m68020inst(Map *map, ulong pc, char modifier, char *buf, int n)
+m68020inst(Map *map, uvlong pc, char modifier, char *buf, int n)
{
Inst i;
Optable *op;
@@ -2062,7 +2066,7 @@ m68020inst(Map *map, ulong pc, char modifier, char *buf, int n)
}
static int
-m68020das(Map *map, ulong pc, char *buf, int n)
+m68020das(Map *map, uvlong pc, char *buf, int n)
{
Inst i;
Optable *op;
diff --git a/utils/libmach/2obj.c b/utils/libmach/2obj.c
index 368e1ec7..ad3540b7 100644
--- a/utils/libmach/2obj.c
+++ b/utils/libmach/2obj.c
@@ -3,6 +3,7 @@
*/
#include <lib9.h>
#include <bio.h>
+#include <mach.h>
#include "2c/2.out.h"
#include "obj.h"
@@ -42,9 +43,12 @@ _read2(Biobuf *bp, Prog *p)
return 0;
as |= ((c & 0xff) << 8);
p->kind = aNone;
+ p->sig = 0;
if(as == ANAME || as == ASIGNAME){
- if(as == ASIGNAME)
- skip(bp, 4); /* signature */
+ if(as == ASIGNAME){
+ Bread(bp, &p->sig, 4);
+ p->sig = beswal(p->sig);
+ }
p->kind = aName;
p->type = type2char(Bgetc(bp)); /* type */
p->sym = Bgetc(bp); /* sym */
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)
diff --git a/utils/libmach/6.c b/utils/libmach/6.c
index 28c74a43..459d1191 100644
--- a/utils/libmach/6.c
+++ b/utils/libmach/6.c
@@ -1,16 +1,12 @@
/*
- * x86-amd64 definition
+ * amd64 definition
*/
#include <lib9.h>
#include <bio.h>
#include "ureg6.h"
#include "mach.h"
-#define REGOFF(x) (uvlong)(&((struct Ureg *) 0)->x)
-
-#define PC REGOFF(pc)
-#define SP REGOFF(sp)
-#define AX REGOFF(ax)
+#define REGOFF(x) offsetof(struct Ureg, x)
#define REGSIZE sizeof(struct Ureg)
#define FP_CTLS(x) (REGSIZE+2*(x))
@@ -21,41 +17,43 @@
#define FPREGSIZE 512 /* TO DO? currently only 0x1A0 used */
Reglist amd64reglist[] = {
- {"R15", REGOFF(r15), RINT, 'Y'},
- {"R14", REGOFF(r14), RINT, 'Y'},
- {"R13", REGOFF(r13), RINT, 'Y'},
- {"R12", REGOFF(r12), RINT, 'Y'},
- {"R11", REGOFF(r11), RINT, 'Y'},
- {"R10", REGOFF(r10), RINT, 'Y'},
- {"R9", REGOFF(r9), RINT, 'Y'},
- {"R8", REGOFF(r8), RINT, 'Y'},
- {"DI", REGOFF(di), RINT, 'X'},
- {"SI", REGOFF(si), RINT, 'Y'},
- {"BP", REGOFF(bp), RINT, 'Y'},
+ {"AX", REGOFF(ax), RINT, 'Y'},
{"BX", REGOFF(bx), RINT, 'Y'},
- {"DX", REGOFF(dx), RINT, 'Y'},
{"CX", REGOFF(cx), RINT, 'Y'},
- {"AX", REGOFF(ax), RINT, 'Y'},
- {"GS", REGOFF(gs), RINT, 'Y'},
- {"FS", REGOFF(fs), RINT, 'Y'},
- {"ES", REGOFF(es), RINT, 'Y'},
- {"DS", REGOFF(ds), RINT, 'Y'},
- {"TRAP", REGOFF(trap), RINT, 'Y'},
- {"ECODE", REGOFF(ecode), RINT, 'Y'},
- {"PC", PC, RINT, 'Y'},
+ {"DX", REGOFF(dx), RINT, 'Y'},
+ {"SI", REGOFF(si), RINT, 'Y'},
+ {"DI", REGOFF(di), RINT, 'Y'},
+ {"BP", REGOFF(bp), RINT, 'Y'},
+ {"R8", REGOFF(r8), RINT, 'Y'},
+ {"R9", REGOFF(r9), RINT, 'Y'},
+ {"R10", REGOFF(r10), RINT, 'Y'},
+ {"R11", REGOFF(r11), RINT, 'Y'},
+ {"R12", REGOFF(r12), RINT, 'Y'},
+ {"R13", REGOFF(r13), RINT, 'Y'},
+ {"R14", REGOFF(r14), RINT, 'Y'},
+ {"R15", REGOFF(r15), RINT, 'Y'},
+ {"DS", REGOFF(ds), RINT, 'x'},
+ {"ES", REGOFF(es), RINT, 'x'},
+ {"FS", REGOFF(fs), RINT, 'x'},
+ {"GS", REGOFF(gs), RINT, 'x'},
+ {"TYPE", REGOFF(type), RINT, 'Y'},
+ {"TRAP", REGOFF(type), RINT, 'Y'}, /* alias for acid */
+ {"ERROR", REGOFF(error), RINT, 'Y'},
+ {"IP", REGOFF(ip), RINT, 'Y'},
+ {"PC", REGOFF(ip), RINT, 'Y'}, /* alias for acid */
{"CS", REGOFF(cs), RINT, 'Y'},
- {"EFLAGS", REGOFF(flags), RINT, 'Y'},
- {"SP", SP, RINT, 'Y'},
+ {"FLAGS", REGOFF(flags), RINT, 'Y'},
+ {"SP", REGOFF(sp), RINT, 'Y'},
{"SS", REGOFF(ss), RINT, 'Y'},
{"FCW", FP_CTLS(0), RFLT, 'x'},
{"FSW", FP_CTLS(1), RFLT, 'x'},
- {"FTW", FP_CTLS(2), RFLT, 'x'},
+ {"FTW", FP_CTLS(2), RFLT, 'b'},
{"FOP", FP_CTLS(3), RFLT, 'x'},
- {"FPC", FP_CTL(2), RFLT, 'Y'},
+ {"RIP", FP_CTL(2), RFLT, 'Y'},
{"RDP", FP_CTL(4), RFLT, 'Y'},
- {"MXCSR", FP_CTL(6), RFLT, 'X'},
- {"MXCSRMSK", FP_CTL(7), RFLT, 'X'},
+ {"MXCSR", FP_CTL(6), RFLT, 'X'},
+ {"MXCSRMASK", FP_CTL(7), RFLT, 'X'},
{"M0", FP_REG(0), RFLT, 'F'}, /* assumes double */
{"M1", FP_REG(1), RFLT, 'F'},
{"M2", FP_REG(2), RFLT, 'F'},
@@ -97,21 +95,22 @@ Reglist amd64reglist[] = {
Mach mamd64=
{
"amd64",
- MI386, /* machine type */ /* TO DO */
- amd64reglist, /* register list */
- REGSIZE, /* size of registers in bytes */
- FPREGSIZE, /* size of fp registers in bytes */
- "PC", /* name of PC */
- "SP", /* name of SP */
- 0, /* link register */
- "setSB", /* static base register name (bogus anyways) */
- 0, /* static base register value */
- 0x1000, /* page size */
- 0x80100000, /* kernel base */ /* TO DO: uvlong or vlong */
- 0, /* kernel text mask */
- 1, /* quantization of pc */
- 8, /* szaddr */
- 4, /* szreg */
- 4, /* szfloat */
- 8, /* szdouble */
+ MAMD64, /* machine type */
+ amd64reglist, /* register list */
+ REGSIZE, /* size of registers in bytes */
+ FPREGSIZE, /* size of fp registers in bytes */
+ "PC", /* name of PC */
+ "SP", /* name of SP */
+ 0, /* link register */
+ "setSB", /* static base register name (bogus anyways) */
+ 0, /* static base register value */
+ 0x1000, /* page size */
+ 0xFFFFFFFF80110000ULL, /* kernel base */
+ 0xFFFF800000000000ULL, /* kernel text mask */
+ 0x00007FFFFFFFF000ULL, /* user stack top */
+ 1, /* quantization of pc */
+ 8, /* szaddr */
+ 4, /* szreg */
+ 4, /* szfloat */
+ 8, /* szdouble */
};
diff --git a/utils/libmach/6obj.c b/utils/libmach/6obj.c
index 7fb95115..d4c72af6 100644
--- a/utils/libmach/6obj.c
+++ b/utils/libmach/6obj.c
@@ -3,6 +3,7 @@
*/
#include <lib9.h>
#include <bio.h>
+#include <mach.h>
#include "6c/6.out.h"
#include "obj.h"
@@ -42,9 +43,12 @@ _read6(Biobuf *bp, Prog* p)
return 0;
as |= ((c & 0xff) << 8);
p->kind = aNone;
+ p->sig = 0;
if(as == ANAME || as == ASIGNAME){
- if(as == ASIGNAME)
- skip(bp, 4); /* signature */
+ if(as == ASIGNAME){
+ Bread(bp, &p->sig, 4);
+ p->sig = leswal(p->sig);
+ }
p->kind = aName;
p->type = type2char(Bgetc(bp)); /* type */
p->sym = Bgetc(bp); /* sym */
diff --git a/utils/libmach/8db.c b/utils/libmach/8db.c
index 86b6e1f2..7177c815 100644
--- a/utils/libmach/8db.c
+++ b/utils/libmach/8db.c
@@ -4,53 +4,49 @@
/*
* i386-specific debugger interface
+ * also amd64 extensions
*/
static char *i386excep(Map*, Rgetter);
-static int i386trace(Map*, ulong, ulong, ulong, Tracer);
-static ulong i386frame(Map*, ulong, ulong, ulong, ulong);
-static int i386foll(Map*, ulong, Rgetter, ulong*);
-static int i386inst(Map*, ulong, char, char*, int);
-static int i386das(Map*, ulong, char*, int);
-static int i386instlen(Map*, ulong);
+static int i386trace(Map*, uvlong, uvlong, uvlong, Tracer);
+static uvlong i386frame(Map*, uvlong, uvlong, uvlong, uvlong);
+static int i386foll(Map*, uvlong, Rgetter, uvlong*);
+static int i386inst(Map*, uvlong, char, char*, int);
+static int i386das(Map*, uvlong, char*, int);
+static int i386instlen(Map*, uvlong);
static char STARTSYM[] = "_main";
static char PROFSYM[] = "_mainp";
static char FRAMENAME[] = ".frame";
static char *excname[] =
{
- "divide error", /* 0 */
- "debug exception", /* 1 */
- 0,0, /* 2, 3 */
- "overflow", /* 4 */
- "bounds check", /* 5 */
- "invalid opcode", /* 6 */
- "math coprocessor emulation", /* 7 */
- "double fault", /* 8 */
- "math coprocessor overrun", /* 9 */
- "invalid TSS", /* 10 */
- "segment not present", /* 11 */
- "stack exception", /* 12 */
- "general protection violation", /* 13 */
- "page fault", /* 14 */
- 0, /* 15 */
- "math coprocessor error", /* 16 */
- 0,0,0,0,0,0,0, /* 17-23 */
- "clock", /* 24 */
- "keyboard", /* 25 */
- 0, /* 26 */
- "modem status", /* 27 */
- "serial line status", /* 28 */
- 0, /* 29 */
- "floppy disk", /* 30 */
- 0,0,0,0,0, /* 31-35 */
- "mouse", /* 36 */
- "math coprocessor", /* 37 */
- "hard disk", /* 38 */
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,/* 39-54 */
- 0,0,0,0,0,0,0,0,0, /* 55-63 */
- "system call", /* 64 */
+[0] "divide error",
+[1] "debug exception",
+[4] "overflow",
+[5] "bounds check",
+[6] "invalid opcode",
+[7] "math coprocessor emulation",
+[8] "double fault",
+[9] "math coprocessor overrun",
+[10] "invalid TSS",
+[11] "segment not present",
+[12] "stack exception",
+[13] "general protection violation",
+[14] "page fault",
+[16] "math coprocessor error",
+[17] "alignment check",
+[18] "machine check",
+[19] "floating-point exception",
+[24] "clock",
+[25] "keyboard",
+[27] "modem status",
+[28] "serial line status",
+[30] "floppy disk",
+[36] "mouse",
+[37] "math coprocessor",
+[38] "hard disk",
+[64] "system call",
};
Machdata i386mach =
@@ -77,7 +73,7 @@ static char*
i386excep(Map *map, Rgetter rget)
{
ulong c;
- ulong pc;
+ uvlong pc;
static char buf[16];
c = (*rget)(map, "TRAP");
@@ -88,17 +84,17 @@ i386excep(Map *map, Rgetter rget)
if (memcmp(buf, machdata->bpinst, machdata->bpsize) == 0)
return "breakpoint";
}
- sprint(buf, "exception %ld", c);
+ snprint(buf, sizeof(buf), "exception %ld", c);
return buf;
} else
return excname[c];
}
static int
-i386trace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
+i386trace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
{
int i;
- ulong osp;
+ uvlong osp;
Symbol s, f;
USED(link);
@@ -118,7 +114,7 @@ i386trace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
sp += f.value-mach->szaddr;
}
- if (get4(map, sp, (long *) &pc) < 0)
+ if (geta(map, sp, &pc) < 0)
break;
if(pc == 0)
@@ -127,14 +123,14 @@ i386trace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
(*trace)(map, pc, sp, &s);
sp += mach->szaddr;
- if(++i > 40)
+ if(++i > 1000)
break;
}
return i;
}
-static ulong
-i386frame(Map *map, ulong addr, ulong pc, ulong sp, ulong link)
+static uvlong
+i386frame(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
{
Symbol s, f;
@@ -152,7 +148,7 @@ i386frame(Map *map, ulong addr, ulong pc, ulong sp, ulong link)
if (s.value == addr)
return sp;
- if (get4(map, sp, (long *)&pc) < 0)
+ if (geta(map, sp, &pc) < 0)
break;
sp += mach->szaddr;
}
@@ -168,22 +164,27 @@ typedef struct Instr Instr;
struct Instr
{
uchar mem[1+1+1+1+2+1+1+4+4]; /* raw instruction */
- ulong addr; /* address of start of instruction */
+ uvlong addr; /* address of start of instruction */
int n; /* number of bytes in instruction */
char *prefix; /* instr prefix */
char *segment; /* segment override */
uchar jumptype; /* set to the operand type for jump/ret/call */
- char osize; /* 'W' or 'L' */
- char asize; /* address size 'W' or 'L' */
+ uchar amd64;
+ uchar rex; /* REX prefix (or zero) */
+ char osize; /* 'W' or 'L' (or 'Q' on amd64) */
+ char asize; /* address size 'W' or 'L' (or 'Q' or amd64) */
uchar mod; /* bits 6-7 of mod r/m field */
uchar reg; /* bits 3-5 of mod r/m field */
char ss; /* bits 6-7 of SIB */
char index; /* bits 3-5 of SIB */
char base; /* bits 0-2 of SIB */
+ char rip; /* RIP-relative in amd64 mode */
+ uchar opre; /* f2/f3 could introduce media */
short seg; /* segment of far address */
ulong disp; /* displacement */
ulong imm; /* immediate */
ulong imm2; /* second immediate operand */
+ uvlong imm64; /* big immediate */
char *curr; /* fill level in output buffer */
char *end; /* end of output buffer */
char *err; /* error message */
@@ -199,7 +200,26 @@ enum{
BP,
SI,
DI,
+
+ /* amd64 */
+ R8,
+ R9,
+ R10,
+ R11,
+ R12,
+ R13,
+ R14,
+ R15
};
+
+ /* amd64 rex extension byte */
+enum{
+ REXW = 1<<3, /* =1, 64-bit operand size */
+ REXR = 1<<2, /* extend modrm reg */
+ REXX = 1<<1, /* extend sib index */
+ REXB = 1<<0 /* extend modrm r/m, sib base, or opcode reg */
+};
+
/* Operand Format codes */
/*
%A - address size register modifier (!asize -> 'E')
@@ -209,7 +229,7 @@ enum{
%O - Operand size register modifier (!osize -> 'E')
%T - Test register TR6/TR7
%S - size code ('W' or 'L')
-%X - Weird opcode: OSIZE == 'W' => "CBW"; else => "CWDE"
+%W - Weird opcode: OSIZE == 'W' => "CBW"; else => "CWDE"
%d - displacement 16-32 bits
%e - effective address - Mod R/M value
%f - floating point register F0-F7 - from Mod R/M register
@@ -217,7 +237,7 @@ enum{
%i - immediate operand 8-32 bits
%p - PC-relative - signed displacement in immediate field
%r - Reg from Mod R/M
-%x - Weird opcode: OSIZE == 'W' => "CWD"; else => "CDQ"
+%w - Weird opcode: OSIZE == 'W' => "CWD"; else => "CDQ"
*/
typedef struct Optable Optable;
@@ -234,6 +254,7 @@ enum {
Iw, /* 16-bit immediate -> imm */
Iw2, /* 16-bit immediate -> imm2 */
Iwd, /* Operand-sized immediate (no sign extension)*/
+ Iwdq, /* Operand-sized immediate, possibly 64 bits */
Awd, /* Address offset */
Iwds, /* Operand-sized immediate (sign extended) */
RM, /* Word or long R/M field with register (/r) */
@@ -251,7 +272,9 @@ enum {
OA, /* literal 0x0a byte */
PTR, /* Seg:Displacement addr (ptr16:16 or ptr16:32) */
AUX, /* Multi-byte op code - Auxiliary table */
+ AUXMM, /* multi-byte op code - auxiliary table chosen by prefix */
PRE, /* Instr Prefix */
+ OPRE, /* Instr Prefix or media op extension */
SEG, /* Segment Prefix */
OPOVER, /* Operand size override */
ADDOVER, /* Address size override */
@@ -259,359 +282,499 @@ enum {
static Optable optab0F00[8]=
{
- 0,0, "MOVW LDT,%e", /* 0x00 */
- 0,0, "MOVW TR,%e", /* 0x01 */
- 0,0, "MOVW %e,LDT", /* 0x02 */
- 0,0, "MOVW %e,TR", /* 0x03 */
- 0,0, "VERR %e", /* 0x04 */
- 0,0, "VERW %e", /* 0x05 */
+[0x00] 0,0, "MOVW LDT,%e",
+[0x01] 0,0, "MOVW TR,%e",
+[0x02] 0,0, "MOVW %e,LDT",
+[0x03] 0,0, "MOVW %e,TR",
+[0x04] 0,0, "VERR %e",
+[0x05] 0,0, "VERW %e",
};
static Optable optab0F01[8]=
{
- 0,0, "MOVL GDTR,%e", /* 0x00 */
- 0,0, "MOVL IDTR,%e", /* 0x01 */
- 0,0, "MOVL %e,GDTR", /* 0x02 */
- 0,0, "MOVL %e,IDTR", /* 0x03 */
- 0,0, "MOVW MSW,%e", /* 0x04 */ /* word */
- 0,0, "", /* 0x05 */
- 0,0, "MOVW %e,MSW", /* 0x06 */ /* word */
+[0x00] 0,0, "MOVL GDTR,%e",
+[0x01] 0,0, "MOVL IDTR,%e",
+[0x02] 0,0, "MOVL %e,GDTR",
+[0x03] 0,0, "MOVL %e,IDTR",
+[0x04] 0,0, "MOVW MSW,%e", /* word */
+[0x06] 0,0, "MOVW %e,MSW", /* word */
+[0x07] 0,0, "INVLPG %e", /* or SWAPGS */
};
+static Optable optab0F01F8[1]=
+{
+[0x00] 0,0, "SWAPGS",
+};
+
+/* 0F71 */
+/* 0F72 */
+/* 0F73 */
+
+static Optable optab0FAE[8]=
+{
+[0x00] 0,0, "FXSAVE %e",
+[0x01] 0,0, "FXRSTOR %e",
+[0x02] 0,0, "LDMXCSR %e",
+[0x03] 0,0, "STMXCSR %e",
+[0x05] 0,0, "LFENCE",
+[0x06] 0,0, "MFENCE",
+[0x07] 0,0, "SFENCE",
+};
+
+/* 0F18 */
+/* 0F0D */
+
static Optable optab0FBA[8]=
{
- 0,0, "", /* 0x00 */
- 0,0, "", /* 0x01 */
- 0,0, "", /* 0x02 */
- 0,0, "", /* 0x03 */
- Ib,0, "BT%S %i,%e", /* 0x04 */
- Ib,0, "BTS%S %i,%e", /* 0x05 */
- Ib,0, "BTR%S %i,%e", /* 0x06 */
- Ib,0, "BTC%S %i,%e", /* 0x07 */
+[0x04] Ib,0, "BT%S %i,%e",
+[0x05] Ib,0, "BTS%S %i,%e",
+[0x06] Ib,0, "BTR%S %i,%e",
+[0x07] Ib,0, "BTC%S %i,%e",
+};
+
+static Optable optab0F0F[256]=
+{
+[0x0c] 0,0, "PI2FW %m,%M",
+[0x0d] 0,0, "PI2L %m,%M",
+[0x1c] 0,0, "PF2IW %m,%M",
+[0x1d] 0,0, "PF2IL %m,%M",
+[0x8a] 0,0, "PFNACC %m,%M",
+[0x8e] 0,0, "PFPNACC %m,%M",
+[0x90] 0,0, "PFCMPGE %m,%M",
+[0x94] 0,0, "PFMIN %m,%M",
+[0x96] 0,0, "PFRCP %m,%M",
+[0x97] 0,0, "PFRSQRT %m,%M",
+[0x9a] 0,0, "PFSUB %m,%M",
+[0x9e] 0,0, "PFADD %m,%M",
+[0xa0] 0,0, "PFCMPGT %m,%M",
+[0xa4] 0,0, "PFMAX %m,%M",
+[0xa6] 0,0, "PFRCPIT1 %m,%M",
+[0xa7] 0,0, "PFRSQIT1 %m,%M",
+[0xaa] 0,0, "PFSUBR %m,%M",
+[0xae] 0,0, "PFACC %m,%M",
+[0xb0] 0,0, "PFCMPEQ %m,%M",
+[0xb4] 0,0, "PFMUL %m,%M",
+[0xb6] 0,0, "PFRCPI2T %m,%M",
+[0xb7] 0,0, "PMULHRW %m,%M",
+[0xbb] 0,0, "PSWAPL %m,%M",
+};
+
+static Optable optab0FC7[8]=
+{
+[0x01] 0,0, "CMPXCHG8B %e",
+};
+
+static Optable optab660F71[8]=
+{
+[0x02] Ib,0, "PSRLW %i,%X",
+[0x04] Ib,0, "PSRAW %i,%X",
+[0x06] Ib,0, "PSLLW %i,%X",
+};
+
+static Optable optab660F72[8]=
+{
+[0x02] Ib,0, "PSRLL %i,%X",
+[0x04] Ib,0, "PSRAL %i,%X",
+[0x06] Ib,0, "PSLLL %i,%X",
+};
+
+static Optable optab660F73[8]=
+{
+[0x02] Ib,0, "PSRLQ %i,%X",
+[0x03] Ib,0, "PSRLO %i,%X",
+[0x06] Ib,0, "PSLLQ %i,%X",
+[0x07] Ib,0, "PSLLO %i,%X",
+};
+
+static Optable optab660F[256]=
+{
+[0x2B] RM,0, "MOVNTPD %x,%e",
+[0x2E] RM,0, "UCOMISD %x,%X",
+[0x2F] RM,0, "COMISD %x,%X",
+[0x5A] RM,0, "CVTPD2PS %x,%X",
+[0x5B] RM,0, "CVTPS2PL %x,%X",
+[0x6A] RM,0, "PUNPCKHLQ %x,%X",
+[0x6B] RM,0, "PACKSSLW %x,%X",
+[0x6C] RM,0, "PUNPCKLQDQ %x,%X",
+[0x6D] RM,0, "PUNPCKHQDQ %x,%X",
+[0x6E] RM,0, "MOV%S %e,%X",
+[0x6F] RM,0, "MOVO %x,%X", /* MOVDQA */
+[0x70] RM,Ib, "PSHUFL %i,%x,%X",
+[0x71] RMOP,0, optab660F71,
+[0x72] RMOP,0, optab660F72,
+[0x73] RMOP,0, optab660F73,
+[0x7E] RM,0, "MOV%S %X,%e",
+[0x7F] RM,0, "MOVO %X,%x",
+[0xC4] RM,Ib, "PINSRW %i,%e,%X",
+[0xC5] RMR,Ib, "PEXTRW %i,%X,%e",
+[0xD4] RM,0, "PADDQ %x,%X",
+[0xD5] RM,0, "PMULLW %x,%X",
+[0xD6] RM,0, "MOVQ %X,%x",
+[0xE6] RM,0, "CVTTPD2PL %x,%X",
+[0xE7] RM,0, "MOVNTO %X,%e",
+[0xF7] RM,0, "MASKMOVOU %x,%X",
+};
+
+static Optable optabF20F[256]=
+{
+[0x10] RM,0, "MOVSD %x,%X",
+[0x11] RM,0, "MOVSD %X,%x",
+[0x2A] RM,0, "CVTS%S2SD %e,%X",
+[0x2C] RM,0, "CVTTSD2S%S %x,%r",
+[0x2D] RM,0, "CVTSD2S%S %x,%r",
+[0x5A] RM,0, "CVTSD2SS %x,%X",
+[0x6F] RM,0, "MOVOU %x,%X",
+[0x70] RM,Ib, "PSHUFLW %i,%x,%X",
+[0x7F] RM,0, "MOVOU %X,%x",
+[0xD6] RM,0, "MOVQOZX %M,%X",
+[0xE6] RM,0, "CVTPD2PL %x,%X",
+};
+
+static Optable optabF30F[256]=
+{
+[0x10] RM,0, "MOVSS %x,%X",
+[0x11] RM,0, "MOVSS %X,%x",
+[0x2A] RM,0, "CVTS%S2SS %e,%X",
+[0x2C] RM,0, "CVTTSS2S%S %x,%r",
+[0x2D] RM,0, "CVTSS2S%S %x,%r",
+[0x5A] RM,0, "CVTSS2SD %x,%X",
+[0x5B] RM,0, "CVTTPS2PL %x,%X",
+[0x6F] RM,0, "MOVOU %x,%X",
+[0x70] RM,Ib, "PSHUFHW %i,%x,%X",
+[0x7E] RM,0, "MOVQOZX %x,%X",
+[0x7F] RM,0, "MOVOU %X,%x",
+[0xD6] RM,0, "MOVQOZX %m*,%X",
+[0xE6] RM,0, "CVTPL2PD %x,%X",
};
static Optable optab0F[256]=
{
- RMOP,0, optab0F00, /* 0x00 */
- RMOP,0, optab0F01, /* 0x01 */
- RM,0, "LAR %e,%r", /* 0x02 */
- RM,0, "LSL %e,%r", /* 0x03 */
- 0,0, "", /* 0x04 */
- 0,0, "", /* 0x05 */
- 0,0, "CLTS", /* 0x06 */
- 0,0, "", /* 0x07 */
- 0,0, "INVD", /* 0x08 */
- 0,0, "WBINVD", /* 0x09 */
- 0,0, "", /* 0x0a */
- 0,0, "", /* 0x0b */
- 0,0, "", /* 0x0c */
- 0,0, "", /* 0x0d */
- 0,0, "", /* 0x0e */
- 0,0, "", /* 0x0f */
- 0,0, "", /* 0x10 */
- 0,0, "", /* 0x11 */
- 0,0, "", /* 0x12 */
- 0,0, "", /* 0x13 */
- 0,0, "", /* 0x14 */
- 0,0, "", /* 0x15 */
- 0,0, "", /* 0x16 */
- 0,0, "", /* 0x17 */
- 0,0, "", /* 0x18 */
- 0,0, "", /* 0x19 */
- 0,0, "", /* 0x1a */
- 0,0, "", /* 0x1b */
- 0,0, "", /* 0x1c */
- 0,0, "", /* 0x1d */
- 0,0, "", /* 0x1e */
- 0,0, "", /* 0x1f */
- RMR,0, "MOVL %C,%e", /* 0x20 */
- RMR,0, "MOVL %D,%e", /* 0x21 */
- RMR,0, "MOVL %e,%C", /* 0x22 */
- RMR,0, "MOVL %e,%D", /* 0x23 */
- RMR,0, "MOVL %T,%e", /* 0x24 */
- 0,0, "", /* 0x25 */
- RMR,0, "MOVL %e,%T", /* 0x26 */
- 0,0, "", /* 0x27 */
- 0,0, "", /* 0x28 */
- 0,0, "", /* 0x29 */
- 0,0, "", /* 0x2a */
- 0,0, "", /* 0x2b */
- 0,0, "", /* 0x2c */
- 0,0, "", /* 0x2d */
- 0,0, "", /* 0x2e */
- 0,0, "", /* 0x2f */
- 0,0, "WRMSR", /* 0x30 */
- 0,0, "RDTSC", /* 0x31 */
- 0,0, "RDMSR", /* 0x32 */
- 0,0, "", /* 0x33 */
- 0,0, "", /* 0x34 */
- 0,0, "", /* 0x35 */
- 0,0, "", /* 0x36 */
- 0,0, "", /* 0x37 */
- 0,0, "", /* 0x38 */
- 0,0, "", /* 0x39 */
- 0,0, "", /* 0x3a */
- 0,0, "", /* 0x3b */
- 0,0, "", /* 0x3c */
- 0,0, "", /* 0x3d */
- 0,0, "", /* 0x3e */
- 0,0, "", /* 0x3f */
- 0,0, "", /* 0x40 */
- 0,0, "", /* 0x41 */
- 0,0, "", /* 0x42 */
- 0,0, "", /* 0x43 */
- 0,0, "", /* 0x44 */
- 0,0, "", /* 0x45 */
- 0,0, "", /* 0x46 */
- 0,0, "", /* 0x47 */
- 0,0, "", /* 0x48 */
- 0,0, "", /* 0x49 */
- 0,0, "", /* 0x4a */
- 0,0, "", /* 0x4b */
- 0,0, "", /* 0x4c */
- 0,0, "", /* 0x4d */
- 0,0, "", /* 0x4e */
- 0,0, "", /* 0x4f */
- 0,0, "", /* 0x50 */
- 0,0, "", /* 0x51 */
- 0,0, "", /* 0x52 */
- 0,0, "", /* 0x53 */
- 0,0, "", /* 0x54 */
- 0,0, "", /* 0x55 */
- 0,0, "", /* 0x56 */
- 0,0, "", /* 0x57 */
- 0,0, "", /* 0x58 */
- 0,0, "", /* 0x59 */
- 0,0, "", /* 0x5a */
- 0,0, "", /* 0x5b */
- 0,0, "", /* 0x5c */
- 0,0, "", /* 0x5d */
- 0,0, "", /* 0x5e */
- 0,0, "", /* 0x5f */
- 0,0, "", /* 0x60 */
- 0,0, "", /* 0x61 */
- 0,0, "", /* 0x62 */
- 0,0, "", /* 0x63 */
- 0,0, "", /* 0x64 */
- 0,0, "", /* 0x65 */
- 0,0, "", /* 0x66 */
- 0,0, "", /* 0x67 */
- 0,0, "", /* 0x68 */
- 0,0, "", /* 0x69 */
- 0,0, "", /* 0x6a */
- 0,0, "", /* 0x6b */
- 0,0, "", /* 0x6c */
- 0,0, "", /* 0x6d */
- 0,0, "", /* 0x6e */
- 0,0, "", /* 0x6f */
- 0,0, "", /* 0x70 */
- 0,0, "", /* 0x71 */
- 0,0, "", /* 0x72 */
- 0,0, "", /* 0x73 */
- 0,0, "", /* 0x74 */
- 0,0, "", /* 0x75 */
- 0,0, "", /* 0x76 */
- 0,0, "", /* 0x77 */
- 0,0, "", /* 0x78 */
- 0,0, "", /* 0x79 */
- 0,0, "", /* 0x7a */
- 0,0, "", /* 0x7b */
- 0,0, "", /* 0x7c */
- 0,0, "", /* 0x7d */
- 0,0, "", /* 0x7e */
- 0,0, "", /* 0x7f */
- Iwds,0, "JOS %p", /* 0x80 */
- Iwds,0, "JOC %p", /* 0x81 */
- Iwds,0, "JCS %p", /* 0x82 */
- Iwds,0, "JCC %p", /* 0x83 */
- Iwds,0, "JEQ %p", /* 0x84 */
- Iwds,0, "JNE %p", /* 0x85 */
- Iwds,0, "JLS %p", /* 0x86 */
- Iwds,0, "JHI %p", /* 0x87 */
- Iwds,0, "JMI %p", /* 0x88 */
- Iwds,0, "JPL %p", /* 0x89 */
- Iwds,0, "JPS %p", /* 0x8a */
- Iwds,0, "JPC %p", /* 0x8b */
- Iwds,0, "JLT %p", /* 0x8c */
- Iwds,0, "JGE %p", /* 0x8d */
- Iwds,0, "JLE %p", /* 0x8e */
- Iwds,0, "JGT %p", /* 0x8f */
- RMB,0, "SETOS %e", /* 0x90 */
- RMB,0, "SETOC %e", /* 0x91 */
- RMB,0, "SETCS %e", /* 0x92 */
- RMB,0, "SETCC %e", /* 0x93 */
- RMB,0, "SETEQ %e", /* 0x94 */
- RMB,0, "SETNE %e", /* 0x95 */
- RMB,0, "SETLS %e", /* 0x96 */
- RMB,0, "SETHI %e", /* 0x97 */
- RMB,0, "SETMI %e", /* 0x98 */
- RMB,0, "SETPL %e", /* 0x99 */
- RMB,0, "SETPS %e", /* 0x9a */
- RMB,0, "SETPC %e", /* 0x9b */
- RMB,0, "SETLT %e", /* 0x9c */
- RMB,0, "SETGE %e", /* 0x9d */
- RMB,0, "SETLE %e", /* 0x9e */
- RMB,0, "SETGT %e", /* 0x9f */
- 0,0, "PUSHL FS", /* 0xa0 */
- 0,0, "POPL FS", /* 0xa1 */
- 0,0, "CPUID", /* 0xa2 */
- RM,0, "BT%S %r,%e", /* 0xa3 */
- RM,Ib, "SHLD%S %r,%i,%e", /* 0xa4 */
- RM,0, "SHLD%S %r,CL,%e", /* 0xa5 */
- 0,0, "", /* 0xa6 */
- 0,0, "", /* 0xa7 */
- 0,0, "PUSHL GS", /* 0xa8 */
- 0,0, "POPL GS", /* 0xa9 */
- 0,0, "", /* 0xaa */
- RM,0, "BTS%S %r,%e", /* 0xab */
- RM,Ib, "SHRD%S %r,%i,%e", /* 0xac */
- RM,0, "SHRD%S %r,CL,%e", /* 0xad */
- 0,0, "", /* 0xae */
- RM,0, "IMUL%S %e,%r", /* 0xaf */
- 0,0, "", /* 0xb0 */
- 0,0, "", /* 0xb1 */
- RMM,0, "LSS %e,%r", /* 0xb2 */
- RM,0, "BTR%S %r,%e", /* 0xb3 */
- RMM,0, "LFS %e,%r", /* 0xb4 */
- RMM,0, "LGS %e,%r", /* 0xb5 */
- RMB,0, "MOVBZX %e,%R", /* 0xb6 */
- RM,0, "MOVWZX %e,%R", /* 0xb7 */
- 0,0, "", /* 0xb8 */
- 0,0, "", /* 0xb9 */
- RMOP,0, optab0FBA, /* 0xba */
- RM,0, "BTC%S %e,%r", /* 0xbb */
- RM,0, "BSF%S %e,%r", /* 0xbc */
- RM,0, "BSR%S %e,%r", /* 0xbd */
- RMB,0, "MOVBSX %e,%R", /* 0xbe */
- RM,0, "MOVWSX %e,%R", /* 0xbf */
+[0x00] RMOP,0, optab0F00,
+[0x01] RMOP,0, optab0F01,
+[0x02] RM,0, "LAR %e,%r",
+[0x03] RM,0, "LSL %e,%r",
+[0x05] 0,0, "SYSCALL",
+[0x06] 0,0, "CLTS",
+[0x07] 0,0, "SYSRET",
+[0x08] 0,0, "INVD",
+[0x09] 0,0, "WBINVD",
+[0x0B] 0,0, "UD2",
+[0x0F] RM,AUX, optab0F0F, /* 3DNow! */
+[0x10] RM,0, "MOVU%s %x,%X",
+[0x11] RM,0, "MOVU%s %X,%x",
+[0x12] RM,0, "MOV[H]L%s %x,%X", /* TO DO: H if source is XMM */
+[0x13] RM,0, "MOVL%s %X,%e",
+[0x14] RM,0, "UNPCKL%s %x,%X",
+[0x15] RM,0, "UNPCKH%s %x,%X",
+[0x16] RM,0, "MOV[L]H%s %x,%X", /* TO DO: L if source is XMM */
+[0x17] RM,0, "MOVH%s %X,%x",
+[0x20] RMR,0, "MOVL %C,%e",
+[0x21] RMR,0, "MOVL %D,%e",
+[0x22] RMR,0, "MOVL %e,%C",
+[0x23] RMR,0, "MOVL %e,%D",
+[0x24] RMR,0, "MOVL %T,%e",
+[0x26] RMR,0, "MOVL %e,%T",
+[0x28] RM,0, "MOVA%s %x,%X",
+[0x29] RM,0, "MOVA%s %X,%x",
+[0x2A] RM,0, "CVTPL2%s %m*,%X",
+[0x2B] RM,0, "MOVNT%s %X,%e",
+[0x2C] RM,0, "CVTT%s2PL %x,%M",
+[0x2D] RM,0, "CVT%s2PL %x,%M",
+[0x2E] RM,0, "UCOMISS %x,%X",
+[0x2F] RM,0, "COMISS %x,%X",
+[0x30] 0,0, "WRMSR",
+[0x31] 0,0, "RDTSC",
+[0x32] 0,0, "RDMSR",
+[0x33] 0,0, "RDPMC",
+[0x42] RM,0, "CMOVC %e,%r", /* CF */
+[0x43] RM,0, "CMOVNC %e,%r", /* ¬ CF */
+[0x44] RM,0, "CMOVZ %e,%r", /* ZF */
+[0x45] RM,0, "CMOVNZ %e,%r", /* ¬ ZF */
+[0x46] RM,0, "CMOVBE %e,%r", /* CF ∨ ZF */
+[0x47] RM,0, "CMOVA %e,%r", /* ¬CF ∧ ¬ZF */
+[0x48] RM,0, "CMOVS %e,%r", /* SF */
+[0x49] RM,0, "CMOVNS %e,%r", /* ¬ SF */
+[0x4A] RM,0, "CMOVP %e,%r", /* PF */
+[0x4B] RM,0, "CMOVNP %e,%r", /* ¬ PF */
+[0x4C] RM,0, "CMOVLT %e,%r", /* LT ≡ OF ≠ SF */
+[0x4D] RM,0, "CMOVGE %e,%r", /* GE ≡ ZF ∨ SF */
+[0x4E] RM,0, "CMOVLE %e,%r", /* LE ≡ ZF ∨ LT */
+[0x4F] RM,0, "CMOVGT %e,%r", /* GT ≡ ¬ZF ∧ GE */
+[0x50] RM,0, "MOVMSK%s %X,%r", /* TO DO: check */
+[0x51] RM,0, "SQRT%s %x,%X",
+[0x52] RM,0, "RSQRT%s %x,%X",
+[0x53] RM,0, "RCP%s %x,%X",
+[0x54] RM,0, "AND%s %x,%X",
+[0x55] RM,0, "ANDN%s %x,%X",
+[0x56] RM,0, "OR%s %x,%X", /* TO DO: S/D */
+[0x57] RM,0, "XOR%s %x,%X", /* S/D */
+[0x58] RM,0, "ADD%s %x,%X", /* S/P S/D */
+[0x59] RM,0, "MUL%s %x,%X",
+[0x5A] RM,0, "CVTPS2PD %x,%X",
+[0x5B] RM,0, "CVTPL2PS %x,%X",
+[0x5C] RM,0, "SUB%s %x,%X",
+[0x5D] RM,0, "MIN%s %x,%X",
+[0x5E] RM,0, "DIV%s %x,%X", /* TO DO: S/P S/D */
+[0x5F] RM,0, "MAX%s %x,%X",
+[0x60] RM,0, "PUNPCKLBW %m,%M",
+[0x61] RM,0, "PUNPCKLWL %m,%M",
+[0x62] RM,0, "PUNPCKLLQ %m,%M",
+[0x63] RM,0, "PACKSSWB %m,%M",
+[0x64] RM,0, "PCMPGTB %m,%M",
+[0x65] RM,0, "PCMPGTW %m,%M",
+[0x66] RM,0, "PCMPGTL %m,%M",
+[0x67] RM,0, "PACKUSWB %m,%M",
+[0x68] RM,0, "PUNPCKHBW %m,%M",
+[0x69] RM,0, "PUNPCKHWL %m,%M",
+[0x6A] RM,0, "PUNPCKHLQ %m,%M",
+[0x6B] RM,0, "PACKSSLW %m,%M",
+[0x6E] RM,0, "MOV%S %e,%M",
+[0x6F] RM,0, "MOVQ %m,%M",
+[0x70] RM,Ib, "PSHUFW %i,%m,%M",
+[0x74] RM,0, "PCMPEQB %m,%M",
+[0x75] RM,0, "PCMPEQW %m,%M",
+[0x76] RM,0, "PCMPEQL %m,%M",
+[0x7E] RM,0, "MOV%S %M,%e",
+[0x7F] RM,0, "MOVQ %M,%m",
+[0xAE] RMOP,0, optab0FAE,
+[0xAA] 0,0, "RSM",
+[0xB0] RM,0, "CMPXCHGB %r,%e",
+[0xB1] RM,0, "CMPXCHG%S %r,%e",
+[0xC0] RMB,0, "XADDB %r,%e",
+[0xC1] RM,0, "XADD%S %r,%e",
+[0xC2] RM,Ib, "CMP%s %i,%x,%X",
+[0xC3] RM,0, "MOVNTI%S %r,%e",
+[0xC6] RM,Ib, "SHUF%s %i,%x,%X",
+[0xC8] 0,0, "BSWAP AX",
+[0xC9] 0,0, "BSWAP CX",
+[0xCA] 0,0, "BSWAP DX",
+[0xCB] 0,0, "BSWAP BX",
+[0xCC] 0,0, "BSWAP SP",
+[0xCD] 0,0, "BSWAP BP",
+[0xCE] 0,0, "BSWAP SI",
+[0xCF] 0,0, "BSWAP DI",
+[0xD1] RM,0, "PSRLW %m,%M",
+[0xD2] RM,0, "PSRLL %m,%M",
+[0xD3] RM,0, "PSRLQ %m,%M",
+[0xD5] RM,0, "PMULLW %m,%M",
+[0xD6] RM,0, "MOVQOZX %m*,%X",
+[0xD7] RM,0, "PMOVMSKB %m,%r",
+[0xD8] RM,0, "PSUBUSB %m,%M",
+[0xD9] RM,0, "PSUBUSW %m,%M",
+[0xDA] RM,0, "PMINUB %m,%M",
+[0xDB] RM,0, "PAND %m,%M",
+[0xDC] RM,0, "PADDUSB %m,%M",
+[0xDD] RM,0, "PADDUSW %m,%M",
+[0xDE] RM,0, "PMAXUB %m,%M",
+[0xDF] RM,0, "PANDN %m,%M",
+[0xE0] RM,0, "PAVGB %m,%M",
+[0xE1] RM,0, "PSRAW %m,%M",
+[0xE2] RM,0, "PSRAL %m,%M",
+[0xE3] RM,0, "PAVGW %m,%M",
+[0xE4] RM,0, "PMULHUW %m,%M",
+[0xE5] RM,0, "PMULHW %m,%M",
+[0xE7] RM,0, "MOVNTQ %M,%e",
+[0xE8] RM,0, "PSUBSB %m,%M",
+[0xE9] RM,0, "PSUBSW %m,%M",
+[0xEA] RM,0, "PMINSW %m,%M",
+[0xEB] RM,0, "POR %m,%M",
+[0xEC] RM,0, "PADDSB %m,%M",
+[0xED] RM,0, "PADDSW %m,%M",
+[0xEE] RM,0, "PMAXSW %m,%M",
+[0xEF] RM,0, "PXOR %m,%M",
+[0xF1] RM,0, "PSLLW %m,%M",
+[0xF2] RM,0, "PSLLL %m,%M",
+[0xF3] RM,0, "PSLLQ %m,%M",
+[0xF4] RM,0, "PMULULQ %m,%M",
+[0xF5] RM,0, "PMADDWL %m,%M",
+[0xF6] RM,0, "PSADBW %m,%M",
+[0xF7] RMR,0, "MASKMOVQ %m,%M",
+[0xF8] RM,0, "PSUBB %m,%M",
+[0xF9] RM,0, "PSUBW %m,%M",
+[0xFA] RM,0, "PSUBL %m,%M",
+[0xFC] RM,0, "PADDB %m,%M",
+[0xFD] RM,0, "PADDW %m,%M",
+[0xFE] RM,0, "PADDL %m,%M",
+
+[0x80] Iwds,0, "JOS %p",
+[0x81] Iwds,0, "JOC %p",
+[0x82] Iwds,0, "JCS %p",
+[0x83] Iwds,0, "JCC %p",
+[0x84] Iwds,0, "JEQ %p",
+[0x85] Iwds,0, "JNE %p",
+[0x86] Iwds,0, "JLS %p",
+[0x87] Iwds,0, "JHI %p",
+[0x88] Iwds,0, "JMI %p",
+[0x89] Iwds,0, "JPL %p",
+[0x8a] Iwds,0, "JPS %p",
+[0x8b] Iwds,0, "JPC %p",
+[0x8c] Iwds,0, "JLT %p",
+[0x8d] Iwds,0, "JGE %p",
+[0x8e] Iwds,0, "JLE %p",
+[0x8f] Iwds,0, "JGT %p",
+[0x90] RMB,0, "SETOS %e",
+[0x91] RMB,0, "SETOC %e",
+[0x92] RMB,0, "SETCS %e",
+[0x93] RMB,0, "SETCC %e",
+[0x94] RMB,0, "SETEQ %e",
+[0x95] RMB,0, "SETNE %e",
+[0x96] RMB,0, "SETLS %e",
+[0x97] RMB,0, "SETHI %e",
+[0x98] RMB,0, "SETMI %e",
+[0x99] RMB,0, "SETPL %e",
+[0x9a] RMB,0, "SETPS %e",
+[0x9b] RMB,0, "SETPC %e",
+[0x9c] RMB,0, "SETLT %e",
+[0x9d] RMB,0, "SETGE %e",
+[0x9e] RMB,0, "SETLE %e",
+[0x9f] RMB,0, "SETGT %e",
+[0xa0] 0,0, "PUSHL FS",
+[0xa1] 0,0, "POPL FS",
+[0xa2] 0,0, "CPUID",
+[0xa3] RM,0, "BT%S %r,%e",
+[0xa4] RM,Ib, "SHLD%S %r,%i,%e",
+[0xa5] RM,0, "SHLD%S %r,CL,%e",
+[0xa8] 0,0, "PUSHL GS",
+[0xa9] 0,0, "POPL GS",
+[0xab] RM,0, "BTS%S %r,%e",
+[0xac] RM,Ib, "SHRD%S %r,%i,%e",
+[0xad] RM,0, "SHRD%S %r,CL,%e",
+[0xaf] RM,0, "IMUL%S %e,%r",
+[0xb2] RMM,0, "LSS %e,%r",
+[0xb3] RM,0, "BTR%S %r,%e",
+[0xb4] RMM,0, "LFS %e,%r",
+[0xb5] RMM,0, "LGS %e,%r",
+[0xb6] RMB,0, "MOVBZX %e,%R",
+[0xb7] RM,0, "MOVWZX %e,%R",
+[0xba] RMOP,0, optab0FBA,
+[0xbb] RM,0, "BTC%S %e,%r",
+[0xbc] RM,0, "BSF%S %e,%r",
+[0xbd] RM,0, "BSR%S %e,%r",
+[0xbe] RMB,0, "MOVBSX %e,%R",
+[0xbf] RM,0, "MOVWSX %e,%R",
+[0xc7] RMOP,0, optab0FC7,
};
static Optable optab80[8]=
{
- Ib,0, "ADDB %i,%e", /* 0x00 */
- Ib,0, "ORB %i,%e", /* 0x01 */
- Ib,0, "ADCB %i,%e", /* 0x02 */
- Ib,0, "SBBB %i,%e", /* 0x03 */
- Ib,0, "ANDB %i,%e", /* 0x04 */
- Ib,0, "SUBB %i,%e", /* 0x05 */
- Ib,0, "XORB %i,%e", /* 0x06 */
- Ib,0, "CMPB %e,%i", /* 0x07 */
+[0x00] Ib,0, "ADDB %i,%e",
+[0x01] Ib,0, "ORB %i,%e",
+[0x02] Ib,0, "ADCB %i,%e",
+[0x03] Ib,0, "SBBB %i,%e",
+[0x04] Ib,0, "ANDB %i,%e",
+[0x05] Ib,0, "SUBB %i,%e",
+[0x06] Ib,0, "XORB %i,%e",
+[0x07] Ib,0, "CMPB %e,%i",
};
static Optable optab81[8]=
{
- Iwd,0, "ADD%S %i,%e", /* 0x00 */
- Iwd,0, "OR%S %i,%e", /* 0x01 */
- Iwd,0, "ADC%S %i,%e", /* 0x02 */
- Iwd,0, "SBB%S %i,%e", /* 0x03 */
- Iwd,0, "AND%S %i,%e", /* 0x04 */
- Iwd,0, "SUB%S %i,%e", /* 0x05 */
- Iwd,0, "XOR%S %i,%e", /* 0x06 */
- Iwd,0, "CMP%S %e,%i", /* 0x07 */
+[0x00] Iwd,0, "ADD%S %i,%e",
+[0x01] Iwd,0, "OR%S %i,%e",
+[0x02] Iwd,0, "ADC%S %i,%e",
+[0x03] Iwd,0, "SBB%S %i,%e",
+[0x04] Iwd,0, "AND%S %i,%e",
+[0x05] Iwd,0, "SUB%S %i,%e",
+[0x06] Iwd,0, "XOR%S %i,%e",
+[0x07] Iwd,0, "CMP%S %e,%i",
};
static Optable optab83[8]=
{
- Ibs,0, "ADD%S %i,%e", /* 0x00 */
- Ibs,0, "OR%S %i,%e", /* 0x01 */
- Ibs,0, "ADC%S %i,%e", /* 0x02 */
- Ibs,0, "SBB%S %i,%e", /* 0x03 */
- Ibs,0, "AND%S %i,%e", /* 0x04 */
- Ibs,0, "SUB%S %i,%e", /* 0x05 */
- Ibs,0, "XOR%S %i,%e", /* 0x06 */
- Ibs,0, "CMP%S %e,%i", /* 0x07 */
+[0x00] Ibs,0, "ADD%S %i,%e",
+[0x01] Ibs,0, "OR%S %i,%e",
+[0x02] Ibs,0, "ADC%S %i,%e",
+[0x03] Ibs,0, "SBB%S %i,%e",
+[0x04] Ibs,0, "AND%S %i,%e",
+[0x05] Ibs,0, "SUB%S %i,%e",
+[0x06] Ibs,0, "XOR%S %i,%e",
+[0x07] Ibs,0, "CMP%S %e,%i",
};
static Optable optabC0[8] =
{
- Ib,0, "ROLB %i,%e", /* 0x00 */
- Ib,0, "RORB %i,%e", /* 0x01 */
- Ib,0, "RCLB %i,%e", /* 0x02 */
- Ib,0, "RCRB %i,%e", /* 0x03 */
- Ib,0, "SHLB %i,%e", /* 0x04 */
- Ib,0, "SHRB %i,%e", /* 0x05 */
- 0,0, "", /* 0x06 */
- Ib,0, "SARB %i,%e", /* 0x07 */
+[0x00] Ib,0, "ROLB %i,%e",
+[0x01] Ib,0, "RORB %i,%e",
+[0x02] Ib,0, "RCLB %i,%e",
+[0x03] Ib,0, "RCRB %i,%e",
+[0x04] Ib,0, "SHLB %i,%e",
+[0x05] Ib,0, "SHRB %i,%e",
+[0x07] Ib,0, "SARB %i,%e",
};
static Optable optabC1[8] =
{
- Ib,0, "ROL%S %i,%e", /* 0x00 */
- Ib,0, "ROR%S %i,%e", /* 0x01 */
- Ib,0, "RCL%S %i,%e", /* 0x02 */
- Ib,0, "RCR%S %i,%e", /* 0x03 */
- Ib,0, "SHL%S %i,%e", /* 0x04 */
- Ib,0, "SHR%S %i,%e", /* 0x05 */
- 0,0, "", /* 0x06 */
- Ib,0, "SAR%S %i,%e", /* 0x07 */
+[0x00] Ib,0, "ROL%S %i,%e",
+[0x01] Ib,0, "ROR%S %i,%e",
+[0x02] Ib,0, "RCL%S %i,%e",
+[0x03] Ib,0, "RCR%S %i,%e",
+[0x04] Ib,0, "SHL%S %i,%e",
+[0x05] Ib,0, "SHR%S %i,%e",
+[0x07] Ib,0, "SAR%S %i,%e",
};
static Optable optabD0[8] =
{
- 0,0, "ROLB %e", /* 0x00 */
- 0,0, "RORB %e", /* 0x01 */
- 0,0, "RCLB %e", /* 0x02 */
- 0,0, "RCRB %e", /* 0x03 */
- 0,0, "SHLB %e", /* 0x04 */
- 0,0, "SHRB %e", /* 0x05 */
- 0,0, "", /* 0x06 */
- 0,0, "SARB %e", /* 0x07 */
+[0x00] 0,0, "ROLB %e",
+[0x01] 0,0, "RORB %e",
+[0x02] 0,0, "RCLB %e",
+[0x03] 0,0, "RCRB %e",
+[0x04] 0,0, "SHLB %e",
+[0x05] 0,0, "SHRB %e",
+[0x07] 0,0, "SARB %e",
};
static Optable optabD1[8] =
{
- 0,0, "ROL%S %e", /* 0x00 */
- 0,0, "ROR%S %e", /* 0x01 */
- 0,0, "RCL%S %e", /* 0x02 */
- 0,0, "RCR%S %e", /* 0x03 */
- 0,0, "SHL%S %e", /* 0x04 */
- 0,0, "SHR%S %e", /* 0x05 */
- 0,0, "", /* 0x06 */
- 0,0, "SAR%S %e", /* 0x07 */
+[0x00] 0,0, "ROL%S %e",
+[0x01] 0,0, "ROR%S %e",
+[0x02] 0,0, "RCL%S %e",
+[0x03] 0,0, "RCR%S %e",
+[0x04] 0,0, "SHL%S %e",
+[0x05] 0,0, "SHR%S %e",
+[0x07] 0,0, "SAR%S %e",
};
static Optable optabD2[8] =
{
- 0,0, "ROLB CL,%e", /* 0x00 */
- 0,0, "RORB CL,%e", /* 0x01 */
- 0,0, "RCLB CL,%e", /* 0x02 */
- 0,0, "RCRB CL,%e", /* 0x03 */
- 0,0, "SHLB CL,%e", /* 0x04 */
- 0,0, "SHRB CL,%e", /* 0x05 */
- 0,0, "", /* 0x06 */
- 0,0, "SARB CL,%e", /* 0x07 */
+[0x00] 0,0, "ROLB CL,%e",
+[0x01] 0,0, "RORB CL,%e",
+[0x02] 0,0, "RCLB CL,%e",
+[0x03] 0,0, "RCRB CL,%e",
+[0x04] 0,0, "SHLB CL,%e",
+[0x05] 0,0, "SHRB CL,%e",
+[0x07] 0,0, "SARB CL,%e",
};
static Optable optabD3[8] =
{
- 0,0, "ROL%S CL,%e", /* 0x00 */
- 0,0, "ROR%S CL,%e", /* 0x01 */
- 0,0, "RCL%S CL,%e", /* 0x02 */
- 0,0, "RCR%S CL,%e", /* 0x03 */
- 0,0, "SHL%S CL,%e", /* 0x04 */
- 0,0, "SHR%S CL,%e", /* 0x05 */
- 0,0, "", /* 0x06 */
- 0,0, "SAR%S CL,%e", /* 0x07 */
+[0x00] 0,0, "ROL%S CL,%e",
+[0x01] 0,0, "ROR%S CL,%e",
+[0x02] 0,0, "RCL%S CL,%e",
+[0x03] 0,0, "RCR%S CL,%e",
+[0x04] 0,0, "SHL%S CL,%e",
+[0x05] 0,0, "SHR%S CL,%e",
+[0x07] 0,0, "SAR%S CL,%e",
};
static Optable optabD8[8+8] =
{
- 0,0, "FADDF %e,F0", /* 0x00 */
- 0,0, "FMULF %e,F0", /* 0x01 */
- 0,0, "FCOMF %e,F0", /* 0x02 */
- 0,0, "FCOMFP %e,F0", /* 0x03 */
- 0,0, "FSUBF %e,F0", /* 0x04 */
- 0,0, "FSUBRF %e,F0", /* 0x05 */
- 0,0, "FDIVF %e,F0", /* 0x06 */
- 0,0, "FDIVRF %e,F0", /* 0x07 */
- 0,0, "FADDD %f,F0", /* 0x08 */
- 0,0, "FMULD %f,F0", /* 0x09 */
- 0,0, "FCOMD %f,F0", /* 0x0a */
- 0,0, "FCOMPD %f,F0", /* 0x0b */
- 0,0, "FSUBD %f,F0", /* 0x0c */
- 0,0, "FSUBRD %f,F0", /* 0x0d */
- 0,0, "FDIVD %f,F0", /* 0x0e */
- 0,0, "FDIVRD %f,F0", /* 0x0f */
+[0x00] 0,0, "FADDF %e,F0",
+[0x01] 0,0, "FMULF %e,F0",
+[0x02] 0,0, "FCOMF %e,F0",
+[0x03] 0,0, "FCOMFP %e,F0",
+[0x04] 0,0, "FSUBF %e,F0",
+[0x05] 0,0, "FSUBRF %e,F0",
+[0x06] 0,0, "FDIVF %e,F0",
+[0x07] 0,0, "FDIVRF %e,F0",
+[0x08] 0,0, "FADDD %f,F0",
+[0x09] 0,0, "FMULD %f,F0",
+[0x0a] 0,0, "FCOMD %f,F0",
+[0x0b] 0,0, "FCOMPD %f,F0",
+[0x0c] 0,0, "FSUBD %f,F0",
+[0x0d] 0,0, "FSUBRD %f,F0",
+[0x0e] 0,0, "FDIVD %f,F0",
+[0x0f] 0,0, "FDIVRD %f,F0",
};
/*
* optabD9 and optabDB use the following encoding:
@@ -623,527 +786,449 @@ static Optable optabD8[8+8] =
*/
static Optable optabD9[64+8] =
{
- 0,0, "FMOVF %e,F0", /* 0x00 */
- 0,0, "", /* 0x01 */
- 0,0, "FMOVF F0,%e", /* 0x02 */
- 0,0, "FMOVFP F0,%e", /* 0x03 */
- 0,0, "FLDENV%S %e", /* 0x04 */
- 0,0, "FLDCW %e", /* 0x05 */
- 0,0, "FSTENV%S %e", /* 0x06 */
- 0,0, "FSTCW %e", /* 0x07 */
- 0,0, "FMOVD F0,F0", /* 0x08 */ /* Mod R/M = 11xx xxxx*/
- 0,0, "FMOVD F1,F0", /* 0x09 */
- 0,0, "FMOVD F2,F0", /* 0x0a */
- 0,0, "FMOVD F3,F0", /* 0x0b */
- 0,0, "FMOVD F4,F0", /* 0x0c */
- 0,0, "FMOVD F5,F0", /* 0x0d */
- 0,0, "FMOVD F6,F0", /* 0x0e */
- 0,0, "FMOVD F7,F0", /* 0x0f */
- 0,0, "FXCHD F0,F0", /* 0x10 */
- 0,0, "FXCHD F1,F0", /* 0x11 */
- 0,0, "FXCHD F2,F0", /* 0x12 */
- 0,0, "FXCHD F3,F0", /* 0x13 */
- 0,0, "FXCHD F4,F0", /* 0x14 */
- 0,0, "FXCHD F5,F0", /* 0x15 */
- 0,0, "FXCHD F6,F0", /* 0x16 */
- 0,0, "FXCHD F7,F0", /* 0x17 */
- 0,0, "FNOP", /* 0x18 */
- 0,0, "", /* 0x19 */
- 0,0, "", /* 0x1a */
- 0,0, "", /* 0x1b */
- 0,0, "", /* 0x1c */
- 0,0, "", /* 0x1d */
- 0,0, "", /* 0x1e */
- 0,0, "", /* 0x1f */
- 0,0, "", /* 0x20 */
- 0,0, "", /* 0x21 */
- 0,0, "", /* 0x22 */
- 0,0, "", /* 0x23 */
- 0,0, "", /* 0x24 */
- 0,0, "", /* 0x25 */
- 0,0, "", /* 0x26 */
- 0,0, "", /* 0x27 */
- 0,0, "FCHS", /* 0x28 */
- 0,0, "FABS", /* 0x29 */
- 0,0, "", /* 0x2a */
- 0,0, "", /* 0x2b */
- 0,0, "FTST", /* 0x2c */
- 0,0, "FXAM", /* 0x2d */
- 0,0, "", /* 0x2e */
- 0,0, "", /* 0x2f */
- 0,0, "FLD1", /* 0x30 */
- 0,0, "FLDL2T", /* 0x31 */
- 0,0, "FLDL2E", /* 0x32 */
- 0,0, "FLDPI", /* 0x33 */
- 0,0, "FLDLG2", /* 0x34 */
- 0,0, "FLDLN2", /* 0x35 */
- 0,0, "FLDZ", /* 0x36 */
- 0,0, "", /* 0x37 */
- 0,0, "F2XM1", /* 0x38 */
- 0,0, "FYL2X", /* 0x39 */
- 0,0, "FPTAN", /* 0x3a */
- 0,0, "FPATAN", /* 0x3b */
- 0,0, "FXTRACT", /* 0x3c */
- 0,0, "FPREM1", /* 0x3d */
- 0,0, "FDECSTP", /* 0x3e */
- 0,0, "FNCSTP", /* 0x3f */
- 0,0, "FPREM", /* 0x40 */
- 0,0, "FYL2XP1", /* 0x41 */
- 0,0, "FSQRT", /* 0x42 */
- 0,0, "FSINCOS", /* 0x43 */
- 0,0, "FRNDINT", /* 0x44 */
- 0,0, "FSCALE", /* 0x45 */
- 0,0, "FSIN", /* 0x46 */
- 0,0, "FCOS", /* 0x47 */
+[0x00] 0,0, "FMOVF %e,F0",
+[0x02] 0,0, "FMOVF F0,%e",
+[0x03] 0,0, "FMOVFP F0,%e",
+[0x04] 0,0, "FLDENV%S %e",
+[0x05] 0,0, "FLDCW %e",
+[0x06] 0,0, "FSTENV%S %e",
+[0x07] 0,0, "FSTCW %e",
+[0x08] 0,0, "FMOVD F0,F0", /* Mod R/M = 11xx xxxx*/
+[0x09] 0,0, "FMOVD F1,F0",
+[0x0a] 0,0, "FMOVD F2,F0",
+[0x0b] 0,0, "FMOVD F3,F0",
+[0x0c] 0,0, "FMOVD F4,F0",
+[0x0d] 0,0, "FMOVD F5,F0",
+[0x0e] 0,0, "FMOVD F6,F0",
+[0x0f] 0,0, "FMOVD F7,F0",
+[0x10] 0,0, "FXCHD F0,F0",
+[0x11] 0,0, "FXCHD F1,F0",
+[0x12] 0,0, "FXCHD F2,F0",
+[0x13] 0,0, "FXCHD F3,F0",
+[0x14] 0,0, "FXCHD F4,F0",
+[0x15] 0,0, "FXCHD F5,F0",
+[0x16] 0,0, "FXCHD F6,F0",
+[0x17] 0,0, "FXCHD F7,F0",
+[0x18] 0,0, "FNOP",
+[0x28] 0,0, "FCHS",
+[0x29] 0,0, "FABS",
+[0x2c] 0,0, "FTST",
+[0x2d] 0,0, "FXAM",
+[0x30] 0,0, "FLD1",
+[0x31] 0,0, "FLDL2T",
+[0x32] 0,0, "FLDL2E",
+[0x33] 0,0, "FLDPI",
+[0x34] 0,0, "FLDLG2",
+[0x35] 0,0, "FLDLN2",
+[0x36] 0,0, "FLDZ",
+[0x38] 0,0, "F2XM1",
+[0x39] 0,0, "FYL2X",
+[0x3a] 0,0, "FPTAN",
+[0x3b] 0,0, "FPATAN",
+[0x3c] 0,0, "FXTRACT",
+[0x3d] 0,0, "FPREM1",
+[0x3e] 0,0, "FDECSTP",
+[0x3f] 0,0, "FNCSTP",
+[0x40] 0,0, "FPREM",
+[0x41] 0,0, "FYL2XP1",
+[0x42] 0,0, "FSQRT",
+[0x43] 0,0, "FSINCOS",
+[0x44] 0,0, "FRNDINT",
+[0x45] 0,0, "FSCALE",
+[0x46] 0,0, "FSIN",
+[0x47] 0,0, "FCOS",
};
static Optable optabDA[8+8] =
{
- 0,0, "FADDL %e,F0", /* 0x00 */
- 0,0, "FMULL %e,F0", /* 0x01 */
- 0,0, "FCOML %e,F0", /* 0x02 */
- 0,0, "FCOMLP %e,F0", /* 0x03 */
- 0,0, "FSUBL %e,F0", /* 0x04 */
- 0,0, "FSUBRL %e,F0", /* 0x05 */
- 0,0, "FDIVL %e,F0", /* 0x06 */
- 0,0, "FDIVRL %e,F0", /* 0x07 */
- 0,0, "", /* 0x08 */
- 0,0, "", /* 0x09 */
- 0,0, "", /* 0x0a */
- 0,0, "", /* 0x0b */
- 0,0, "", /* 0x0c */
- R1,0, "FUCOMPP", /* 0x0d */
+[0x00] 0,0, "FADDL %e,F0",
+[0x01] 0,0, "FMULL %e,F0",
+[0x02] 0,0, "FCOML %e,F0",
+[0x03] 0,0, "FCOMLP %e,F0",
+[0x04] 0,0, "FSUBL %e,F0",
+[0x05] 0,0, "FSUBRL %e,F0",
+[0x06] 0,0, "FDIVL %e,F0",
+[0x07] 0,0, "FDIVRL %e,F0",
+[0x0d] R1,0, "FUCOMPP",
};
static Optable optabDB[8+64] =
{
- 0,0, "FMOVL %e,F0", /* 0x00 */
- 0,0, "", /* 0x01 */
- 0,0, "FMOVL F0,%e", /* 0x02 */
- 0,0, "FMOVLP F0,%e", /* 0x03 */
- 0,0, "", /* 0x04 */
- 0,0, "FMOVX %e,F0", /* 0x05 */
- 0,0, "", /* 0x06 */
- 0,0, "FMOVXP F0,%e", /* 0x07 */
- 0,0, "", /* 0x08 */
- 0,0, "", /* 0x09 */
- 0,0, "", /* 0x0a */
- 0,0, "", /* 0x0b */
- 0,0, "", /* 0x0c */
- 0,0, "", /* 0x0d */
- 0,0, "", /* 0x0e */
- 0,0, "", /* 0x0f */
- 0,0, "", /* 0x10 */
- 0,0, "", /* 0x11 */
- 0,0, "", /* 0x12 */
- 0,0, "", /* 0x13 */
- 0,0, "", /* 0x14 */
- 0,0, "", /* 0x15 */
- 0,0, "", /* 0x16 */
- 0,0, "", /* 0x17 */
- 0,0, "", /* 0x18 */
- 0,0, "", /* 0x19 */
- 0,0, "", /* 0x1a */
- 0,0, "", /* 0x1b */
- 0,0, "", /* 0x1c */
- 0,0, "", /* 0x1d */
- 0,0, "", /* 0x1e */
- 0,0, "", /* 0x1f */
- 0,0, "", /* 0x20 */
- 0,0, "", /* 0x21 */
- 0,0, "", /* 0x22 */
- 0,0, "", /* 0x23 */
- 0,0, "", /* 0x24 */
- 0,0, "", /* 0x25 */
- 0,0, "", /* 0x26 */
- 0,0, "", /* 0x27 */
- 0,0, "", /* 0x28 */
- 0,0, "", /* 0x29 */
- 0,0, "FCLEX", /* 0x2a */
- 0,0, "FINIT", /* 0x2b */
+[0x00] 0,0, "FMOVL %e,F0",
+[0x02] 0,0, "FMOVL F0,%e",
+[0x03] 0,0, "FMOVLP F0,%e",
+[0x05] 0,0, "FMOVX %e,F0",
+[0x07] 0,0, "FMOVXP F0,%e",
+[0x2a] 0,0, "FCLEX",
+[0x2b] 0,0, "FINIT",
};
static Optable optabDC[8+8] =
{
- 0,0, "FADDD %e,F0", /* 0x00 */
- 0,0, "FMULD %e,F0", /* 0x01 */
- 0,0, "FCOMD %e,F0", /* 0x02 */
- 0,0, "FCOMDP %e,F0", /* 0x03 */
- 0,0, "FSUBD %e,F0", /* 0x04 */
- 0,0, "FSUBRD %e,F0", /* 0x05 */
- 0,0, "FDIVD %e,F0", /* 0x06 */
- 0,0, "FDIVRD %e,F0", /* 0x07 */
- 0,0, "FADDD F0,%f", /* 0x08 */
- 0,0, "FMULD F0,%f", /* 0x09 */
- 0,0, "", /* 0x0a */
- 0,0, "", /* 0x0b */
- 0,0, "FSUBRD F0,%f", /* 0x0c */
- 0,0, "FSUBD F0,%f", /* 0x0d */
- 0,0, "FDIVRD F0,%f", /* 0x0e */
- 0,0, "FDIVD F0,%f", /* 0x0f */
+[0x00] 0,0, "FADDD %e,F0",
+[0x01] 0,0, "FMULD %e,F0",
+[0x02] 0,0, "FCOMD %e,F0",
+[0x03] 0,0, "FCOMDP %e,F0",
+[0x04] 0,0, "FSUBD %e,F0",
+[0x05] 0,0, "FSUBRD %e,F0",
+[0x06] 0,0, "FDIVD %e,F0",
+[0x07] 0,0, "FDIVRD %e,F0",
+[0x08] 0,0, "FADDD F0,%f",
+[0x09] 0,0, "FMULD F0,%f",
+[0x0c] 0,0, "FSUBRD F0,%f",
+[0x0d] 0,0, "FSUBD F0,%f",
+[0x0e] 0,0, "FDIVRD F0,%f",
+[0x0f] 0,0, "FDIVD F0,%f",
};
static Optable optabDD[8+8] =
{
- 0,0, "FMOVD %e,F0", /* 0x00 */
- 0,0, "", /* 0x01 */
- 0,0, "FMOVD F0,%e", /* 0x02 */
- 0,0, "FMOVDP F0,%e", /* 0x03 */
- 0,0, "FRSTOR%S %e", /* 0x04 */
- 0,0, "", /* 0x05 */
- 0,0, "FSAVE%S %e", /* 0x06 */
- 0,0, "FSTSW %e", /* 0x07 */
- 0,0, "FFREED %f", /* 0x08 */
- 0,0, "", /* 0x09 */
- 0,0, "FMOVD %f,F0", /* 0x0a */
- 0,0, "FMOVDP %f,F0", /* 0x0b */
- 0,0, "FUCOMD %f,F0", /* 0x0c */
- 0,0, "FUCOMDP %f,F0", /* 0x0d */
+[0x00] 0,0, "FMOVD %e,F0",
+[0x02] 0,0, "FMOVD F0,%e",
+[0x03] 0,0, "FMOVDP F0,%e",
+[0x04] 0,0, "FRSTOR%S %e",
+[0x06] 0,0, "FSAVE%S %e",
+[0x07] 0,0, "FSTSW %e",
+[0x08] 0,0, "FFREED %f",
+[0x0a] 0,0, "FMOVD %f,F0",
+[0x0b] 0,0, "FMOVDP %f,F0",
+[0x0c] 0,0, "FUCOMD %f,F0",
+[0x0d] 0,0, "FUCOMDP %f,F0",
};
static Optable optabDE[8+8] =
{
- 0,0, "FADDW %e,F0", /* 0x00 */
- 0,0, "FMULW %e,F0", /* 0x01 */
- 0,0, "FCOMW %e,F0", /* 0x02 */
- 0,0, "FCOMWP %e,F0", /* 0x03 */
- 0,0, "FSUBW %e,F0", /* 0x04 */
- 0,0, "FSUBRW %e,F0", /* 0x05 */
- 0,0, "FDIVW %e,F0", /* 0x06 */
- 0,0, "FDIVRW %e,F0", /* 0x07 */
- 0,0, "FADDDP F0,%f", /* 0x08 */
- 0,0, "FMULDP F0,%f", /* 0x09 */
- 0,0, "", /* 0x0a */
- R1,0, "FCOMPDP", /* 0x0b */
- 0,0, "FSUBRDP F0,%f", /* 0x0c */
- 0,0, "FSUBDP F0,%f", /* 0x0d */
- 0,0, "FDIVRDP F0,%f", /* 0x0e */
- 0,0, "FDIVDP F0,%f", /* 0x0f */
+[0x00] 0,0, "FADDW %e,F0",
+[0x01] 0,0, "FMULW %e,F0",
+[0x02] 0,0, "FCOMW %e,F0",
+[0x03] 0,0, "FCOMWP %e,F0",
+[0x04] 0,0, "FSUBW %e,F0",
+[0x05] 0,0, "FSUBRW %e,F0",
+[0x06] 0,0, "FDIVW %e,F0",
+[0x07] 0,0, "FDIVRW %e,F0",
+[0x08] 0,0, "FADDDP F0,%f",
+[0x09] 0,0, "FMULDP F0,%f",
+[0x0b] R1,0, "FCOMPDP",
+[0x0c] 0,0, "FSUBRDP F0,%f",
+[0x0d] 0,0, "FSUBDP F0,%f",
+[0x0e] 0,0, "FDIVRDP F0,%f",
+[0x0f] 0,0, "FDIVDP F0,%f",
};
static Optable optabDF[8+8] =
{
- 0,0, "FMOVW %e,F0", /* 0x00 */
- 0,0, "", /* 0x01 */
- 0,0, "FMOVW F0,%e", /* 0x02 */
- 0,0, "FMOVWP F0,%e", /* 0x03 */
- 0,0, "FBLD %e", /* 0x04 */
- 0,0, "FMOVL %e,F0", /* 0x05 */
- 0,0, "FBSTP %e", /* 0x06 */
- 0,0, "FMOVLP F0,%e", /* 0x07 */
- 0,0, "", /* 0x08 */
- 0,0, "", /* 0x09 */
- 0,0, "", /* 0x0a */
- 0,0, "", /* 0x0b */
- R0,0, "FSTSW %OAX", /* 0x0c */
+[0x00] 0,0, "FMOVW %e,F0",
+[0x02] 0,0, "FMOVW F0,%e",
+[0x03] 0,0, "FMOVWP F0,%e",
+[0x04] 0,0, "FBLD %e",
+[0x05] 0,0, "FMOVL %e,F0",
+[0x06] 0,0, "FBSTP %e",
+[0x07] 0,0, "FMOVLP F0,%e",
+[0x0c] R0,0, "FSTSW %OAX",
};
static Optable optabF6[8] =
{
- Ib,0, "TESTB %i,%e", /* 0x00 */
- 0,0, "", /* 0x01 */
- 0,0, "NOTB %e", /* 0x02 */
- 0,0, "NEGB %e", /* 0x03 */
- 0,0, "MULB AL,%e", /* 0x04 */
- 0,0, "IMULB AL,%e", /* 0x05 */
- 0,0, "DIVB AL,%e", /* 0x06 */
- 0,0, "IDIVB AL,%e", /* 0x07 */
+[0x00] Ib,0, "TESTB %i,%e",
+[0x02] 0,0, "NOTB %e",
+[0x03] 0,0, "NEGB %e",
+[0x04] 0,0, "MULB AL,%e",
+[0x05] 0,0, "IMULB AL,%e",
+[0x06] 0,0, "DIVB AL,%e",
+[0x07] 0,0, "IDIVB AL,%e",
};
static Optable optabF7[8] =
{
- Iwd,0, "TEST%S %i,%e", /* 0x00 */
- 0,0, "", /* 0x01 */
- 0,0, "NOT%S %e", /* 0x02 */
- 0,0, "NEG%S %e", /* 0x03 */
- 0,0, "MUL%S %OAX,%e", /* 0x04 */
- 0,0, "IMUL%S %OAX,%e", /* 0x05 */
- 0,0, "DIV%S %OAX,%e", /* 0x06 */
- 0,0, "IDIV%S %OAX,%e", /* 0x07 */
+[0x00] Iwd,0, "TEST%S %i,%e",
+[0x02] 0,0, "NOT%S %e",
+[0x03] 0,0, "NEG%S %e",
+[0x04] 0,0, "MUL%S %OAX,%e",
+[0x05] 0,0, "IMUL%S %OAX,%e",
+[0x06] 0,0, "DIV%S %OAX,%e",
+[0x07] 0,0, "IDIV%S %OAX,%e",
};
static Optable optabFE[8] =
{
- 0,0, "INCB %e", /* 0x00 */
- 0,0, "DECB %e", /* 0x01 */
+[0x00] 0,0, "INCB %e",
+[0x01] 0,0, "DECB %e",
};
static Optable optabFF[8] =
{
- 0,0, "INC%S %e", /* 0x00 */
- 0,0, "DEC%S %e", /* 0x01 */
- JUMP,0, "CALL*%S %e", /* 0x02 */
- JUMP,0, "CALLF*%S %e", /* 0x03 */
- JUMP,0, "JMP*%S %e", /* 0x04 */
- JUMP,0, "JMPF*%S %e", /* 0x05 */
- 0,0, "PUSHL %e", /* 0x06 */
+[0x00] 0,0, "INC%S %e",
+[0x01] 0,0, "DEC%S %e",
+[0x02] JUMP,0, "CALL* %e",
+[0x03] JUMP,0, "CALLF* %e",
+[0x04] JUMP,0, "JMP* %e",
+[0x05] JUMP,0, "JMPF* %e",
+[0x06] 0,0, "PUSHL %e",
};
-static Optable optable[256] =
+static Optable optable[256+1] =
{
- RMB,0, "ADDB %r,%e", /* 0x00 */
- RM,0, "ADD%S %r,%e", /* 0x01 */
- RMB,0, "ADDB %e,%r", /* 0x02 */
- RM,0, "ADD%S %e,%r", /* 0x03 */
- Ib,0, "ADDB %i,AL", /* 0x04 */
- Iwd,0, "ADD%S %i,%OAX", /* 0x05 */
- 0,0, "PUSHL ES", /* 0x06 */
- 0,0, "POPL ES", /* 0x07 */
- RMB,0, "ORB %r,%e", /* 0x08 */
- RM,0, "OR%S %r,%e", /* 0x09 */
- RMB,0, "ORB %e,%r", /* 0x0a */
- RM,0, "OR%S %e,%r", /* 0x0b */
- Ib,0, "ORB %i,AL", /* 0x0c */
- Iwd,0, "OR%S %i,%OAX", /* 0x0d */
- 0,0, "PUSHL CS", /* 0x0e */
- AUX,0, optab0F, /* 0x0f */
- RMB,0, "ADCB %r,%e", /* 0x10 */
- RM,0, "ADC%S %r,%e", /* 0x11 */
- RMB,0, "ADCB %e,%r", /* 0x12 */
- RM,0, "ADC%S %e,%r", /* 0x13 */
- Ib,0, "ADCB %i,AL", /* 0x14 */
- Iwd,0, "ADC%S %i,%OAX", /* 0x15 */
- 0,0, "PUSHL SS", /* 0x16 */
- 0,0, "POPL SS", /* 0x17 */
- RMB,0, "SBBB %r,%e", /* 0x18 */
- RM,0, "SBB%S %r,%e", /* 0x19 */
- RMB,0, "SBBB %e,%r", /* 0x1a */
- RM,0, "SBB%S %e,%r", /* 0x1b */
- Ib,0, "SBBB %i,AL", /* 0x1c */
- Iwd,0, "SBB%S %i,%OAX", /* 0x1d */
- 0,0, "PUSHL DS", /* 0x1e */
- 0,0, "POPL DS", /* 0x1f */
- RMB,0, "ANDB %r,%e", /* 0x20 */
- RM,0, "AND%S %r,%e", /* 0x21 */
- RMB,0, "ANDB %e,%r", /* 0x22 */
- RM,0, "AND%S %e,%r", /* 0x23 */
- Ib,0, "ANDB %i,AL", /* 0x24 */
- Iwd,0, "AND%S %i,%OAX", /* 0x25 */
- SEG,0, "ES:", /* 0x26 */
- 0,0, "DAA", /* 0x27 */
- RMB,0, "SUBB %r,%e", /* 0x28 */
- RM,0, "SUB%S %r,%e", /* 0x29 */
- RMB,0, "SUBB %e,%r", /* 0x2a */
- RM,0, "SUB%S %e,%r", /* 0x2b */
- Ib,0, "SUBB %i,AL", /* 0x2c */
- Iwd,0, "SUB%S %i,%OAX", /* 0x2d */
- SEG,0, "CS:", /* 0x2e */
- 0,0, "DAS", /* 0x2f */
- RMB,0, "XORB %r,%e", /* 0x30 */
- RM,0, "XOR%S %r,%e", /* 0x31 */
- RMB,0, "XORB %e,%r", /* 0x32 */
- RM,0, "XOR%S %e,%r", /* 0x33 */
- Ib,0, "XORB %i,AL", /* 0x34 */
- Iwd,0, "XOR%S %i,%OAX", /* 0x35 */
- SEG,0, "SS:", /* 0x36 */
- 0,0, "AAA", /* 0x37 */
- RMB,0, "CMPB %r,%e", /* 0x38 */
- RM,0, "CMP%S %r,%e", /* 0x39 */
- RMB,0, "CMPB %e,%r", /* 0x3a */
- RM,0, "CMP%S %e,%r", /* 0x3b */
- Ib,0, "CMPB %i,AL", /* 0x3c */
- Iwd,0, "CMP%S %i,%OAX", /* 0x3d */
- SEG,0, "DS:", /* 0x3e */
- 0,0, "AAS", /* 0x3f */
- 0,0, "INC%S %OAX", /* 0x40 */
- 0,0, "INC%S %OCX", /* 0x41 */
- 0,0, "INC%S %ODX", /* 0x42 */
- 0,0, "INC%S %OBX", /* 0x43 */
- 0,0, "INC%S %OSP", /* 0x44 */
- 0,0, "INC%S %OBP", /* 0x45 */
- 0,0, "INC%S %OSI", /* 0x46 */
- 0,0, "INC%S %ODI", /* 0x47 */
- 0,0, "DEC%S %OAX", /* 0x48 */
- 0,0, "DEC%S %OCX", /* 0x49 */
- 0,0, "DEC%S %ODX", /* 0x4a */
- 0,0, "DEC%S %OBX", /* 0x4b */
- 0,0, "DEC%S %OSP", /* 0x4c */
- 0,0, "DEC%S %OBP", /* 0x4d */
- 0,0, "DEC%S %OSI", /* 0x4e */
- 0,0, "DEC%S %ODI", /* 0x4f */
- 0,0, "PUSH%S %OAX", /* 0x50 */
- 0,0, "PUSH%S %OCX", /* 0x51 */
- 0,0, "PUSH%S %ODX", /* 0x52 */
- 0,0, "PUSH%S %OBX", /* 0x53 */
- 0,0, "PUSH%S %OSP", /* 0x54 */
- 0,0, "PUSH%S %OBP", /* 0x55 */
- 0,0, "PUSH%S %OSI", /* 0x56 */
- 0,0, "PUSH%S %ODI", /* 0x57 */
- 0,0, "POP%S %OAX", /* 0x58 */
- 0,0, "POP%S %OCX", /* 0x59 */
- 0,0, "POP%S %ODX", /* 0x5a */
- 0,0, "POP%S %OBX", /* 0x5b */
- 0,0, "POP%S %OSP", /* 0x5c */
- 0,0, "POP%S %OBP", /* 0x5d */
- 0,0, "POP%S %OSI", /* 0x5e */
- 0,0, "POP%S %ODI", /* 0x5f */
- 0,0, "PUSHA%S", /* 0x60 */
- 0,0, "POPA%S", /* 0x61 */
- RMM,0, "BOUND %e,%r", /* 0x62 */
- RM,0, "ARPL %r,%e", /* 0x63 */
- SEG,0, "FS:", /* 0x64 */
- SEG,0, "GS:", /* 0x65 */
- OPOVER,0, "", /* 0x66 */
- ADDOVER,0, "", /* 0x67 */
- Iwd,0, "PUSH%S %i", /* 0x68 */
- RM,Iwd, "IMUL%S %e,%i,%r", /* 0x69 */
- Ib,0, "PUSH%S %i", /* 0x6a */
- RM,Ibs, "IMUL%S %e,%i,%r", /* 0x6b */
- 0,0, "INSB DX,(%ODI)", /* 0x6c */
- 0,0, "INS%S DX,(%ODI)", /* 0x6d */
- 0,0, "OUTSB (%ASI),DX", /* 0x6e */
- 0,0, "OUTS%S (%ASI),DX", /* 0x6f */
- Jbs,0, "JOS %p", /* 0x70 */
- Jbs,0, "JOC %p", /* 0x71 */
- Jbs,0, "JCS %p", /* 0x72 */
- Jbs,0, "JCC %p", /* 0x73 */
- Jbs,0, "JEQ %p", /* 0x74 */
- Jbs,0, "JNE %p", /* 0x75 */
- Jbs,0, "JLS %p", /* 0x76 */
- Jbs,0, "JHI %p", /* 0x77 */
- Jbs,0, "JMI %p", /* 0x78 */
- Jbs,0, "JPL %p", /* 0x79 */
- Jbs,0, "JPS %p", /* 0x7a */
- Jbs,0, "JPC %p", /* 0x7b */
- Jbs,0, "JLT %p", /* 0x7c */
- Jbs,0, "JGE %p", /* 0x7d */
- Jbs,0, "JLE %p", /* 0x7e */
- Jbs,0, "JGT %p", /* 0x7f */
- RMOPB,0, optab80, /* 0x80 */
- RMOP,0, optab81, /* 0x81 */
- 0,0, "", /* 0x82 */
- RMOP,0, optab83, /* 0x83 */
- RMB,0, "TESTB %r,%e", /* 0x84 */
- RM,0, "TEST%S %r,%e", /* 0x85 */
- RMB,0, "XCHGB %r,%e", /* 0x86 */
- RM,0, "XCHG%S %r,%e", /* 0x87 */
- RMB,0, "MOVB %r,%e", /* 0x88 */
- RM,0, "MOV%S %r,%e", /* 0x89 */
- RMB,0, "MOVB %e,%r", /* 0x8a */
- RM,0, "MOV%S %e,%r", /* 0x8b */
- RM,0, "MOVW %g,%e", /* 0x8c */
- RM,0, "LEA %e,%r", /* 0x8d */
- RM,0, "MOVW %e,%g", /* 0x8e */
- RM,0, "POP%S %e", /* 0x8f */
- 0,0, "NOP", /* 0x90 */
- 0,0, "XCHG %OCX,%OAX", /* 0x91 */
- 0,0, "XCHG %OCX,%OAX", /* 0x92 */
- 0,0, "XCHG %OCX,%OAX", /* 0x93 */
- 0,0, "XCHG %OSP,%OAX", /* 0x94 */
- 0,0, "XCHG %OBP,%OAX", /* 0x95 */
- 0,0, "XCHG %OSI,%OAX", /* 0x96 */
- 0,0, "XCHG %ODI,%OAX", /* 0x97 */
- 0,0, "%X", /* 0x98 */ /* miserable CBW or CWDE */
- 0,0, "%x", /* 0x99 */ /* idiotic CWD or CDQ */
- PTR,0, "CALL%S %d", /* 0x9a */
- 0,0, "WAIT", /* 0x9b */
- 0,0, "PUSHF", /* 0x9c */
- 0,0, "POPF", /* 0x9d */
- 0,0, "SAHF", /* 0x9e */
- 0,0, "LAHF", /* 0x9f */
- Awd,0, "MOVB %i,AL", /* 0xa0 */
- Awd,0, "MOV%S %i,%OAX", /* 0xa1 */
- Awd,0, "MOVB AL,%i", /* 0xa2 */
- Awd,0, "MOV%S %OAX,%i", /* 0xa3 */
- 0,0, "MOVSB (%ASI),(%ADI)", /* 0xa4 */
- 0,0, "MOVS%S (%ASI),(%ADI)", /* 0xa5 */
- 0,0, "CMPSB (%ASI),(%ADI)", /* 0xa6 */
- 0,0, "CMPS%S (%ASI),(%ADI)", /* 0xa7 */
- Ib,0, "TESTB %i,AL", /* 0xa8 */
- Iwd,0, "TEST%S %i,%OAX", /* 0xa9 */
- 0,0, "STOSB AL,(%ADI)", /* 0xaa */
- 0,0, "STOS%S %OAX,(%ADI)", /* 0xab */
- 0,0, "LODSB (%ASI),AL", /* 0xac */
- 0,0, "LODS%S (%ASI),%OAX", /* 0xad */
- 0,0, "SCASB (%ADI),AL", /* 0xae */
- 0,0, "SCAS%S (%ADI),%OAX", /* 0xaf */
- Ib,0, "MOVB %i,AL", /* 0xb0 */
- Ib,0, "MOVB %i,CL", /* 0xb1 */
- Ib,0, "MOVB %i,DL", /* 0xb2 */
- Ib,0, "MOVB %i,BL", /* 0xb3 */
- Ib,0, "MOVB %i,AH", /* 0xb4 */
- Ib,0, "MOVB %i,CH", /* 0xb5 */
- Ib,0, "MOVB %i,DH", /* 0xb6 */
- Ib,0, "MOVB %i,BH", /* 0xb7 */
- Iwd,0, "MOV%S %i,%OAX", /* 0xb8 */
- Iwd,0, "MOV%S %i,%OCX", /* 0xb9 */
- Iwd,0, "MOV%S %i,%ODX", /* 0xba */
- Iwd,0, "MOV%S %i,%OBX", /* 0xbb */
- Iwd,0, "MOV%S %i,%OSP", /* 0xbc */
- Iwd,0, "MOV%S %i,%OBP", /* 0xbd */
- Iwd,0, "MOV%S %i,%OSI", /* 0xbe */
- Iwd,0, "MOV%S %i,%ODI", /* 0xbf */
- RMOPB,0, optabC0, /* 0xc0 */
- RMOP,0, optabC1, /* 0xc1 */
- Iw,0, "RET %i", /* 0xc2 */
- RET,0, "RET", /* 0xc3 */
- RM,0, "LES %e,%r", /* 0xc4 */
- RM,0, "LDS %e,%r", /* 0xc5 */
- RMB,Ib, "MOVB %i,%e", /* 0xc6 */
- RM,Iwd, "MOV%S %i,%e", /* 0xc7 */
- Iw2,Ib, "ENTER %i,%I", /* 0xc8 */ /* loony ENTER */
- RET,0, "LEAVE", /* 0xc9 */ /* bizarre LEAVE */
- Iw,0, "RETF %i", /* 0xca */
- RET,0, "RETF", /* 0xcb */
- 0,0, "INT 3", /* 0xcc */
- Ib,0, "INTB %i", /* 0xcd */
- 0,0, "INTO", /* 0xce */
- 0,0, "IRET", /* 0xcf */
- RMOPB,0, optabD0, /* 0xd0 */
- RMOP,0, optabD1, /* 0xd1 */
- RMOPB,0, optabD2, /* 0xd2 */
- RMOP,0, optabD3, /* 0xd3 */
- OA,0, "AAM", /* 0xd4 */
- OA,0, "AAD", /* 0xd5 */
- 0,0, "", /* 0xd6 */
- 0,0, "XLAT", /* 0xd7 */
- FRMOP,0, optabD8, /* 0xd8 */
- FRMEX,0, optabD9, /* 0xd9 */
- FRMOP,0, optabDA, /* 0xda */
- FRMEX,0, optabDB, /* 0xdb */
- FRMOP,0, optabDC, /* 0xdc */
- FRMOP,0, optabDD, /* 0xdd */
- FRMOP,0, optabDE, /* 0xde */
- FRMOP,0, optabDF, /* 0xdf */
- Jbs,0, "LOOPNE %p", /* 0xe0 */
- Jbs,0, "LOOPE %p", /* 0xe1 */
- Jbs,0, "LOOP %p", /* 0xe2 */
- Jbs,0, "JCXZ %p", /* 0xe3 */
- Ib,0, "INB %i,AL", /* 0xe4 */
- Ib,0, "IN%S %i,%OAX", /* 0xe5 */
- Ib,0, "OUTB AL,%i", /* 0xe6 */
- Ib,0, "OUT%S %OAX,%i", /* 0xe7 */
- Iwds,0, "CALL %p", /* 0xe8 */
- Iwds,0, "JMP %p", /* 0xe9 */
- PTR,0, "JMP %d", /* 0xea */
- Jbs,0, "JMP %p", /* 0xeb */
- 0,0, "INB DX,AL", /* 0xec */
- 0,0, "IN%S DX,%OAX", /* 0xed */
- 0,0, "OUTB AL,DX", /* 0xee */
- 0,0, "OUT%S %OAX,DX", /* 0xef */
- PRE,0, "LOCK", /* 0xf0 */
- 0,0, "", /* 0xf1 */
- PRE,0, "REPNE", /* 0xf2 */
- PRE,0, "REP", /* 0xf3 */
- 0,0, "HALT", /* 0xf4 */
- 0,0, "CMC", /* 0xf5 */
- RMOPB,0, optabF6, /* 0xf6 */
- RMOP,0, optabF7, /* 0xf7 */
- 0,0, "CLC", /* 0xf8 */
- 0,0, "STC", /* 0xf9 */
- 0,0, "CLI", /* 0xfa */
- 0,0, "STI", /* 0xfb */
- 0,0, "CLD", /* 0xfc */
- 0,0, "STD", /* 0xfd */
- RMOPB,0, optabFE, /* 0xfe */
- RMOP,0, optabFF, /* 0xff */
+[0x00] RMB,0, "ADDB %r,%e",
+[0x01] RM,0, "ADD%S %r,%e",
+[0x02] RMB,0, "ADDB %e,%r",
+[0x03] RM,0, "ADD%S %e,%r",
+[0x04] Ib,0, "ADDB %i,AL",
+[0x05] Iwd,0, "ADD%S %i,%OAX",
+[0x06] 0,0, "PUSHL ES",
+[0x07] 0,0, "POPL ES",
+[0x08] RMB,0, "ORB %r,%e",
+[0x09] RM,0, "OR%S %r,%e",
+[0x0a] RMB,0, "ORB %e,%r",
+[0x0b] RM,0, "OR%S %e,%r",
+[0x0c] Ib,0, "ORB %i,AL",
+[0x0d] Iwd,0, "OR%S %i,%OAX",
+[0x0e] 0,0, "PUSHL CS",
+[0x0f] AUXMM,0, optab0F,
+[0x10] RMB,0, "ADCB %r,%e",
+[0x11] RM,0, "ADC%S %r,%e",
+[0x12] RMB,0, "ADCB %e,%r",
+[0x13] RM,0, "ADC%S %e,%r",
+[0x14] Ib,0, "ADCB %i,AL",
+[0x15] Iwd,0, "ADC%S %i,%OAX",
+[0x16] 0,0, "PUSHL SS",
+[0x17] 0,0, "POPL SS",
+[0x18] RMB,0, "SBBB %r,%e",
+[0x19] RM,0, "SBB%S %r,%e",
+[0x1a] RMB,0, "SBBB %e,%r",
+[0x1b] RM,0, "SBB%S %e,%r",
+[0x1c] Ib,0, "SBBB %i,AL",
+[0x1d] Iwd,0, "SBB%S %i,%OAX",
+[0x1e] 0,0, "PUSHL DS",
+[0x1f] 0,0, "POPL DS",
+[0x20] RMB,0, "ANDB %r,%e",
+[0x21] RM,0, "AND%S %r,%e",
+[0x22] RMB,0, "ANDB %e,%r",
+[0x23] RM,0, "AND%S %e,%r",
+[0x24] Ib,0, "ANDB %i,AL",
+[0x25] Iwd,0, "AND%S %i,%OAX",
+[0x26] SEG,0, "ES:",
+[0x27] 0,0, "DAA",
+[0x28] RMB,0, "SUBB %r,%e",
+[0x29] RM,0, "SUB%S %r,%e",
+[0x2a] RMB,0, "SUBB %e,%r",
+[0x2b] RM,0, "SUB%S %e,%r",
+[0x2c] Ib,0, "SUBB %i,AL",
+[0x2d] Iwd,0, "SUB%S %i,%OAX",
+[0x2e] SEG,0, "CS:",
+[0x2f] 0,0, "DAS",
+[0x30] RMB,0, "XORB %r,%e",
+[0x31] RM,0, "XOR%S %r,%e",
+[0x32] RMB,0, "XORB %e,%r",
+[0x33] RM,0, "XOR%S %e,%r",
+[0x34] Ib,0, "XORB %i,AL",
+[0x35] Iwd,0, "XOR%S %i,%OAX",
+[0x36] SEG,0, "SS:",
+[0x37] 0,0, "AAA",
+[0x38] RMB,0, "CMPB %r,%e",
+[0x39] RM,0, "CMP%S %r,%e",
+[0x3a] RMB,0, "CMPB %e,%r",
+[0x3b] RM,0, "CMP%S %e,%r",
+[0x3c] Ib,0, "CMPB %i,AL",
+[0x3d] Iwd,0, "CMP%S %i,%OAX",
+[0x3e] SEG,0, "DS:",
+[0x3f] 0,0, "AAS",
+[0x40] 0,0, "INC%S %OAX",
+[0x41] 0,0, "INC%S %OCX",
+[0x42] 0,0, "INC%S %ODX",
+[0x43] 0,0, "INC%S %OBX",
+[0x44] 0,0, "INC%S %OSP",
+[0x45] 0,0, "INC%S %OBP",
+[0x46] 0,0, "INC%S %OSI",
+[0x47] 0,0, "INC%S %ODI",
+[0x48] 0,0, "DEC%S %OAX",
+[0x49] 0,0, "DEC%S %OCX",
+[0x4a] 0,0, "DEC%S %ODX",
+[0x4b] 0,0, "DEC%S %OBX",
+[0x4c] 0,0, "DEC%S %OSP",
+[0x4d] 0,0, "DEC%S %OBP",
+[0x4e] 0,0, "DEC%S %OSI",
+[0x4f] 0,0, "DEC%S %ODI",
+[0x50] 0,0, "PUSH%S %OAX",
+[0x51] 0,0, "PUSH%S %OCX",
+[0x52] 0,0, "PUSH%S %ODX",
+[0x53] 0,0, "PUSH%S %OBX",
+[0x54] 0,0, "PUSH%S %OSP",
+[0x55] 0,0, "PUSH%S %OBP",
+[0x56] 0,0, "PUSH%S %OSI",
+[0x57] 0,0, "PUSH%S %ODI",
+[0x58] 0,0, "POP%S %OAX",
+[0x59] 0,0, "POP%S %OCX",
+[0x5a] 0,0, "POP%S %ODX",
+[0x5b] 0,0, "POP%S %OBX",
+[0x5c] 0,0, "POP%S %OSP",
+[0x5d] 0,0, "POP%S %OBP",
+[0x5e] 0,0, "POP%S %OSI",
+[0x5f] 0,0, "POP%S %ODI",
+[0x60] 0,0, "PUSHA%S",
+[0x61] 0,0, "POPA%S",
+[0x62] RMM,0, "BOUND %e,%r",
+[0x63] RM,0, "ARPL %r,%e",
+[0x64] SEG,0, "FS:",
+[0x65] SEG,0, "GS:",
+[0x66] OPOVER,0, "",
+[0x67] ADDOVER,0, "",
+[0x68] Iwd,0, "PUSH%S %i",
+[0x69] RM,Iwd, "IMUL%S %e,%i,%r",
+[0x6a] Ib,0, "PUSH%S %i",
+[0x6b] RM,Ibs, "IMUL%S %e,%i,%r",
+[0x6c] 0,0, "INSB DX,(%ODI)",
+[0x6d] 0,0, "INS%S DX,(%ODI)",
+[0x6e] 0,0, "OUTSB (%ASI),DX",
+[0x6f] 0,0, "OUTS%S (%ASI),DX",
+[0x70] Jbs,0, "JOS %p",
+[0x71] Jbs,0, "JOC %p",
+[0x72] Jbs,0, "JCS %p",
+[0x73] Jbs,0, "JCC %p",
+[0x74] Jbs,0, "JEQ %p",
+[0x75] Jbs,0, "JNE %p",
+[0x76] Jbs,0, "JLS %p",
+[0x77] Jbs,0, "JHI %p",
+[0x78] Jbs,0, "JMI %p",
+[0x79] Jbs,0, "JPL %p",
+[0x7a] Jbs,0, "JPS %p",
+[0x7b] Jbs,0, "JPC %p",
+[0x7c] Jbs,0, "JLT %p",
+[0x7d] Jbs,0, "JGE %p",
+[0x7e] Jbs,0, "JLE %p",
+[0x7f] Jbs,0, "JGT %p",
+[0x80] RMOPB,0, optab80,
+[0x81] RMOP,0, optab81,
+[0x83] RMOP,0, optab83,
+[0x84] RMB,0, "TESTB %r,%e",
+[0x85] RM,0, "TEST%S %r,%e",
+[0x86] RMB,0, "XCHGB %r,%e",
+[0x87] RM,0, "XCHG%S %r,%e",
+[0x88] RMB,0, "MOVB %r,%e",
+[0x89] RM,0, "MOV%S %r,%e",
+[0x8a] RMB,0, "MOVB %e,%r",
+[0x8b] RM,0, "MOV%S %e,%r",
+[0x8c] RM,0, "MOVW %g,%e",
+[0x8d] RM,0, "LEA%S %e,%r",
+[0x8e] RM,0, "MOVW %e,%g",
+[0x8f] RM,0, "POP%S %e",
+[0x90] 0,0, "NOP",
+[0x91] 0,0, "XCHG %OCX,%OAX",
+[0x92] 0,0, "XCHG %ODX,%OAX",
+[0x93] 0,0, "XCHG %OBX,%OAX",
+[0x94] 0,0, "XCHG %OSP,%OAX",
+[0x95] 0,0, "XCHG %OBP,%OAX",
+[0x96] 0,0, "XCHG %OSI,%OAX",
+[0x97] 0,0, "XCHG %ODI,%OAX",
+[0x98] 0,0, "%W", /* miserable CBW or CWDE */
+[0x99] 0,0, "%w", /* idiotic CWD or CDQ */
+[0x9a] PTR,0, "CALL%S %d",
+[0x9b] 0,0, "WAIT",
+[0x9c] 0,0, "PUSHF",
+[0x9d] 0,0, "POPF",
+[0x9e] 0,0, "SAHF",
+[0x9f] 0,0, "LAHF",
+[0xa0] Awd,0, "MOVB %i,AL",
+[0xa1] Awd,0, "MOV%S %i,%OAX",
+[0xa2] Awd,0, "MOVB AL,%i",
+[0xa3] Awd,0, "MOV%S %OAX,%i",
+[0xa4] 0,0, "MOVSB (%ASI),(%ADI)",
+[0xa5] 0,0, "MOVS%S (%ASI),(%ADI)",
+[0xa6] 0,0, "CMPSB (%ASI),(%ADI)",
+[0xa7] 0,0, "CMPS%S (%ASI),(%ADI)",
+[0xa8] Ib,0, "TESTB %i,AL",
+[0xa9] Iwd,0, "TEST%S %i,%OAX",
+[0xaa] 0,0, "STOSB AL,(%ADI)",
+[0xab] 0,0, "STOS%S %OAX,(%ADI)",
+[0xac] 0,0, "LODSB (%ASI),AL",
+[0xad] 0,0, "LODS%S (%ASI),%OAX",
+[0xae] 0,0, "SCASB (%ADI),AL",
+[0xaf] 0,0, "SCAS%S (%ADI),%OAX",
+[0xb0] Ib,0, "MOVB %i,AL",
+[0xb1] Ib,0, "MOVB %i,CL",
+[0xb2] Ib,0, "MOVB %i,DL",
+[0xb3] Ib,0, "MOVB %i,BL",
+[0xb4] Ib,0, "MOVB %i,AH",
+[0xb5] Ib,0, "MOVB %i,CH",
+[0xb6] Ib,0, "MOVB %i,DH",
+[0xb7] Ib,0, "MOVB %i,BH",
+[0xb8] Iwdq,0, "MOV%S %i,%OAX",
+[0xb9] Iwdq,0, "MOV%S %i,%OCX",
+[0xba] Iwdq,0, "MOV%S %i,%ODX",
+[0xbb] Iwdq,0, "MOV%S %i,%OBX",
+[0xbc] Iwdq,0, "MOV%S %i,%OSP",
+[0xbd] Iwdq,0, "MOV%S %i,%OBP",
+[0xbe] Iwdq,0, "MOV%S %i,%OSI",
+[0xbf] Iwdq,0, "MOV%S %i,%ODI",
+[0xc0] RMOPB,0, optabC0,
+[0xc1] RMOP,0, optabC1,
+[0xc2] Iw,0, "RET %i",
+[0xc3] RET,0, "RET",
+[0xc4] RM,0, "LES %e,%r",
+[0xc5] RM,0, "LDS %e,%r",
+[0xc6] RMB,Ib, "MOVB %i,%e",
+[0xc7] RM,Iwd, "MOV%S %i,%e",
+[0xc8] Iw2,Ib, "ENTER %i,%I", /* loony ENTER */
+[0xc9] RET,0, "LEAVE", /* bizarre LEAVE */
+[0xca] Iw,0, "RETF %i",
+[0xcb] RET,0, "RETF",
+[0xcc] 0,0, "INT 3",
+[0xcd] Ib,0, "INTB %i",
+[0xce] 0,0, "INTO",
+[0xcf] 0,0, "IRET",
+[0xd0] RMOPB,0, optabD0,
+[0xd1] RMOP,0, optabD1,
+[0xd2] RMOPB,0, optabD2,
+[0xd3] RMOP,0, optabD3,
+[0xd4] OA,0, "AAM",
+[0xd5] OA,0, "AAD",
+[0xd7] 0,0, "XLAT",
+[0xd8] FRMOP,0, optabD8,
+[0xd9] FRMEX,0, optabD9,
+[0xda] FRMOP,0, optabDA,
+[0xdb] FRMEX,0, optabDB,
+[0xdc] FRMOP,0, optabDC,
+[0xdd] FRMOP,0, optabDD,
+[0xde] FRMOP,0, optabDE,
+[0xdf] FRMOP,0, optabDF,
+[0xe0] Jbs,0, "LOOPNE %p",
+[0xe1] Jbs,0, "LOOPE %p",
+[0xe2] Jbs,0, "LOOP %p",
+[0xe3] Jbs,0, "JCXZ %p",
+[0xe4] Ib,0, "INB %i,AL",
+[0xe5] Ib,0, "IN%S %i,%OAX",
+[0xe6] Ib,0, "OUTB AL,%i",
+[0xe7] Ib,0, "OUT%S %OAX,%i",
+[0xe8] Iwds,0, "CALL %p",
+[0xe9] Iwds,0, "JMP %p",
+[0xea] PTR,0, "JMP %d",
+[0xeb] Jbs,0, "JMP %p",
+[0xec] 0,0, "INB DX,AL",
+[0xed] 0,0, "IN%S DX,%OAX",
+[0xee] 0,0, "OUTB AL,DX",
+[0xef] 0,0, "OUT%S %OAX,DX",
+[0xf0] PRE,0, "LOCK",
+[0xf2] OPRE,0, "REPNE",
+[0xf3] OPRE,0, "REP",
+[0xf4] 0,0, "HLT",
+[0xf5] 0,0, "CMC",
+[0xf6] RMOPB,0, optabF6,
+[0xf7] RMOP,0, optabF7,
+[0xf8] 0,0, "CLC",
+[0xf9] 0,0, "STC",
+[0xfa] 0,0, "CLI",
+[0xfb] 0,0, "STI",
+[0xfc] 0,0, "CLD",
+[0xfd] 0,0, "STD",
+[0xfe] RMOPB,0, optabFE,
+[0xff] RMOP,0, optabFF,
+[0x100] RM,0, "MOVLQSX %r,%e",
};
/*
* get a byte of the instruction
*/
static int
-igetc(Map * map, Instr *ip, uchar *c)
+igetc(Map *map, Instr *ip, uchar *c)
{
if(ip->n+1 > sizeof(ip->mem)){
werrstr("instruction too long");
@@ -1163,7 +1248,7 @@ igetc(Map * map, Instr *ip, uchar *c)
static int
igets(Map *map, Instr *ip, ushort *sp)
{
- uchar c;
+ uchar c;
ushort s;
if (igetc(map, ip, &c) < 0)
@@ -1195,8 +1280,27 @@ igetl(Map *map, Instr *ip, ulong *lp)
return 1;
}
+/*
+ * get 8 bytes of the instruction
+ */
static int
-getdisp(Map *map, Instr *ip, int mod, int rm, int code)
+igetq(Map *map, Instr *ip, vlong *qp)
+{
+ ulong l;
+ uvlong q;
+
+ if (igetl(map, ip, &l) < 0)
+ return -1;
+ q = l;
+ if (igetl(map, ip, &l) < 0)
+ return -1;
+ q |= ((uvlong)l<<32);
+ *qp = q;
+ return 1;
+}
+
+static int
+getdisp(Map *map, Instr *ip, int mod, int rm, int code, int pcrel)
{
uchar c;
ushort s;
@@ -1214,6 +1318,8 @@ getdisp(Map *map, Instr *ip, int mod, int rm, int code)
if (ip->asize == 'E') {
if (igetl(map, ip, &ip->disp) < 0)
return -1;
+ if (mod == 0)
+ ip->rip = pcrel;
} else {
if (igets(map, ip, &s) < 0)
return -1;
@@ -1238,11 +1344,11 @@ modrm(Map *map, Instr *ip, uchar c)
ip->mod = mod;
ip->base = rm;
ip->reg = (c>>3)&7;
+ ip->rip = 0;
if (mod == 3) /* register */
return 1;
if (ip->asize == 0) { /* 16-bit mode */
- switch(rm)
- {
+ switch(rm) {
case 0:
ip->base = BX; ip->index = SI;
break;
@@ -1270,7 +1376,7 @@ modrm(Map *map, Instr *ip, uchar c)
default:
break;
}
- return getdisp(map, ip, mod, rm, 6);
+ return getdisp(map, ip, mod, rm, 6, 0);
}
if (rm == 4) { /* scummy sib byte */
if (igetc(map, ip, &c) < 0)
@@ -1280,21 +1386,22 @@ modrm(Map *map, Instr *ip, uchar c)
if (ip->index == 4)
ip->index = -1;
ip->base = c&0x07;
- return getdisp(map, ip, mod, ip->base, 5);
+ return getdisp(map, ip, mod, ip->base, 5, 0);
}
- return getdisp(map, ip, mod, rm, 5);
+ return getdisp(map, ip, mod, rm, 5, ip->amd64);
}
static Optable *
-mkinstr(Map *map, Instr *ip, ulong pc)
+mkinstr(Map *map, Instr *ip, uvlong pc)
{
- int i, n;
+ int i, n, norex;
uchar c;
ushort s;
Optable *op, *obase;
char buf[128];
memset(ip, 0, sizeof(*ip));
+ norex = 1;
ip->base = -1;
ip->index = -1;
if(asstype == AI8086)
@@ -1302,13 +1409,27 @@ mkinstr(Map *map, Instr *ip, ulong pc)
else {
ip->osize = 'L';
ip->asize = 'E';
+ ip->amd64 = asstype != AI386;
+ norex = 0;
}
ip->addr = pc;
if (igetc(map, ip, &c) < 0)
return 0;
obase = optable;
newop:
+ if(ip->amd64 && !norex){
+ if(c >= 0x40 && c <= 0x4f) {
+ ip->rex = c;
+ if(igetc(map, ip, &c) < 0)
+ return 0;
+ }
+ if(c == 0x63){
+ op = &obase[0x100]; /* MOVLQSX */
+ goto hack;
+ }
+ }
op = &obase[c];
+hack:
if (op->proto == 0) {
badop:
n = snprint(buf, sizeof(buf), "opcode: ??");
@@ -1319,12 +1440,12 @@ badop:
return 0;
}
for(i = 0; i < 2 && op->operand[i]; i++) {
- switch(op->operand[i])
- {
+ switch(op->operand[i]) {
case Ib: /* 8-bit immediate - (no sign extension)*/
if (igetc(map, ip, &c) < 0)
return 0;
ip->imm = c&0xff;
+ ip->imm64 = ip->imm;
break;
case Jbs: /* 8-bit jump immediate (sign extended) */
if (igetc(map, ip, &c) < 0)
@@ -1333,6 +1454,7 @@ badop:
ip->imm = c|0xffffff00;
else
ip->imm = c&0xff;
+ ip->imm64 = (long)ip->imm;
ip->jumptype = Jbs;
break;
case Ibs: /* 8-bit immediate (sign extended) */
@@ -1345,11 +1467,13 @@ badop:
ip->imm = c|0xff00;
else
ip->imm = c&0xff;
+ ip->imm64 = (long)ip->imm;
break;
case Iw: /* 16-bit immediate -> imm */
if (igets(map, ip, &s) < 0)
return 0;
ip->imm = s&0xffff;
+ ip->imm64 = ip->imm;
ip->jumptype = Iw;
break;
case Iw2: /* 16-bit immediate -> in imm2*/
@@ -1357,10 +1481,31 @@ badop:
return 0;
ip->imm2 = s&0xffff;
break;
- case Iwd: /* Operand-sized immediate (no sign extension)*/
+ case Iwd: /* Operand-sized immediate (no sign extension unless 64 bits)*/
if (ip->osize == 'L') {
if (igetl(map, ip, &ip->imm) < 0)
return 0;
+ ip->imm64 = ip->imm;
+ if(ip->rex&REXW && (ip->imm & (1<<31)) != 0)
+ ip->imm64 |= (vlong)~0 << 32;
+ } else {
+ if (igets(map, ip, &s)< 0)
+ return 0;
+ ip->imm = s&0xffff;
+ ip->imm64 = ip->imm;
+ }
+ break;
+ case Iwdq: /* Operand-sized immediate, possibly big */
+ if (ip->osize == 'L') {
+ if (igetl(map, ip, &ip->imm) < 0)
+ return 0;
+ ip->imm64 = ip->imm;
+ if (ip->rex & REXW) {
+ ulong l;
+ if (igetl(map, ip, &l) < 0)
+ return 0;
+ ip->imm64 |= (uvlong)l << 32;
+ }
} else {
if (igets(map, ip, &s)< 0)
return 0;
@@ -1371,6 +1516,7 @@ badop:
if (ip->asize == 'E') {
if (igetl(map, ip, &ip->imm) < 0)
return 0;
+ /* TO DO: REX */
} else {
if (igets(map, ip, &s)< 0)
return 0;
@@ -1432,8 +1578,10 @@ badop:
return 0;
if (modrm(map, ip, c) < 0)
return 0;
- c = ip->reg;
obase = (Optable*)op->proto;
+ if(ip->amd64 && obase == optab0F01 && c == 0xF8)
+ return optab0F01F8;
+ c = ip->reg;
goto newop;
case FRMOP: /* FP R/M field with op code (/digit) */
if (igetc(map, ip, &c) < 0)
@@ -1490,15 +1638,35 @@ badop:
return 0;
ip->jumptype = PTR;
break;
+ case AUXMM: /* Multi-byte op code; prefix determines table selection */
+ if (igetc(map, ip, &c) < 0)
+ return 0;
+ obase = (Optable*)op->proto;
+ switch (ip->opre) {
+ case 0x66: op = optab660F; break;
+ case 0xF2: op = optabF20F; break;
+ case 0xF3: op = optabF30F; break;
+ default: op = nil; break;
+ }
+ if(op != nil && op[c].proto != nil)
+ obase = op;
+ norex = 1; /* no more rex prefixes */
+ /* otherwise the optab entry captures it */
+ goto newop;
case AUX: /* Multi-byte op code - Auxiliary table */
obase = (Optable*)op->proto;
if (igetc(map, ip, &c) < 0)
return 0;
goto newop;
+ case OPRE: /* Instr Prefix or media op */
+ ip->opre = c;
+ /* fall through */
case PRE: /* Instr Prefix */
ip->prefix = (char*)op->proto;
if (igetc(map, ip, &c) < 0)
return 0;
+ if (ip->opre && c == 0x0F)
+ ip->prefix = 0;
goto newop;
case SEG: /* Segment Prefix */
ip->segment = (char*)op->proto;
@@ -1506,9 +1674,14 @@ badop:
return 0;
goto newop;
case OPOVER: /* Operand size override */
+ ip->opre = c;
ip->osize = 'W';
if (igetc(map, ip, &c) < 0)
return 0;
+ if (c == 0x0F)
+ ip->osize = 'L';
+ else if (ip->amd64 && (c&0xF0) == 0x40)
+ ip->osize = 'Q';
goto newop;
case ADDOVER: /* Address size override */
ip->asize = 0;
@@ -1527,6 +1700,8 @@ badop:
return op;
}
+#pragma varargck argpos bprint 2
+
static void
bprint(Instr *ip, char *fmt, ...)
{
@@ -1548,23 +1723,36 @@ bprint(Instr *ip, char *fmt, ...)
#define ONAME(ip) ""
static char *reg[] = {
- "AX", /* 0 */
- "CX", /* 1 */
- "DX", /* 2 */
- "BX", /* 3 */
- "SP", /* 4 */
- "BP", /* 5 */
- "SI", /* 6 */
- "DI", /* 7 */
+[AX] "AX",
+[CX] "CX",
+[DX] "DX",
+[BX] "BX",
+[SP] "SP",
+[BP] "BP",
+[SI] "SI",
+[DI] "DI",
+
+ /* amd64 */
+[R8] "R8",
+[R9] "R9",
+[R10] "R10",
+[R11] "R11",
+[R12] "R12",
+[R13] "R13",
+[R14] "R14",
+[R15] "R15",
};
static char *breg[] = { "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH" };
+static char *breg64[] = { "AL", "CL", "DL", "BL", "SPB", "BPB", "SIB", "DIB",
+ "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B" };
static char *sreg[] = { "ES", "CS", "SS", "DS", "FS", "GS" };
static void
plocal(Instr *ip)
{
- int ret, offset;
+ int ret;
+ long offset;
Symbol s;
char *reg;
@@ -1589,60 +1777,143 @@ plocal(Instr *ip)
bprint(ip, "%lux%s", offset, reg);
}
-static void
-pea(Instr *ip)
+static int
+isjmp(Instr *ip)
{
- if (ip->mod == 3) {
- if (ip->osize == 'B')
- bprint(ip, breg[ip->base]);
- else
- bprint(ip, "%s%s", ANAME(ip), reg[ip->base]);
- return;
+ switch(ip->jumptype){
+ case Iwds:
+ case Jbs:
+ case JUMP:
+ return 1;
+ default:
+ return 0;
}
- if (ip->segment)
- bprint(ip, ip->segment);
- if (ip->asize == 'E' && ip->base == SP)
- plocal(ip);
- else {
- bprint(ip,"%lux", ip->disp);
- if (ip->base >= 0)
- bprint(ip,"(%s%s)", ANAME(ip), reg[ip->base]);
+}
+
+/*
+ * This is too smart for its own good, but it really is nice
+ * to have accurate translations when debugging, and it
+ * helps us identify which code is different in binaries that
+ * are changed on sources.
+ */
+static int
+issymref(Instr *ip, Symbol *s, long w, long val)
+{
+ Symbol next, tmp;
+ long isstring, size;
+
+ if (isjmp(ip))
+ return 1;
+ if (s->class==CTEXT && w==0)
+ return 1;
+ if (s->class==CDATA) {
+ /* use first bss symbol (or "end") rather than edata */
+ if (s->name[0]=='e' && strcmp(s->name, "edata") == 0){
+ if((s ->index >= 0 && globalsym(&tmp, s->index+1) && tmp.value==s->value)
+ || (s->index > 0 && globalsym(&tmp, s->index-1) && tmp.value==s->value))
+ *s = tmp;
+ }
+ if (w == 0)
+ return 1;
+ for (next=*s; next.value==s->value; next=tmp)
+ if (!globalsym(&tmp, next.index+1))
+ break;
+ size = next.value - s->value;
+ if (w >= size)
+ return 0;
+ if (w > size-w)
+ w = size-w;
+ /* huge distances are usually wrong except in .string */
+ isstring = (s->name[0]=='.' && strcmp(s->name, ".string") == 0);
+ if (w > 8192 && !isstring)
+ return 0;
+ /* medium distances are tricky - look for constants */
+ /* near powers of two */
+ if ((val&(val-1)) == 0 || (val&(val+1)) == 0)
+ return 0;
+ return 1;
}
- if (ip->index >= 0)
- bprint(ip,"(%s%s*%d)", ANAME(ip), reg[ip->index], 1<<ip->ss);
+ return 0;
}
static void
-immediate(Instr *ip, long val)
+immediate(Instr *ip, vlong val)
{
Symbol s;
long w;
- if (findsym(val, CANY, &s)) {
+ if (findsym(val, CANY, &s)) { /* TO DO */
w = val - s.value;
if (w < 0)
w = -w;
- if (w < 4096) {
+ if (issymref(ip, &s, w, val)) {
if (w)
bprint(ip, "%s+%lux(SB)", s.name, w);
else
bprint(ip, "%s(SB)", s.name);
return;
}
+/*
+ if (s.class==CDATA && globalsym(&s, s.index+1)) {
+ w = s.value - val;
+ if (w < 0)
+ w = -w;
+ if (w < 4096) {
+ bprint(ip, "%s-%lux(SB)", s.name, w);
+ return;
+ }
+ }
+*/
+ }
+ if((ip->rex & REXW) == 0)
+ bprint(ip, "%lux", (long)val);
+ else
+ bprint(ip, "%llux", val);
+}
+
+static void
+pea(Instr *ip)
+{
+ if (ip->mod == 3) {
+ if (ip->osize == 'B')
+ bprint(ip, (ip->rex & REXB? breg64: breg)[ip->base]);
+ else if(ip->rex & REXB)
+ bprint(ip, "%s%s", ANAME(ip), reg[ip->base+8]);
+ else
+ bprint(ip, "%s%s", ANAME(ip), reg[ip->base]);
+ return;
+ }
+ if (ip->segment)
+ bprint(ip, ip->segment);
+ if (ip->asize == 'E' && ip->base == SP)
+ plocal(ip);
+ else {
+ if (ip->base < 0)
+ immediate(ip, ip->disp);
+ else {
+ bprint(ip, "%lux", ip->disp);
+ if(ip->rip)
+ bprint(ip, "(RIP)");
+ bprint(ip,"(%s%s)", ANAME(ip), reg[ip->rex&REXB? ip->base+8: ip->base]);
+ }
}
- bprint(ip, "%lux", val);
+ if (ip->index >= 0)
+ bprint(ip,"(%s%s*%d)", ANAME(ip), reg[ip->rex&REXX? ip->index+8: ip->index], 1<<ip->ss);
}
static void
prinstr(Instr *ip, char *fmt)
{
+ vlong v;
+
if (ip->prefix)
bprint(ip, "%s ", ip->prefix);
for (; *fmt && ip->curr < ip->end; fmt++) {
- if (*fmt != '%')
+ if (*fmt != '%'){
*ip->curr++ = *fmt;
- else switch(*++fmt)
- {
+ continue;
+ }
+ switch(*++fmt){
case '%':
*ip->curr++ = '%';
break;
@@ -1667,13 +1938,29 @@ prinstr(Instr *ip, char *fmt)
break;
case 'i':
bprint(ip, "$");
- immediate(ip,ip->imm);
+ v = ip->imm;
+ if(ip->rex & REXW)
+ v = ip->imm64;
+ immediate(ip, v);
break;
case 'R':
- bprint(ip, "%s%s", ONAME(ip), reg[ip->reg]);
+ bprint(ip, "%s%s", ONAME(ip), reg[ip->rex&REXR? ip->reg+8: ip->reg]);
break;
case 'S':
- bprint(ip, "%c", ip->osize);
+ if(ip->osize == 'Q' || ip->osize == 'L' && ip->rex & REXW)
+ bprint(ip, "Q");
+ else
+ bprint(ip, "%c", ip->osize);
+ break;
+ case 's':
+ if(ip->opre == 0 || ip->opre == 0x66)
+ bprint(ip, "P");
+ else
+ bprint(ip, "S");
+ if(ip->opre == 0xf2 || ip->opre == 0x66)
+ bprint(ip, "D");
+ else
+ bprint(ip, "S");
break;
case 'T':
if (ip->reg == 6 || ip->reg == 7)
@@ -1681,14 +1968,30 @@ prinstr(Instr *ip, char *fmt)
else
bprint(ip, "???");
break;
- case 'X':
- if (ip->osize == 'L')
+ case 'W':
+ if (ip->osize == 'Q' || ip->osize == 'L' && ip->rex & REXW)
+ bprint(ip, "CDQE");
+ else if (ip->osize == 'L')
bprint(ip,"CWDE");
else
bprint(ip, "CBW");
break;
case 'd':
- bprint(ip,"%lux:%lux",ip->seg,ip->disp);
+ bprint(ip,"%ux:%lux",ip->seg,ip->disp);
+ break;
+ case 'm':
+ if (ip->mod == 3 && ip->osize != 'B') {
+ if(fmt[1] != '*'){
+ if(ip->opre != 0) {
+ bprint(ip, "X%d", ip->rex&REXB? ip->base+8: ip->base);
+ break;
+ }
+ } else
+ fmt++;
+ bprint(ip, "M%d", ip->base);
+ break;
+ }
+ pea(ip);
break;
case 'e':
pea(ip);
@@ -1703,20 +2006,42 @@ prinstr(Instr *ip, char *fmt)
bprint(ip,"???");
break;
case 'p':
- immediate(ip, ip->imm+ip->addr+ip->n);
+ /*
+ * signed immediate in the ulong ip->imm.
+ */
+ v = (long)ip->imm;
+ immediate(ip, v+ip->addr+ip->n);
break;
case 'r':
if (ip->osize == 'B')
- bprint(ip,"%s",breg[ip->reg]);
+ bprint(ip,"%s", (ip->rex? breg64: breg)[ip->rex&REXR? ip->reg+8: ip->reg]);
else
- bprint(ip, reg[ip->reg]);
+ bprint(ip, reg[ip->rex&REXR? ip->reg+8: ip->reg]);
break;
- case 'x':
- if (ip->osize == 'L')
+ case 'w':
+ if (ip->osize == 'Q' || ip->rex & REXW)
+ bprint(ip, "CQO");
+ else if (ip->osize == 'L')
bprint(ip,"CDQ");
else
bprint(ip, "CWD");
break;
+ case 'M':
+ if(ip->opre != 0)
+ bprint(ip, "X%d", ip->rex&REXR? ip->reg+8: ip->reg);
+ else
+ bprint(ip, "M%d", ip->reg);
+ break;
+ case 'x':
+ if (ip->mod == 3 && ip->osize != 'B') {
+ bprint(ip, "X%d", ip->rex&REXB? ip->base+8: ip->base);
+ break;
+ }
+ pea(ip);
+ break;
+ case 'X':
+ bprint(ip, "X%d", ip->rex&REXR? ip->reg+8: ip->reg);
+ break;
default:
bprint(ip, "%%%c", *fmt);
break;
@@ -1726,15 +2051,14 @@ prinstr(Instr *ip, char *fmt)
}
static int
-i386inst(Map *map, ulong pc, char modifier, char *buf, int n)
+i386inst(Map *map, uvlong pc, char modifier, char *buf, int n)
{
- Instr instr;
+ Instr instr;
Optable *op;
USED(modifier);
op = mkinstr(map, &instr, pc);
if (op == 0) {
- buf[0] = 0;
errstr(buf, n);
return -1;
}
@@ -1745,13 +2069,12 @@ i386inst(Map *map, ulong pc, char modifier, char *buf, int n)
}
static int
-i386das(Map *map, ulong pc, char *buf, int n)
+i386das(Map *map, uvlong pc, char *buf, int n)
{
- Instr instr;
+ Instr instr;
int i;
if (mkinstr(map, &instr, pc) == 0) {
- buf[0] = 0;
errstr(buf, n);
return -1;
}
@@ -1765,7 +2088,7 @@ i386das(Map *map, ulong pc, char *buf, int n)
}
static int
-i386instlen(Map *map, ulong pc)
+i386instlen(Map *map, uvlong pc)
{
Instr i;
@@ -1775,12 +2098,13 @@ i386instlen(Map *map, ulong pc)
}
static int
-i386foll(Map *map, ulong pc, Rgetter rget, ulong *foll)
+i386foll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
{
Instr i;
Optable *op;
ushort s;
- ulong l, addr;
+ uvlong l, addr;
+ vlong v;
int n;
op = mkinstr(map, &i, pc);
@@ -1793,15 +2117,16 @@ i386foll(Map *map, ulong pc, Rgetter rget, ulong *foll)
case RET: /* RETURN or LEAVE */
case Iw: /* RETURN */
if (strcmp(op->proto, "LEAVE") == 0) {
- if (get4(map, (*rget)(map, "BP"), (long*)&l) < 0)
+ if (geta(map, (*rget)(map, "BP"), &l) < 0)
return -1;
- } else if (get4(map, (*rget)(map, mach->sp), (long*)&l) < 0)
+ } else if (geta(map, (*rget)(map, mach->sp), &l) < 0)
return -1;
foll[0] = l;
return 1;
case Iwds: /* pc relative JUMP or CALL*/
case Jbs: /* pc relative JUMP or CALL */
- foll[0] = pc+i.imm+i.n;
+ v = (long)i.imm;
+ foll[0] = pc+v+i.n;
n = 1;
break;
case PTR: /* seg:displacement JUMP or CALL */
@@ -1810,28 +2135,28 @@ i386foll(Map *map, ulong pc, Rgetter rget, ulong *foll)
case JUMP: /* JUMP or CALL EA */
if(i.mod == 3) {
- foll[0] = (*rget)(map, reg[i.base]);
+ foll[0] = (*rget)(map, reg[i.rex&REXB? i.base+8: i.base]);
return 1;
}
/* calculate the effective address */
addr = i.disp;
if (i.base >= 0) {
- if (get4(map, (*rget)(map, reg[i.base]), (long*)&l) < 0)
+ if (geta(map, (*rget)(map, reg[i.rex&REXB? i.base+8: i.base]), &l) < 0)
return -1;
addr += l;
}
if (i.index >= 0) {
- if (get4(map, (*rget)(map, reg[i.index]), (long*)&l) < 0)
+ if (geta(map, (*rget)(map, reg[i.rex&REXX? i.index+8: i.index]), &l) < 0)
return -1;
addr += l*(1<<i.ss);
}
/* now retrieve a seg:disp value at that address */
- if (get2(map, addr, &s) < 0) /* seg */
+ if (get2(map, addr, &s) < 0) /* seg */
return -1;
foll[0] = s<<4;
addr += 2;
if (i.asize == 'L') {
- if (get4(map, addr, (long*)&l) < 0) /* disp32 */
+ if (geta(map, addr, &l) < 0) /* disp32 */
return -1;
foll[0] += l;
} else { /* disp16 */
diff --git a/utils/libmach/9.c b/utils/libmach/9.c
new file mode 100644
index 00000000..aeeebae3
--- /dev/null
+++ b/utils/libmach/9.c
@@ -0,0 +1,120 @@
+/*
+ * PowerPC 64 definition
+ * forsyth@vitanuova.com
+ */
+#include <lib9.h>
+#include <bio.h>
+#include "ureg9.h"
+#include <mach.h>
+
+
+#define REGOFF(x) offsetof(struct Ureg, x)
+
+#define R31 REGOFF(r31)
+#define FP_REG(x) (R31+4+8*(x))
+
+#define REGSIZE sizeof(struct Ureg)
+#define FPREGSIZE (8*33)
+
+Reglist power64reglist[] = {
+ {"CAUSE", REGOFF(cause), RINT|RRDONLY, 'Y'},
+ {"TRAP", REGOFF(cause), RINT|RRDONLY, 'Y'}, /* alias for acid */
+ {"MSR", REGOFF(msr), RINT|RRDONLY, 'Y'},
+ {"PC", REGOFF(pc), RINT, 'Y'},
+ {"LR", REGOFF(lr), RINT, 'Y'},
+ {"CR", REGOFF(cr), RINT, 'X'},
+ {"XER", REGOFF(xer), RINT, 'Y'},
+ {"CTR", REGOFF(ctr), RINT, 'Y'},
+ {"PC", REGOFF(pc), RINT, 'Y'},
+ {"SP", REGOFF(sp), RINT, 'Y'},
+ {"R0", REGOFF(r0), RINT, 'Y'},
+ /* R1 is SP */
+ {"R2", REGOFF(r2), RINT, 'Y'},
+ {"R3", REGOFF(r3), RINT, 'Y'},
+ {"R4", REGOFF(r4), RINT, 'Y'},
+ {"R5", REGOFF(r5), RINT, 'Y'},
+ {"R6", REGOFF(r6), RINT, 'Y'},
+ {"R7", REGOFF(r7), RINT, 'Y'},
+ {"R8", REGOFF(r8), RINT, 'Y'},
+ {"R9", REGOFF(r9), RINT, 'Y'},
+ {"R10", REGOFF(r10), RINT, 'Y'},
+ {"R11", REGOFF(r11), RINT, 'Y'},
+ {"R12", REGOFF(r12), RINT, 'Y'},
+ {"R13", REGOFF(r13), RINT, 'Y'},
+ {"R14", REGOFF(r14), RINT, 'Y'},
+ {"R15", REGOFF(r15), RINT, 'Y'},
+ {"R16", REGOFF(r16), RINT, 'Y'},
+ {"R17", REGOFF(r17), RINT, 'Y'},
+ {"R18", REGOFF(r18), RINT, 'Y'},
+ {"R19", REGOFF(r19), RINT, 'Y'},
+ {"R20", REGOFF(r20), RINT, 'Y'},
+ {"R21", REGOFF(r21), RINT, 'Y'},
+ {"R22", REGOFF(r22), RINT, 'Y'},
+ {"R23", REGOFF(r23), RINT, 'Y'},
+ {"R24", REGOFF(r24), RINT, 'Y'},
+ {"R25", REGOFF(r25), RINT, 'Y'},
+ {"R26", REGOFF(r26), RINT, 'Y'},
+ {"R27", REGOFF(r27), RINT, 'Y'},
+ {"R28", REGOFF(r28), RINT, 'Y'},
+ {"R29", REGOFF(r29), RINT, 'Y'},
+ {"R30", REGOFF(r30), RINT, 'Y'},
+ {"R31", REGOFF(r31), RINT, 'Y'},
+ {"F0", FP_REG(0), RFLT, 'F'},
+ {"F1", FP_REG(1), RFLT, 'F'},
+ {"F2", FP_REG(2), RFLT, 'F'},
+ {"F3", FP_REG(3), RFLT, 'F'},
+ {"F4", FP_REG(4), RFLT, 'F'},
+ {"F5", FP_REG(5), RFLT, 'F'},
+ {"F6", FP_REG(6), RFLT, 'F'},
+ {"F7", FP_REG(7), RFLT, 'F'},
+ {"F8", FP_REG(8), RFLT, 'F'},
+ {"F9", FP_REG(9), RFLT, 'F'},
+ {"F10", FP_REG(10), RFLT, 'F'},
+ {"F11", FP_REG(11), RFLT, 'F'},
+ {"F12", FP_REG(12), RFLT, 'F'},
+ {"F13", FP_REG(13), RFLT, 'F'},
+ {"F14", FP_REG(14), RFLT, 'F'},
+ {"F15", FP_REG(15), RFLT, 'F'},
+ {"F16", FP_REG(16), RFLT, 'F'},
+ {"F17", FP_REG(17), RFLT, 'F'},
+ {"F18", FP_REG(18), RFLT, 'F'},
+ {"F19", FP_REG(19), RFLT, 'F'},
+ {"F20", FP_REG(20), RFLT, 'F'},
+ {"F21", FP_REG(21), RFLT, 'F'},
+ {"F22", FP_REG(22), RFLT, 'F'},
+ {"F23", FP_REG(23), RFLT, 'F'},
+ {"F24", FP_REG(24), RFLT, 'F'},
+ {"F25", FP_REG(25), RFLT, 'F'},
+ {"F26", FP_REG(26), RFLT, 'F'},
+ {"F27", FP_REG(27), RFLT, 'F'},
+ {"F28", FP_REG(28), RFLT, 'F'},
+ {"F29", FP_REG(29), RFLT, 'F'},
+ {"F30", FP_REG(30), RFLT, 'F'},
+ {"F31", FP_REG(31), RFLT, 'F'},
+ {"FPSCR", FP_REG(32)+4, RFLT, 'X'},
+ { 0 }
+};
+
+ /* the machine description */
+Mach mpower64 =
+{
+ "power64",
+ MPOWER64, /* machine type */
+ power64reglist, /* register set */
+ REGSIZE, /* number of bytes in register set */
+ FPREGSIZE, /* number of bytes in FP register set */
+ "PC", /* name of PC */
+ "SP", /* name of SP */
+ "LR", /* name of link register */
+ "setSB", /* static base register name */
+ 0, /* value */
+ 0x1000, /* page size */
+ 0x80000000ULL, /* kernel base */
+ 0, /* kernel text mask */
+ 0x7FFFFFFFULL, /* user stack top */
+ 4, /* quantization of pc */
+ 8, /* szaddr */
+ 8, /* szreg */
+ 4, /* szfloat */
+ 8, /* szdouble */
+};
diff --git a/utils/libmach/9obj.c b/utils/libmach/9obj.c
new file mode 100644
index 00000000..4ec76b98
--- /dev/null
+++ b/utils/libmach/9obj.c
@@ -0,0 +1,155 @@
+/*
+ * 9obj.c - identify and parse a PowerPC-64 object file
+ * forsyth@terzarima.net
+ */
+#include <lib9.h>
+#include <bio.h>
+#include "mach.h"
+#include "9c/9.out.h"
+#include "obj.h"
+
+typedef struct Addr Addr;
+struct Addr
+{
+ char type;
+ char sym;
+ char name;
+};
+static Addr addr(Biobuf*);
+static char type2char(int);
+static void skip(Biobuf*, int);
+
+int
+_is9(char *s)
+{
+ return (s[0]&0377) == ANAME /* ANAME */
+ && (s[1]&0377) == ANAME>>8
+ && s[2] == D_FILE /* type */
+ && s[3] == 1 /* sym */
+ && s[4] == '<'; /* name of file */
+}
+
+int
+_read9(Biobuf *bp, Prog *p)
+{
+ int as, n, c;
+ Addr a;
+
+ as = Bgetc(bp); /* as(low) */
+ if(as < 0)
+ return 0;
+ c = Bgetc(bp); /* as(high) */
+ if(c < 0)
+ return 0;
+ as |= ((c & 0xff) << 8);
+ p->kind = aNone;
+ p->sig = 0;
+ if(as == ANAME || as == ASIGNAME){
+ if(as == ASIGNAME){
+ Bread(bp, &p->sig, 4);
+ p->sig = beswal(p->sig);
+ }
+ p->kind = aName;
+ p->type = type2char(Bgetc(bp)); /* type */
+ p->sym = Bgetc(bp); /* sym */
+ n = 0;
+ for(;;) {
+ as = Bgetc(bp);
+ if(as < 0)
+ return 0;
+ n++;
+ if(as == 0)
+ break;
+ }
+ p->id = malloc(n);
+ if(p->id == 0)
+ return 0;
+ Bseek(bp, -n, 1);
+ if(Bread(bp, p->id, n) != n)
+ return 0;
+ return 1;
+ }
+ if(as == ATEXT)
+ p->kind = aText;
+ else if(as == AGLOBL)
+ p->kind = aData;
+ n = Bgetc(bp); /* reg and flag */
+ skip(bp, 4); /* lineno(4) */
+ a = addr(bp);
+ if(n & 0x40)
+ addr(bp);
+ addr(bp);
+ if(a.type != D_OREG || a.name != D_STATIC && a.name != D_EXTERN)
+ p->kind = aNone;
+ p->sym = a.sym;
+ return 1;
+}
+
+static Addr
+addr(Biobuf *bp)
+{
+ Addr a;
+ vlong off;
+ long l;
+
+ a.type = Bgetc(bp); /* a.type */
+ skip(bp,1); /* reg */
+ a.sym = Bgetc(bp); /* sym index */
+ a.name = Bgetc(bp); /* sym type */
+ switch(a.type){
+ default:
+ case D_NONE: case D_REG: case D_FREG: case D_CREG:
+ case D_FPSCR: case D_MSR:
+ break;
+ case D_SPR:
+ case D_OREG:
+ case D_CONST:
+ case D_BRANCH:
+ case D_DCONST:
+ case D_DCR:
+ l = Bgetc(bp);
+ l |= Bgetc(bp) << 8;
+ l |= Bgetc(bp) << 16;
+ l |= Bgetc(bp) << 24;
+ off = l;
+ if(a.type == D_DCONST){
+ l = Bgetc(bp);
+ l |= Bgetc(bp) << 8;
+ l |= Bgetc(bp) << 16;
+ l |= Bgetc(bp) << 24;
+ off = ((vlong)l << 32) | (off & 0xFFFFFFFF);
+ a.type = D_CONST; /* perhaps */
+ }
+ if(off < 0)
+ off = -off;
+ if(a.sym && (a.name==D_PARAM || a.name==D_AUTO))
+ _offset(a.sym, off);
+ break;
+ case D_SCONST:
+ skip(bp, NSNAME);
+ break;
+ case D_FCONST:
+ skip(bp, 8);
+ break;
+ }
+ return a;
+}
+
+static char
+type2char(int t)
+{
+ switch(t){
+ case D_EXTERN: return 'U';
+ case D_STATIC: return 'b';
+ case D_AUTO: return 'a';
+ case D_PARAM: return 'p';
+ default: return UNKNOWN;
+ }
+}
+
+static void
+skip(Biobuf *bp, int n)
+{
+ while (n-- > 0)
+ Bgetc(bp);
+}
diff --git a/utils/libmach/a.out.h b/utils/libmach/a.out.h
index 8c0b7137..59077860 100644
--- a/utils/libmach/a.out.h
+++ b/utils/libmach/a.out.h
@@ -11,7 +11,6 @@ struct Exec
long pcsz; /* size of pc/line number table */
};
-
#define HDR_MAGIC 0x00008000 /* header expansion */
#define _MAGIC(f, b) ((f)|((((4*(b))+0)*(b))+7))
@@ -30,16 +29,18 @@ struct Exec
#define P_MAGIC _MAGIC(0, 24) /* mips 3000 LE */
#define U_MAGIC _MAGIC(0, 25) /* sparc64 */
#define S_MAGIC _MAGIC(HDR_MAGIC, 26) /* amd64 */
+#define T_MAGIC _MAGIC(HDR_MAGIC, 27) /* powerpc64 */
#define MIN_MAGIC 8
-#define MAX_MAGIC 26 /* <= 90 */
+#define MAX_MAGIC 27 /* <= 90 */
-#define DYN_MAGIC 0x80000000 /* or'd in for dynamically loaded modules */
+#define DYN_MAGIC 0x80000000 /* dlm */
typedef struct Sym Sym;
struct Sym
{
- long value;
+ vlong value;
+ uint sig;
char type;
char *name;
};
diff --git a/utils/libmach/access.c b/utils/libmach/access.c
index 6a58cdea..e054839e 100644
--- a/utils/libmach/access.c
+++ b/utils/libmach/access.c
@@ -6,16 +6,35 @@
#include <bio.h>
#include "mach.h"
-static int mget(Map*, ulong, char*, int);
-static int mput(Map*, ulong, char*, int);
-struct segment* reloc(Map*, ulong, long*);
+static int mget(Map*, uvlong, void*, int);
+static int mput(Map*, uvlong, void*, int);
+static struct segment* reloc(Map*, uvlong, vlong*);
/*
* routines to get/put various types
*/
+int
+geta(Map *map, uvlong addr, uvlong *x)
+{
+ ulong l;
+ uvlong vl;
+
+ if (mach->szaddr == 8){
+ if (get8(map, addr, &vl) < 0)
+ return -1;
+ *x = vl;
+ return 1;
+ }
+
+ if (get4(map, addr, &l) < 0)
+ return -1;
+ *x = l;
+
+ return 1;
+}
int
-get8(Map *map, ulong addr, vlong *x)
+get8(Map *map, uvlong addr, uvlong *x)
{
if (!map) {
werrstr("get8: invalid map");
@@ -23,17 +42,17 @@ get8(Map *map, ulong addr, vlong *x)
}
if (map->nsegs == 1 && map->seg[0].fd < 0) {
- *x = (vlong)addr;
+ *x = addr;
return 1;
}
- if (mget(map, addr, (char *)x, 8) < 0)
+ if (mget(map, addr, x, 8) < 0)
return -1;
*x = machdata->swav(*x);
- return (1);
+ return 1;
}
int
-get4(Map *map, ulong addr, long *x)
+get4(Map *map, uvlong addr, ulong *x)
{
if (!map) {
werrstr("get4: invalid map");
@@ -44,14 +63,14 @@ get4(Map *map, ulong addr, long *x)
*x = addr;
return 1;
}
- if (mget(map, addr, (char *)x, 4) < 0)
+ if (mget(map, addr, x, 4) < 0)
return -1;
*x = machdata->swal(*x);
- return (1);
+ return 1;
}
int
-get2(Map *map, ulong addr, ushort *x)
+get2(Map *map, uvlong addr, ushort *x)
{
if (!map) {
werrstr("get2: invalid map");
@@ -62,14 +81,14 @@ get2(Map *map, ulong addr, ushort *x)
*x = addr;
return 1;
}
- if (mget(map, addr, (char *)x, 2) < 0)
+ if (mget(map, addr, x, 2) < 0)
return -1;
*x = machdata->swab(*x);
- return (1);
+ return 1;
}
int
-get1(Map *map, ulong addr, uchar *x, int size)
+get1(Map *map, uvlong addr, uchar *x, int size)
{
uchar *cp;
@@ -85,61 +104,103 @@ get1(Map *map, ulong addr, uchar *x, int size)
while (size-- > 0)
*x++ = 0;
} else
- return mget(map, addr, (char*)x, size);
+ return mget(map, addr, x, size);
return 1;
}
int
-put8(Map *map, ulong addr, vlong v)
+puta(Map *map, uvlong addr, uvlong v)
+{
+ if (mach->szaddr == 8)
+ return put8(map, addr, v);
+
+ return put4(map, addr, v);
+}
+
+int
+put8(Map *map, uvlong addr, uvlong v)
{
if (!map) {
werrstr("put8: invalid map");
return -1;
}
v = machdata->swav(v);
- return mput(map, addr, (char *)&v, 8);
+ return mput(map, addr, &v, 8);
}
int
-put4(Map *map, ulong addr, long v)
+put4(Map *map, uvlong addr, ulong v)
{
if (!map) {
werrstr("put4: invalid map");
return -1;
}
v = machdata->swal(v);
- return mput(map, addr, (char *)&v, 4);
+ return mput(map, addr, &v, 4);
}
int
-put2(Map *map, ulong addr, ushort v)
+put2(Map *map, uvlong addr, ushort v)
{
if (!map) {
werrstr("put2: invalid map");
return -1;
}
v = machdata->swab(v);
- return mput(map, addr, (char *)&v, 2);
+ return mput(map, addr, &v, 2);
}
int
-put1(Map *map, ulong addr, uchar *v, int size)
+put1(Map *map, uvlong addr, uchar *v, int size)
{
if (!map) {
werrstr("put1: invalid map");
return -1;
}
- return mput(map, addr, (char *)v, size);
+ return mput(map, addr, v, size);
+}
+
+static int
+spread(struct segment *s, void *buf, int n, uvlong off)
+{
+ uvlong base;
+
+ static struct {
+ struct segment *s;
+ char a[8192];
+ uvlong off;
+ } cache;
+
+ if(s->cache){
+ base = off&~(sizeof cache.a-1);
+ if(cache.s != s || cache.off != base){
+ cache.off = ~0;
+ if(seek(s->fd, base, 0) >= 0
+ && readn(s->fd, cache.a, sizeof cache.a) == sizeof cache.a){
+ cache.s = s;
+ cache.off = base;
+ }
+ }
+ if(cache.s == s && cache.off == base){
+ off &= sizeof cache.a-1;
+ if(off+n > sizeof cache.a)
+ n = sizeof cache.a - off;
+ memmove(buf, cache.a+off, n);
+ return n;
+ }
+ }
+
+ return pread(s->fd, buf, n, off);
}
static int
-mget(Map *map, ulong addr, char *buf, int size)
+mget(Map *map, uvlong addr, void *buf, int size)
{
- long off;
+ uvlong off;
int i, j, k;
struct segment *s;
- s = reloc(map, addr, &off);
+ s = reloc(map, addr, (vlong*)&off);
if (!s)
return -1;
if (s->fd < 0) {
@@ -148,25 +209,24 @@ mget(Map *map, ulong addr, char *buf, int size)
}
if (s->mget)
return s->mget(s, addr, off, buf, size);
- seek(s->fd, off, 0);
for (i = j = 0; i < 2; i++) { /* in case read crosses page */
- k = read(s->fd, buf, size-j);
+ k = spread(s, (void*)((uchar *)buf+j), size-j, off+j);
if (k < 0) {
- werrstr("can't read address %lux: %r", addr);
+ werrstr("can't read address %llux: %r", addr);
return -1;
}
j += k;
if (j == size)
return j;
}
- werrstr("partial read at address %lux", addr);
+ werrstr("partial read at address %llux (size %d j %d)", addr, size, j);
return -1;
}
static int
-mput(Map *map, ulong addr, char *buf, int size)
+mput(Map *map, uvlong addr, void *buf, int size)
{
- long off;
+ vlong off;
int i, j, k;
struct segment *s;
@@ -184,22 +244,22 @@ mput(Map *map, ulong addr, char *buf, int size)
for (i = j = 0; i < 2; i++) { /* in case read crosses page */
k = write(s->fd, buf, size-j);
if (k < 0) {
- werrstr("can't write address %lux: %r", addr);
+ werrstr("can't write address %llux: %r", addr);
return -1;
}
j += k;
if (j == size)
return j;
}
- werrstr("partial write at address %lux", addr);
+ werrstr("partial write at address %llux", addr);
return -1;
}
/*
* convert address to file offset; returns nonzero if ok
*/
-struct segment*
-reloc(Map *map, ulong addr, long *offp)
+static struct segment*
+reloc(Map *map, uvlong addr, vlong *offp)
{
int i;
@@ -210,6 +270,6 @@ reloc(Map *map, ulong addr, long *offp)
return &map->seg[i];
}
}
- werrstr("can't translate address %lux", addr);
+ werrstr("can't translate address %llux", addr);
return 0;
}
diff --git a/utils/libmach/ar.h b/utils/libmach/ar.h
index 71ffff12..cd538fab 100644
--- a/utils/libmach/ar.h
+++ b/utils/libmach/ar.h
@@ -14,5 +14,4 @@ struct ar_hdr
char size[10];
char fmag[2];
};
-#define SAR_HDR 60
-
+#define SAR_HDR (SARNAME+44)
diff --git a/utils/libmach/bootexec.h b/utils/libmach/bootexec.h
index a844ec7c..b401d394 100644
--- a/utils/libmach/bootexec.h
+++ b/utils/libmach/bootexec.h
@@ -33,12 +33,10 @@ struct mipsexec
long data_start; /* base of data used for this file */
long bss_start; /* base of bss used for this file */
long gprmask; /* general purpose register mask */
-union{
- long mcprmask[4]; /* co-processor register masks */
- long mpcsize;
-} u0;
+ long cprmask[4]; /* co-processor register masks */
long gp_value; /* the gp value used for this object */
};
+#define pcsize cprmask[0]
struct mips4kexec
{
@@ -136,37 +134,3 @@ struct i386exec
struct coffsect icomments;
};
-struct i960exec
-{
- struct i960coff{
- ulong i6sectmagic;
- ulong i6time;
- ulong i6syms;
- ulong i6nsyms;
- ulong i6opthdrflags;
- }i6coff;
- struct i960hdr{
- ulong i6magic;
- ulong i6textsize;
- ulong i6datasize;
- ulong i6bsssize;
- ulong i6entry;
- ulong i6textstart;
- ulong i6datastart;
- ulong i6tagentries;
- }i6hdr;
- struct i960sect{
- char name[8];
- ulong phys;
- ulong virt;
- ulong size;
- ulong fptr;
- ulong fptrreloc;
- ulong fptrlineno;
- ulong nrelocnlineno;
- ulong flags;
- ulong align;
- }i6texts;
- struct i960sect i6datas;
-};
-
diff --git a/utils/libmach/elf.h b/utils/libmach/elf.h
index b182135b..5d755b7a 100644
--- a/utils/libmach/elf.h
+++ b/utils/libmach/elf.h
@@ -2,20 +2,20 @@
* Definitions needed for accessing Irix ELF headers
*/
typedef struct {
- unsigned char ident[16]; /* ident bytes */
- ushort type; /* file type */
- ushort machine; /* target machine */
- int version; /* file version */
- ulong elfentry; /* start address */
- ulong phoff; /* phdr file offset */
- ulong shoff; /* shdr file offset */
- int flags; /* file flags */
- ushort ehsize; /* sizeof ehdr */
- ushort phentsize; /* sizeof phdr */
- ushort phnum; /* number phdrs */
- ushort shentsize; /* sizeof shdr */
- ushort shnum; /* number shdrs */
- ushort shstrndx; /* shdr string index */
+ uchar ident[16]; /* ident bytes */
+ ushort type; /* file type */
+ ushort machine; /* target machine */
+ int version; /* file version */
+ ulong elfentry; /* start address */
+ ulong phoff; /* phdr file offset */
+ ulong shoff; /* shdr file offset */
+ int flags; /* file flags */
+ ushort ehsize; /* sizeof ehdr */
+ ushort phentsize; /* sizeof phdr */
+ ushort phnum; /* number phdrs */
+ ushort shentsize; /* sizeof shdr */
+ ushort shnum; /* number shdrs */
+ ushort shstrndx; /* shdr string index */
} Ehdr;
typedef struct {
@@ -78,7 +78,9 @@ enum {
I860 = 7, /* Intel i860 */
MIPS = 8, /* Mips R2000 */
S370 = 9, /* Amdhal */
+ SPARC64 = 18, /* Sun SPARC v9 */
POWER = 20, /* PowerPC */
+ ARM = 40, /* ARM */
AMD64 = 62, /* Amd64 */
NO_VERSION = 0, /* version, ident[VERSION] */
@@ -96,6 +98,15 @@ enum {
R = 0x4, /* flags */
W = 0x2,
X = 0x1,
+
+ /* Shdr Codes */
+ Progbits = 1, /* section types */
+ Strtab = 3,
+ Nobits = 8,
+
+ Swrite = 1, /* section attributes */
+ Salloc = 2,
+ Sexec = 4,
};
#define ELF_MAG ((0x7f<<24) | ('E'<<16) | ('L'<<8) | 'F')
diff --git a/utils/libmach/executable.c b/utils/libmach/executable.c
index a17d6ae2..12099593 100644
--- a/utils/libmach/executable.c
+++ b/utils/libmach/executable.c
@@ -1,6 +1,6 @@
#include <lib9.h>
#include <bio.h>
-#include "bootexec.h"
+#include <bootexec.h>
#include "mach.h"
#include "elf.h"
@@ -11,14 +11,18 @@
typedef struct {
union{
- Exec exec; /* in a.out.h */
- Ehdr ehdr; /* in elf.h */
- struct mipsexec mipsexec;
- struct mips4kexec mips4kexec;
- struct sparcexec sparcexec;
- struct nextexec nextexec;
+ Exec exec;
+ struct {
+ u32int ohdr[8]; /* Exec */
+ uvlong hdr[1];
+ } exechdr64;
+ Ehdr elfhdr32; /* elf.h */
+ struct mipsexec mips; /* bootexec.h */
+ struct mips4kexec mips4k; /* bootexec.h */
+ struct sparcexec sparc; /* bootexec.h */
+ struct nextexec next; /* bootexec.h */
} e;
- long dummy; /* padding to ensure extra long */
+ u32int dummy; /* padding to ensure extra u32int */
} ExecHdr;
static int nextboot(int, Fhdr*, ExecHdr*);
@@ -26,14 +30,15 @@ static int sparcboot(int, Fhdr*, ExecHdr*);
static int mipsboot(int, Fhdr*, ExecHdr*);
static int mips4kboot(int, Fhdr*, ExecHdr*);
static int common(int, Fhdr*, ExecHdr*);
+static int commonllp64(int, Fhdr*, ExecHdr*);
static int adotout(int, Fhdr*, ExecHdr*);
static int elfdotout(int, Fhdr*, ExecHdr*);
static int armdotout(int, Fhdr*, ExecHdr*);
-static void setsym(Fhdr*, long, long, long, long);
-static void setdata(Fhdr*, long, long, long, long);
-static void settext(Fhdr*, long, long, long, long);
-static void hswal(long*, int, long(*)(long));
-static long _round(long, long);
+static void setsym(Fhdr*, long, long, long, vlong);
+static void setdata(Fhdr*, uvlong, long, vlong, long);
+static void settext(Fhdr*, uvlong, uvlong, long, vlong);
+static void hswal(void*, int, ulong(*)(ulong));
+static uvlong _round(uvlong, ulong);
/*
* definition of per-executable file type structures
@@ -42,10 +47,12 @@ static long _round(long, long);
typedef struct Exectable{
long magic; /* big-endian magic number of file */
char *name; /* executable identifier */
- int type; /* Internal code */
+ char *dlmname; /* dynamically loadable module identifier */
+ uchar type; /* Internal code */
+ uchar _magic; /* _MAGIC() magic */
Mach *mach; /* Per-machine data */
- ulong hsize; /* header size */
- long (*swal)(long); /* beswal or leswal */
+ long hsize; /* header size */
+ ulong (*swal)(ulong); /* beswal or leswal */
int (*hparse)(int, Fhdr*, ExecHdr*);
} ExecTable;
@@ -55,115 +62,172 @@ extern Mach mmips2be;
extern Mach msparc;
extern Mach m68020;
extern Mach mi386;
+extern Mach mamd64;
extern Mach marm;
extern Mach mpower;
+extern Mach mpower64;
ExecTable exectab[] =
{
{ V_MAGIC, /* Mips v.out */
- "mips plan 9 executable",
+ "mips plan 9 executable BE",
+ "mips plan 9 dlm BE",
FMIPS,
+ 1,
+ &mmips,
+ sizeof(Exec),
+ beswal,
+ adotout },
+ { P_MAGIC, /* Mips 0.out (r3k le) */
+ "mips plan 9 executable LE",
+ "mips plan 9 dlm LE",
+ FMIPSLE,
+ 1,
&mmips,
sizeof(Exec),
beswal,
adotout },
{ M_MAGIC, /* Mips 4.out */
"mips 4k plan 9 executable BE",
+ "mips 4k plan 9 dlm BE",
FMIPS2BE,
+ 1,
&mmips2be,
sizeof(Exec),
beswal,
adotout },
{ N_MAGIC, /* Mips 0.out */
"mips 4k plan 9 executable LE",
+ "mips 4k plan 9 dlm LE",
FMIPS2LE,
+ 1,
&mmips2le,
sizeof(Exec),
beswal,
adotout },
{ 0x160<<16, /* Mips boot image */
"mips plan 9 boot image",
+ nil,
FMIPSB,
+ 0,
&mmips,
sizeof(struct mipsexec),
beswal,
mipsboot },
{ (0x160<<16)|3, /* Mips boot image */
"mips 4k plan 9 boot image",
+ nil,
FMIPSB,
- &mmips,
+ 0,
+ &mmips2be,
sizeof(struct mips4kexec),
beswal,
mips4kboot },
{ K_MAGIC, /* Sparc k.out */
"sparc plan 9 executable",
+ "sparc plan 9 dlm",
FSPARC,
+ 1,
&msparc,
sizeof(Exec),
beswal,
adotout },
{ 0x01030107, /* Sparc boot image */
"sparc plan 9 boot image",
+ nil,
FSPARCB,
+ 0,
&msparc,
sizeof(struct sparcexec),
beswal,
sparcboot },
{ A_MAGIC, /* 68020 2.out & boot image */
"68020 plan 9 executable",
+ "68020 plan 9 dlm",
F68020,
+ 1,
&m68020,
sizeof(Exec),
beswal,
common },
{ 0xFEEDFACE, /* Next boot image */
"next plan 9 boot image",
+ nil,
FNEXTB,
+ 0,
&m68020,
sizeof(struct nextexec),
beswal,
nextboot },
{ I_MAGIC, /* I386 8.out & boot image */
"386 plan 9 executable",
+ "386 plan 9 dlm",
FI386,
+ 1,
&mi386,
sizeof(Exec),
beswal,
common },
- { ELF_MAG,
- "Irix 5.X Elf executable",
- FMIPS,
- &mmips,
- sizeof(Ehdr),
+ { S_MAGIC, /* amd64 6.out & boot image */
+ "amd64 plan 9 executable",
+ "amd64 plan 9 dlm",
+ FAMD64,
+ 1,
+ &mamd64,
+ sizeof(Exec)+8,
+ nil,
+ commonllp64 },
+ { Q_MAGIC, /* PowerPC q.out & boot image */
+ "power plan 9 executable",
+ "power plan 9 dlm",
+ FPOWER,
+ 1,
+ &mpower,
+ sizeof(Exec),
beswal,
+ common },
+ { T_MAGIC, /* power64 9.out & boot image */
+ "power64 plan 9 executable",
+ "power64 plan 9 dlm",
+ FPOWER64,
+ 1,
+ &mpower64,
+ sizeof(Exec)+8,
+ nil,
+ commonllp64 },
+ { ELF_MAG, /* any elf32 */
+ "elf executable",
+ nil,
+ FNONE,
+ 0,
+ &mi386,
+ sizeof(Ehdr),
+ nil,
elfdotout },
- { E_MAGIC, /* Arm 5.out */
- "Arm plan 9 executable",
+ { E_MAGIC, /* Arm 5.out and boot image */
+ "arm plan 9 executable",
+ "arm plan 9 dlm",
FARM,
+ 1,
&marm,
sizeof(Exec),
beswal,
common },
{ (143<<16)|0413, /* (Free|Net)BSD Arm */
- "Arm *BSD executable",
+ "arm *bsd executable",
+ nil,
FARM,
+ 0,
&marm,
sizeof(Exec),
leswal,
armdotout },
- { Q_MAGIC, /* PowerPC q.out */
- "power plan 9 executable",
- FPOWER,
- &mpower,
- sizeof(Exec),
- beswal,
- common },
{ 0 },
};
-Mach *mach = &mmips; /* Global current machine table */
+Mach *mach = &mi386; /* Global current machine table */
-ExecTable*
+static ExecTable*
couldbe4k(ExecTable *mp)
{
Dir *d;
@@ -184,13 +248,13 @@ couldbe4k(ExecTable *mp)
return mp;
}
-
int
crackhdr(int fd, Fhdr *fp)
{
ExecTable *mp;
ExecHdr d;
- int nb, magic, ret;
+ int nb, ret;
+ ulong magic;
fp->type = FNONE;
nb = read(fd, (char *)&d.e, sizeof(d.e));
@@ -198,37 +262,67 @@ crackhdr(int fd, Fhdr *fp)
return 0;
ret = 0;
- fp->magic = magic = beswal(d.e.exec.magic); /* big-endian */
+ magic = beswal(d.e.exec.magic); /* big-endian */
for (mp = exectab; mp->magic; mp++) {
- if (mp->magic == magic && nb >= mp->hsize) {
+ if (nb < mp->hsize)
+ continue;
+
+ /*
+ * The.exec.magic number has morphed into something
+ * with fields (the straw was DYN_MAGIC) so now
+ * a flag is needed in Fhdr to distinguish _MAGIC()
+ * magic numbers from foreign magic numbers.
+ *
+ * This code is creaking a bit and if it has to
+ * be modified/extended much more it's probably
+ * time to step back and redo it all.
+ */
+ if(mp->_magic){
+ if(mp->magic != (magic & ~DYN_MAGIC))
+ continue;
+
if(mp->magic == V_MAGIC)
mp = couldbe4k(mp);
- hswal((long *) &d, sizeof(d.e)/sizeof(long), mp->swal);
- fp->type = mp->type;
+ if ((magic & DYN_MAGIC) && mp->dlmname != nil)
+ fp->name = mp->dlmname;
+ else
+ fp->name = mp->name;
+ }
+ else{
+ if(mp->magic != magic)
+ continue;
fp->name = mp->name;
- fp->hdrsz = mp->hsize; /* zero on bootables */
- mach = mp->mach;
- ret = mp->hparse(fd, fp, &d);
- seek(fd, mp->hsize, 0); /* seek to end of header */
- break;
}
+ fp->type = mp->type;
+ fp->hdrsz = mp->hsize; /* will be zero on bootables */
+ fp->_magic = mp->_magic;
+ fp->magic = magic;
+
+ mach = mp->mach;
+ if(mp->swal != nil)
+ hswal(&d, sizeof(d.e)/sizeof(ulong), mp->swal);
+ ret = mp->hparse(fd, fp, &d);
+ seek(fd, mp->hsize, 0); /* seek to end of header */
+ break;
}
if(mp->magic == 0)
werrstr("unknown header type");
return ret;
}
+
/*
* Convert header to canonical form
*/
static void
-hswal(long *lp, int n, long (*swap) (long))
+hswal(void *v, int n, ulong (*swap)(ulong))
{
- while (n--) {
- *lp = (*swap) (*lp);
- lp++;
- }
+ ulong *ulp;
+
+ for(ulp = v; n--; ulp++)
+ *ulp = (*swap)(*ulp);
}
+
/*
* Crack a normal a.out-type header
*/
@@ -247,57 +341,103 @@ adotout(int fd, Fhdr *fp, ExecHdr *hp)
return 1;
}
+static void
+commonboot(Fhdr *fp)
+{
+ if (!(fp->entry & mach->ktmask))
+ return;
+
+ switch(fp->type) { /* boot image */
+ case F68020:
+ fp->type = F68020B;
+ fp->name = "68020 plan 9 boot image";
+ break;
+ case FI386:
+ fp->type = FI386B;
+ fp->txtaddr = (u32int)fp->entry;
+ fp->name = "386 plan 9 boot image";
+ fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
+ break;
+ case FARM:
+ fp->type = FARMB;
+ fp->txtaddr = (u32int)fp->entry;
+ fp->name = "ARM plan 9 boot image";
+ fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
+ return;
+ case FALPHA:
+ fp->type = FALPHAB;
+ fp->txtaddr = (u32int)fp->entry;
+ fp->name = "alpha plan 9 boot image";
+ fp->dataddr = fp->txtaddr+fp->txtsz;
+ break;
+ case FPOWER:
+ fp->type = FPOWERB;
+ fp->txtaddr = (u32int)fp->entry;
+ fp->name = "power plan 9 boot image";
+ fp->dataddr = fp->txtaddr+fp->txtsz;
+ break;
+ case FAMD64:
+ fp->type = FAMD64B;
+ fp->txtaddr = fp->entry;
+ fp->name = "amd64 plan 9 boot image";
+ fp->dataddr = _round(fp->txtaddr+fp->txtsz, mach->pgsize);
+ break;
+ default:
+ return;
+ }
+ fp->hdrsz = 0; /* header stripped */
+}
+
/*
- * 68020 2.out and 68020 bootable images
- * 386I 8.out and 386I bootable images
+ * _MAGIC() style headers and
+ * alpha plan9-style bootable images for axp "headerless" boot
*
*/
static int
common(int fd, Fhdr *fp, ExecHdr *hp)
{
- long kbase;
-
adotout(fd, fp, hp);
- kbase = mach->kbase;
- if ((fp->entry & kbase) == kbase) { /* Boot image */
- switch(fp->type) {
- case F68020:
- fp->type = F68020B;
- fp->name = "68020 plan 9 boot image";
- fp->hdrsz = 0; /* header stripped */
- break;
- case FI386:
- fp->type = FI386B;
- fp->txtaddr = sizeof(Exec);
- fp->name = "386 plan 9 boot image";
- fp->hdrsz = 0; /* header stripped */
- fp->dataddr = fp->txtaddr+fp->txtsz;
- break;
- case FARM:
- fp->txtaddr = kbase+0x8000+sizeof(Exec);
- fp->name = "ARM plan 9 boot image";
- fp->hdrsz = 0; /* header stripped */
- fp->dataddr = fp->txtaddr+fp->txtsz;
- return 1;
- default:
- break;
- }
- fp->txtaddr |= kbase;
- fp->entry |= kbase;
- fp->dataddr |= kbase;
- }
- else if (fp->type == FARM && (fp->entry == 0x8020 || fp->entry == 0x8080)) {
- fp->txtaddr = fp->entry;
- fp->name = "ARM Inferno boot image";
- fp->hdrsz = 0; /* header stripped */
- fp->dataddr = fp->txtaddr+fp->txtsz;
+ if(hp->e.exec.magic & DYN_MAGIC) {
+ fp->txtaddr = 0;
+ fp->dataddr = fp->txtsz;
+ return 1;
}
- else if (fp->type == FPOWER && fp->entry == 0x3020) {
- fp->txtaddr = fp->entry;
- fp->name = "Power Inferno boot image";
- fp->hdrsz = 0; /* header stripped */
- fp->dataddr = fp->txtaddr+fp->txtsz;
+ commonboot(fp);
+ return 1;
+}
+
+static int
+commonllp64(int, Fhdr *fp, ExecHdr *hp)
+{
+ long pgsize;
+ uvlong entry;
+
+ hswal(&hp->e, sizeof(Exec)/sizeof(long), beswal);
+ if(!(hp->e.exec.magic & HDR_MAGIC))
+ return 0;
+
+ /*
+ * There can be more.exec.magic here if the
+ * header ever needs more expansion.
+ * For now just catch use of any of the
+ * unused bits.
+ */
+ if((hp->e.exec.magic & ~DYN_MAGIC)>>16)
+ return 0;
+ entry = beswav(hp->e.exechdr64.hdr[0]);
+
+ pgsize = mach->pgsize;
+ settext(fp, entry, pgsize+fp->hdrsz, hp->e.exec.text, fp->hdrsz);
+ setdata(fp, _round(pgsize+fp->txtsz+fp->hdrsz, pgsize),
+ hp->e.exec.data, fp->txtsz+fp->hdrsz, hp->e.exec.bss);
+ setsym(fp, hp->e.exec.syms, hp->e.exec.spsz, hp->e.exec.pcsz, fp->datoff+fp->datsz);
+
+ if(hp->e.exec.magic & DYN_MAGIC) {
+ fp->txtaddr = 0;
+ fp->dataddr = fp->txtsz;
+ return 1;
}
+ commonboot(fp);
return 1;
}
@@ -308,24 +448,24 @@ static int
mipsboot(int fd, Fhdr *fp, ExecHdr *hp)
{
USED(fd);
- switch(hp->e.mipsexec.amagic) {
+ fp->type = FMIPSB;
+ switch(hp->e.mips.amagic) {
default:
case 0407: /* some kind of mips */
- fp->type = FMIPSB;
- settext(fp, hp->e.mipsexec.mentry, hp->e.mipsexec.text_start, hp->e.mipsexec.tsize,
- sizeof(struct mipsexec)+4);
- setdata(fp, hp->e.mipsexec.data_start, hp->e.mipsexec.dsize,
- fp->txtoff+hp->e.mipsexec.tsize, hp->e.mipsexec.bsize);
+ settext(fp, (u32int)hp->e.mips.mentry, (u32int)hp->e.mips.text_start,
+ hp->e.mips.tsize, sizeof(struct mipsexec)+4);
+ setdata(fp, (u32int)hp->e.mips.data_start, hp->e.mips.dsize,
+ fp->txtoff+hp->e.mips.tsize, hp->e.mips.bsize);
break;
case 0413: /* some kind of mips */
- fp->type = FMIPSB;
- settext(fp, hp->e.mipsexec.mentry, hp->e.mipsexec.text_start, hp->e.mipsexec.tsize, 0);
- setdata(fp, hp->e.mipsexec.data_start, hp->e.mipsexec.dsize, hp->e.mipsexec.tsize,
- hp->e.mipsexec.bsize);
+ settext(fp, (u32int)hp->e.mips.mentry, (u32int)hp->e.mips.text_start,
+ hp->e.mips.tsize, 0);
+ setdata(fp, (u32int)hp->e.mips.data_start, hp->e.mips.dsize,
+ hp->e.mips.tsize, hp->e.mips.bsize);
break;
}
- setsym(fp, hp->e.mipsexec.nsyms, 0, hp->e.mipsexec.u0.mpcsize, hp->e.mipsexec.symptr);
- fp->hdrsz = 0; /* header stripped */
+ setsym(fp, hp->e.mips.nsyms, 0, hp->e.mips.pcsize, hp->e.mips.symptr);
+ fp->hdrsz = 0; /* header stripped */
return 1;
}
@@ -336,24 +476,24 @@ static int
mips4kboot(int fd, Fhdr *fp, ExecHdr *hp)
{
USED(fd);
- switch(hp->e.mipsexec.amagic) {
+ fp->type = FMIPSB;
+ switch(hp->e.mips4k.h.amagic) {
default:
case 0407: /* some kind of mips */
- fp->type = FMIPSB;
- settext(fp, hp->e.mipsexec.mentry, hp->e.mipsexec.text_start, hp->e.mipsexec.tsize,
- sizeof(struct mips4kexec));
- setdata(fp, hp->e.mipsexec.data_start, hp->e.mipsexec.dsize,
- fp->txtoff+hp->e.mipsexec.tsize, hp->e.mipsexec.bsize);
+ settext(fp, (u32int)hp->e.mips4k.h.mentry, (u32int)hp->e.mips4k.h.text_start,
+ hp->e.mips4k.h.tsize, sizeof(struct mips4kexec));
+ setdata(fp, (u32int)hp->e.mips4k.h.data_start, hp->e.mips4k.h.dsize,
+ fp->txtoff+hp->e.mips4k.h.tsize, hp->e.mips4k.h.bsize);
break;
case 0413: /* some kind of mips */
- fp->type = FMIPSB;
- settext(fp, hp->e.mipsexec.mentry, hp->e.mipsexec.text_start, hp->e.mipsexec.tsize, 0);
- setdata(fp, hp->e.mipsexec.data_start, hp->e.mipsexec.dsize, hp->e.mipsexec.tsize,
- hp->e.mipsexec.bsize);
+ settext(fp, (u32int)hp->e.mips4k.h.mentry, (u32int)hp->e.mips4k.h.text_start,
+ hp->e.mips4k.h.tsize, 0);
+ setdata(fp, (u32int)hp->e.mips4k.h.data_start, hp->e.mips4k.h.dsize,
+ hp->e.mips4k.h.tsize, hp->e.mips4k.h.bsize);
break;
}
- setsym(fp, hp->e.mipsexec.nsyms, 0, hp->e.mipsexec.u0.mpcsize, hp->e.mipsexec.symptr);
- fp->hdrsz = 0; /* header stripped */
+ setsym(fp, hp->e.mips4k.h.nsyms, 0, hp->e.mips4k.h.pcsize, hp->e.mips4k.h.symptr);
+ fp->hdrsz = 0; /* header stripped */
return 1;
}
@@ -365,12 +505,12 @@ sparcboot(int fd, Fhdr *fp, ExecHdr *hp)
{
USED(fd);
fp->type = FSPARCB;
- settext(fp, hp->e.sparcexec.sentry, hp->e.sparcexec.sentry, hp->e.sparcexec.stext,
- sizeof(struct sparcexec));
- setdata(fp, hp->e.sparcexec.sentry+hp->e.sparcexec.stext, hp->e.sparcexec.sdata,
- fp->txtoff+hp->e.sparcexec.stext, hp->e.sparcexec.sbss);
- setsym(fp, hp->e.sparcexec.ssyms, 0, hp->e.sparcexec.sdrsize, fp->datoff+hp->e.sparcexec.sdata);
- fp->hdrsz = 0; /* header stripped */
+ settext(fp, hp->e.sparc.sentry, hp->e.sparc.sentry, hp->e.sparc.stext,
+ sizeof(struct sparcexec));
+ setdata(fp, hp->e.sparc.sentry+hp->e.sparc.stext, hp->e.sparc.sdata,
+ fp->txtoff+hp->e.sparc.stext, hp->e.sparc.sbss);
+ setsym(fp, hp->e.sparc.ssyms, 0, hp->e.sparc.sdrsize, fp->datoff+hp->e.sparc.sdata);
+ fp->hdrsz = 0; /* header stripped */
return 1;
}
@@ -382,129 +522,150 @@ nextboot(int fd, Fhdr *fp, ExecHdr *hp)
{
USED(fd);
fp->type = FNEXTB;
- settext(fp, hp->e.nextexec.textc.vmaddr, hp->e.nextexec.textc.vmaddr,
- hp->e.nextexec.texts.size, hp->e.nextexec.texts.offset);
- setdata(fp, hp->e.nextexec.datac.vmaddr, hp->e.nextexec.datas.size,
- hp->e.nextexec.datas.offset, hp->e.nextexec.bsss.size);
- setsym(fp, hp->e.nextexec.symc.nsyms, hp->e.nextexec.symc.spoff, hp->e.nextexec.symc.pcoff,
- hp->e.nextexec.symc.symoff);
- fp->hdrsz = 0; /* header stripped */
+ settext(fp, hp->e.next.textc.vmaddr, hp->e.next.textc.vmaddr,
+ hp->e.next.texts.size, hp->e.next.texts.offset);
+ setdata(fp, hp->e.next.datac.vmaddr, hp->e.next.datas.size,
+ hp->e.next.datas.offset, hp->e.next.bsss.size);
+ setsym(fp, hp->e.next.symc.nsyms, hp->e.next.symc.spoff, hp->e.next.symc.pcoff,
+ hp->e.next.symc.symoff);
+ fp->hdrsz = 0; /* header stripped */
return 1;
}
-static Shdr*
-elfsectbyname(int fd, Ehdr *hp, Shdr *sp, char *name)
-{
- int i, offset, n;
- char s[64];
-
- offset = sp[hp->shstrndx].offset;
- for(i = 1; i < hp->shnum; i++) {
- seek(fd, offset+sp[i].name, 0);
- n = read(fd, s, sizeof(s)-1);
- if(n < 0)
- continue;
- s[n] = 0;
- if(strcmp(s, name) == 0)
- return &sp[i];
- }
- return 0;
-}
/*
- * Decode an Irix 5.x ELF header
+ * Elf32 binaries.
*/
static int
elfdotout(int fd, Fhdr *fp, ExecHdr *hp)
{
+ ulong (*swal)(ulong);
+ ushort (*swab)(ushort);
Ehdr *ep;
- Shdr *es, *txt, *init, *s;
- long addr, size, offset, bsize;
-
- ep = &hp->e.ehdr;
- fp->magic = ELF_MAG;
- fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
+ Phdr *ph;
+ int i, it, id, is, phsz;
- if(ep->shnum <= 0) {
- werrstr("no ELF header sections");
+ /* bitswap the header according to the DATA format */
+ ep = &hp->e.elfhdr32;
+ if(ep->ident[CLASS] != ELFCLASS32) {
+ werrstr("bad ELF class - not 32 bit");
return 0;
}
- es = malloc(sizeof(Shdr)*ep->shnum);
- if(es == 0)
+ if(ep->ident[DATA] == ELFDATA2LSB) {
+ swab = leswab;
+ swal = leswal;
+ } else if(ep->ident[DATA] == ELFDATA2MSB) {
+ swab = beswab;
+ swal = beswal;
+ } else {
+ werrstr("bad ELF encoding - not big or little endian");
return 0;
+ }
- seek(fd, ep->shoff, 0);
- if(read(fd, es, sizeof(Shdr)*ep->shnum) < 0){
- free(es);
+ ep->type = swab(ep->type);
+ ep->machine = swab(ep->machine);
+ ep->version = swal(ep->version);
+ ep->elfentry = swal(ep->elfentry);
+ ep->phoff = swal(ep->phoff);
+ ep->shoff = swal(ep->shoff);
+ ep->flags = swal(ep->flags);
+ ep->ehsize = swab(ep->ehsize);
+ ep->phentsize = swab(ep->phentsize);
+ ep->phnum = swab(ep->phnum);
+ ep->shentsize = swab(ep->shentsize);
+ ep->shnum = swab(ep->shnum);
+ ep->shstrndx = swab(ep->shstrndx);
+ if(ep->type != EXEC || ep->version != CURRENT)
return 0;
- }
- txt = elfsectbyname(fd, ep, es, ".text");
- init = elfsectbyname(fd, ep, es, ".init");
- if(txt == 0 || init == 0 || init != txt+1)
- goto bad;
- if(txt->addr+txt->size != init->addr)
- goto bad;
- settext(fp, ep->elfentry, txt->addr, txt->size+init->size, txt->offset);
-
- addr = 0;
- offset = 0;
- size = 0;
- s = elfsectbyname(fd, ep, es, ".data");
- if(s) {
- addr = s->addr;
- size = s->size;
- offset = s->offset;
+ /* we could definitely support a lot more machines here */
+ fp->magic = ELF_MAG;
+ fp->hdrsz = (ep->ehsize+ep->phnum*ep->phentsize+16)&~15;
+ switch(ep->machine) {
+ case I386:
+ mach = &mi386;
+ fp->type = FI386;
+ break;
+ case MIPS:
+ mach = &mmips;
+ fp->type = FMIPS;
+ break;
+ case SPARC64:
+ return 0;
+ case POWER:
+ mach = &mpower;
+ fp->type = FPOWER;
+ break;
+ case AMD64:
+ mach = &mamd64;
+ fp->type = FAMD64;
+ break;
+ default:
+ return 0;
}
- s = elfsectbyname(fd, ep, es, ".rodata");
- if(s) {
- if(addr){
- if(addr+size != s->addr)
- goto bad;
- } else {
- addr = s->addr;
- offset = s->offset;
- }
- size += s->size;
+ if(ep->phentsize != sizeof(Phdr)) {
+ werrstr("bad ELF header size");
+ return 0;
}
-
- s = elfsectbyname(fd, ep, es, ".got");
- if(s) {
- if(addr){
- if(addr+size != s->addr)
- goto bad;
- } else {
- addr = s->addr;
- offset = s->offset;
- }
- size += s->size;
+ phsz = sizeof(Phdr)*ep->phnum;
+ ph = malloc(phsz);
+ if(!ph)
+ return 0;
+ seek(fd, ep->phoff, 0);
+ if(read(fd, ph, phsz) < 0) {
+ free(ph);
+ return 0;
}
-
- bsize = 0;
- s = elfsectbyname(fd, ep, es, ".bss");
- if(s) {
- if(addr){
- if(addr+size != s->addr)
- goto bad;
- } else {
- addr = s->addr;
- offset = s->offset;
- }
- bsize = s->size;
+ hswal(ph, phsz/sizeof(ulong), swal);
+
+ /* find text, data and symbols and install them */
+ it = id = is = -1;
+ for(i = 0; i < ep->phnum; i++) {
+ if(ph[i].type == LOAD
+ && (ph[i].flags & (R|X)) == (R|X) && it == -1)
+ it = i;
+ else if(ph[i].type == LOAD
+ && (ph[i].flags & (R|W)) == (R|W) && id == -1)
+ id = i;
+ else if(ph[i].type == NOPTYPE && is == -1)
+ is = i;
}
+ if(it == -1 || id == -1) {
+ /*
+ * The SPARC64 boot image is something of an ELF hack.
+ * Text+Data+BSS are represented by ph[0]. Symbols
+ * are represented by ph[1]:
+ *
+ * filesz, memsz, vaddr, paddr, off
+ * ph[0] : txtsz+datsz, txtsz+datsz+bsssz, txtaddr-KZERO, datasize, txtoff
+ * ph[1] : symsz, lcsz, 0, 0, symoff
+ */
+ if(ep->machine == SPARC64 && ep->phnum == 2) {
+ ulong txtaddr, txtsz, dataddr, bsssz;
+
+ txtaddr = ph[0].vaddr | 0x80000000;
+ txtsz = ph[0].filesz - ph[0].paddr;
+ dataddr = txtaddr + txtsz;
+ bsssz = ph[0].memsz - ph[0].filesz;
+ settext(fp, ep->elfentry | 0x80000000, txtaddr, txtsz, ph[0].offset);
+ setdata(fp, dataddr, ph[0].paddr, ph[0].offset + txtsz, bsssz);
+ setsym(fp, ph[1].filesz, 0, ph[1].memsz, ph[1].offset);
+ free(ph);
+ return 1;
+ }
- if(addr == 0)
- goto bad;
+ werrstr("No TEXT or DATA sections");
+ free(ph);
+ return 0;
+ }
- setdata(fp, addr, size, offset, bsize);
- fp->name = "IRIX Elf a.out executable";
- free(es);
+ settext(fp, ep->elfentry, ph[it].vaddr, ph[it].memsz, ph[it].offset);
+ setdata(fp, ph[id].vaddr, ph[id].filesz, ph[id].offset, ph[id].memsz - ph[id].filesz);
+ if(is != -1)
+ setsym(fp, ph[is].filesz, 0, ph[is].memsz, ph[is].offset);
+ free(ph);
return 1;
-bad:
- free(es);
- werrstr("ELF sections scrambled");
- return 0;
}
/*
@@ -513,7 +674,7 @@ bad:
static int
armdotout(int fd, Fhdr *fp, ExecHdr *hp)
{
- long kbase;
+ uvlong kbase;
USED(fd);
settext(fp, hp->e.exec.entry, sizeof(Exec), hp->e.exec.text, sizeof(Exec));
@@ -531,37 +692,39 @@ armdotout(int fd, Fhdr *fp, ExecHdr *hp)
}
static void
-settext(Fhdr *fp, long e, long a, long s, long off)
+settext(Fhdr *fp, uvlong e, uvlong a, long s, vlong off)
{
fp->txtaddr = a;
fp->entry = e;
fp->txtsz = s;
fp->txtoff = off;
}
+
static void
-setdata(Fhdr *fp, long a, long s, long off, long bss)
+setdata(Fhdr *fp, uvlong a, long s, vlong off, long bss)
{
fp->dataddr = a;
fp->datsz = s;
fp->datoff = off;
fp->bsssz = bss;
}
+
static void
-setsym(Fhdr *fp, long sy, long sppc, long lnpc, long symoff)
+setsym(Fhdr *fp, long symsz, long sppcsz, long lnpcsz, vlong symoff)
{
- fp->symsz = sy;
+ fp->symsz = symsz;
fp->symoff = symoff;
- fp->sppcsz = sppc;
+ fp->sppcsz = sppcsz;
fp->sppcoff = fp->symoff+fp->symsz;
- fp->lnpcsz = lnpc;
+ fp->lnpcsz = lnpcsz;
fp->lnpcoff = fp->sppcoff+fp->sppcsz;
}
-static long
-_round(long a, long b)
+static uvlong
+_round(uvlong a, ulong b)
{
- long w;
+ uvlong w;
w = (a/b)*b;
if (a!=w)
diff --git a/utils/libmach/kdb.c b/utils/libmach/kdb.c
index bffd5e77..eb52b3c2 100644
--- a/utils/libmach/kdb.c
+++ b/utils/libmach/kdb.c
@@ -7,10 +7,10 @@
*/
static char *sparcexcep(Map*, Rgetter);
-static int sparcfoll(Map*, ulong, Rgetter, ulong*);
-static int sparcinst(Map*, ulong, char, char*, int);
-static int sparcdas(Map*, ulong, char*, int);
-static int sparcinstlen(Map*, ulong);
+static int sparcfoll(Map*, uvlong, Rgetter, uvlong*);
+static int sparcinst(Map*, uvlong, char, char*, int);
+static int sparcdas(Map*, uvlong, char*, int);
+static int sparcinstlen(Map*, uvlong);
Machdata sparcmach =
{
@@ -85,16 +85,16 @@ sparcexcep(Map *map, Rgetter rget)
/* Sparc disassembler and related functions */
-typedef struct instr Instr;
-
struct opcode {
char *mnemonic;
- void (*f)(Instr*, char*);
+ void (*f)(struct instr*, char*);
int flag;
};
static char FRAMENAME[] = ".frame";
+typedef struct instr Instr;
+
struct instr {
uchar op; /* bits 31-30 */
uchar rd; /* bits 29-25 */
@@ -115,7 +115,7 @@ struct instr {
int target; /* SETHI+ADD dest reg */
long w0;
long w1;
- ulong addr; /* pc of instruction */
+ uvlong addr; /* pc of instruction */
char *curr; /* current fill level in output buffer */
char *end; /* end of buffer */
int size; /* number of longs in instr */
@@ -125,7 +125,7 @@ struct instr {
static Map *mymap; /* disassembler context */
static int dascase;
-static int mkinstr(ulong, Instr*);
+static int mkinstr(uvlong, Instr*);
static void bra1(Instr*, char*, char*[]);
static void bra(Instr*, char*);
static void fbra(Instr*, char*);
@@ -150,140 +150,152 @@ static void loadcsr(Instr*, char*);
static void trap(Instr*, char*);
static struct opcode sparcop0[8] = {
- "UNIMP", unimp, 0, /* page 137 */ /* 0 */
- "", 0, 0, /* 1 */
- "B", bra, 0, /* page 119 */ /* 2 */
- "", 0, 0, /* 3 */
- "SETHI", sethi, 0, /* page 104 */ /* 4 */
- "", 0, 0, /* 5 */
- "FB", fbra, 0, /* page 121 */ /* 6 */
- "CB", cbra, 0, /* page 123 */ /* 7 */
+ [0] "UNIMP", unimp, 0, /* page 137 */
+ [2] "B", bra, 0, /* page 119 */
+ [4] "SETHI", sethi, 0, /* page 104 */
+ [6] "FB", fbra, 0, /* page 121 */
+ [7] "CB", cbra, 0, /* page 123 */
};
static struct opcode sparcop2[64] = {
- "ADD", add, 0, /* page 108 */ /* 0x00 */
- "AND", add, 0, /* page 106 */ /* 0x01 */
- "OR", add, 0, /* 0x02 */
- "XOR", add, 0, /* 0x03 */
- "SUB", add, 0, /* page 110 */ /* 0x04 */
- "ANDN", add, 0, /* 0x05 */
- "ORN", add, 0, /* 0x06 */
- "XORN", add, 0, /* 0x07 */
- "ADDX", add, 0, /* 0x08 */
- "", 0, 0, /* 0x09 */
- "UMUL", add, 0, /* page 113 */ /* 0x0a */
- "SMUL", add, 0, /* 0x0b */
- "SUBX", add, 0, /* 0x0c */
- "", 0, 0, /* 0x0d */
- "UDIV", add, 0, /* page 115 */ /* 0x0e */
- "SDIV", add, 0, /* 0x0f */
- "ADDCC", add, 0, /* 0x10 */
- "ANDCC", add, 0, /* 0x11 */
- "ORCC", add, 0, /* 0x12 */
- "XORCC", add, 0, /* 0x13 */
- "SUBCC", cmp, 0, /* 0x14 */
- "ANDNCC", add, 0, /* 0x15 */
- "ORNCC", add, 0, /* 0x16 */
- "XORNCC", add, 0, /* 0x17 */
- "ADDXCC", add, 0, /* 0x18 */
- "", 0, 0, /* 0x19 */
- "UMULCC", add, 0, /* 0x1a */
- "SMULCC", add, 0, /* 0x1b */
- "SUBXCC", add, 0, /* 0x1c */
- "", 0, 0, /* 0x1d */
- "UDIVCC", add, 0, /* 0x1e */
- "SDIVCC", add, 0, /* 0x1f */
- "TADD", add, 0, /* page 109 */ /* 0x20 */
- "TSUB", add, 0, /* page 111 */ /* 0x21 */
- "TADDCCTV", add, 0, /* 0x22 */
- "TSUBCCTV", add, 0, /* 0x23 */
- "MULSCC", add, 0, /* page 112 */ /* 0x24 */
- "SLL", shift, 0, /* page 107 */ /* 0x25 */
- "SRL", shift, 0, /* 0x26 */
- "SRA", shift, 0, /* 0x27 */
- "rdy", rd, 0, /* page 131 */ /* 0x28 */
- "rdpsr", rd, 0, /* 0x29 */
- "rdwim", rd, 0, /* 0x2a */
- "rdtbr", rd, 0, /* 0x2b */
- "", 0, 0, /* 0x2c */
- "", 0, 0, /* 0x2d */
- "", 0, 0, /* 0x2e */
- "", 0, 0, /* 0x2f */
- "wry", wr, 0, /* page 133 */ /* 0x30 */
- "wrpsr", wr, 0, /* 0x31 */
- "wrwim", wr, 0, /* 0x32 */
- "wrtbr", wr, 0, /* 0x33 */
- "FPOP", fpop, 0, /* page 140 */ /* 0x34 */
- "FPOP", fpop, 0, /* 0x35 */
- "", 0, 0, /* 0x36 */
- "", 0, 0, /* 0x37 */
- "JMPL", jmpl, 0, /* page 126 */ /* 0x38 */
- "RETT", add, 0, /* page 127 */ /* 0x39 */
- "T", trap, 0, /* page 129 */ /* 0x3a */
- "flush", add, 0, /* page 138 */ /* 0x3b */
- "SAVE", add, 0, /* page 117 */ /* 0x3c */
- "RESTORE", add, 0, /* 0x3d */
+ [0x00] "ADD", add, 0, /* page 108 */
+ [0x10] "ADDCC", add, 0,
+ [0x08] "ADDX", add, 0,
+ [0x18] "ADDXCC", add, 0,
+
+ [0x20] "TADD", add, 0, /* page 109 */
+ [0x22] "TADDCCTV", add, 0,
+
+ [0x04] "SUB", add, 0, /* page 110 */
+ [0x14] "SUBCC", cmp, 0,
+ [0x0C] "SUBX", add, 0,
+ [0x1C] "SUBXCC", add, 0,
+
+ [0x21] "TSUB", add, 0, /* page 111 */
+ [0x23] "TSUBCCTV", add, 0,
+
+ [0x24] "MULSCC", add, 0, /* page 112 */
+
+ [0x0A] "UMUL", add, 0, /* page 113 */
+ [0x0B] "SMUL", add, 0,
+ [0x1A] "UMULCC", add, 0,
+ [0x1B] "SMULCC", add, 0,
+
+ [0x0E] "UDIV", add, 0, /* page 115 */
+ [0x0F] "SDIV", add, 0,
+ [0x1E] "UDIVCC", add, 0,
+ [0x1F] "SDIVCC", add, 0,
+
+ [0x01] "AND", add, 0, /* page 106 */
+ [0x11] "ANDCC", add, 0,
+ [0x05] "ANDN", add, 0,
+ [0x15] "ANDNCC", add, 0,
+ [0x02] "OR", add, 0,
+ [0x12] "ORCC", add, 0,
+ [0x06] "ORN", add, 0,
+ [0x16] "ORNCC", add, 0,
+ [0x03] "XOR", add, 0,
+ [0x13] "XORCC", add, 0,
+ [0x07] "XORN", add, 0,
+ [0x17] "XORNCC", add, 0,
+
+ [0x25] "SLL", shift, 0, /* page 107 */
+ [0x26] "SRL", shift, 0,
+ [0x27] "SRA", shift, 0,
+
+ [0x3C] "SAVE", add, 0, /* page 117 */
+ [0x3D] "RESTORE", add, 0,
+
+ [0x38] "JMPL", jmpl, 0, /* page 126 */
+
+ [0x39] "RETT", add, 0, /* page 127 */
+
+ [0x3A] "T", trap, 0, /* page 129 */
+
+ [0x28] "rdy", rd, 0, /* page 131 */
+ [0x29] "rdpsr", rd, 0,
+ [0x2A] "rdwim", rd, 0,
+ [0x2B] "rdtbr", rd, 0,
+
+ [0x30] "wry", wr, 0, /* page 133 */
+ [0x31] "wrpsr", wr, 0,
+ [0x32] "wrwim", wr, 0,
+ [0x33] "wrtbr", wr, 0,
+
+ [0x3B] "flush", add, 0, /* page 138 */
+
+ [0x34] "FPOP", fpop, 0, /* page 140 */
+ [0x35] "FPOP", fpop, 0,
};
static struct opcode sparcop3[64]={
- "ld", load, 0, /* 0x00 */
- "ldub", load, 0, /* 0x01 */
- "lduh", load, 0, /* 0x02 */
- "ldd", load, 0, /* 0x03 */
- "st", store, 0, /* 0x04 */
- "stb", store, 0, /* page 95 */ /* 0x05 */
- "sth", store, 0, /* 0x06 */
- "std", store, 0, /* 0x07 */
- "", 0, 0, /* 0x08 */
- "ldsb", load, 0, /* page 90 */ /* 0x09 */
- "ldsh", load, 0, /* 0x0a */
- "", 0, 0, /* 0x0b */
- "", 0, 0, /* 0x0c */
- "ldstub", store, 0, /* page 101 */ /* 0x0d */
- "", 0, 0, /* 0x0e */
- "swap", load, 0, /* page 102 */ /* 0x0f */
- "lda", loada, 0, /* 0x10 */
- "lduba", loada, 0, /* 0x11 */
- "lduha", loada, 0, /* 0x12 */
- "ldda", loada, 0, /* 0x13 */
- "sta", storea, 0, /* 0x14 */
- "stba", storea, 0, /* 0x15 */
- "stha", storea, 0, /* 0x16 */
- "stda", storea, 0, /* 0x17 */
- "", 0, 0, /* 0x18 */
- "ldsba", loada, 0, /* 0x19 */
- "ldsha", loada, 0, /* 0x1a */
- "", 0, 0, /* 0x1b */
- "", 0, 0, /* 0x1c */
- "ldstuba", storea, 0, /* 0x1d */
- "", 0, 0, /* 0x1e */
- "swapa", loada, 0, /* 0x1f */
- "ldf", loadf, 0, /* page 92 */ /* 0x20 */
- "ldfsr", loadf,0, /* 0x21 */
- "", 0, 0, /* 0x22 */
- "lddf", loadf, 0, /* 0x23 */
- "stf", storef, 0, /* page 97 */ /* 0x24 */
- "stfsr", storef,0, /* 0x25 */
- "stdfq", storef,0, /* 0x26 */
- "stdf", storef, 0, /* 0x27 */
- "", 0, 0, /* 0x28 */
- "", 0, 0, /* 0x29 */
- "", 0, 0, /* 0x2a */
- "", 0, 0, /* 0x2b */
- "", 0, 0, /* 0x2c */
- "", 0, 0, /* 0x2d */
- "", 0, 0, /* 0x2e */
- "", 0, 0, /* 0x2f */
- "ldc", loadc, 0, /* page 94 */ /* 0x30 */
- "ldcsr", loadcsr,0, /* 0x31 */
- "", 0, 0, /* 0x32 */
- "lddc", loadc, 0, /* 0x33 */
- "stc", loadc, 0, /* page 99 */ /* 0x34 */
- "stcsr", loadcsr,0, /* 0x35 */
- "stdcq", loadcsr,0, /* 0x36 */
- "stdc", loadc, 0, /* 0x37 */
+ [0x09] "ldsb", load, 0, /* page 90 */
+ [0x19] "ldsba", loada, 0,
+ [0x0A] "ldsh", load, 0,
+ [0x1A] "ldsha", loada, 0,
+ [0x01] "ldub", load, 0,
+ [0x11] "lduba", loada, 0,
+ [0x02] "lduh", load, 0,
+ [0x12] "lduha", loada, 0,
+ [0x00] "ld", load, 0,
+ [0x10] "lda", loada, 0,
+ [0x03] "ldd", load, 0,
+ [0x13] "ldda", loada, 0,
+
+ [0x20] "ldf", loadf, 0, /* page 92 */
+ [0x23] "lddf", loadf, 0,
+ [0x21] "ldfsr", loadf,0,
+
+ [0x30] "ldc", loadc, 0, /* page 94 */
+ [0x33] "lddc", loadc, 0,
+ [0x31] "ldcsr", loadcsr,0,
+
+ [0x05] "stb", store, 0, /* page 95 */
+ [0x15] "stba", storea, 0,
+ [0x06] "sth", store, 0,
+ [0x16] "stha", storea, 0,
+ [0x04] "st", store, 0,
+ [0x14] "sta", storea, 0,
+ [0x07] "std", store, 0,
+ [0x17] "stda", storea, 0,
+
+ [0x24] "stf", storef, 0, /* page 97 */
+ [0x27] "stdf", storef, 0,
+ [0x25] "stfsr", storef,0,
+ [0x26] "stdfq", storef,0,
+
+ [0x34] "stc", loadc, 0, /* page 99 */
+ [0x37] "stdc", loadc, 0,
+ [0x35] "stcsr", loadcsr,0,
+ [0x36] "stdcq", loadcsr,0,
+
+ [0x0D] "ldstub", store, 0, /* page 101 */
+ [0x1D] "ldstuba", storea, 0,
+
+ [0x0F] "swap", load, 0, /* page 102 */
+ [0x1F] "swapa", loada, 0,
};
+#pragma varargck argpos bprint 2
+#pragma varargck type "T" char*
+
+/* convert to lower case from upper, according to dascase */
+static int
+Tfmt(Fmt *f)
+{
+ char buf[128];
+ char *s, *t, *oa;
+
+ oa = va_arg(f->args, char*);
+ if(dascase){
+ for(s=oa,t=buf; *t = *s; s++,t++)
+ if('A'<=*t && *t<='Z')
+ *t += 'a'-'A';
+ return fmtstrcpy(f, buf);
+ }
+ return fmtstrcpy(f, oa);
+}
+
static void
bprint(Instr *i, char *fmt, ...)
{
@@ -295,9 +307,9 @@ bprint(Instr *i, char *fmt, ...)
}
static int
-decode(ulong pc, Instr *i)
+decode(uvlong pc, Instr *i)
{
- long w;
+ ulong w;
if (get4(mymap, pc, &w) < 0) {
werrstr("can't read instruction: %r");
@@ -330,7 +342,7 @@ decode(ulong pc, Instr *i)
}
static int
-mkinstr(ulong pc, Instr *i)
+mkinstr(uvlong pc, Instr *i)
{
Instr xi;
@@ -361,7 +373,7 @@ mkinstr(ulong pc, Instr *i)
}
static int
-printins(Map *map, ulong pc, char *buf, int n)
+printins(Map *map, uvlong pc, char *buf, int n)
{
Instr instr;
void (*f)(Instr*, char*);
@@ -382,7 +394,7 @@ printins(Map *map, ulong pc, char *buf, int n)
break;
case 1:
- bprint(&instr, "%X", "CALL\t");
+ bprint(&instr, "%T", "CALL\t");
instr.curr += symoff(instr.curr, instr.end-instr.curr,
pc+instr.disp30*4, CTEXT);
if (!dascase)
@@ -413,32 +425,15 @@ printins(Map *map, ulong pc, char *buf, int n)
return instr.size*4;
}
-/* convert to lower case from upper, according to dascase */
-static int
-Xconv(Fmt *f)
-{
- char buf[128];
- char *s, *t, *oa;
-
- oa = va_arg(f->args, char*);
- if(dascase){
- for(s=oa,t=buf; *t = *s; s++,t++)
- if('A'<=*t && *t<='Z')
- *t += 'a'-'A';
- return fmtstrcpy(f, buf);
- }
- return fmtstrcpy(f, oa);
-}
-
static int
-sparcinst(Map *map, ulong pc, char modifier, char *buf, int n)
+sparcinst(Map *map, uvlong pc, char modifier, char *buf, int n)
{
static int fmtinstalled = 0;
/* a modifier of 'I' toggles the dissassembler type */
if (!fmtinstalled) {
fmtinstalled = 1;
- fmtinstall('X', Xconv);
+ fmtinstall('T', Tfmt);
}
if ((asstype == ASUNSPARC && modifier == 'i')
|| (asstype == ASPARC && modifier == 'I'))
@@ -449,7 +444,7 @@ sparcinst(Map *map, ulong pc, char modifier, char *buf, int n)
}
static int
-sparcdas(Map *map, ulong pc, char *buf, int n)
+sparcdas(Map *map, uvlong pc, char *buf, int n)
{
Instr instr;
@@ -470,7 +465,7 @@ sparcdas(Map *map, ulong pc, char *buf, int n)
}
static int
-sparcinstlen(Map *map, ulong pc)
+sparcinstlen(Map *map, uvlong pc)
{
Instr i;
@@ -490,7 +485,7 @@ plocal(Instr *i)
return -1;
if (s.value > i->simm13) {
if(getauto(&s, s.value-i->simm13, CAUTO, &s)) {
- bprint(i, "%s+%d(SP)", s.name, s.value);
+ bprint(i, "%s+%lld(SP)", s.name, s.value);
return 1;
}
} else {
@@ -507,7 +502,7 @@ static void
address(Instr *i)
{
Symbol s, s2;
- long off, off1;
+ uvlong off, off1;
if (i->rs1 == 1 && plocal(i) >= 0)
return;
@@ -517,7 +512,7 @@ address(Instr *i)
&& (s.class == CDATA || s.class == CTEXT)) {
if(off==s.value && s.name[0]=='$'){
off1 = 0;
- get4(mymap, s.value, &off1);
+ geta(mymap, s.value, &off1);
if(off1 && findsym(off1, CANY, &s2) && s2.value == off1){
bprint(i, "$%s(SB)", s2.name);
return;
@@ -525,74 +520,74 @@ address(Instr *i)
}
bprint(i, "%s", s.name);
if (s.value != off)
- bprint(i, "+%lux", s.value-off);
+ bprint(i, "+%llux", s.value-off);
bprint(i, "(SB)");
return;
}
- bprint(i, "%lux(R%d)", i->simm13, i->rs1);
+ bprint(i, "%ux(R%d)", i->simm13, i->rs1);
}
static void
unimp(Instr *i, char *m)
{
- bprint(i, "%X", m);
+ bprint(i, "%T", m);
}
static char *bratab[16] = { /* page 91 */
- "N", /* 0x0 */
- "E", /* 0x1 */
- "LE", /* 0x2 */
- "L", /* 0x3 */
- "LEU", /* 0x4 */
- "CS", /* 0x5 */
- "NEG", /* 0x6 */
- "VS", /* 0x7 */
- "A", /* 0x8 */
- "NE", /* 0x9 */
- "G", /* 0xa */
- "GE", /* 0xb */
- "GU", /* 0xc */
- "CC", /* 0xd */
- "POS", /* 0xe */
- "VC", /* 0xf */
+ [0X8] "A",
+ [0X0] "N",
+ [0X9] "NE",
+ [0X1] "E",
+ [0XA] "G",
+ [0X2] "LE",
+ [0XB] "GE",
+ [0X3] "L",
+ [0XC] "GU",
+ [0X4] "LEU",
+ [0XD] "CC",
+ [0X5] "CS",
+ [0XE] "POS",
+ [0X6] "NEG",
+ [0XF] "VC",
+ [0X7] "VS",
};
static char *fbratab[16] = { /* page 91 */
- "N", /* 0x0 */
- "NE", /* 0x1 */
- "LG", /* 0x2 */
- "UL", /* 0x3 */
- "L", /* 0x4 */
- "UG", /* 0x5 */
- "G", /* 0x6 */
- "U", /* 0x7 */
- "A", /* 0x8 */
- "E", /* 0x9 */
- "UE", /* 0xa */
- "GE", /* 0xb */
- "UGE", /* 0xc */
- "LE", /* 0xd */
- "ULE", /* 0xe */
- "O", /* 0xf */
+ [0X8] "A",
+ [0X0] "N",
+ [0X7] "U",
+ [0X6] "G",
+ [0X5] "UG",
+ [0X4] "L",
+ [0X3] "UL",
+ [0X2] "LG",
+ [0X1] "NE",
+ [0X9] "E",
+ [0XA] "UE",
+ [0XB] "GE",
+ [0XC] "UGE",
+ [0XD] "LE",
+ [0XE] "ULE",
+ [0XF] "O",
};
static char *cbratab[16] = { /* page 91 */
- "N", /* 0x0 */
- "123", /* 0x1 */
- "12", /* 0x2 */
- "13", /* 0x3 */
- "1", /* 0x4 */
- "23", /* 0x5 */
- "2", /* 0x6 */
- "3", /* 0x7 */
- "A", /* 0x8 */
- "0", /* 0x9 */
- "03", /* 0xa */
- "02", /* 0xb */
- "023", /* 0xc */
- "01", /* 0xd */
- "013", /* 0xe */
- "012", /* 0xf */
+ [0X8] "A",
+ [0X0] "N",
+ [0X7] "3",
+ [0X6] "2",
+ [0X5] "23",
+ [0X4] "1",
+ [0X3] "13",
+ [0X2] "12",
+ [0X1] "123",
+ [0X9] "0",
+ [0XA] "03",
+ [0XB] "02",
+ [0XC] "023",
+ [0XD] "01",
+ [0XE] "013",
+ [0XF] "012",
};
static void
@@ -602,9 +597,9 @@ bra1(Instr *i, char *m, char *tab[])
imm = i->simmdisp22;
if(i->a)
- bprint(i, "%X%X.%c\t", m, tab[i->cond], 'A'+dascase);
+ bprint(i, "%T%T.%c\t", m, tab[i->cond], 'A'+dascase);
else
- bprint(i, "%X%X\t", m, tab[i->cond]);
+ bprint(i, "%T%T\t", m, tab[i->cond]);
i->curr += symoff(i->curr, i->end-i->curr, i->addr+4*imm, CTEXT);
if (!dascase)
bprint(i, "(SB)");
@@ -632,9 +627,9 @@ static void
trap(Instr *i, char *m) /* page 101 */
{
if(i->i == 0)
- bprint(i, "%X%X\tR%d+R%d", m, bratab[i->cond], i->rs2, i->rs1);
+ bprint(i, "%T%T\tR%d+R%d", m, bratab[i->cond], i->rs2, i->rs1);
else
- bprint(i, "%X%X\t$%lux+R%d", m, bratab[i->cond], i->simm13, i->rs1);
+ bprint(i, "%T%T\t$%ux+R%d", m, bratab[i->cond], i->simm13, i->rs1);
}
static void
@@ -644,7 +639,7 @@ sethi(Instr *i, char *m) /* page 89 */
imm = i->immdisp22<<10;
if(dascase){
- bprint(i, "%X\t%lux, R%d", m, imm, i->rd);
+ bprint(i, "%T\t%lux, R%d", m, imm, i->rd);
return;
}
if(imm==0 && i->rd==0){
@@ -740,25 +735,25 @@ shift(Instr *i, char *m) /* page 88 */
if(i->i == 0){
if(i->rs1 == i->rd)
if(dascase)
- bprint(i, "%X\tR%d, R%d", m, i->rs1, i->rs2);
+ bprint(i, "%T\tR%d, R%d", m, i->rs1, i->rs2);
else
- bprint(i, "%X\tR%d, R%d", m, i->rs2, i->rs1);
+ bprint(i, "%T\tR%d, R%d", m, i->rs2, i->rs1);
else
if(dascase)
- bprint(i, "%X\tR%d, R%d, R%d", m, i->rs1, i->rs2, i->rd);
+ bprint(i, "%T\tR%d, R%d, R%d", m, i->rs1, i->rs2, i->rd);
else
- bprint(i, "%X\tR%d, R%d, R%d", m, i->rs2, i->rs1, i->rd);
+ bprint(i, "%T\tR%d, R%d, R%d", m, i->rs2, i->rs1, i->rd);
}else{
if(i->rs1 == i->rd)
if(dascase)
- bprint(i, "%X\t$%d,R%d", m, i->simm13&0x1F, i->rs1);
+ bprint(i, "%T\t$%d,R%d", m, i->simm13&0x1F, i->rs1);
else
- bprint(i, "%X\tR%d, $%d", m, i->rs1, i->simm13&0x1F);
+ bprint(i, "%T\tR%d, $%d", m, i->rs1, i->simm13&0x1F);
else
if(dascase)
- bprint(i, "%X\tR%d, $%d, R%d",m,i->rs1,i->simm13&0x1F,i->rd);
+ bprint(i, "%T\tR%d, $%d, R%d",m,i->rs1,i->simm13&0x1F,i->rd);
else
- bprint(i, "%X\t$%d, R%d, R%d",m,i->simm13&0x1F,i->rs1,i->rd);
+ bprint(i, "%T\t$%d, R%d, R%d",m,i->simm13&0x1F,i->rs1,i->rd);
}
}
@@ -767,24 +762,24 @@ add(Instr *i, char *m) /* page 82 */
{
if(i->i == 0){
if(dascase)
- bprint(i, "%X\tR%d, R%d", m, i->rs1, i->rs2);
+ bprint(i, "%T\tR%d, R%d", m, i->rs1, i->rs2);
else
if(i->op3==2 && i->rs1==0 && i->rd) /* OR R2, R0, R1 */
bprint(i, "MOVW\tR%d", i->rs2);
else
- bprint(i, "%X\tR%d, R%d", m, i->rs2, i->rs1);
+ bprint(i, "%T\tR%d, R%d", m, i->rs2, i->rs1);
}else{
if(dascase)
- bprint(i, "%X\tR%d, $%lux", m, i->rs1, i->simm13);
+ bprint(i, "%T\tR%d, $%ux", m, i->rs1, i->simm13);
else
if(i->op3==0 && i->rd && i->rs1==0) /* ADD $x, R0, R1 */
- bprint(i, "MOVW\t$%lux", i->simm13);
+ bprint(i, "MOVW\t$%ux", i->simm13);
else if(i->op3==0 && i->rd && i->rs1==2){
/* ADD $x, R2, R1 -> MOVW $x(SB), R1 */
bprint(i, "MOVW\t$");
address(i);
} else
- bprint(i, "%X\t$%lux, R%d", m, i->simm13, i->rs1);
+ bprint(i, "%T\t$%ux, R%d", m, i->simm13, i->rs1);
}
if(i->rs1 != i->rd)
bprint(i, ", R%d", i->rd);
@@ -800,7 +795,7 @@ cmp(Instr *i, char *m)
if(i->i == 0)
bprint(i, "CMP\tR%d, R%d", i->rs1, i->rs2);
else
- bprint(i, "CMP\tR%d, $%lux", i->rs1, i->simm13);
+ bprint(i, "CMP\tR%d, $%ux", i->rs1, i->simm13);
}
static char *regtab[4] = {
@@ -817,14 +812,14 @@ wr(Instr *i, char *m) /* page 82 */
if(i->i == 0)
bprint(i, "%s\tR%d, R%d", m, i->rs1, i->rs2);
else
- bprint(i, "%s\tR%d, $%lux", m, i->rs1, i->simm13);
+ bprint(i, "%s\tR%d, $%ux", m, i->rs1, i->simm13);
}else{
if(i->i && i->simm13==0)
bprint(i, "MOVW\tR%d", i->rs1);
else if(i->i == 0)
bprint(i, "wr\tR%d, R%d", i->rs2, i->rs1);
else
- bprint(i, "wr\t$%lux, R%d", i->simm13, i->rs1);
+ bprint(i, "wr\t$%ux, R%d", i->simm13, i->rs1);
}
bprint(i, ", %s", regtab[i->op3&3]);
}
@@ -849,14 +844,14 @@ jmpl(Instr *i, char *m) /* page 82 */
{
if(i->i == 0){
if(i->rd == 15)
- bprint(i, "%X\t(R%d+R%d)", "CALL", i->rs2, i->rs1);
+ bprint(i, "%T\t(R%d+R%d)", "CALL", i->rs2, i->rs1);
else
- bprint(i, "%X\t(R%d+R%d), R%d", m, i->rs2, i->rs1, i->rd);
+ bprint(i, "%T\t(R%d+R%d), R%d", m, i->rs2, i->rs1, i->rd);
}else{
if(!dascase && i->simm13==8 && i->rs1==15 && i->rd==0)
bprint(i, "RETURN");
else{
- bprint(i, "%X\t", m);
+ bprint(i, "%T\t", m);
address(i);
bprint(i, ", R%d", i->rd);
}
@@ -885,8 +880,8 @@ loadf(Instr *i, char *m) /* page 70 */
bprint(i, ", R%d", i->rd);
}
-static
-void storef(Instr *i, char *m) /* page 70 */
+static void
+storef(Instr *i, char *m) /* page 70 */
{
if(!dascase){
m = "FMOVD";
@@ -908,8 +903,8 @@ void storef(Instr *i, char *m) /* page 70 */
address(i);
}
-static
-void loadc(Instr *i, char *m) /* page 72 */
+static void
+loadc(Instr *i, char *m) /* page 72 */
{
if(i->i == 0)
bprint(i, "%s\t(R%d+R%d), C%d", m, i->rs1, i->rs2, i->rd);
@@ -920,8 +915,8 @@ void loadc(Instr *i, char *m) /* page 72 */
}
}
-static
-void loadcsr(Instr *i, char *m) /* page 72 */
+static void
+loadcsr(Instr *i, char *m) /* page 72 */
{
if(i->i == 0)
bprint(i, "%s\t(R%d+R%d), CSR", m, i->rs1, i->rs2);
@@ -1002,19 +997,19 @@ fpop(Instr *i, char *m) /* page 108-116 */
}
for(j=0; fptab1[j].name; j++)
if(fptab1[j].opf == i->opf){
- bprint(i, "%X\tF%d, F%d", fptab1[j].name, i->rs2, i->rd);
+ bprint(i, "%T\tF%d, F%d", fptab1[j].name, i->rs2, i->rd);
return;
}
for(j=0; fptab2[j].name; j++)
if(fptab2[j].opf == i->opf){
- bprint(i, "%X\tF%d, F%d, F%d", fptab2[j].name, i->rs1, i->rs2, i->rd);
+ bprint(i, "%T\tF%d, F%d, F%d", fptab2[j].name, i->rs1, i->rs2, i->rd);
return;
}
- bprint(i, "%X%ux\tF%d, F%d, F%d", m, i->opf, i->rs1, i->rs2, i->rd);
+ bprint(i, "%T%ux\tF%d, F%d, F%d", m, i->opf, i->rs1, i->rs2, i->rd);
}
static int
-sparcfoll(Map *map, ulong pc, Rgetter rget, ulong *foll)
+sparcfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
{
ulong w, r1, r2;
char buf[8];
diff --git a/utils/libmach/machdata.c b/utils/libmach/machdata.c
index a82e14e8..425173e6 100644
--- a/utils/libmach/machdata.c
+++ b/utils/libmach/machdata.c
@@ -16,11 +16,10 @@ int asstype = AMIPS; /* disassembler type */
Machdata *machdata; /* machine-dependent functions */
int
-localaddr(Map *map, char *fn, char *var, long *r, Rgetter rget)
+localaddr(Map *map, char *fn, char *var, uvlong *r, Rgetter rget)
{
Symbol s;
- ulong fp;
- ulong pc, sp, link;
+ uvlong fp, pc, sp, link;
if (!lookup(fn, 0, &s)) {
werrstr("function not found");
@@ -63,10 +62,10 @@ localaddr(Map *map, char *fn, char *var, long *r, Rgetter rget)
}
/*
- * Print value v as name[+offset] and then the string s.
+ * Print value v as s.name[+offset] if possible, or just v.
*/
int
-symoff(char *buf, int n, long v, int space)
+symoff(char *buf, int n, uvlong v, int space)
{
Symbol s;
int r;
@@ -81,16 +80,17 @@ symoff(char *buf, int n, long v, int space)
delta = -delta;
}
if (v == 0 || r == 0)
- return snprint(buf, n, "%lux", v);
+ return snprint(buf, n, "%llux", v);
if (s.type != 't' && s.type != 'T' && delta >= 4096)
- return snprint(buf, n, "%lux", v);
- if (strcmp(s.name, ".string") == 0)
- return snprint(buf, n, "%lux", v);
- if (delta)
- return snprint(buf, n, "%s+%lux", s.name, v-s.value);
+ return snprint(buf, n, "%llux", v);
+ else if (strcmp(s.name, ".string") == 0)
+ return snprint(buf, n, "%llux", v);
+ else if (delta)
+ return snprint(buf, n, "%s+%lux", s.name, delta);
else
return snprint(buf, n, "%s", s.name);
}
+
/*
* Format floating point registers
*
@@ -105,7 +105,7 @@ int
fpformat(Map *map, Reglist *rp, char *buf, int n, int modif)
{
char reg[12];
- long r;
+ ulong r;
switch(rp->rformat)
{
@@ -116,10 +116,12 @@ fpformat(Map *map, Reglist *rp, char *buf, int n, int modif)
break;
case 'F': /* first reg of double reg pair */
if (modif == 'F')
- if (((rp+1)->rflags&RFLT) && (rp+1)->rformat == 'f') {
+ if ((rp->rformat=='F') || (((rp+1)->rflags&RFLT) && (rp+1)->rformat == 'f')) {
if (get1(map, rp->roffs, (uchar *)reg, 8) < 0)
return -1;
machdata->dftos(buf, n, reg);
+ if (rp->rformat == 'F')
+ return 1;
return 2;
}
/* treat it like 'f' */
@@ -316,7 +318,6 @@ beieee80ftos(char *buf, int n, void *s)
return beieeedftos(buf, n, (void*)ieee);
}
-
int
leieee80ftos(char *buf, int n, void *s)
{
@@ -331,19 +332,18 @@ leieee80ftos(char *buf, int n, void *s)
}
int
-cisctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
+cisctrace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
{
Symbol s;
- int found;
- ulong opc;
- long moved, j;
+ int found, i;
+ uvlong opc, moved;
USED(link);
- j = 0;
+ i = 0;
opc = 0;
while(pc && opc != pc) {
moved = pc2sp(pc);
- if (moved == -1)
+ if (moved == ~0)
break;
found = findsym(pc, CTEXT, &s);
if (!found)
@@ -353,22 +353,22 @@ cisctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
sp += moved;
opc = pc;
- if (get4(map, sp, (long *)&pc) < 0)
+ if (geta(map, sp, &pc) < 0)
break;
(*trace)(map, pc, sp, &s);
sp += mach->szaddr; /*assumes address size = stack width*/
- if(++j > 40)
+ if(++i > 40)
break;
}
- return j;
+ return i;
}
int
-risctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
+risctrace(Map *map, uvlong pc, uvlong sp, uvlong link, Tracer trace)
{
int i;
Symbol s, f;
- ulong oldpc;
+ uvlong oldpc;
i = 0;
while(findsym(pc, CTEXT, &s)) {
@@ -384,7 +384,7 @@ risctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
if(s.type == 'L' || s.type == 'l' || pc <= s.value+mach->pcquant)
pc = link;
else
- if (get4(map, sp, (long *) &pc) < 0)
+ if (geta(map, sp, &pc) < 0)
break;
if(pc == 0 || (pc == oldpc && f.value == 0))
@@ -399,30 +399,30 @@ risctrace(Map *map, ulong pc, ulong sp, ulong link, Tracer trace)
return i;
}
-ulong
-ciscframe(Map *map, ulong addr, ulong pc, ulong sp, ulong link)
+uvlong
+ciscframe(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
{
Symbol s;
- int moved;
+ uvlong moved;
USED(link);
for(;;) {
moved = pc2sp(pc);
- if (moved == -1)
+ if (moved == ~0)
break;
sp += moved;
findsym(pc, CTEXT, &s);
if (addr == s.value)
return sp;
- if (get4(map, sp, (long *) &pc) < 0)
+ if (geta(map, sp, &pc) < 0)
break;
sp += mach->szaddr; /*assumes sizeof(addr) = stack width*/
}
return 0;
}
-ulong
-riscframe(Map *map, ulong addr, ulong pc, ulong sp, ulong link)
+uvlong
+riscframe(Map *map, uvlong addr, uvlong pc, uvlong sp, uvlong link)
{
Symbol s, f;
@@ -443,7 +443,7 @@ riscframe(Map *map, ulong addr, ulong pc, ulong sp, ulong link)
if (s.type == 'L' || s.type == 'l' || pc-s.value <= mach->szaddr*2)
pc = link;
else
- if (get4(map, sp-f.value, (long *)&pc) < 0)
+ if (geta(map, sp-f.value, &pc) < 0)
break;
}
return 0;
diff --git a/utils/libmach/map.c b/utils/libmach/map.c
index afb19b11..e1d6010e 100644
--- a/utils/libmach/map.c
+++ b/utils/libmach/map.c
@@ -25,7 +25,7 @@ newmap(Map *map, int n)
}
int
-setmap(Map *map, int fd, ulong b, ulong e, ulong f, char *name)
+setmap(Map *map, int fd, uvlong b, uvlong e, vlong f, char *name)
{
int i;
@@ -45,7 +45,7 @@ setmap(Map *map, int fd, ulong b, ulong e, ulong f, char *name)
return 1;
}
-static ulong
+static uvlong
stacktop(int pid)
{
char buf[64];
@@ -53,7 +53,7 @@ stacktop(int pid)
int n;
char *cp;
- sprint(buf, "/proc/%d/segment", pid);
+ snprint(buf, sizeof(buf), "/proc/%d/segment", pid);
fd = open(buf, 0);
if (fd < 0)
return 0;
@@ -73,7 +73,7 @@ stacktop(int pid)
cp++;
if (!*cp)
return 0;
- return strtoul(cp, 0, 16);
+ return strtoull(cp, 0, 16);
}
Map*
@@ -82,7 +82,7 @@ attachproc(int pid, int kflag, int corefd, Fhdr *fp)
char buf[64], *regs;
int fd;
Map *map;
- ulong n;
+ uvlong n;
int mode;
map = newmap(0, 4);
@@ -115,13 +115,13 @@ attachproc(int pid, int kflag, int corefd, Fhdr *fp)
setmap(map, fd, mach->regsize, mach->regsize+mach->fpregsize, 0, "fpregs");
}
setmap(map, corefd, fp->txtaddr, fp->txtaddr+fp->txtsz, fp->txtaddr, "text");
- if(kflag || (ulong) fp->dataddr >= 0x7fffffff) {
- setmap(map, corefd, fp->dataddr, 0xffffffff, fp->dataddr, "data");
+ if(kflag || fp->dataddr >= mach->utop) {
+ setmap(map, corefd, fp->dataddr, ~0, fp->dataddr, "data");
return map;
}
n = stacktop(pid);
if (n == 0) {
- setmap(map, corefd, fp->dataddr, 0x7fffffff, fp->dataddr, "data");
+ setmap(map, corefd, fp->dataddr, mach->utop, fp->dataddr, "data");
return map;
}
setmap(map, corefd, fp->dataddr, n, fp->dataddr, "data");
@@ -149,6 +149,28 @@ unusemap(Map *map, int i)
}
Map*
+loadmap(Map *map, int fd, Fhdr *fp)
+{
+ map = newmap(map, 2);
+ if (map == 0)
+ return 0;
+
+ map->seg[0].b = fp->txtaddr;
+ map->seg[0].e = fp->txtaddr+fp->txtsz;
+ map->seg[0].f = fp->txtoff;
+ map->seg[0].fd = fd;
+ map->seg[0].inuse = 1;
+ map->seg[0].name = "text";
+ map->seg[1].b = fp->dataddr;
+ map->seg[1].e = fp->dataddr+fp->datsz;
+ map->seg[1].f = fp->datoff;
+ map->seg[1].fd = fd;
+ map->seg[1].inuse = 1;
+ map->seg[1].name = "data";
+ return map;
+}
+
+Map*
attachremt(int fd, Fhdr *f)
{
Map *m;
@@ -171,28 +193,6 @@ attachremt(int fd, Fhdr *f)
return m;
}
-Map*
-loadmap(Map *map, int fd, Fhdr *fp)
-{
- map = newmap(map, 2);
- if (map == 0)
- return 0;
-
- map->seg[0].b = fp->txtaddr;
- map->seg[0].e = fp->txtaddr+fp->txtsz;
- map->seg[0].f = fp->txtoff;
- map->seg[0].fd = fd;
- map->seg[0].inuse = 1;
- map->seg[0].name = "text";
- map->seg[1].b = fp->dataddr;
- map->seg[1].e = fp->dataddr+fp->datsz;
- map->seg[1].f = fp->datoff;
- map->seg[1].fd = fd;
- map->seg[1].inuse = 1;
- map->seg[1].name = "data";
- return map;
-}
-
void
setmapio(Map *map, int i, Rsegio get, Rsegio put)
{
diff --git a/utils/libmach/mkfile b/utils/libmach/mkfile
index 1f0a2950..a5e87357 100644
--- a/utils/libmach/mkfile
+++ b/utils/libmach/mkfile
@@ -7,12 +7,12 @@ OFILES=\
5.$O\
6.$O\
8.$O\
+ 9.$O\
k.$O\
q.$O\
t.$O\
v.$O\
2db.$O\
- 4db.$O\
5db.$O\
8db.$O\
kdb.$O\
@@ -23,6 +23,7 @@ OFILES=\
5obj.$O\
6obj.$O\
8obj.$O\
+ 9obj.$O\
kobj.$O\
qobj.$O\
vobj.$O\
@@ -36,10 +37,10 @@ OFILES=\
executable.$O\
vcodas.$O\
-HFILES=mach.h a.out.h bootexec.h elf.h ureg2.h ureg4.h ureg6.h ureg8.h uregk.h uregv.h ureg5.h
+HFILES=../include/mach.h ../include/a.out.h bootexec.h elf.h ureg2.h ureg4.h ureg6.h ureg8.h uregk.h uregv.h ureg5.h
<$ROOT/mkfiles/mksyslib-$SHELLTYPE
-CFLAGS= $CFLAGS -I..
+CFLAGS= $CFLAGS -I../include -I..
package:QV:
$TRUE
diff --git a/utils/libmach/obj.c b/utils/libmach/obj.c
index 39f2fad4..812369ba 100644
--- a/utils/libmach/obj.c
+++ b/utils/libmach/obj.c
@@ -4,7 +4,7 @@
*/
#include <lib9.h>
#include <bio.h>
-#include "ar.h"
+#include <ar.h>
#include "mach.h"
#include "obj.h"
@@ -22,23 +22,21 @@ enum
int _is2(char*), /* in [$OS].c */
_is5(char*),
_is6(char*),
+ _is7(char*),
_is8(char*),
_is9(char*),
_isk(char*),
_isq(char*),
- _ist(char*),
_isv(char*),
- _isx(char*),
_read2(Biobuf*, Prog*),
_read5(Biobuf*, Prog*),
_read6(Biobuf*, Prog*),
+ _read7(Biobuf*, Prog*),
_read8(Biobuf*, Prog*),
_read9(Biobuf*, Prog*),
_readk(Biobuf*, Prog*),
_readq(Biobuf*, Prog*),
- _readt(Biobuf*, Prog*),
- _readv(Biobuf*, Prog*),
- _readx(Biobuf*, Prog*);
+ _readv(Biobuf*, Prog*);
typedef struct Obj Obj;
typedef struct Symtab Symtab;
@@ -52,18 +50,15 @@ struct Obj /* functions to handle each intermediate (.$O) file */
static Obj obj[] =
{ /* functions to identify and parse each type of obj */
- /*[Obj68020]*/ "68020 .2", _is2, _read2,
- /*[ObjSparc]*/ "sparc .k", _isk, _readk,
- /*[ObjMips]*/ "mips .v", _isv, _readv,
- /*[Obj386]*/ "386 .8", _is8, _read8,
- /*[Obj960]*/ "960 .6", 0, 0,
- /*[Obj3210]*/ "3210 .x", 0, 0,
- /*[ObjMips2]*/ "mips2 .4", 0, 0,
- /*[Obj29000]*/ "29000 .9", 0, 0,
- /*[ObjArm]*/ "arm .5", _is5, _read5,
- /*[ObjPower]*/ "power .q", _isq, _readq,
- /*[ObjMips2le]*/ "mips2 .0", 0, 0,
- /*[Maxobjtype]*/ 0, 0
+ [Obj68020] "68020 .2", _is2, _read2,
+ [ObjAmd64] "amd64 .6", _is6, _read6,
+ [ObjArm] "arm .5", _is5, _read5,
+ [Obj386] "386 .8", _is8, _read8,
+ [ObjSparc] "sparc .k", _isk, _readk,
+ [ObjPower] "power .q", _isq, _readq,
+ [ObjMips] "mips .v", _isv, _readv,
+ [ObjPower64] "power64 .9", _is9, _read9,
+ [Maxobjtype] 0, 0
};
struct Symtab
@@ -77,7 +72,7 @@ static Sym *names[NNAMES]; /* working set of active names */
static int processprog(Prog*,int); /* decode each symbol reference */
static void objreset(void);
-static void objlookup(int, char *, int );
+static void objlookup(int, char *, int, uint);
static void objupdate(int, int);
int
@@ -130,14 +125,14 @@ readobj(Biobuf *bp, int objtype)
}
int
-readar(Biobuf *bp, int objtype, int end, int doautos)
+readar(Biobuf *bp, int objtype, vlong end, int doautos)
{
Prog p;
if (objtype < 0 || objtype >= Maxobjtype || obj[objtype].is == 0)
return 1;
objreset();
- while ((*obj[objtype].read)(bp, &p) && BOFFSET(bp) < end)
+ while ((*obj[objtype].read)(bp, &p) && Boffset(bp) < end)
if (!processprog(&p, doautos))
return 0;
return 1;
@@ -159,7 +154,7 @@ processprog(Prog *p, int doautos)
if (!doautos)
if(p->type != 'U' && p->type != 'b')
break;
- objlookup(p->sym, p->id, p->type);
+ objlookup(p->sym, p->id, p->type, p->sig);
break;
case aText:
objupdate(p->sym, 'T');
@@ -178,7 +173,7 @@ processprog(Prog *p, int doautos)
* make a new entry if it is not already there.
*/
static void
-objlookup(int id, char *name, int type)
+objlookup(int id, char *name, int type, uint sig)
{
long h;
char *cp;
@@ -188,6 +183,7 @@ objlookup(int id, char *name, int type)
s = names[id];
if(s && strcmp(s->name, name) == 0) {
s->type = type;
+ s->sig = sig;
return;
}
@@ -232,6 +228,7 @@ objlookup(int id, char *name, int type)
sp = malloc(sizeof(Symtab));
sp->s.name = name;
sp->s.type = type;
+ sp->s.sig = sig;
sp->s.value = islocal(type) ? MAXOFF : 0;
names[id] = &sp->s;
sp->next = hash[h];
@@ -256,7 +253,7 @@ objtraverse(void (*fn)(Sym*, void*), void *pointer)
* update the offset information for a 'a' or 'p' symbol in an intermediate file
*/
void
-_offset(int id, long off)
+_offset(int id, vlong off)
{
Sym *s;
@@ -302,7 +299,7 @@ nextar(Biobuf *bp, int offset, char *buf)
for(i=0; i<sizeof(a.name) && i<SARNAME && a.name[i] != ' '; i++)
buf[i] = a.name[i];
buf[i] = 0;
- arsize = atol(a.size);
+ arsize = strtol(a.size, 0, 0);
if (arsize&1)
arsize++;
return arsize + SAR_HDR;
diff --git a/utils/libmach/obj.h b/utils/libmach/obj.h
index 2d2dfea6..d8c507aa 100644
--- a/utils/libmach/obj.h
+++ b/utils/libmach/obj.h
@@ -18,7 +18,8 @@ struct Prog /* info from .$O files */
char type; /* type of the symbol: ie, 'T', 'a', etc. */
char sym; /* index of symbol's name */
char *id; /* name for the symbol, if it introduces one */
+ uint sig; /* type signature for symbol */
};
#define UNKNOWN '?'
-void _offset(int, long);
+void _offset(int, vlong);
diff --git a/utils/libmach/q.c b/utils/libmach/q.c
index 858882bf..f73ade9f 100644
--- a/utils/libmach/q.c
+++ b/utils/libmach/q.c
@@ -2,7 +2,7 @@
* PowerPC definition
* forsyth@terzarima.net
*/
-#include <lib9.h>
+#include <u.h>
#include <bio.h>
#include "uregq.h"
#include "mach.h"
@@ -17,84 +17,84 @@
#define R31 REGOFF(r31)
#define FP_REG(x) (R31+4+8*(x))
-#define REGSIZE sizeof(struct Ureg)
-#define FPREGSIZE (8*33)
+#define REGSIZE sizeof(struct Ureg)
+#define FPREGSIZE (8*33)
Reglist powerreglist[] = {
- {"CAUSE", REGOFF(cause), RINT|RRDONLY, 'X'},
- {"SRR1", REGOFF(status), RINT|RRDONLY, 'X'},
- {"PC", REGOFF(pc), RINT, 'X'},
- {"LR", REGOFF(lr), RINT, 'X'},
- {"CR", REGOFF(cr), RINT, 'X'},
- {"XER", REGOFF(xer), RINT, 'X'},
- {"CTR", REGOFF(ctr), RINT, 'X'},
- {"PC", PC, RINT, 'X'},
- {"SP", SP, RINT, 'X'},
- {"R0", REGOFF(r0), RINT, 'X'},
+ {"CAUSE", REGOFF(cause), RINT|RRDONLY, 'X'},
+ {"SRR1", REGOFF(srr1), RINT|RRDONLY, 'X'},
+ {"PC", REGOFF(pc), RINT, 'X'},
+ {"LR", REGOFF(lr), RINT, 'X'},
+ {"CR", REGOFF(cr), RINT, 'X'},
+ {"XER", REGOFF(xer), RINT, 'X'},
+ {"CTR", REGOFF(ctr), RINT, 'X'},
+ {"PC", PC, RINT, 'X'},
+ {"SP", SP, RINT, 'X'},
+ {"R0", REGOFF(r0), RINT, 'X'},
/* R1 is SP */
- {"R2", REGOFF(r2), RINT, 'X'},
- {"R3", REGOFF(r3), RINT, 'X'},
- {"R4", REGOFF(r4), RINT, 'X'},
- {"R5", REGOFF(r5), RINT, 'X'},
- {"R6", REGOFF(r6), RINT, 'X'},
- {"R7", REGOFF(r7), RINT, 'X'},
- {"R8", REGOFF(r8), RINT, 'X'},
- {"R9", REGOFF(r9), RINT, 'X'},
- {"R10", REGOFF(r10), RINT, 'X'},
- {"R11", REGOFF(r11), RINT, 'X'},
- {"R12", REGOFF(r12), RINT, 'X'},
- {"R13", REGOFF(r13), RINT, 'X'},
- {"R14", REGOFF(r14), RINT, 'X'},
- {"R15", REGOFF(r15), RINT, 'X'},
- {"R16", REGOFF(r16), RINT, 'X'},
- {"R17", REGOFF(r17), RINT, 'X'},
- {"R18", REGOFF(r18), RINT, 'X'},
- {"R19", REGOFF(r19), RINT, 'X'},
- {"R20", REGOFF(r20), RINT, 'X'},
- {"R21", REGOFF(r21), RINT, 'X'},
- {"R22", REGOFF(r22), RINT, 'X'},
- {"R23", REGOFF(r23), RINT, 'X'},
- {"R24", REGOFF(r24), RINT, 'X'},
- {"R25", REGOFF(r25), RINT, 'X'},
- {"R26", REGOFF(r26), RINT, 'X'},
- {"R27", REGOFF(r27), RINT, 'X'},
- {"R28", REGOFF(r28), RINT, 'X'},
- {"R29", REGOFF(r29), RINT, 'X'},
- {"R30", REGOFF(r30), RINT, 'X'},
- {"R31", REGOFF(r31), RINT, 'X'},
- {"F0", FP_REG(0), RFLT, 'D'},
- {"F1", FP_REG(1), RFLT, 'D'},
- {"F2", FP_REG(2), RFLT, 'D'},
- {"F3", FP_REG(3), RFLT, 'D'},
- {"F4", FP_REG(4), RFLT, 'D'},
- {"F5", FP_REG(5), RFLT, 'D'},
- {"F6", FP_REG(6), RFLT, 'D'},
- {"F7", FP_REG(7), RFLT, 'D'},
- {"F8", FP_REG(8), RFLT, 'D'},
- {"F9", FP_REG(9), RFLT, 'D'},
- {"F10", FP_REG(10), RFLT, 'D'},
- {"F11", FP_REG(11), RFLT, 'D'},
- {"F12", FP_REG(12), RFLT, 'D'},
- {"F13", FP_REG(13), RFLT, 'D'},
- {"F14", FP_REG(14), RFLT, 'D'},
- {"F15", FP_REG(15), RFLT, 'D'},
- {"F16", FP_REG(16), RFLT, 'D'},
- {"F17", FP_REG(17), RFLT, 'D'},
- {"F18", FP_REG(18), RFLT, 'D'},
- {"F19", FP_REG(19), RFLT, 'D'},
- {"F20", FP_REG(20), RFLT, 'D'},
- {"F21", FP_REG(21), RFLT, 'D'},
- {"F22", FP_REG(22), RFLT, 'D'},
- {"F23", FP_REG(23), RFLT, 'D'},
- {"F24", FP_REG(24), RFLT, 'D'},
- {"F25", FP_REG(25), RFLT, 'D'},
- {"F26", FP_REG(26), RFLT, 'D'},
- {"F27", FP_REG(27), RFLT, 'D'},
- {"F28", FP_REG(28), RFLT, 'D'},
- {"F29", FP_REG(29), RFLT, 'D'},
- {"F30", FP_REG(30), RFLT, 'D'},
- {"F31", FP_REG(31), RFLT, 'D'},
- {"FPSCR", FP_REG(32)+4, RFLT, 'X'},
+ {"R2", REGOFF(r2), RINT, 'X'},
+ {"R3", REGOFF(r3), RINT, 'X'},
+ {"R4", REGOFF(r4), RINT, 'X'},
+ {"R5", REGOFF(r5), RINT, 'X'},
+ {"R6", REGOFF(r6), RINT, 'X'},
+ {"R7", REGOFF(r7), RINT, 'X'},
+ {"R8", REGOFF(r8), RINT, 'X'},
+ {"R9", REGOFF(r9), RINT, 'X'},
+ {"R10", REGOFF(r10), RINT, 'X'},
+ {"R11", REGOFF(r11), RINT, 'X'},
+ {"R12", REGOFF(r12), RINT, 'X'},
+ {"R13", REGOFF(r13), RINT, 'X'},
+ {"R14", REGOFF(r14), RINT, 'X'},
+ {"R15", REGOFF(r15), RINT, 'X'},
+ {"R16", REGOFF(r16), RINT, 'X'},
+ {"R17", REGOFF(r17), RINT, 'X'},
+ {"R18", REGOFF(r18), RINT, 'X'},
+ {"R19", REGOFF(r19), RINT, 'X'},
+ {"R20", REGOFF(r20), RINT, 'X'},
+ {"R21", REGOFF(r21), RINT, 'X'},
+ {"R22", REGOFF(r22), RINT, 'X'},
+ {"R23", REGOFF(r23), RINT, 'X'},
+ {"R24", REGOFF(r24), RINT, 'X'},
+ {"R25", REGOFF(r25), RINT, 'X'},
+ {"R26", REGOFF(r26), RINT, 'X'},
+ {"R27", REGOFF(r27), RINT, 'X'},
+ {"R28", REGOFF(r28), RINT, 'X'},
+ {"R29", REGOFF(r29), RINT, 'X'},
+ {"R30", REGOFF(r30), RINT, 'X'},
+ {"R31", REGOFF(r31), RINT, 'X'},
+ {"F0", FP_REG(0), RFLT, 'F'},
+ {"F1", FP_REG(1), RFLT, 'F'},
+ {"F2", FP_REG(2), RFLT, 'F'},
+ {"F3", FP_REG(3), RFLT, 'F'},
+ {"F4", FP_REG(4), RFLT, 'F'},
+ {"F5", FP_REG(5), RFLT, 'F'},
+ {"F6", FP_REG(6), RFLT, 'F'},
+ {"F7", FP_REG(7), RFLT, 'F'},
+ {"F8", FP_REG(8), RFLT, 'F'},
+ {"F9", FP_REG(9), RFLT, 'F'},
+ {"F10", FP_REG(10), RFLT, 'F'},
+ {"F11", FP_REG(11), RFLT, 'F'},
+ {"F12", FP_REG(12), RFLT, 'F'},
+ {"F13", FP_REG(13), RFLT, 'F'},
+ {"F14", FP_REG(14), RFLT, 'F'},
+ {"F15", FP_REG(15), RFLT, 'F'},
+ {"F16", FP_REG(16), RFLT, 'F'},
+ {"F17", FP_REG(17), RFLT, 'F'},
+ {"F18", FP_REG(18), RFLT, 'F'},
+ {"F19", FP_REG(19), RFLT, 'F'},
+ {"F20", FP_REG(20), RFLT, 'F'},
+ {"F21", FP_REG(21), RFLT, 'F'},
+ {"F22", FP_REG(22), RFLT, 'F'},
+ {"F23", FP_REG(23), RFLT, 'F'},
+ {"F24", FP_REG(24), RFLT, 'F'},
+ {"F25", FP_REG(25), RFLT, 'F'},
+ {"F26", FP_REG(26), RFLT, 'F'},
+ {"F27", FP_REG(27), RFLT, 'F'},
+ {"F28", FP_REG(28), RFLT, 'F'},
+ {"F29", FP_REG(29), RFLT, 'F'},
+ {"F30", FP_REG(30), RFLT, 'F'},
+ {"F31", FP_REG(31), RFLT, 'F'},
+ {"FPSCR", FP_REG(32)+4, RFLT, 'X'},
{ 0 }
};
@@ -104,16 +104,17 @@ Mach mpower =
"power",
MPOWER, /* machine type */
powerreglist, /* register set */
- REGSIZE, /* register set size in bytes */
- FPREGSIZE, /* floating point register size in bytes */
+ REGSIZE, /* number of bytes in register set */
+ FPREGSIZE, /* number of bytes in FP register set */
"PC", /* name of PC */
"SP", /* name of SP */
"LR", /* name of link register */
"setSB", /* static base register name */
0, /* value */
0x1000, /* page size */
- 0x20000000, /* kernel base */
- 0, /* kernel text mask */
+ 0x80000000ULL, /* kernel base */
+ 0xF0000000ULL, /* kernel text mask */
+ 0x7FFFFFFFULL, /* user stack top */
4, /* quantization of pc */
4, /* szaddr */
4, /* szreg */
diff --git a/utils/libmach/qdb.c b/utils/libmach/qdb.c
index 890408b1..36bc3436 100644
--- a/utils/libmach/qdb.c
+++ b/utils/libmach/qdb.c
@@ -3,15 +3,16 @@
#include "mach.h"
/*
- * PowerPC-specific debugger interface
+ * PowerPC-specific debugger interface,
+ * including 64-bit modes
* forsyth@terzarima.net
*/
static char *powerexcep(Map*, Rgetter);
-static int powerfoll(Map*, ulong, Rgetter, ulong*);
-static int powerinst(Map*, ulong, char, char*, int);
-static int powerinstlen(Map*, ulong);
-static int powerdas(Map*, ulong, char*, int);
+static int powerfoll(Map*, uvlong, Rgetter, uvlong*);
+static int powerinst(Map*, uvlong, char, char*, int);
+static int powerinstlen(Map*, uvlong);
+static int powerdas(Map*, uvlong, char*, int);
/*
* Machine description
@@ -21,8 +22,8 @@ Machdata powermach =
{0x07f, 0xe0, 0x00, 0x08}, /* breakpoint (tw 31,r0,r0) */
4, /* break point size */
- beswab, /* convert short to local byte order */
- beswal, /* convert long to local byte order */
+ beswab, /* short to local byte order */
+ beswal, /* long to local byte order */
beswav, /* vlong to local byte order */
risctrace, /* print C traceback */
riscframe, /* frame finder */
@@ -66,11 +67,11 @@ static char *excname[] =
"reserved 19",
"reserved 1A",
/* the following are made up on a program exception */
- "floating point exception", /* 1B: FPEXC */
- "illegal instruction", /* 1C */
- "privileged instruction", /* 1D */
- "trap", /* 1E */
- "illegal operation", /* 1F */
+ "floating point exception", /* FPEXC */
+ "illegal instruction",
+ "privileged instruction",
+ "trap",
+ "illegal operation",
"breakpoint", /* 20 */
};
@@ -112,11 +113,11 @@ typedef struct {
uchar bi; /* bits 11-15 */
uchar bo; /* bits 6-10 */
uchar crbd; /* bits 6-10 */
- /*union {*/
+ /* union { */
short d; /* bits 16-31 */
short simm;
ushort uimm;
- /*};*/
+ /*}; */
uchar fm; /* bits 7-14 */
uchar fra; /* bits 11-15 */
uchar frb; /* bits 16-20 */
@@ -128,13 +129,15 @@ typedef struct {
uchar lk; /* bit 31 */
uchar mb; /* bits 21-25 */
uchar me; /* bits 26-30 */
+ uchar xmbe; /* bits 26,21-25: mb[5] || mb[0:4], also xme */
+ uchar xsh; /* bits 30,16-20: sh[5] || sh[0:4] */
uchar nb; /* bits 16-20 */
uchar op; /* bits 0-5 */
uchar oe; /* bit 21 */
uchar ra; /* bits 11-15 */
uchar rb; /* bits 16-20 */
uchar rc; /* bit 31 */
- /* union {*/
+ /* union { */
uchar rs; /* bits 6-10 */
uchar rd;
/*};*/
@@ -143,11 +146,12 @@ typedef struct {
uchar to; /* bits 6-10 */
uchar imm; /* bits 16-19 */
ushort xo; /* bits 21-30, 22-30, 26-30, or 30 (beware) */
- long immediate;
+ uvlong imm64;
long w0;
long w1;
- ulong addr; /* pc of instruction */
+ uvlong addr; /* pc of instruction */
short target;
+ short m64; /* 64-bit mode */
char *curr; /* current fill level in output buffer */
char *end; /* end of buffer */
int size; /* number of longs in instr */
@@ -157,6 +161,8 @@ typedef struct {
#define IBF(v,a,b) (((ulong)(v)>>(32-(b)-1)) & ~(~0L<<(((b)-(a)+1))))
#define IB(v,b) IBF((v),(b),(b))
+#pragma varargck argpos bprint 2
+
static void
bprint(Instr *i, char *fmt, ...)
{
@@ -168,14 +174,15 @@ bprint(Instr *i, char *fmt, ...)
}
static int
-decode(ulong pc, Instr *i)
+decode(uvlong pc, Instr *i)
{
- long w;
+ ulong w;
if (get4(mymap, pc, &w) < 0) {
werrstr("can't read instruction: %r");
return -1;
}
+ i->m64 = asstype == APOWER64;
i->aa = IB(w, 30);
i->crba = IBF(w, 11, 15);
i->crbb = IBF(w, 16, 20);
@@ -188,8 +195,6 @@ decode(ulong pc, Instr *i)
i->bo = IBF(w, 6, 10);
i->crbd = IBF(w, 6, 10);
i->uimm = IBF(w, 16, 31); /* also d, simm */
- i->simm = i->uimm;
- i->d = i->uimm;
i->fm = IBF(w, 7, 14);
i->fra = IBF(w, 11, 15);
i->frb = IBF(w, 16, 20);
@@ -203,6 +208,7 @@ decode(ulong pc, Instr *i)
i->lk = IB(w, 31);
i->mb = IBF(w, 21, 25);
i->me = IBF(w, 26, 30);
+ i->xmbe = (IB(w,26)<<5) | i->mb;
i->nb = IBF(w, 16, 20);
i->op = IBF(w, 0, 5);
i->oe = IB(w, 21);
@@ -210,15 +216,21 @@ decode(ulong pc, Instr *i)
i->rb = IBF(w, 16, 20);
i->rc = IB(w, 31);
i->rs = IBF(w, 6, 10); /* also rd */
- i->rd = i->rs;
i->sh = IBF(w, 16, 20);
+ i->xsh = (IB(w, 30)<<5) | i->sh;
i->spr = IBF(w, 11, 20);
i->to = IBF(w, 6, 10);
i->imm = IBF(w, 16, 19);
i->xo = IBF(w, 21, 30); /* bits 21-30, 22-30, 26-30, or 30 (beware) */
- i->immediate = i->simm;
+ if(i->op == 58){ /* class of 64-bit loads */
+ i->xo = i->simm & 3;
+ i->simm &= ~3;
+ }
+ i->imm64 = i->simm;
if(i->op == 15)
- i->immediate <<= 16;
+ i->imm64 <<= 16;
+ else if(i->op == 25 || i->op == 27 || i->op == 29)
+ i->imm64 = (uvlong)(i->uimm<<16);
i->w0 = w;
i->target = -1;
i->addr = pc;
@@ -227,7 +239,7 @@ decode(ulong pc, Instr *i)
}
static int
-mkinstr(ulong pc, Instr *i)
+mkinstr(uvlong pc, Instr *i)
{
Instr x;
@@ -235,26 +247,15 @@ mkinstr(ulong pc, Instr *i)
return -1;
/*
* combine ADDIS/ORI (CAU/ORIL) into MOVW
+ * also ORIS/ORIL for unsigned in 64-bit mode
*/
- if (i->op == 15 && i->ra==0) {
+ if ((i->op == 15 || i->op == 25) && i->ra==0) {
if(decode(pc+4, &x) < 0)
return -1;
if (x.op == 24 && x.rs == x.ra && x.ra == i->rd) {
- i->immediate |= (x.immediate & 0xFFFF);
- i->w1 = x.w0;
- i->target = x.rd;
- i->size++;
- return 1;
- }
- }
- if (i->op == 15 && i->ra==REGSB && mach->sb) {
- if(decode(pc+4, &x) < 0)
- return -1;
- if (x.op >= 32 && x.op < 54 && i->rd == x.ra) {
- i->op = x.op;
- i->ra = REGSB;
- i->rs = i->rd = x.rd;
- i->immediate += x.simm;
+ i->imm64 |= (x.imm64 & 0xFFFF);
+ if(i->op != 15)
+ i->imm64 &= 0xFFFFFFFFUL;
i->w1 = x.w0;
i->target = x.rd;
i->size++;
@@ -267,20 +268,20 @@ mkinstr(ulong pc, Instr *i)
static int
plocal(Instr *i)
{
- int offset;
+ long offset;
Symbol s;
if (!findsym(i->addr, CTEXT, &s) || !findlocal(&s, FRAMENAME, &s))
return -1;
- offset = s.value - i->immediate;
+ offset = s.value - i->imm64;
if (offset > 0) {
if(getauto(&s, offset, CAUTO, &s)) {
- bprint(i, "%s+%d(SP)", s.name, s.value);
+ bprint(i, "%s+%lld(SP)", s.name, s.value);
return 1;
}
} else {
if (getauto(&s, -offset-4, CPARAM, &s)) {
- bprint(i, "%s+%d(FP)", s.name, -offset);
+ bprint(i, "%s+%ld(FP)", s.name, -offset);
return 1;
}
}
@@ -288,18 +289,17 @@ plocal(Instr *i)
}
static int
-pglobal(Instr *i, long off, int anyoff, char *reg)
+pglobal(Instr *i, uvlong off, int anyoff, char *reg)
{
Symbol s, s2;
- long off1;
+ uvlong off1;
if(findsym(off, CANY, &s) &&
- strcmp(s.name, ".string") != 0 &&
- (ulong)(off-s.value) < 4096 &&
+ s.value-off < 4096 &&
(s.class == CDATA || s.class == CTEXT)) {
if(off==s.value && s.name[0]=='$'){
off1 = 0;
- get4(mymap, s.value, &off1);
+ geta(mymap, s.value, &off1);
if(off1 && findsym(off1, CANY, &s2) && s2.value == off1){
bprint(i, "$%s%s", s2.name, reg);
return 1;
@@ -307,13 +307,13 @@ pglobal(Instr *i, long off, int anyoff, char *reg)
}
bprint(i, "%s", s.name);
if (s.value != off)
- bprint(i, "+%lux", off-s.value);
+ bprint(i, "+%llux", off-s.value);
bprint(i, reg);
return 1;
}
if(!anyoff)
return 0;
- bprint(i, "%lux%s", off, reg);
+ bprint(i, "%llux%s", off, reg);
return 1;
}
@@ -322,16 +322,12 @@ address(Instr *i)
{
if (i->ra == REGSP && plocal(i) >= 0)
return;
- if (i->ra == REGSB && mach->sb && pglobal(i, mach->sb+i->immediate, 0, "(SB)") > 0)
+ if (i->ra == REGSB && mach->sb && pglobal(i, mach->sb+i->imm64, 0, "(SB)") >= 0)
return;
- if(i->immediate < 0)
- bprint(i, "-%lx", -i->immediate);
- else
- bprint(i, "%lux", i->immediate);
- if (i->ra == REGSB && mach->sb)
- bprint(i, "(SB)");
+ if(i->simm < 0)
+ bprint(i, "-%x(R%d)", -i->simm, i->ra);
else
- bprint(i, "(R%d)", i->ra);
+ bprint(i, "%llux(R%d)", i->imm64, i->ra);
}
static char *tcrbits[] = {"LT", "GT", "EQ", "VS"};
@@ -362,12 +358,12 @@ branch(Opcode *o, Instr *i)
if(bo != 20) {
bi = i->bi&3;
sprint(buf, "B%s%%L", bo==12? tcrbits[bi]: fcrbits[bi]);
- format(buf, i, 0);
+ format(buf, i, nil);
bprint(i, "\t");
if(i->bi > 4)
bprint(i, "CR(%d),", i->bi/4);
} else
- format("BR%L\t", i, 0);
+ format("BR%L\t", i, nil);
if(i->op == 16)
format(0, i, "%J");
else if(i->op == 19 && i->xo == 528)
@@ -383,7 +379,7 @@ addi(Opcode *o, Instr *i)
{
if (i->op==14 && i->ra == 0)
format("MOVW", i, "%i,R%d");
- else if (i->ra == REGSP || i->ra == REGSB) {
+ else if (i->ra == REGSB) {
bprint(i, "MOVW\t$");
address(i);
bprint(i, ",R%d", i->rd);
@@ -403,23 +399,19 @@ addis(Opcode *o, Instr *i)
{
long v;
- v = i->immediate;
- if (i->op==15 && i->ra == 0) {
- bprint(i, "MOVW\t$");
- pglobal(i, i->immediate, 1, "");
- bprint(i, ",R%d", i->rd);
- }
- else if (i->op==15 && i->ra == REGSB && mach->sb) {
+ v = i->imm64;
+ if (i->op==15 && i->ra == 0)
+ bprint(i, "MOVW\t$%lux,R%d", v, i->rd);
+ else if (i->op==15 && i->ra == REGSB) {
bprint(i, "MOVW\t$");
address(i);
bprint(i, ",R%d", i->rd);
-/* how about auto/param addresses? */
} else if(i->op==15 && v < 0) {
- bprint(i, "SUB\t$%d,R%d", -v, i->ra);
+ bprint(i, "SUB\t$%ld,R%d", -v, i->ra);
if(i->rd != i->ra)
bprint(i, ",R%d", i->rd);
} else {
- format(o->mnemonic, i, 0);
+ format(o->mnemonic, i, nil);
bprint(i, "\t$%ld,R%d", v, i->ra);
if(i->rd != i->ra)
bprint(i, ",R%d", i->rd);
@@ -509,7 +501,8 @@ dcb(Opcode *o, Instr *i)
static void
lw(Opcode *o, Instr *i, char r)
{
- bprint(i, "%s\t", o->mnemonic);
+ format(o->mnemonic, i, nil);
+ bprint(i, "\t");
address(i);
bprint(i, ",%c%d", r, i->rd);
}
@@ -530,29 +523,28 @@ static void
sw(Opcode *o, Instr *i, char r)
{
int offset;
- char *m;
Symbol s;
- m = o->mnemonic;
- if (i->ra == REGSP) {
+ if (i->rs == REGSP) {
if (findsym(i->addr, CTEXT, &s) && findlocal(&s, FRAMENAME, &s)) {
- offset = s.value-i->immediate;
+ offset = s.value-i->imm64;
if (offset > 0 && getauto(&s, offset, CAUTO, &s)) {
- bprint(i, "%s\t%c%d,%s-%d(SP)", m, r, i->rs,
- s.name, offset);
+ format(o->mnemonic, i, nil);
+ bprint(i, "\t%c%d,%s-%d(SP)", r, i->rd, s.name, offset);
return;
}
}
}
- if (i->ra == REGSP || i->ra == REGSB && mach->sb) {
- bprint(i, "%s\t%c%d,", m, r, i->rs);
+ if (i->rs == REGSB && mach->sb) {
+ format(o->mnemonic, i, nil);
+ bprint(i, "\t%c%d,", r, i->rd);
address(i);
return;
}
if (r == 'F')
- format(m, i, "F%d,%l");
+ format(o->mnemonic, i, "F%d,%l");
else
- format(m, i, o->ken);
+ format(o->mnemonic, i, o->ken);
}
static void
@@ -599,7 +591,8 @@ add(Opcode *o, Instr *i)
static void
sub(Opcode *o, Instr *i)
{
- format(o->mnemonic, i, 0);
+ format(o->mnemonic, i, nil);
+ bprint(i, "\t");
if(i->op == 31) {
bprint(i, "\tR%d,R%d", i->ra, i->rb); /* subtract Ra from Rb */
if(i->rd != i->rb)
@@ -609,9 +602,9 @@ sub(Opcode *o, Instr *i)
}
static void
-qmuldiv(Opcode *o, Instr *i)
+qdiv(Opcode *o, Instr *i)
{
- format(o->mnemonic, i, 0);
+ format(o->mnemonic, i, nil);
if(i->op == 31)
bprint(i, "\tR%d,R%d", i->rb, i->ra);
else
@@ -646,7 +639,7 @@ or(Opcode *o, Instr *i)
if (i->op == 31) {
/* Rb,Rs,Ra */
if (i->rs == 0 && i->ra == 0 && i->rb == 0)
- format("NOP", i, 0);
+ format("NOP", i, nil);
else if (i->rs == i->rb)
format("MOVW", i, "R%b,R%a");
else
@@ -658,7 +651,7 @@ or(Opcode *o, Instr *i)
static void
shifted(Opcode *o, Instr *i)
{
- format(o->mnemonic, i, 0);
+ format(o->mnemonic, i, nil);
bprint(i, "\t$%lux,", (ulong)i->uimm<<16);
if (i->rs == i->ra)
bprint(i, "R%d", i->ra);
@@ -679,7 +672,7 @@ static char ir2[] = "R%a,R%d"; /* reverse of IBM order */
static char ir3[] = "R%b,R%a,R%d";
static char ir3r[] = "R%a,R%b,R%d";
static char il3[] = "R%b,R%s,R%a";
-static char il2u[] = "%I,R%s,R%a";
+static char il2u[] = "%I,R%a,R%d";
static char il3s[] = "$%k,R%s,R%a";
static char il2[] = "R%s,R%a";
static char icmp3[] = "R%a,R%b,%D";
@@ -694,12 +687,16 @@ static char ldop[] = "%l,R%d";
static char stop[] = "R%d,%l";
static char fldop[] = "%l,F%d";
static char fstop[] = "F%d,%l";
+static char rldc[] = "R%b,R%s,$%E,R%a";
static char rlim[] = "R%b,R%s,$%z,R%a";
static char rlimi[] = "$%k,R%s,$%z,R%a";
+static char rldi[] = "$%e,R%s,$%E,R%a";
#define OEM IBF(~0,22,30)
#define FP4 IBF(~0,26,30)
-#define ALL ((ushort)~0)
+#define ALL (~0)
+#define RLDC 0xF
+#define RLDI 0xE
/*
notes:
10-26: crfD = rD>>2; rD&3 mbz
@@ -707,8 +704,6 @@ notes:
*/
static Opcode opcodes[] = {
- {31, 360, OEM, "ABS%V%C", 0, ir2}, /* POWER */
-
{31, 266, OEM, "ADD%V%C", add, ir3},
{31, 10, OEM, "ADDC%V%C", add, ir3},
{31, 138, OEM, "ADDE%V%C", add, ir3},
@@ -721,22 +716,21 @@ static Opcode opcodes[] = {
{31, 28, ALL, "AND%C", and, il3},
{31, 60, ALL, "ANDN%C", and, il3},
- {28, 0, 0, "ANDCC", andi, il2u},
- {29, 0, 0, "ANDCC", shifted, 0},
+ {28, 0, 0, "ANDCC", andi, il2u},
+ {29, 0, 0, "ANDCC", shifted, 0},
{18, 0, 0, "B%L", gencc, "%j"},
{16, 0, 0, "BC%L", branch, "%d,%a,%J"},
{19, 528, ALL, "BC%L", branch, "%d,%a,(CTR)"},
{19, 16, ALL, "BC%L", branch, "%d,%a,(LR)"},
- {31, 531, ALL, "CLCS", gen, ir2}, /* POWER */
-
{31, 0, ALL, "CMP", 0, icmp3},
{11, 0, 0, "CMP", 0, "R%a,%i,%D"},
{31, 32, ALL, "CMPU", 0, icmp3},
{10, 0, 0, "CMPU", 0, "R%a,%I,%D"},
- {31, 26, ALL, "CNTLZ%C", gencc, ir2},
+ {31, 58, ALL, "CNTLZD%C", gencc, ir2}, /* 64 */
+ {31, 26, ALL, "CNTLZ%W%C", gencc, ir2},
{19, 257, ALL, "CRAND", gen, cr3op},
{19, 129, ALL, "CRANDN", gen, cr3op},
@@ -753,14 +747,13 @@ static Opcode opcodes[] = {
{31, 278, ALL, "DCBT", dcb, 0},
{31, 246, ALL, "DCBTST", dcb, 0},
{31, 1014, ALL, "DCBZ", dcb, 0},
+ {31, 454, ALL, "DCCCI", dcb, 0},
+ {31, 966, ALL, "ICCCI", dcb, 0},
- {31, 331, OEM, "DIV%V%C", qmuldiv, ir3}, /* POWER */
- {31, 363, OEM, "DIVS%V%C", qmuldiv, ir3}, /* POWER */
- {31, 491, OEM, "DIVW%V%C", qmuldiv, ir3},
- {31, 459, OEM, "DIVWU%V%C", qmuldiv, ir3},
-
- {31, 264, OEM, "DOZ%V%C", gencc, ir3r}, /* POWER */
- {9, 0, 0, "DOZ", gen, ir2i}, /* POWER */
+ {31, 489, OEM, "DIVD%V%C", qdiv, ir3}, /* 64 */
+ {31, 457, OEM, "DIVDU%V%C", qdiv, ir3}, /* 64 */
+ {31, 491, OEM, "DIVW%V%C", qdiv, ir3},
+ {31, 459, OEM, "DIVWU%V%C", qdiv, ir3},
{31, 310, ALL, "ECIWX", ldx, 0},
{31, 438, ALL, "ECOWX", stx, 0},
@@ -770,12 +763,16 @@ static Opcode opcodes[] = {
{31, 954, ALL, "EXTSB%C", gencc, il2},
{31, 922, ALL, "EXTSH%C", gencc, il2},
+ {31, 986, ALL, "EXTSW%C", gencc, il2}, /* 64 */
{63, 264, ALL, "FABS%C", gencc, fp2},
{63, 21, ALL, "FADD%C", gencc, fp3},
{59, 21, ALL, "FADDS%C", gencc, fp3},
{63, 32, ALL, "FCMPO", gen, fpcmp},
{63, 0, ALL, "FCMPU", gen, fpcmp},
+ {63, 846, ALL, "FCFID%C", gencc, fp2}, /* 64 */
+ {63, 814, ALL, "FCTID%C", gencc, fp2}, /* 64 */
+ {63, 815, ALL, "FCTIDZ%C", gencc, fp2}, /* 64 */
{63, 14, ALL, "FCTIW%C", gencc, fp2},
{63, 15, ALL, "FCTIWZ%C", gencc, fp2},
{63, 18, ALL, "FDIV%C", gencc, fp3},
@@ -793,11 +790,16 @@ static Opcode opcodes[] = {
{59, 31, FP4, "FNMADDS%C", gencc, fp4},
{63, 30, FP4, "FNMSUB%C", gencc, fp4},
{59, 30, FP4, "FNMSUBS%C", gencc, fp4},
+ {59, 24, ALL, "FRES%C", gencc, fp2}, /* optional */
{63, 12, ALL, "FRSP%C", gencc, fp2},
+ {63, 26, ALL, "FRSQRTE%C", gencc, fp2}, /* optional */
+ {63, 23, FP4, "FSEL%CC", gencc, fp4}, /* optional */
+ {63, 22, ALL, "FSQRT%C", gencc, fp2}, /* optional */
+ {59, 22, ALL, "FSQRTS%C", gencc, fp2}, /* optional */
{63, 20, FP4, "FSUB%C", gencc, fp3},
{59, 20, FP4, "FSUBS%C", gencc, fp3},
- {31, 982, ALL, "ICBI", dcb, 0},
+ {31, 982, ALL, "ICBI", dcb, 0}, /* optional */
{19, 150, ALL, "ISYNC", gen, 0},
{34, 0, 0, "MOVBZ", load, ldop},
@@ -822,18 +824,26 @@ static Opcode opcodes[] = {
{31, 311, ALL, "MOVHZU", ldx, 0},
{31, 279, ALL, "MOVHZ", ldx, 0},
{46, 0, 0, "MOVMW", load, ldop},
- {31, 277, ALL, "LSCBX%C", ldx, 0}, /* POWER */
{31, 597, ALL, "LSW", gen, "(R%a),$%n,R%d"},
{31, 533, ALL, "LSW", ldx, 0},
{31, 20, ALL, "LWAR", ldx, 0},
+ {31, 84, ALL, "LWARD", ldx, 0}, /* 64 */
+
+ {58, 0, ALL, "MOVD", load, ldop}, /* 64 */
+ {58, 1, ALL, "MOVDU", load, ldop}, /* 64 */
+ {31, 53, ALL, "MOVDU", ldx, 0}, /* 64 */
+ {31, 21, ALL, "MOVD", ldx, 0}, /* 64 */
+
{31, 534, ALL, "MOVWBR", ldx, 0},
- {32, 0, 0, "MOVW", load, ldop},
- {33, 0, 0, "MOVWU", load, ldop},
- {31, 55, ALL, "MOVWU", ldx, 0},
- {31, 23, ALL, "MOVW", ldx, 0},
- {31, 29, ALL, "MASKG%C", gencc, "R%s:R%b,R%d"}, /* POWER */
- {31, 541, ALL, "MASKIR%C", gencc, "R%s,R%b,R%a"}, /* POWER */
+ {58, 2, ALL, "MOVW", load, ldop}, /* 64 (lwa) */
+ {31, 373, ALL, "MOVWU", ldx, 0}, /* 64 */
+ {31, 341, ALL, "MOVW", ldx, 0}, /* 64 */
+
+ {32, 0, 0, "MOVW%Z", load, ldop},
+ {33, 0, 0, "MOVW%ZU", load, ldop},
+ {31, 55, ALL, "MOVW%ZU", ldx, 0},
+ {31, 23, ALL, "MOVW%Z", ldx, 0},
{19, 0, ALL, "MOVFL", gen, "%S,%D"},
{63, 64, ALL, "MOVCRFS", gen, "%S,%D"},
@@ -845,67 +855,63 @@ static Opcode opcodes[] = {
{31, 339, ALL, "MOVW", gen, "%P,R%d"},
{31, 595, ALL, "MOVW", gen, "SEG(%a),R%d"},
{31, 659, ALL, "MOVW", gen, "SEG(R%b),R%d"},
+ {31, 323, ALL, "MOVW", gen, "DCR(%Q),R%d"},
+ {31, 451, ALL, "MOVW", gen, "R%s,DCR(%Q)"},
{31, 144, ALL, "MOVFL", gen, "R%s,%m,CR"},
{63, 70, ALL, "MTFSB0%C", gencc, "%D"},
{63, 38, ALL, "MTFSB1%C", gencc, "%D"},
{63, 711, ALL, "MOVFL%C", gencc, "F%b,%M,FPSCR"}, /* mtfsf */
{63, 134, ALL, "MOVFL%C", gencc, "%K,%D"},
{31, 146, ALL, "MOVW", gen, "R%s,MSR"},
+ {31, 178, ALL, "MOVD", gen, "R%s,MSR"},
{31, 467, ALL, "MOVW", gen, "R%s,%P"},
{31, 210, ALL, "MOVW", gen, "R%s,SEG(%a)"},
{31, 242, ALL, "MOVW", gen, "R%s,SEG(R%b)"},
- {31, 107, OEM, "MUL%V%C", gencc, ir3}, /* POWER */
- {31, 75, ALL, "MULHW%C", gencc, ir3}, /* POWER */
- {31, 11, ALL, "MULHWU%C", gencc, ir3}, /* POWER */
+ {31, 73, ALL, "MULHD%C", gencc, ir3},
+ {31, 9, ALL, "MULHDU%C", gencc, ir3},
+ {31, 233, OEM, "MULLD%V%C", gencc, ir3},
+ {31, 75, ALL, "MULHW%C", gencc, ir3},
+ {31, 11, ALL, "MULHWU%C", gencc, ir3},
{31, 235, OEM, "MULLW%V%C", gencc, ir3},
- {7, 0, 0, "MULLW", qmuldiv, "%i,R%a,R%d"},
- {31, 488, OEM, "NABS%V%C", neg, ir2}, /* POWER */
+ {7, 0, 0, "MULLW", qdiv, "%i,R%a,R%d"},
{31, 476, ALL, "NAND%C", gencc, il3},
{31, 104, OEM, "NEG%V%C", neg, ir2},
{31, 124, ALL, "NOR%C", gencc, il3},
- {31, 444, ALL, "OR%C", or, il3},
+ {31, 444, ALL, "OR%C", or, il3},
{31, 412, ALL, "ORN%C", or, il3},
{24, 0, 0, "OR", and, "%I,R%d,R%a"},
{25, 0, 0, "OR", shifted, 0},
{19, 50, ALL, "RFI", gen, 0},
+ {19, 51, ALL, "RFCI", gen, 0},
+
+ {30, 8, RLDC, "RLDCL%C", gencc, rldc}, /* 64 */
+ {30, 9, RLDC, "RLDCR%C", gencc, rldc}, /* 64 */
+ {30, 0, RLDI, "RLDCL%C", gencc, rldi}, /* 64 */
+ {30, 1<<1, RLDI, "RLDCR%C", gencc, rldi}, /* 64 */
+ {30, 2<<1, RLDI, "RLDC%C", gencc, rldi}, /* 64 */
+ {30, 3<<1, RLDI, "RLDMI%C", gencc, rldi}, /* 64 */
- {22, 0, 0, "RLMI%C", gencc, rlim}, /* POWER */
{20, 0, 0, "RLWMI%C", gencc, rlimi},
{21, 0, 0, "RLWNM%C", gencc, rlimi},
{23, 0, 0, "RLWNM%C", gencc, rlim},
- {31, 537, ALL, "RRIB%C", gencc, il3}, /* POWER */
-
{17, 1, ALL, "SYSCALL", gen, 0},
- {31, 153, ALL, "SLE%C", shift, il3}, /* POWER */
- {31, 217, ALL, "SLEQ%C", shift, il3}, /* POWER */
- {31, 184, ALL, "SLQ%C", shifti, il3s}, /* POWER */
- {31, 248, ALL, "SLLQ%C", shifti, il3s}, /* POWER */
- {31, 216, ALL, "SLLQ%C", shift, il3}, /* POWER */
- {31, 152, ALL, "SLQ%C", shift, il3}, /* POWER */
-
+ {31, 27, ALL, "SLD%C", shift, il3}, /* 64 */
{31, 24, ALL, "SLW%C", shift, il3},
- {31, 920, ALL, "SRAQ%C", shift, il3}, /* POWER */
- {31, 952, ALL, "SRAQ%C", shifti, il3s}, /* POWER */
-
+ {31, 794, ALL, "SRAD%C", shift, il3}, /* 64 */
+ {31, (413<<1)|0, ALL, "SRAD%C", shifti, il3s}, /* 64 */
+ {31, (413<<1)|1, ALL, "SRAD%C", shifti, il3s}, /* 64 */
{31, 792, ALL, "SRAW%C", shift, il3},
{31, 824, ALL, "SRAW%C", shifti, il3s},
- {31, 665, ALL, "SRE%C", shift, il3}, /* POWER */
- {31, 921, ALL, "SREA%C", shift, il3}, /* POWER */
- {31, 729, ALL, "SREQ%C", shift, il3}, /* POWER */
- {31, 696, ALL, "SRQ%C", shifti, il3s}, /* POWER */
- {31, 760, ALL, "SRLQ%C", shifti, il3s}, /* POWER */
- {31, 728, ALL, "SRLQ%C", shift, il3}, /* POWER */
- {31, 664, ALL, "SRQ%C", shift, il3}, /* POWER */
-
+ {31, 539, ALL, "SRD%C", shift, il3}, /* 64 */
{31, 536, ALL, "SRW%C", shift, il3},
{38, 0, 0, "MOVB", store, stop},
@@ -931,10 +937,22 @@ static Opcode opcodes[] = {
{36, 0, 0, "MOVW", store, stop},
{31, 662, ALL, "MOVWBR", stx, 0},
{31, 150, ALL, "STWCCC", stx, 0},
+ {31, 214, ALL, "STDCCC", stx, 0}, /* 64 */
{37, 0, 0, "MOVWU", store, stop},
{31, 183, ALL, "MOVWU", stx, 0},
{31, 151, ALL, "MOVW", stx, 0},
+ {62, 0, 0, "MOVD%U", store, stop}, /* 64 */
+ {31, 149, ALL, "MOVD", stx, 0,}, /* 64 */
+ {31, 181, ALL, "MOVDU", stx, 0}, /* 64 */
+
+ {31, 498, ALL, "SLBIA", gen, 0}, /* 64 */
+ {31, 434, ALL, "SLBIE", gen, "R%b"}, /* 64 */
+ {31, 466, ALL, "SLBIEX", gen, "R%b"}, /* 64 */
+ {31, 915, ALL, "SLBMFEE", gen, "R%b,R%d"}, /* 64 */
+ {31, 851, ALL, "SLBMFEV", gen, "R%b,R%d"}, /* 64 */
+ {31, 402, ALL, "SLBMTE", gen, "R%s,R%b"}, /* 64 */
+
{31, 40, OEM, "SUB%V%C", sub, ir3},
{31, 8, OEM, "SUBC%V%C", sub, ir3},
{31, 136, OEM, "SUBE%V%C", sub, ir3},
@@ -942,11 +960,15 @@ static Opcode opcodes[] = {
{31, 232, OEM, "SUBME%V%C", sub, ir2},
{31, 200, OEM, "SUBZE%V%C", sub, ir2},
- {31, 598, ALL, "SYNC", gen, 0},
- {31, 306, ALL, "TLBIE", gen, "R%b"},
- {31, 370, ALL, "TLBIA", gen, 0},
- {31, 1010, ALL, "TLBLI", gen, "R%b"},
- {31, 978, ALL, "TLBLD", gen, "R%b"},
+ {31, 598, ALL, "SYNC", gen, 0}, /* TO DO: there's a parameter buried in there */
+ {2, 0, 0, "TD", gen, "%d,R%a,%i"}, /* 64 */
+ {31, 370, ALL, "TLBIA", gen, 0}, /* optional */
+ {31, 306, ALL, "TLBIE", gen, "R%b"}, /* optional */
+ {31, 274, ALL, "TLBIEL", gen, "R%b"}, /* optional */
+ {31, 1010, ALL, "TLBLI", gen, "R%b"}, /* optional */
+ {31, 978, ALL, "TLBLD", gen, "R%b"}, /* optional */
+ {31, 566, ALL, "TLBSYNC", gen, 0}, /* optional */
+ {31, 68, ALL, "TD", gen, "%d,R%a,R%b"}, /* 64 */
{31, 4, ALL, "TW", gen, "%d,R%a,R%b"},
{3, 0, 0, "TW", gen, "%d,R%a,%i"},
@@ -1013,11 +1035,31 @@ static Spr sprname[] = {
{0,0},
};
+static int
+shmask(uvlong *m)
+{
+ int i;
+
+ for(i=0; i<63; i++)
+ if(*m & ((uvlong)1<<i))
+ break;
+ if(i > 63)
+ return 0;
+ if(*m & ~((uvlong)1<<i)){ /* more than one bit: do multiples of bytes */
+ i = (i/8)*8;
+ if(i == 0)
+ return 0;
+ }
+ *m >>= i;
+ return i;
+}
+
static void
format(char *mnemonic, Instr *i, char *f)
{
int n, s;
ulong mask;
+ uvlong vmask;
if (mnemonic)
format(0, i, mnemonic);
@@ -1031,15 +1073,6 @@ format(char *mnemonic, Instr *i, char *f)
continue;
}
switch (*++f) {
- case 'V':
- if(i->oe)
- bprint(i, "V");
- break;
-
- case 'C':
- if(i->rc)
- bprint(i, "CC");
- break;
case 'a':
bprint(i, "%d", i->ra);
@@ -1058,13 +1091,9 @@ format(char *mnemonic, Instr *i, char *f)
bprint(i, "%d", i->rd);
break;
- case 'S':
- if(i->ra & 3)
- bprint(i, "CR(INVAL:%d)", i->ra);
- else if(i->op == 63)
- bprint(i, "FPSCR(%d)", i->crfs);
- else
- bprint(i, "CR(%d)", i->crfs);
+ case 'C':
+ if(i->rc)
+ bprint(i, "CC");
break;
case 'D':
@@ -1076,20 +1105,83 @@ format(char *mnemonic, Instr *i, char *f)
bprint(i, "CR(%d)", i->crfd);
break;
- case 'l':
- address(i);
+ case 'e':
+ bprint(i, "%d", i->xsh);
+ break;
+
+ case 'E':
+ switch(IBF(i->w0,27,30)){ /* low bit is top bit of shift in rldiX cases */
+ case 8: i->mb = i->xmbe; i->me = 63; break; /* rldcl */
+ case 9: i->mb = 0; i->me = i->xmbe; break; /* rldcr */
+ case 4: case 5:
+ i->mb = i->xmbe; i->me = 63-i->xsh; break; /* rldic */
+ case 0: case 1:
+ i->mb = i->xmbe; i->me = 63; break; /* rldicl */
+ case 2: case 3:
+ i->mb = 0; i->me = i->xmbe; break; /* rldicr */
+ case 6: case 7:
+ i->mb = i->xmbe; i->me = 63-i->xsh; break; /* rldimi */
+ }
+ vmask = (~(uvlong)0>>i->mb) & (~(uvlong)0<<(63-i->me));
+ s = shmask(&vmask);
+ if(s)
+ bprint(i, "(%llux<<%d)", vmask, s);
+ else
+ bprint(i, "%llux", vmask);
break;
case 'i':
- bprint(i, "$%ld", i->simm);
+ bprint(i, "$%d", i->simm);
break;
case 'I':
- bprint(i, "$%lx", i->uimm);
+ bprint(i, "$%ux", i->uimm);
break;
- case 'w':
- bprint(i, "[%lux]", i->w0);
+ case 'j':
+ if(i->aa)
+ pglobal(i, i->li, 1, "(SB)");
+ else
+ pglobal(i, i->addr+i->li, 1, "");
+ break;
+
+ case 'J':
+ if(i->aa)
+ pglobal(i, i->bd, 1, "(SB)");
+ else
+ pglobal(i, i->addr+i->bd, 1, "");
+ break;
+
+ case 'k':
+ bprint(i, "%d", i->sh);
+ break;
+
+ case 'K':
+ bprint(i, "$%x", i->imm);
+ break;
+
+ case 'L':
+ if(i->lk)
+ bprint(i, "L");
+ break;
+
+ case 'l':
+ if(i->simm < 0)
+ bprint(i, "-%x(R%d)", -i->simm, i->ra);
+ else
+ bprint(i, "%x(R%d)", i->simm, i->ra);
+ break;
+
+ case 'm':
+ bprint(i, "%ux", i->crm);
+ break;
+
+ case 'M':
+ bprint(i, "%ux", i->fm);
+ break;
+
+ case 'n':
+ bprint(i, "%d", i->nb==0? 32: i->nb); /* eg, pg 10-103 */
break;
case 'P':
@@ -1098,7 +1190,7 @@ format(char *mnemonic, Instr *i, char *f)
if(sprname[s].n == n)
break;
if(sprname[s].name) {
- if(n < 10)
+ if(s < 10)
bprint(i, sprname[s].name);
else
bprint(i, "SPR(%s)", sprname[s].name);
@@ -1106,51 +1198,50 @@ format(char *mnemonic, Instr *i, char *f)
bprint(i, "SPR(%d)", n);
break;
- case 'n':
- bprint(i, "%d", i->nb==0? 32: i->nb); /* eg, pg 10-103 */
- break;
-
- case 'm':
- bprint(i, "%lx", i->crm);
+ case 'Q':
+ n = ((i->spr&0x1f)<<5)|((i->spr>>5)&0x1f);
+ bprint(i, "%d", n);
break;
- case 'M':
- bprint(i, "%lx", i->fm);
+ case 'S':
+ if(i->ra & 3)
+ bprint(i, "CR(INVAL:%d)", i->ra);
+ else if(i->op == 63)
+ bprint(i, "FPSCR(%d)", i->crfs);
+ else
+ bprint(i, "CR(%d)", i->crfs);
break;
- case 'z':
- if(i->mb <= i->me)
- mask = ((ulong)~0L>>i->mb) & (~0L<<(31-i->me));
- else
- mask = ~(((ulong)~0L>>(i->me+1)) & (~0L<<(31-(i->mb-1))));
- bprint(i, "%lux", mask);
+ case 'U':
+ if(i->rc)
+ bprint(i, "U");
break;
- case 'k':
- bprint(i, "%d", i->sh);
+ case 'V':
+ if(i->oe)
+ bprint(i, "V");
break;
- case 'K':
- bprint(i, "$%x", i->imm);
+ case 'w':
+ bprint(i, "[%lux]", i->w0);
break;
- case 'L':
- if(i->lk)
- bprint(i, "L");
+ case 'W':
+ if(i->m64)
+ bprint(i, "W");
break;
- case 'j':
- if(i->aa)
- pglobal(i, i->li, 1, "(SB)");
- else
- pglobal(i, i->addr+i->li, 1, "");
+ case 'Z':
+ if(i->m64)
+ bprint(i, "Z");
break;
- case 'J':
- if(i->aa)
- pglobal(i, i->bd, 1, "(SB)");
+ case 'z':
+ if(i->mb <= i->me)
+ mask = ((ulong)~0L>>i->mb) & (~0L<<(31-i->me));
else
- pglobal(i, i->addr+i->bd, 1, "");
+ mask = ~(((ulong)~0L>>(i->me+1)) & (~0L<<(31-(i->mb-1))));
+ bprint(i, "%lux", mask);
break;
case '\0':
@@ -1165,7 +1256,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;
Opcode *o;
@@ -1189,14 +1280,14 @@ printins(Map *map, ulong pc, char *buf, int n)
}
static int
-powerinst(Map *map, ulong pc, char modifier, char *buf, int n)
+powerinst(Map *map, uvlong pc, char modifier, char *buf, int n)
{
USED(modifier);
return printins(map, pc, buf, n);
}
static int
-powerdas(Map *map, ulong pc, char *buf, int n)
+powerdas(Map *map, uvlong pc, char *buf, int n)
{
Instr instr;
@@ -1217,7 +1308,7 @@ powerdas(Map *map, ulong pc, char *buf, int n)
}
static int
-powerinstlen(Map *map, ulong pc)
+powerinstlen(Map *map, uvlong pc)
{
Instr i;
@@ -1228,7 +1319,7 @@ powerinstlen(Map *map, ulong pc)
}
static int
-powerfoll(Map *map, ulong pc, Rgetter rget, ulong *foll)
+powerfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
{
char *reg;
Instr i;
diff --git a/utils/libmach/qobj.c b/utils/libmach/qobj.c
index 5decad08..e5a2222b 100644
--- a/utils/libmach/qobj.c
+++ b/utils/libmach/qobj.c
@@ -4,6 +4,7 @@
*/
#include <lib9.h>
#include <bio.h>
+#include <mach.h>
#include "qc/q.out.h"
#include "obj.h"
@@ -21,25 +22,33 @@ static void skip(Biobuf*, int);
int
_isq(char *s)
{
- return (s[0]&0377) == ANAME /* ANAME */
- && s[1] == D_FILE /* type */
- && s[2] == 1 /* sym */
- && s[3] == '<'; /* name of file */
+ return (s[0]&0377) == ANAME /* ANAME */
+ && (s[1]&0377) == ANAME>>8
+ && s[2] == D_FILE /* type */
+ && s[3] == 1 /* sym */
+ && s[4] == '<'; /* name of file */
}
int
_readq(Biobuf *bp, Prog *p)
{
- int as, n;
+ int as, n, c;
Addr a;
- as = Bgetc(bp); /* as */
+ as = Bgetc(bp); /* as(low) */
if(as < 0)
return 0;
+ c = Bgetc(bp); /* as(high) */
+ if(c < 0)
+ return 0;
+ as |= ((c & 0xff) << 8);
p->kind = aNone;
+ p->sig = 0;
if(as == ANAME || as == ASIGNAME){
- if(as == ASIGNAME)
- skip(bp, 4); /* signature */
+ if(as == ASIGNAME){
+ Bread(bp, &p->sig, 4);
+ p->sig = beswal(p->sig);
+ }
p->kind = aName;
p->type = type2char(Bgetc(bp)); /* type */
p->sym = Bgetc(bp); /* sym */
@@ -93,6 +102,7 @@ addr(Biobuf *bp)
break;
case D_SPR:
case D_OREG:
+ case D_DCR:
case D_CONST:
case D_BRANCH:
off = Bgetc(bp);
diff --git a/utils/libmach/swap.c b/utils/libmach/swap.c
index 3ca9cf27..63f76293 100644
--- a/utils/libmach/swap.c
+++ b/utils/libmach/swap.c
@@ -1,4 +1,6 @@
#include <lib9.h>
+#include <bio.h>
+#include "mach.h"
/*
* big-endian short
@@ -15,8 +17,8 @@ beswab(ushort s)
/*
* big-endian long
*/
-long
-beswal(long l)
+ulong
+beswal(ulong l)
{
uchar *p;
@@ -27,16 +29,16 @@ beswal(long l)
/*
* big-endian vlong
*/
-vlong
-beswav(vlong v)
+uvlong
+beswav(uvlong v)
{
uchar *p;
p = (uchar*)&v;
- return ((vlong)p[0]<<56) | ((vlong)p[1]<<48) | ((vlong)p[2]<<40)
- | ((vlong)p[3]<<32) | ((vlong)p[4]<<24)
- | ((vlong)p[5]<<16) | ((vlong)p[6]<<8)
- | (vlong)p[7];
+ return ((uvlong)p[0]<<56) | ((uvlong)p[1]<<48) | ((uvlong)p[2]<<40)
+ | ((uvlong)p[3]<<32) | ((uvlong)p[4]<<24)
+ | ((uvlong)p[5]<<16) | ((uvlong)p[6]<<8)
+ | (uvlong)p[7];
}
/*
@@ -54,8 +56,8 @@ leswab(ushort s)
/*
* little-endian long
*/
-long
-leswal(long l)
+ulong
+leswal(ulong l)
{
uchar *p;
@@ -66,14 +68,14 @@ leswal(long l)
/*
* little-endian vlong
*/
-vlong
-leswav(vlong v)
+uvlong
+leswav(uvlong v)
{
uchar *p;
p = (uchar*)&v;
- return ((vlong)p[7]<<56) | ((vlong)p[6]<<48) | ((vlong)p[5]<<40)
- | ((vlong)p[4]<<32) | ((vlong)p[3]<<24)
- | ((vlong)p[2]<<16) | ((vlong)p[1]<<8)
- | (vlong)p[0];
+ return ((uvlong)p[7]<<56) | ((uvlong)p[6]<<48) | ((uvlong)p[5]<<40)
+ | ((uvlong)p[4]<<32) | ((uvlong)p[3]<<24)
+ | ((uvlong)p[2]<<16) | ((uvlong)p[1]<<8)
+ | (uvlong)p[0];
}
diff --git a/utils/libmach/sym.c b/utils/libmach/sym.c
index 476e5e3d..751d933d 100644
--- a/utils/libmach/sym.c
+++ b/utils/libmach/sym.c
@@ -8,7 +8,6 @@
typedef struct txtsym Txtsym;
typedef struct file File;
typedef struct hist Hist;
-typedef struct pcl Pcl;
struct txtsym { /* Text Symbol table */
int n; /* number of local vars */
@@ -16,27 +15,20 @@ struct txtsym { /* Text Symbol table */
Sym *sym; /* function symbol entry */
};
-struct hist { /* Stack of include files & #line directives */
+struct hist { /* Stack of include files & #line directives */
char *name; /* Assumes names Null terminated in file */
long line; /* line # where it was included */
long offset; /* line # of #line directive */
};
-struct pcl {
- uchar *pcline; /* start of pcline data for this file */
- long pc; /* starting pc for pcline crunch */
- long line; /* starting line for pcline crunch */
-};
-
struct file { /* Per input file header to history stack */
- long addr; /* address of first text sym */
- union {
- Txtsym *ftxt; /* first text symbol */
- Sym *fsym; /* only during initilization */
- } u0;
- int n; /* size of history stack */
- Hist *hist; /* history stack */
- Pcl pcl; /* pcline startup data */
+ uvlong addr; /* address of first text sym */
+ /* union { */
+ Txtsym *txt; /* first text symbol */
+ Sym *sym; /* only during initilization */
+ /* }; */
+ int n; /* size of history stack */
+ Hist *hist; /* history stack */
};
static int debug = 0;
@@ -53,19 +45,18 @@ static long nfiles; /* number of files */
static long nglob; /* number of globals */
static long nhist; /* number of history stack entries */
static long nsym; /* number of symbols */
-static long ntxt; /* number of text symbols */
+static int ntxt; /* number of text symbols */
static uchar *pcline; /* start of pc-line state table */
static uchar *pclineend; /* end of pc-line table */
-static int npcl; /* number of files pcl-decoded so far */
static uchar *spoff; /* start of pc-sp state table */
static uchar *spoffend; /* end of pc-sp offset table */
static Sym *symbols; /* symbol table */
static Txtsym *txt; /* Base of text symbol table */
-static long txtstart; /* start of text segment */
-static long txtend; /* end of text segment */
+static uvlong txtstart; /* start of text segment */
+static uvlong txtend; /* end of text segment */
static void cleansyms(void);
-static int decodename(Biobuf*, Sym*);
+static long decodename(Biobuf*, Sym*);
static short *encfname(char*);
static int fline(char*, int, long, Hist*, Hist**);
static void fillsym(Sym*, Symbol*);
@@ -73,11 +64,8 @@ static int findglobal(char*, Symbol*);
static int findlocvar(Symbol*, char *, Symbol*);
static int findtext(char*, Symbol*);
static int hcomp(Hist*, short*);
-static int hline(File*, short*, ulong*);
+static int hline(File*, short*, long*);
static void printhist(char*, Hist*, int);
-static long pcl2line(ulong, Pcl *, Pcl *);
-static long pc2fline(ulong, File **);
-static int pc2filex(ulong);
static int buildtbls(void);
static int symcomp(void*, void*);
static int symerrmsg(int, char*);
@@ -91,9 +79,10 @@ int
syminit(int fd, Fhdr *fp)
{
Sym *p;
- int i, size;
+ long i, l, size;
+ vlong vl;
Biobuf b;
- extern void thumbpctab(Biobuf*, Fhdr*);
+ int svalsz;
if(fp->symsz == 0)
return 0;
@@ -108,22 +97,30 @@ syminit(int fd, Fhdr *fp)
werrstr("can't malloc %ld bytes", fp->symsz);
return -1;
}
-
Binit(&b, fd, OREAD);
Bseek(&b, fp->symoff, 0);
nsym = 0;
size = 0;
for(p = symbols; size < fp->symsz; p++, nsym++) {
- if(Bread(&b, &p->value, sizeof(p->value)) != sizeof(p->value))
- return symerrmsg(sizeof(p->value), "symbol");
- p->value = beswal(p->value);
+ if(fp->_magic && (fp->magic & HDR_MAGIC)){
+ svalsz = 8;
+ if(Bread(&b, &vl, 8) != 8)
+ return symerrmsg(8, "symbol");
+ p->value = beswav(vl);
+ }
+ else{
+ svalsz = 4;
+ if(Bread(&b, &l, 4) != 4)
+ return symerrmsg(4, "symbol");
+ p->value = (u32int)beswal(l);
+ }
if(Bread(&b, &p->type, sizeof(p->type)) != sizeof(p->type))
return symerrmsg(sizeof(p->value), "symbol");
i = decodename(&b, p);
if(i < 0)
return -1;
- size += i+sizeof(p->value)+sizeof(p->type);
+ size += i+svalsz+sizeof(p->type);
/* count global & auto vars, text symbols, and file names */
switch (p->type) {
@@ -164,7 +161,7 @@ syminit(int fd, Fhdr *fp)
}
}
if (debug)
- fprint(2,"NG: %ld NT: %ld NF: %d\n", nglob, ntxt, fpmax);
+ print("NG: %ld NT: %d NF: %d\n", nglob, ntxt, fpmax);
if (fp->sppcsz) { /* pc-sp offset table */
spoff = (uchar *)malloc(fp->sppcsz);
if(spoff == 0) {
@@ -172,8 +169,7 @@ syminit(int fd, Fhdr *fp)
return -1;
}
Bseek(&b, fp->sppcoff, 0);
- i = Bread(&b, spoff, fp->sppcsz);
- if(i != fp->sppcsz){
+ if(Bread(&b, spoff, fp->sppcsz) != fp->sppcsz){
spoff = 0;
return symerrmsg(fp->sppcsz, "sp-pc");
}
@@ -186,8 +182,7 @@ syminit(int fd, Fhdr *fp)
return -1;
}
Bseek(&b, fp->lnpcoff, 0);
- i = Bread(&b, pcline, fp->lnpcsz);
- if(i != fp->lnpcsz){
+ if(Bread(&b, pcline, fp->lnpcsz) != fp->lnpcsz){
pcline = 0;
return symerrmsg(fp->lnpcsz, "pc-line");
}
@@ -205,12 +200,13 @@ symerrmsg(int n, char *table)
return -1;
}
-static int
+static long
decodename(Biobuf *bp, Sym *p)
{
char *cp;
int c1, c2;
- int n;
+ long n;
+ vlong o;
if((p->type & 0x80) == 0) { /* old-style, fixed length names */
p->name = malloc(NNAME);
@@ -226,7 +222,7 @@ decodename(Biobuf *bp, Sym *p)
p->type &= ~0x80;
if(p->type == 'z' || p->type == 'Z') {
- n = Bseek(bp, 0, 1);
+ o = Bseek(bp, 0, 1);
if(Bgetc(bp) < 0) {
werrstr("can't read symbol name");
return -1;
@@ -241,15 +237,15 @@ decodename(Biobuf *bp, Sym *p)
if(c1 == 0 && c2 == 0)
break;
}
- n = Bseek(bp, 0, 1)-n;
+ n = Bseek(bp, 0, 1)-o;
p->name = malloc(n);
if(p->name == 0) {
- werrstr("can't malloc %d bytes", n);
+ werrstr("can't malloc %ld bytes", n);
return -1;
}
Bseek(bp, -n, 1);
if(Bread(bp, p->name, n) != n) {
- werrstr("can't read %d bytes of symbol name", n);
+ werrstr("can't read %ld bytes of symbol name", n);
return -1;
}
} else {
@@ -261,13 +257,14 @@ decodename(Biobuf *bp, Sym *p)
n = Blinelen(bp);
p->name = malloc(n);
if(p->name == 0) {
- werrstr("can't malloc %d bytes", n);
+ werrstr("can't malloc %ld bytes", n);
return -1;
}
strcpy(p->name, cp);
}
return n;
}
+
/*
* free any previously loaded symbol tables
*/
@@ -310,18 +307,18 @@ cleansyms(void)
if(pcline)
free(pcline);
pcline = 0;
- npcl = 0;
}
+
/*
* delimit the text segment
*/
void
-textseg(ulong base, Fhdr *fp)
+textseg(uvlong base, Fhdr *fp)
{
txtstart = base;
txtend = base+fp->txtsz;
- npcl = 0; /* all pcls must be recomputed */
}
+
/*
* symbase: return base and size of raw symbol table
* (special hack for high access rate operations)
@@ -332,13 +329,14 @@ symbase(long *n)
*n = nsym;
return symbols;
}
+
/*
* Get the ith symbol table entry
*/
Sym *
getsym(int index)
{
- if(index < nsym)
+ if(index >= 0 && index < nsym)
return &symbols[index];
return 0;
}
@@ -349,7 +347,8 @@ getsym(int index)
static int
buildtbls(void)
{
- int i, j, nh, ng, nt;
+ long i;
+ int j, nh, ng, nt;
File *f;
Txtsym *tp;
Hist *hp;
@@ -373,13 +372,12 @@ buildtbls(void)
return 0;
}
}
- fpmax++;
- fnames = malloc(fpmax*sizeof(*fnames));
+ fnames = malloc((fpmax+1)*sizeof(*fnames));
if (!fnames) {
werrstr("can't malloc file name table");
return 0;
}
- memset(fnames, 0, fpmax*sizeof(*fnames));
+ memset(fnames, 0, (fpmax+1)*sizeof(*fnames));
files = malloc(nfiles*sizeof(*files));
if(!files) {
werrstr("can't malloc file table");
@@ -409,7 +407,7 @@ buildtbls(void)
case 'B':
case 'b':
if(debug)
- fprint(2,"Global: %s %lux\n", p->name, p->value);
+ print("Global: %s %llux\n", p->name, p->value);
globals[ng++] = p;
break;
case 'z':
@@ -420,9 +418,10 @@ buildtbls(void)
hp += nh+1;
f++;
}
- else f = files;
+ else
+ f = files;
f->hist = hp;
- f->u0.fsym = 0;
+ f->sym = 0;
f->addr = 0;
nh = 0;
}
@@ -447,9 +446,9 @@ buildtbls(void)
tp->sym = p;
tp->locals = ap;
if(debug)
- fprint(2,"TEXT: %s at %lux\n", p->name, p->value);
- if(f && !f->u0.fsym) { /* first */
- f->u0.fsym = p;
+ print("TEXT: %s at %llux\n", p->name, p->value);
+ if(f && !f->sym) { /* first */
+ f->sym = p;
f->addr = p->value;
}
break;
@@ -457,10 +456,11 @@ buildtbls(void)
case 'p':
case 'm': /* Local Vars */
if(!tp)
- print("Warning: Free floating local var");
+ print("Warning: Free floating local var: %s\n",
+ p->name);
else {
if(debug)
- fprint(2,"Local: %s %lux\n", p->name, p->value);
+ print("Local: %s %llux\n", p->name, p->value);
tp->locals[tp->n] = p;
tp->n++;
ap++;
@@ -468,7 +468,7 @@ buildtbls(void)
break;
case 'f': /* File names */
if(debug)
- fprint(2,"Fname: %s\n", p->name);
+ print("Fname: %s\n", p->name);
fnames[p->value] = p;
break;
default:
@@ -482,12 +482,12 @@ buildtbls(void)
tp = txt;
for(i = 0, f = files; i < nfiles; i++, f++) {
for(j = 0; j < ntxt; j++) {
- if(f->u0.fsym == tp->sym) {
+ if(f->sym == tp->sym) {
if(debug) {
- fprint(2,"LINK: %s to at %lux", f->u0.fsym->name, f->addr);
+ print("LINK: %s to at %llux", f->sym->name, f->addr);
printhist("... ", f->hist, 1);
}
- f->u0.ftxt = tp++;
+ f->txt = tp++;
break;
}
if(++tp >= txt+ntxt) /* wrap around */
@@ -527,6 +527,7 @@ lookup(char *fn, char *var, Symbol *s)
return findglobal(var, s); /* case 3: var not found */
}
+
/*
* find a function by name
*/
@@ -539,6 +540,7 @@ findtext(char *name, Symbol *s)
if(strcmp(txt[i].sym->name, name) == 0) {
fillsym(txt[i].sym, s);
s->handle = (void *) &txt[i];
+ s->index = i;
return 1;
}
}
@@ -550,16 +552,18 @@ findtext(char *name, Symbol *s)
static int
findglobal(char *name, Symbol *s)
{
- int i;
+ long i;
for(i = 0; i < nglob; i++) {
if(strcmp(globals[i]->name, name) == 0) {
fillsym(globals[i], s);
+ s->index = i;
return 1;
}
}
return 0;
}
+
/*
* find the local variable by name within a given function
*/
@@ -572,6 +576,7 @@ findlocal(Symbol *s1, char *name, Symbol *s2)
return 0;
return findlocvar(s1, name, s2);
}
+
/*
* find the local variable by name within a given function
* (internal function - does no parameter validation)
@@ -588,11 +593,13 @@ findlocvar(Symbol *s1, char *name, Symbol *s2)
if (strcmp(tp->locals[i]->name, name) == 0) {
fillsym(tp->locals[i], s2);
s2->handle = (void *)tp;
+ s2->index = tp->n-1 - i;
return 1;
}
}
return 0;
}
+
/*
* Get ith text symbol
*/
@@ -602,12 +609,14 @@ textsym(Symbol *s, int index)
if(buildtbls() == 0)
return 0;
- if(index >= ntxt)
+ if(index < 0 || index >= ntxt)
return 0;
fillsym(txt[index].sym, s);
s->handle = (void *)&txt[index];
+ s->index = index;
return 1;
}
+
/*
* Get ith file name
*/
@@ -618,13 +627,14 @@ filesym(int index, char *buf, int n)
if(buildtbls() == 0)
return 0;
- if(index >= nfiles)
+ if(index < 0 || index >= nfiles)
return 0;
hp = files[index].hist;
if(!hp || !hp->name)
return 0;
return fileelem(fnames, (uchar*)hp->name, buf, n);
}
+
/*
* Lookup name of local variable located at an offset into the frame.
* The type selects either a parameter or automatic.
@@ -654,6 +664,7 @@ getauto(Symbol *s1, int off, int type, Symbol *s2)
if(p->type == t && p->value == off) {
fillsym(p, s2);
s2->handle = s1->handle;
+ s2->index = tp->n-1 - i;
return 1;
}
}
@@ -664,9 +675,9 @@ getauto(Symbol *s1, int off, int type, Symbol *s2)
* Find text symbol containing addr; binary search assumes text array is sorted by addr
*/
static int
-srchtext(long addr)
+srchtext(uvlong addr)
{
- ulong val;
+ uvlong val;
int top, bot, mid;
Sym *sp;
@@ -675,9 +686,9 @@ srchtext(long addr)
top = ntxt;
for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
sp = txt[mid].sym;
- if(val < (ulong)sp->value)
+ if(val < sp->value)
top = mid;
- else if(mid != ntxt-1 && val >= (ulong)txt[mid+1].sym->value)
+ else if(mid != ntxt-1 && val >= txt[mid+1].sym->value)
bot = mid;
else
return mid;
@@ -688,10 +699,10 @@ srchtext(long addr)
/*
* Find data symbol containing addr; binary search assumes data array is sorted by addr
*/
-static
-int srchdata(long addr)
+static int
+srchdata(uvlong addr)
{
- ulong val;
+ uvlong val;
int top, bot, mid;
Sym *sp;
@@ -700,15 +711,16 @@ int srchdata(long addr)
val = addr;
for(mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {
sp = globals[mid];
- if(val < (ulong)sp->value)
+ if(val < sp->value)
top = mid;
- else if(mid < nglob-1 && val >= (ulong)globals[mid+1]->value)
+ else if(mid < nglob-1 && val >= globals[mid+1]->value)
bot = mid;
else
return mid;
}
return -1;
}
+
/*
* Find symbol containing val in specified search space
* There is a special case when a value falls beyond the end
@@ -717,7 +729,7 @@ int srchdata(long addr)
* data space are searched for a match.
*/
int
-findsym(long w, int type, Symbol *s)
+findsym(uvlong val, int type, Symbol *s)
{
int i;
@@ -725,19 +737,21 @@ findsym(long w, int type, Symbol *s)
return 0;
if(type == CTEXT || type == CANY) {
- i = srchtext(w);
+ i = srchtext(val);
if(i >= 0) {
if(type == CTEXT || i != ntxt-1) {
fillsym(txt[i].sym, s);
s->handle = (void *) &txt[i];
+ s->index = i;
return 1;
}
}
}
if(type == CDATA || type == CANY) {
- i = srchdata(w);
+ i = srchdata(val);
if(i >= 0) {
fillsym(globals[i], s);
+ s->index = i;
return 1;
}
}
@@ -748,7 +762,7 @@ findsym(long w, int type, Symbol *s)
* Find the start and end address of the function containing addr
*/
int
-fnbound(long addr, ulong *bounds)
+fnbound(uvlong addr, uvlong *bounds)
{
int i;
@@ -774,7 +788,7 @@ localsym(Symbol *s, int index)
{
Txtsym *tp;
- if(s == 0)
+ if(s == 0 || index < 0)
return 0;
if(buildtbls() == 0)
return 0;
@@ -783,10 +797,12 @@ localsym(Symbol *s, int index)
if(tp && tp->locals && index < tp->n) {
fillsym(tp->locals[tp->n-index-1], s); /* reverse */
s->handle = (void *)tp;
+ s->index = index;
return 1;
}
return 0;
}
+
/*
* get the ith global symbol
*/
@@ -798,30 +814,31 @@ globalsym(Symbol *s, int index)
if(buildtbls() == 0)
return 0;
- if(index < nglob) {
+ if(index >=0 && index < nglob) {
fillsym(globals[index], s);
+ s->index = index;
return 1;
}
return 0;
}
+
/*
* find the pc given a file name and line offset into it.
*/
-long
-file2pc(char *file, ulong line)
+uvlong
+file2pc(char *file, long line)
{
File *fp;
- int i;
- long pc;
- ulong start, end;
+ long i;
+ uvlong pc, start, end;
short *name;
if(buildtbls() == 0 || files == 0)
- return -1;
+ return ~0;
name = encfname(file);
if(name == 0) { /* encode the file name */
werrstr("file %s not found", file);
- return -1;
+ return ~0;
}
/* find this history stack */
for(i = 0, fp = files; i < nfiles; i++, fp++)
@@ -830,7 +847,7 @@ file2pc(char *file, ulong line)
free(name);
if(i >= nfiles) {
werrstr("line %ld in file %s not found", line, file);
- return -1;
+ return ~0;
}
start = fp->addr; /* first text addr this file */
if(i < nfiles-1)
@@ -842,14 +859,15 @@ file2pc(char *file, ulong line)
* run the state machine to locate the pc closest to that value.
*/
if(debug)
- fprint(2,"find pc for %ld - between: %lux and %lux\n", line, start, end);
+ print("find pc for %ld - between: %llux and %llux\n", line, start, end);
pc = line2addr(line, start, end);
- if(pc == -1) {
+ if(pc == ~0) {
werrstr("line %ld not in file %s", line, file);
- return -1;
+ return ~0;
}
return pc;
}
+
/*
* search for a path component index
*/
@@ -859,10 +877,11 @@ pathcomp(char *s, int n)
int i;
for(i = 0; i <= fpmax; i++)
- if(fnames[i] && strncmp(s, fnames[i]->name, n) == 0 && fnames[i]->name[n] == 0)
+ if(fnames[i] && strncmp(s, fnames[i]->name, n) == 0)
return i;
return -1;
}
+
/*
* Encode a char file name as a sequence of short indices
* into the file name dictionary.
@@ -900,12 +919,13 @@ encfname(char *file)
dest[i] = 0;
return dest;
}
+
/*
* Search a history stack for a matching file name accumulating
* the size of intervening files in the stack.
*/
static int
-hline(File *fp, short *name, ulong *line)
+hline(File *fp, short *name, long *line)
{
Hist *hp;
int offset, depth;
@@ -949,6 +969,7 @@ hline(File *fp, short *name, ulong *line)
*line = ln+offset;
return 1;
}
+
/*
* compare two encoded file names
*/
@@ -973,42 +994,19 @@ hcomp(Hist *hp, short *sp)
}
return *s == 0;
}
+
/*
* Convert a pc to a "file:line {file:line}" string.
*/
-int
-fileline(char *str, int n, ulong dot)
+long
+fileline(char *str, int n, uvlong dot)
{
- long line;
+ long line, top, bot, mid;
File *f;
- int i;
*str = 0;
if(buildtbls() == 0)
return 0;
-
- i = pc2filex(dot);
- if (i >= 0)
- {
- f = &files[i];
- line = pc2line(dot);
- if(line >= 0 && fline(str, n, line, f->hist, 0) >= 0)
- return 1;
- }
- return 0;
-}
-/*
- * Convert a pc to an index to the file table
- */
-static int
-pc2filex(ulong dot)
-{
- int top, bot, mid;
- File *f;
-
- if(buildtbls() == 0)
- return -1;
-
/* binary search assumes file list is sorted by addr */
bot = 0;
top = nfiles;
@@ -1018,10 +1016,14 @@ pc2filex(ulong dot)
top = mid;
else if(mid < nfiles-1 && dot >= (f+1)->addr)
bot = mid;
- else
- return mid;
+ else {
+ line = pc2line(dot);
+ if(line > 0 && fline(str, n, line, f->hist, 0) >= 0)
+ return 1;
+ break;
+ }
}
- return -1;
+ return 0;
}
/*
@@ -1034,7 +1036,7 @@ fline(char *str, int n, long line, Hist *base, Hist **ret)
{
Hist *start; /* start of current level */
Hist *h; /* current entry */
- int delta; /* sum of size of files this level */
+ long delta; /* sum of size of files this level */
int k;
start = base;
@@ -1056,9 +1058,8 @@ fline(char *str, int n, long line, Hist *base, Hist **ret)
}
}
} else {
- if(start == base) { /* end of recursion level */
- if(ret)
- *ret = h;
+ if(start == base && ret) { /* end of recursion level */
+ *ret = h;
return 1;
} else { /* end of included file */
delta += h->line-start->line;
@@ -1094,6 +1095,7 @@ fline(char *str, int n, long line, Hist *base, Hist **ret)
********************/
return 0;
}
+
/*
* convert an encoded file name to a string.
*/
@@ -1113,16 +1115,28 @@ fileelem(Sym **fp, uchar *cp, char *buf, int n)
*bp++ = *c++;
}
*bp = 0;
- return bp-buf;
+ i = bp-buf;
+ if(i > 1) {
+ cleanname(buf);
+ i = strlen(buf);
+ }
+ return i;
}
+
/*
* compare the values of two symbol table entries.
*/
static int
symcomp(void *a, void *b)
{
- return (*(Sym**)a)->value - (*(Sym**)b)->value;
+ int i;
+
+ i = (*(Sym**)a)->value - (*(Sym**)b)->value;
+ if (i)
+ return i;
+ return strcmp((*(Sym**)a)->name, (*(Sym**)b)->name);
}
+
/*
* compare the values of the symbols referenced by two text table entries
*/
@@ -1131,6 +1145,7 @@ txtcomp(void *a, void *b)
{
return ((Txtsym*)a)->sym->value - ((Txtsym*)b)->sym->value;
}
+
/*
* compare the values of the symbols referenced by two file table entries
*/
@@ -1139,6 +1154,7 @@ filecomp(void *a, void *b)
{
return ((File*)a)->addr - ((File*)b)->addr;
}
+
/*
* fill an interface Symbol structure from a symbol table entry
*/
@@ -1148,6 +1164,7 @@ fillsym(Sym *sp, Symbol *s)
s->type = sp->type;
s->value = sp->value;
s->name = sp->name;
+ s->index = 0;
switch(sp->type) {
case 'b':
case 'B':
@@ -1176,24 +1193,23 @@ fillsym(Sym *sp, Symbol *s)
}
s->handle = 0;
}
+
/*
* find the stack frame, given the pc
*/
-long
-pc2sp(ulong pc)
+uvlong
+pc2sp(uvlong pc)
{
- uchar *c;
- uchar u;
- ulong currpc;
- long currsp;
+ uchar *c, u;
+ uvlong currpc, currsp;
if(spoff == 0)
- return -1;
+ return ~0;
currsp = 0;
currpc = txtstart - mach->pcquant;
if(pc<currpc || pc>txtend)
- return -1;
+ return ~0;
for(c = spoff; c < spoffend; c++) {
if (currpc >= pc)
return currsp;
@@ -1210,76 +1226,29 @@ pc2sp(ulong pc)
currpc += mach->pcquant*(u-129);
currpc += mach->pcquant;
}
- return -1;
+ return ~0;
}
+
/*
* find the source file line number for a given value of the pc
*/
long
-pc2line(ulong pc)
-{
- File *fp;
- return pc2fline(pc, &fp);
-}
-/*
- * Convert a pc into a file table pointer & line offset
- */
-static long
-pc2fline(ulong pc, File **fpp)
+pc2line(uvlong pc)
{
- File *f;
- int i;
-
- i = pc2filex(pc);
- if (i < 0)
- return i;
- if (i >= npcl){
- /* Precompute starting points by file, else too slow */
- if (npcl == 0){
- Pcl pcl;
-
- /* decode start for pcline machine */
- pcl.pcline = pcline;
- pcl.pc = txtstart - mach->pcquant;
- pcl.line = 0;
- pcl2line(files->addr, &pcl, &files[0].pcl);
- npcl = 1;
- }
- for (f = &files[npcl]; npcl <= i; npcl++, f++)
- if (pcl2line(f->addr, &(f-1)->pcl, &f->pcl) < 0)
- break;
- }
- f = &files[i];
- *fpp = f;
- return pcl2line(pc, &f->pcl, 0);
-}
-/*
- * Convert pc to line offset, given Pcl starting point,
- * saving Pcl result.
- */
-static long
-pcl2line(ulong pc, Pcl *bp, Pcl *rp)
-{
- uchar *c;
- uchar u;
- ulong currpc;
+ uchar *c, u;
+ uvlong currpc;
long currline;
- if(bp->pcline == 0)
+ if(pcline == 0)
return -1;
- currpc = bp->pc;
- currline = bp->line;
+ currline = 0;
+ currpc = txtstart-mach->pcquant;
if(pc<currpc || pc>txtend)
- return -1;
- for(c = bp->pcline; c < pclineend; c++) {
- if (currpc >= pc) {
- if (rp){
- rp->pc = currpc;
- rp->line = currline;
- rp->pcline = c;
- }
+ return ~0;
+
+ for(c = pcline; c < pclineend; c++) {
+ if(currpc >= pc)
return currline;
- }
u = *c;
if(u == 0) {
currline += (c[1]<<24)|(c[2]<<16)|(c[3]<<8)|c[4];
@@ -1293,8 +1262,9 @@ pcl2line(ulong pc, Pcl *bp, Pcl *rp)
currpc += mach->pcquant*(u-129);
currpc += mach->pcquant;
}
- return -1;
+ return ~0;
}
+
/*
* find the pc associated with a line number
* basepc and endpc are text addresses bounding the search.
@@ -1302,22 +1272,21 @@ pcl2line(ulong pc, Pcl *bp, Pcl *rp)
* usually, basepc and endpc contain the first text address in
* a file and the first text address in the following file, respectively.
*/
-long
-line2addr(ulong line, ulong basepc, ulong endpc)
+uvlong
+line2addr(long line, uvlong basepc, uvlong endpc)
{
- uchar *c;
- uchar u;
- ulong currpc;
+ uchar *c, u;
+ uvlong currpc, pc;
long currline;
long delta, d;
- long pc, found;
+ int found;
if(pcline == 0 || line == 0)
- return -1;
+ return ~0;
currline = 0;
currpc = txtstart-mach->pcquant;
- pc = -1;
+ pc = ~0;
found = 0;
delta = HUGEINT;
@@ -1350,8 +1319,9 @@ line2addr(ulong line, ulong basepc, ulong endpc)
}
if(found)
return pc;
- return -1;
+ return ~0;
}
+
/*
* Print a history stack (debug). if count is 0, prints the whole stack
*/
@@ -1366,15 +1336,15 @@ printhist(char *msg, Hist *hp, int count)
while(hp->name) {
if(count && ++i > count)
break;
- fprint(2,"%s Line: %lx (%ld) Offset: %lx (%ld) Name: ", msg,
+ print("%s Line: %lx (%ld) Offset: %lx (%ld) Name: ", msg,
hp->line, hp->line, hp->offset, hp->offset);
for(cp = (uchar *)hp->name+1; (*cp<<8)|cp[1]; cp += 2) {
if (cp != (uchar *)hp->name+1)
- fprint(2,"/");
- fprint(2,"%x", (*cp<<8)|cp[1]);
+ print("/");
+ print("%x", (*cp<<8)|cp[1]);
}
fileelem(fnames, (uchar *) hp->name, buf, sizeof(buf));
- fprint(2," (%s)\n", buf);
+ print(" (%s)\n", buf);
hp++;
}
}
diff --git a/utils/libmach/t.c b/utils/libmach/t.c
index adea089b..809168e0 100644
--- a/utils/libmach/t.c
+++ b/utils/libmach/t.c
@@ -56,6 +56,7 @@ Mach mthumb =
0x1000, /* page size */
0x80000000, /* kernel base */
0, /* kernel text mask */
+ 0x7FFFFFFF, /* stack top */
2, /* quantization of pc */
4, /* szaddr */
4, /* szreg */
@@ -99,9 +100,9 @@ thumbpctab(Biobuf *b, Fhdr *fp)
}
int
-thumbpclookup(ulong pc)
+thumbpclookup(uvlong pc)
{
- ulong l, u, m;
+ uvlong l, u, m;
pcentry *tab = pctab;
l = 0;
@@ -115,8 +116,7 @@ thumbpclookup(ulong pc)
else
l = u = m;
}
- if(l == u && u >= 0 && u < npctab && tab[u].start <= pc && pc <= tab[u].stop)
+ if(l == u && u < npctab && tab[u].start <= pc && pc <= tab[u].stop)
return 1; // thumb
return 0; // arm
}
-
diff --git a/utils/libmach/tdb.c b/utils/libmach/tdb.c
index 8eddc43a..8838d852 100644
--- a/utils/libmach/tdb.c
+++ b/utils/libmach/tdb.c
@@ -28,7 +28,7 @@ struct Opcode
{
char* o;
void (*fmt)(Opcode*, Instr*);
- ulong (*foll)(Map*, Rgetter, Instr*, ulong);
+ uvlong (*foll)(Map*, Rgetter, Instr*, uvlong);
char* a;
};
@@ -40,10 +40,10 @@ static char FRAMENAME[] = ".frame";
*/
static char *thumbexcep(Map*, Rgetter);
-static int thumbfoll(Map*, ulong, Rgetter, ulong*);
-static int thumbinst(Map*, ulong, char, char*, int);
-static int thumbdas(Map*, ulong, char*, int);
-static int thumbinstlen(Map*, ulong);
+static int thumbfoll(Map*, uvlong, Rgetter, uvlong*);
+static int thumbinst(Map*, uvlong, char, char*, int);
+static int thumbdas(Map*, uvlong, char*, int);
+static int thumbinstlen(Map*, uvlong);
/*
* Debugger interface
@@ -191,7 +191,7 @@ thumbclass(long w)
}
static int
-decode(Map *map, ulong pc, Instr *i)
+decode(Map *map, uvlong pc, Instr *i)
{
ushort w;
@@ -277,7 +277,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);
}
@@ -318,8 +318,8 @@ thumbcondpass(Map *map, Rgetter rget, uchar cond)
return 0;
}
-static ulong
-thumbfbranch(Map *map, Rgetter rget, Instr *i, ulong pc)
+static uvlong
+thumbfbranch(Map *map, Rgetter rget, Instr *i, uvlong pc)
{
char buf[8];
@@ -346,8 +346,8 @@ thumbfbranch(Map *map, Rgetter rget, Instr *i, ulong pc)
return 0;
}
-static ulong
-thumbfmov(Map *map, Rgetter rget, Instr *i, ulong pc)
+static uvlong
+thumbfmov(Map *map, Rgetter rget, Instr *i, uvlong pc)
{
char buf[8];
ulong rd;
@@ -360,8 +360,8 @@ thumbfmov(Map *map, Rgetter rget, Instr *i, ulong pc)
return rget(map, buf);
}
-static ulong
-thumbfadd(Map *map, Rgetter rget, Instr *i, ulong pc)
+static uvlong
+thumbfadd(Map *map, Rgetter rget, Instr *i, uvlong pc)
{
char buf[8];
ulong rd, v;
@@ -712,7 +712,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, &i->imm) > 0)
+ if (get4(i->map, i->addr + i->imm, (ulong*)&i->imm) > 0)
{
g = 1;
fmt = "";
@@ -773,7 +773,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;
@@ -787,14 +787,14 @@ printins(Map *map, ulong pc, char *buf, int n)
}
static int
-thumbinst(Map *map, ulong pc, char modifier, char *buf, int n)
+thumbinst(Map *map, uvlong pc, char modifier, char *buf, int n)
{
USED(modifier);
return printins(map, pc, buf, n);
}
static int
-thumbdas(Map *map, ulong pc, char *buf, int n)
+thumbdas(Map *map, uvlong pc, char *buf, int n)
{
Instr i;
@@ -809,7 +809,7 @@ thumbdas(Map *map, ulong pc, char *buf, int n)
}
static int
-thumbinstlen(Map *map, ulong pc)
+thumbinstlen(Map *map, uvlong pc)
{
Instr i;
@@ -819,7 +819,7 @@ thumbinstlen(Map *map, ulong pc)
}
static int
-thumbfoll(Map *map, ulong pc, Rgetter rget, ulong *foll)
+thumbfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
{
ulong d;
Instr i;
diff --git a/utils/libmach/ureg6.h b/utils/libmach/ureg6.h
index 46fa1f61..6e58d250 100644
--- a/utils/libmach/ureg6.h
+++ b/utils/libmach/ureg6.h
@@ -1,30 +1,30 @@
-struct Ureg
-{
- uvlong r15; /* general registers */
- uvlong r14;
- uvlong r13;
- uvlong r12;
- uvlong r11;
- uvlong r10;
- uvlong r9;
- uvlong r8;
- uvlong di;
- uvlong si; /* ... */
- uvlong bp; /* ... */
- uvlong nsp;
- uvlong bx; /* ... */
- uvlong dx; /* ... */
- uvlong cx; /* ... */
- uvlong ax; /* ... */
- uvlong gs; /* data segments */
- uvlong fs; /* ... */
- uvlong es; /* ... */
- uvlong ds; /* ... */
- uvlong trap; /* trap type */
- uvlong ecode; /* error code (or zero) */
- uvlong pc; /* pc */
- uvlong cs; /* old context */
- uvlong flags; /* old flags */
- uvlong sp;
- uvlong ss; /* old stack segment */
+struct Ureg {
+ u64int ax;
+ u64int bx;
+ u64int cx;
+ u64int dx;
+ u64int si;
+ u64int di;
+ u64int bp;
+ u64int r8;
+ u64int r9;
+ u64int r10;
+ u64int r11;
+ u64int r12;
+ u64int r13;
+ u64int r14;
+ u64int r15;
+
+ u16int ds;
+ u16int es;
+ u16int fs;
+ u16int gs;
+
+ u64int type;
+ u64int error; /* error code (or zero) */
+ u64int ip; /* pc */
+ u64int cs; /* old context */
+ u64int flags; /* old flags */
+ u64int sp; /* sp */
+ u64int ss; /* old stack segment */
};
diff --git a/utils/libmach/ureg9.h b/utils/libmach/ureg9.h
new file mode 100644
index 00000000..676f5a57
--- /dev/null
+++ b/utils/libmach/ureg9.h
@@ -0,0 +1,44 @@
+struct Ureg
+{
+/* 0*/ u64int cause; /* trap or interrupt vector */
+/* 8*/ u64int msr; /* SRR1 */
+/* 16*/ u64int pc; /* SRR0 */
+/* 24*/ u64int unused;
+/* 32*/ u64int lr;
+/* 36*/ u32int pad;
+/* 40*/ u32int cr;
+/* 48*/ u64int xer;
+/* 56*/ u64int ctr;
+/* 64*/ u64int r0;
+/* 72*/ union{ u64int r1; u64int sp; u64int usp; };
+/* 80*/ u64int r2;
+/* 88*/ u64int r3;
+/* 96*/ u64int r4;
+/*104*/ u64int r5;
+/*112*/ u64int r6;
+/*120*/ u64int r7;
+/*128*/ u64int r8;
+/*136*/ u64int r9;
+/*144*/ u64int r10;
+/*152*/ u64int r11;
+/*160*/ u64int r12;
+/*168*/ u64int r13;
+/*176*/ u64int r14;
+/*184*/ u64int r15;
+/*192*/ u64int r16;
+/*200*/ u64int r17;
+/*208*/ u64int r18;
+/*216*/ u64int r19;
+/*224*/ u64int r20;
+/*232*/ u64int r21;
+/*240*/ u64int r22;
+/*248*/ u64int r23;
+/*256*/ u64int r24;
+/*264*/ u64int r25;
+/*272*/ u64int r26;
+/*280*/ u64int r27;
+/*288*/ u64int r28;
+/*296*/ u64int r29;
+/*304*/ u64int r30;
+/*312*/ u64int r31;
+};
diff --git a/utils/libmach/uregq.h b/utils/libmach/uregq.h
index 409b13d3..d412b05a 100644
--- a/utils/libmach/uregq.h
+++ b/utils/libmach/uregq.h
@@ -1,7 +1,7 @@
struct Ureg
{
ulong cause;
- ulong status;
+ ulong srr1;
ulong pc; /* SRR0 */
ulong pad;
ulong lr;
diff --git a/utils/libmach/uregt.h b/utils/libmach/uregt.h
index ffdad423..705a8675 100644
--- a/utils/libmach/uregt.h
+++ b/utils/libmach/uregt.h
@@ -1,21 +1,21 @@
struct Ureg {
- uint r0;
- uint r1;
- uint r2;
- uint r3;
- uint r4;
- uint r5;
- uint r6;
- uint r7;
- uint r8;
- uint r9;
- uint r10;
- uint r11;
- uint r12;
- uint r13;
- uint r14;
- uint link;
- uint type;
- uint psr;
- uint pc;
+ u32int r0;
+ u32int r1;
+ u32int r2;
+ u32int r3;
+ u32int r4;
+ u32int r5;
+ u32int r6;
+ u32int r7;
+ u32int r8;
+ u32int r9;
+ u32int r10;
+ u32int r11;
+ u32int r12;
+ u32int r13;
+ u32int r14;
+ u32int link;
+ u32int type;
+ u32int psr;
+ u32int pc;
};
diff --git a/utils/libmach/vcodas.c b/utils/libmach/vcodas.c
index ce505ea2..b31fdb3e 100644
--- a/utils/libmach/vcodas.c
+++ b/utils/libmach/vcodas.c
@@ -5,7 +5,7 @@
/* mips native disassembler */
typedef struct {
- long addr; /* pc of instr */
+ uvlong addr; /* pc of instr */
uchar op; /* bits 31-26 */
uchar rs; /* bits 25-21 */
uchar rt; /* bits 20-16 */
@@ -281,9 +281,9 @@ static char fsub[16] = {
static int
-mkinstr(Instr *i, Map *map, ulong pc)
+mkinstr(Instr *i, Map *map, uvlong pc)
{
- long w;
+ ulong w;
if (get4(map, pc, &w) < 0) {
werrstr("can't read instruction: %r");
@@ -305,6 +305,8 @@ mkinstr(Instr *i, Map *map, ulong pc)
return 1;
}
+#pragma varargck argpos bprint 2
+
static void
bprint(Instr *i, char *fmt, ...)
{
@@ -505,7 +507,7 @@ cop0(Instr *i)
}
int
-_mipscoinst(Map *map, ulong pc, char *buf, int n)
+_mipscoinst(Map *map, uvlong pc, char *buf, int n)
{
Instr i;
Opcode *o;
diff --git a/utils/libmach/vdb.c b/utils/libmach/vdb.c
index 0624a106..55798978 100644
--- a/utils/libmach/vdb.c
+++ b/utils/libmach/vdb.c
@@ -5,11 +5,12 @@
* Mips-specific debugger interface
*/
-extern char *mipsexcep(Map*, Rgetter);
-extern int mipsfoll(Map*, ulong, Rgetter, ulong*);
-extern int mipsinst(Map*, ulong, char, char*, int);
-extern int mipsdas(Map*, ulong, char*, int);
-extern int mipsinstlen(Map*, ulong);
+static char *mipsexcep(Map*, Rgetter);
+static int mipsfoll(Map*, uvlong, Rgetter, uvlong*);
+static int mipsinst(Map*, uvlong, char, char*, int);
+static int mipsdas(Map*, uvlong, char*, int);
+static int mipsinstlen(Map*, uvlong);
+
/*
* Debugger interface
*/
@@ -33,6 +34,73 @@ Machdata mipsmach =
mipsinstlen, /* instruction size */
};
+Machdata mipsmachle =
+{
+ {0, 0, 0, 0xD}, /* break point */
+ 4, /* break point size */
+
+ leswab, /* short to local byte order */
+ leswal, /* long to local byte order */
+ leswav, /* vlong to local byte order */
+ risctrace, /* C traceback */
+ riscframe, /* Frame finder */
+ mipsexcep, /* print exception */
+ 0, /* breakpoint fixup */
+ leieeesftos, /* single precision float printer */
+ leieeedftos, /* double precisioin float printer */
+ mipsfoll, /* following addresses */
+ mipsinst, /* print instruction */
+ mipsdas, /* dissembler */
+ mipsinstlen, /* instruction size */
+};
+
+/*
+ * mips r4k little-endian
+ */
+Machdata mipsmach2le =
+{
+ {0, 0, 0, 0xD}, /* break point */
+ 4, /* break point size */
+
+ leswab, /* short to local byte order */
+ leswal, /* long to local byte order */
+ leswav, /* vlong to local byte order */
+ risctrace, /* C traceback */
+ riscframe, /* Frame finder */
+ mipsexcep, /* print exception */
+ 0, /* breakpoint fixup */
+ leieeesftos, /* single precision float printer */
+ leieeedftos, /* double precisioin float printer */
+ mipsfoll, /* following addresses */
+ mipsinst, /* print instruction */
+ mipsdas, /* dissembler */
+ mipsinstlen, /* instruction size */
+};
+
+/*
+ * mips r4k big-endian
+ */
+Machdata mipsmach2be =
+{
+ {0, 0, 0, 0xD}, /* break point */
+ 4, /* break point size */
+
+ beswab, /* short to local byte order */
+ beswal, /* long to local byte order */
+ beswav, /* vlong to local byte order */
+ risctrace, /* C traceback */
+ riscframe, /* Frame finder */
+ mipsexcep, /* print exception */
+ 0, /* breakpoint fixup */
+ beieeesftos, /* single precision float printer */
+ beieeedftos, /* double precisioin float printer */
+ mipsfoll, /* following addresses */
+ mipsinst, /* print instruction */
+ mipsdas, /* dissembler */
+ mipsinstlen, /* instruction size */
+};
+
+
static char *excname[] =
{
"external interrupt",
@@ -55,7 +123,7 @@ static char *excname[] =
"floating point exception" /* FPEXC */
};
-char*
+static char*
mipsexcep(Map *map, Rgetter rget)
{
int e;
@@ -74,7 +142,7 @@ mipsexcep(Map *map, Rgetter rget)
static char FRAMENAME[] = ".frame";
typedef struct {
- ulong addr;
+ uvlong addr;
uchar op; /* bits 31-26 */
uchar rs; /* bits 25-21 */
uchar rt; /* bits 20-16 */
@@ -95,14 +163,15 @@ typedef struct {
static Map *mymap;
static int
-decode(ulong pc, Instr *i)
+decode(uvlong pc, Instr *i)
{
- long w;
+ ulong w;
if (get4(mymap, pc, &w) < 0) {
werrstr("can't read instruction: %r");
return -1;
}
+
i->addr = pc;
i->size = 1;
i->op = (w >> 26) & 0x3F;
@@ -121,7 +190,7 @@ decode(ulong pc, Instr *i)
}
static int
-mkinstr(ulong pc, Instr *i)
+mkinstr(uvlong pc, Instr *i)
{
Instr x;
@@ -173,6 +242,8 @@ mkinstr(ulong pc, Instr *i)
return 1;
}
+#pragma varargck argpos bprint 2
+
static void
bprint(Instr *i, char *fmt, ...)
{
@@ -942,7 +1013,7 @@ cop1(Instr *i)
}
static int
-printins(Map *map, ulong pc, char *buf, int n)
+printins(Map *map, uvlong pc, char *buf, int n)
{
Instr i;
Opcode *o;
@@ -995,11 +1066,11 @@ printins(Map *map, ulong pc, char *buf, int n)
return i.size*4;
}
-extern int _mipscoinst(Map *, ulong, char*, int);
+extern int _mipscoinst(Map *, uvlong, char*, int);
/* modifier 'I' toggles the default disassembler type */
-int
-mipsinst(Map *map, ulong pc, char modifier, char *buf, int n)
+static int
+mipsinst(Map *map, uvlong pc, char modifier, char *buf, int n)
{
if ((asstype == AMIPSCO && modifier == 'i')
|| (asstype == AMIPS && modifier == 'I'))
@@ -1008,8 +1079,8 @@ mipsinst(Map *map, ulong pc, char modifier, char *buf, int n)
return printins(map, pc, buf, n);
}
-int
-mipsdas(Map *map, ulong pc, char *buf, int n)
+static int
+mipsdas(Map *map, uvlong pc, char *buf, int n)
{
Instr i;
@@ -1028,8 +1099,8 @@ mipsdas(Map *map, ulong pc, char *buf, int n)
return i.size*4;
}
-int
-mipsinstlen(Map *map, ulong pc)
+static int
+mipsinstlen(Map *map, uvlong pc)
{
Instr i;
@@ -1039,8 +1110,8 @@ mipsinstlen(Map *map, ulong pc)
return i.size*4;
}
-int
-mipsfoll(Map *map, ulong pc, Rgetter rget, ulong *foll)
+static int
+mipsfoll(Map *map, uvlong pc, Rgetter rget, uvlong *foll)
{
ulong w, l;
char buf[8];