long u;
};
+#if defined(__i386__)
+# define GPREGS(_) \
+ _(a) _(b) _(c) _(d) _(si) _(di) _(bp)
+#elif defined(__x86_64__)
+# define GPREGS(_) \
+ _(a) _(b) _(c) _(d) _(si) _(di) _(bp) \
+ _(r8) _(r9) _(r10) _(r11) _(r12) _(r13) _(r14) _(r15)
+#elif defined(__arm__)
+# define GPREGS(_) \
+ _(r0) _(r1) _(r2) _(r3) _(r4) _(r5) _(r6) _(r7) \
+ _(r8) _(r9) _(r10) _(r11) _(r12)
+#elif defined(__aarch64__)
+# define GPREGS(_) \
+ _(x0) _(x1) _(x2) _(x3) _(x4) _(x5) _(x6) _(x7) \
+ _(x8) _(x9) _(x10) _(x11) _(x12) _(x13) _(x14) _(x15) \
+ _(x16) _(x17) _(x19) _(x20) _(x21) _(x22) _(x23) \
+ _(x24) _(x25) _(x26) _(x27) _(x28) _(x29)
+#else
+# error "not supported"
+#endif
+
+enum {
+#define DEFCONST(r) R_##r,
+ GPREGS(DEFCONST)
+#undef DEFCONST
+ R_flags,
+ NREGS
+};
+
+static const char *const rname[] = {
+#define DEFNAME(r) #r,
+ GPREGS(DEFNAME)
+#undef DEFNAME
+ "f"
+};
+
struct regs {
- union reg
- a, b, c, d, si, di, bp, f,
- r8, r9, r10, r11, r12, r13, r14, r15;
+ union reg r[NREGS];
};
struct seg {
#define N(v) (sizeof(v)/sizeof((v)[0]))
+#define STRCMP(a, op, b) (strcmp((a), (b)) op 0)
+#define STRNCMP(a, op, b, n) (strncmp((a), (b), (n)) op 0)
#define CTYPE_HACK(func, ch) func((unsigned char)(ch))
#define ISDIGIT(ch) CTYPE_HACK(isdigit, ch)
#define ISSPACE(ch) CTYPE_HACK(isspace, ch)
else return (-1);
}
-static void setreg(union reg *r,
- struct seg **seg_inout,
- int *i_inout, int argc, char *argv[])
+static void setreg(union reg *r, struct seg **seg_inout, const char *p)
{
struct seg *seg;
- const char *p, *pp;
+ const char *pp;
unsigned char *q;
int hi, lo;
size_t n;
#define LONG_REG(p) (parse_long("signed register", (p), LONG_MIN, LONG_MAX))
#define ULONG_REG(p) (parse_ulong("unsigned register", (p), 0, ULONG_MAX))
- p = *i_inout >= argc ? "-" : argv[(*i_inout)++];
switch (*p) {
case '-':
if (p[1]) r->i = LONG_REG(p);
- else r->u = 0xdeadbeefdeadbeef;
break;
case 'i':
if (p[1] != ':') goto bad;
}
r->p = seg->p;
break;
+ case 'z':
+ if (p[1] != ':') goto bad;
+ n = parse_ulong("buffer length", p + 2, 0, ~(size_t)0);
+ seg = (*seg_inout)++; seg->p = q = xmalloc(n); seg->sz = n;
+ r->p = q; memset(q, 0, n);
+ break;
default:
if (ISDIGIT(*p)) r->u = ULONG_REG(p);
else if (*p == '+') r->i = LONG_REG(p);
{
size_t i;
+#if ULONG_MAX == 0xffffffff
+ printf("%3s = 0x%08lx = %20ld = %20lu", name, r->u, r->i, r->u);
+#else
printf("%3s = 0x%016lx = %20ld = %20lu", name, r->u, r->i, r->u);
+#endif
if (r->u >= ' ' && r->u <= '~') printf(" = '%c'", (int)r->u);
for (i = 0; i < nseg; i++) {
if (r->p == seg[i].p)
{
struct regs r;
struct seg seg[16], *segp = seg;
- size_t nseg;
- int i, j;
+ size_t nseg, n;
+ const char *p;
+ char *q;
+ unsigned long f;
+ int i, j, k;
+ unsigned long l;
prog = strrchr(argv[0], '/'); if (prog) prog++; else prog = argv[0];
if (argc < 2)
- barf("usage: %s I [A B C D SI DI BP R8 R9 R10 R11 R12 R13 R14 R15 F]",
+ barf("usage: %s I [REG...]",
prog);
j = parse_long("program index", argv[1], -1, N(x) - 1);
- i = 2;
- setreg(&r.a, &segp, &i, argc, argv);
- setreg(&r.b, &segp, &i, argc, argv);
- setreg(&r.c, &segp, &i, argc, argv);
- setreg(&r.d, &segp, &i, argc, argv);
- setreg(&r.si, &segp, &i, argc, argv);
- setreg(&r.di, &segp, &i, argc, argv);
- setreg(&r.bp, &segp, &i, argc, argv);
- setreg(&r.r8, &segp, &i, argc, argv);
- setreg(&r.r9, &segp, &i, argc, argv);
- setreg(&r.r10, &segp, &i, argc, argv);
- setreg(&r.r11, &segp, &i, argc, argv);
- setreg(&r.r12, &segp, &i, argc, argv);
- setreg(&r.r13, &segp, &i, argc, argv);
- setreg(&r.r14, &segp, &i, argc, argv);
- setreg(&r.r15, &segp, &i, argc, argv);
- setreg(&r.f, &segp, &i, argc, argv);
- nseg = segp - seg;
+#if ULONG_MAX == 0xffffffff
+# define DEAD 0xdeadbeef
+#else
+# define DEAD 0xdeadbeefdeadbeef
+#endif
+ for (i = 0; i < NREGS - 1; i++) r.r[i].u = DEAD;
+#undef DEAD
+ r.r[R_flags].u = 0;
+
+ i = 0;
+ argv += 2;
+ while (*argv) {
+ p = *argv++;
+ if (ISDIGIT(*p)) {
+ l = strtoul(p, &q, 10);
+ if (l < NREGS && *q == '=') { p = q + 1; i = l; }
+ } else for (k = 0; k < NREGS; k++) {
+ n = strlen(rname[k]);
+ if (STRNCMP(p, ==, rname[k], n) && p[n] == '=')
+ { i = k; p += n + 1; break; }
+ }
+ if (i >= NREGS) barf("too many registers");
+ setreg(&r.r[i], &segp, p); i++;
+ }
+ nseg = segp - seg;
call_example(j < 0 ? &nop : x[j], &r);
- dumpreg("rax", &r.a, seg, nseg);
- dumpreg("rbx", &r.b, seg, nseg);
- dumpreg("rcx", &r.c, seg, nseg);
- dumpreg("rdx", &r.d, seg, nseg);
- dumpreg("rsi", &r.si, seg, nseg);
- dumpreg("rdi", &r.di, seg, nseg);
- dumpreg("rbp", &r.bp, seg, nseg);
- dumpreg("rbp", &r.bp, seg, nseg);
- dumpreg("r8", &r.r8, seg, nseg);
- dumpreg("r9", &r.r9, seg, nseg);
- dumpreg("r10", &r.r10, seg, nseg);
- dumpreg("r11", &r.r11, seg, nseg);
- dumpreg("r12", &r.r12, seg, nseg);
- dumpreg("r13", &r.r13, seg, nseg);
- dumpreg("r14", &r.r14, seg, nseg);
- dumpreg("r15", &r.r15, seg, nseg);
+ for (i = 0; i < NREGS; i++) dumpreg(rname[i], &r.r[i], seg, nseg);
+
+ f = r.r[R_flags].u;
+
+#if defined(__i386__) || defined(__x86_64__)
#define CF (1 << 0)
#define PF (1 << 2)
#define SF (1 << 7)
#define OF (1 << 11)
- dumpreg("f", &r.f, seg, nseg);
printf("\tstatus: %ccf %cpf %caf %czf %csf %cdf %cof\n",
- (r.f.u >> 0)&1u ? '+' : '-',
- (r.f.u >> 2)&1u ? '+' : '-',
- (r.f.u >> 4)&1u ? '+' : '-',
- (r.f.u >> 6)&1u ? '+' : '-',
- (r.f.u >> 7)&1u ? '+' : '-',
- (r.f.u >> 10)&1u ? '+' : '-',
- (r.f.u >> 11)&1u ? '+' : '-');
+ (f >> 0)&1u ? '+' : '-',
+ (f >> 2)&1u ? '+' : '-',
+ (f >> 4)&1u ? '+' : '-',
+ (f >> 6)&1u ? '+' : '-',
+ (f >> 7)&1u ? '+' : '-',
+ (f >> 10)&1u ? '+' : '-',
+ (f >> 11)&1u ? '+' : '-');
printf("\tcond:");
- if (r.f.u&CF) printf(" c/b/nae"); else printf(" nc/ae/nb");
- if (r.f.u&ZF) printf(" e/z"); else printf(" ne/nz");
- if (r.f.u&SF) printf(" s"); else printf(" ns");
- if (r.f.u&OF) printf(" o"); else printf(" no");
- if (r.f.u&PF) printf(" p"); else printf(" np");
- if ((r.f.u&CF) || (r.f.u&ZF)) printf(" be/na"); else printf(" a/nbe");
- if (!(r.f.u&OF) == !(r.f.u&SF)) printf(" ge/nl"); else printf(" l/nge");
- if (!(r.f.u&OF) == !(r.f.u&SF) && !(r.f.u&ZF))
+ if (f&CF) printf(" c/b/nae"); else printf(" nc/ae/nb");
+ if (f&ZF) printf(" e/z"); else printf(" ne/nz");
+ if (f&SF) printf(" s"); else printf(" ns");
+ if (f&OF) printf(" o"); else printf(" no");
+ if (f&PF) printf(" p"); else printf(" np");
+ if ((f&CF) || (f&ZF)) printf(" be/na"); else printf(" a/nbe");
+ if (!(f&OF) == !(f&SF)) printf(" ge/nl"); else printf(" l/nge");
+ if (!(f&OF) == !(f&SF) && !(f&ZF))
printf(" g/nle"); else printf(" le/ng");
putchar('\n');
printf("\tsystem: %ctf %cif iopl=%d %cnt "
"%crf %cvm %cac %cvif %cvip %cid\n",
- (r.f.u >> 8)&1u ? '+' : '-',
- (r.f.u >> 9)&1u ? '+' : '-',
- (int)((r.f.u >> 12)&1u),
- (r.f.u >> 14)&1u ? '+' : '-',
- (r.f.u >> 16)&1u ? '+' : '-',
- (r.f.u >> 17)&1u ? '+' : '-',
- (r.f.u >> 18)&1u ? '+' : '-',
- (r.f.u >> 19)&1u ? '+' : '-',
- (r.f.u >> 20)&1u ? '+' : '-',
- (r.f.u >> 21)&1u ? '+' : '-');
+ (f >> 8)&1u ? '+' : '-',
+ (f >> 9)&1u ? '+' : '-',
+ (int)((f >> 12)&1u),
+ (f >> 14)&1u ? '+' : '-',
+ (f >> 16)&1u ? '+' : '-',
+ (f >> 17)&1u ? '+' : '-',
+ (f >> 18)&1u ? '+' : '-',
+ (f >> 19)&1u ? '+' : '-',
+ (f >> 20)&1u ? '+' : '-',
+ (f >> 21)&1u ? '+' : '-');
#undef CF
#undef PF
#undef SF
#undef OF
+#elif defined(__arm__)
+
+#define NF (1u << 31)
+#define ZF (1u << 30)
+#define CF (1u << 29)
+#define VF (1u << 28)
+
+ {
+ static const char
+ *modetab[] = { "?00", "?01", "?02", "?03", "?04", "?05", "?06", "?07",
+ "?08", "?09", "?10", "?11", "?12", "?13", "?14", "?15",
+ "usr", "fiq", "irq", "svc", "?20", "?21", "mon", "abt",
+ "?24", "?25", "hyp", "und", "?28", "?29", "?30", "sys" },
+ *condtab[] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
+ "hi", "ls", "ge", "lt", "gt", "le", "al", "nv" };
+
+ printf("\tuser: %cn %cz %cc %cv %cq ge=%c%c%c%c;",
+ (f >> 31)&1u ? '+' : '-',
+ (f >> 30)&1u ? '+' : '-',
+ (f >> 29)&1u ? '+' : '-',
+ (f >> 28)&1u ? '+' : '-',
+ (f >> 27)&1u ? '+' : '-',
+ (f >> 19)&1u ? '1' : '0',
+ (f >> 18)&1u ? '1' : '0',
+ (f >> 17)&1u ? '1' : '0',
+ (f >> 16)&1u ? '1' : '0');
+ if (f&NF) printf(" mi"); else printf(" pl");
+ if (f&ZF) printf(" eq"); else printf(" ne");
+ if (f&CF) printf(" cs/hs"); else printf(" cc/lo");
+ if (f&VF) printf(" vs"); else printf(" vc");
+ if ((f&CF) && !(f&ZF)) printf(" hi"); else printf(" ls");
+ if (!(f&VF) == !(f&NF)) printf(" ge"); else printf(" lt");
+ if (!(f&VF) == !(f&NF) && !(f&ZF)) printf(" gt"); else printf(" le");
+ putchar('\n');
+ printf("\tsystem: %cj it=%s:%c%c%c%c %ce %ca %ci %cf %ct m=%s\n",
+ (f >> 24)&1u ? '+' : '-',
+ condtab[(f >> 12)&15u],
+ (f >> 11)&1u ? '1' : '0',
+ (f >> 10)&1u ? '1' : '0',
+ (f >> 26)&1u ? '1' : '0',
+ (f >> 25)&1u ? '1' : '0',
+ (f >> 9)&1u ? '+' : '-',
+ (f >> 8)&1u ? '+' : '-',
+ (f >> 7)&1u ? '+' : '-',
+ (f >> 6)&1u ? '+' : '-',
+ (f >> 5)&1u ? '+' : '-',
+ modetab[(f >> 0)&31u]);
+ }
+
+#undef NF
+#undef ZF
+#undef CF
+#undef VF
+
+#elif defined(__aarch64__)
+
+#define NF (1u << 31)
+#define ZF (1u << 30)
+#define CF (1u << 29)
+#define VF (1u << 28)
+
+ printf("\tuser: %cn %cz %cc %cv;",
+ (f >> 31)&1u ? '+' : '-',
+ (f >> 30)&1u ? '+' : '-',
+ (f >> 29)&1u ? '+' : '-',
+ (f >> 28)&1u ? '+' : '-');
+ if (f&NF) printf(" mi"); else printf(" pl");
+ if (f&ZF) printf(" eq"); else printf(" ne");
+ if (f&CF) printf(" cs/hs"); else printf(" cc/lo");
+ if (f&VF) printf(" vs"); else printf(" vc");
+ if ((f&CF) && !(f&ZF)) printf(" hi"); else printf(" ls");
+ if (!(f&VF) == !(f&NF)) printf(" ge"); else printf(" lt");
+ if (!(f&VF) == !(f&NF) && !(f&ZF)) printf(" gt"); else printf(" le");
+ putchar('\n');
+
+#undef NF
+#undef ZF
+#undef CF
+#undef VF
+
+#else
+# error "not supported"
+#endif
+
for (i = 0; i < nseg; i++)
{ printf("seg[%d] (%p):\n", i, seg[i].p); dumpseg(&seg[i]); }