17 _(a) _(b) _(c) _(d) _(si) _(di) _(bp)
18 #elif defined(__x86_64__)
20 _(a) _(b) _(c) _(d) _(si) _(di) _(bp) \
21 _(r8) _(r9) _(r10) _(r11) _(r12) _(r13) _(r14) _(r15)
22 #elif defined(__arm__)
24 _(r0) _(r1) _(r2) _(r3) _(r4) _(r5) _(r6) _(r7) \
25 _(r8) _(r9) _(r10) _(r11) _(r12)
26 #elif defined(__aarch64__)
28 _(x0) _(x1) _(x2) _(x3) _(x4) _(x5) _(x6) _(x7) \
29 _(x8) _(x9) _(x10) _(x11) _(x12) _(x13) _(x14) _(x15) \
30 _(x16) _(x17) _(x19) _(x20) _(x21) _(x22) _(x23) \
31 _(x24) _(x25) _(x26) _(x27) _(x28) _(x29)
33 # error "not supported"
37 #define DEFCONST(r) R_##r,
44 static const char *const rname
[] = {
45 #define DEFNAME(r) #r,
60 #define N(v) (sizeof(v)/sizeof((v)[0]))
62 #define STRCMP(a, op, b) (strcmp((a), (b)) op 0)
63 #define STRNCMP(a, op, b, n) (strncmp((a), (b), (n)) op 0)
64 #define CTYPE_HACK(func, ch) func((unsigned char)(ch))
65 #define ISDIGIT(ch) CTYPE_HACK(isdigit, ch)
66 #define ISSPACE(ch) CTYPE_HACK(isspace, ch)
69 _(x00) _(x01) _(x02) _(x03) _(x04) _(x05) _(x06) _(x07) \
70 _(x08) _(x09) _(x0a) _(x0b) _(x0c) _(x0d) _(x0e) _(x0f) \
71 _(x10) _(x11) _(x12) _(x13) _(x14) _(x15) _(x16) _(x17) \
72 _(x18) _(x19) _(x1a) _(x1b) _(x1c) _(x1d) _(x1e) _(x1f) \
73 _(x20) _(x21) _(x22) _(x23) _(x24) _(x25) _(x26) _(x27) \
74 _(x28) _(x29) _(x2a) _(x2b) _(x2c) _(x2d) _(x2e) _(x2f) \
75 _(x30) _(x31) _(x32) _(x33) _(x34) _(x35) _(x36) _(x37) \
76 _(x38) _(x39) _(x3a) _(x3b) _(x3c) _(x3d) _(x3e) _(x3f)
78 #define DECL(x) extern const int x;
82 static const int *x
[] = {
87 extern void call_example(const int *f
, struct regs
*r
);
89 static const char *prog
= "???";
91 __attribute__((format(printf
, 1, 2), noreturn
))
92 static void barf(const char *m
, ...)
97 fprintf(stderr
, "%s: ", prog
);
98 vfprintf(stderr
, m
, ap
);
104 static void *xmalloc(size_t sz
)
110 if (!p
) barf("malloc failed");
114 #define DEF_PARSEINT(name, ty, strto) \
115 static ty parse_##name(const char *what, const char *p, ty min, ty max) \
117 const char *pp = p; \
122 if (ISSPACE(*p)) goto bad; \
123 err = errno; errno = 0; \
124 i = strto(p, &q, 0); \
125 if (errno) goto bad; \
127 if (i < min || i > max) goto bad; \
132 barf("bad %s `%s'", what, pp); \
134 DEF_PARSEINT(long, long, strtol
)
135 DEF_PARSEINT(ulong
, unsigned long, strtoul
)
137 static int hex_digit(char ch
)
139 if ('0' <= ch
&& ch
<= '9') return (ch
- '0');
140 else if ('A' <= ch
&& ch
<= 'F') return (ch
- 'A' + 10);
141 else if ('a' <= ch
&& ch
<= 'f') return (ch
- 'a' + 10);
145 static void setreg(union reg
*r
, struct seg
**seg_inout
, const char *p
)
153 #define LONG_REG(p) (parse_long("signed register", (p), LONG_MIN, LONG_MAX))
154 #define ULONG_REG(p) (parse_ulong("unsigned register", (p), 0, ULONG_MAX))
158 if (p
[1]) r
->i
= LONG_REG(p
);
161 if (p
[1] != ':') goto bad
;
162 r
->i
= LONG_REG(p
+ 2);
165 if (p
[1] != ':') goto bad
;
166 r
->u
= ULONG_REG(p
+ 2);
169 if (p
[1] != ':' || p
[3]) goto bad
;
173 if (p
[1] != ':') goto bad
;
174 pp
= p
+ 2; n
= strlen(pp
) + 1;
175 seg
= (*seg_inout
)++; seg
->p
= xmalloc(n
); seg
->sz
= n
;
176 memcpy(seg
->p
, pp
, n
); r
->p
= seg
->p
;
179 if (p
[1] != ':') goto bad
;
180 pp
= p
+ 2; n
= strlen(pp
); if (n
%2) goto bad
;
181 seg
= (*seg_inout
)++; seg
->p
= q
= xmalloc(n
/2); seg
->sz
= n
/2;
183 hi
= hex_digit(pp
[0]); lo
= hex_digit(pp
[1]);
184 if (hi
< 0 || lo
< 0) goto bad
;
185 *q
++ = 16*hi
+ lo
; n
-= 2; pp
+= 2;
190 if (p
[1] != ':') goto bad
;
191 n
= parse_ulong("buffer length", p
+ 2, 0, ~(size_t)0);
192 seg
= (*seg_inout
)++; seg
->p
= q
= xmalloc(n
); seg
->sz
= n
;
193 r
->p
= q
; memset(q
, 0, n
);
196 if (ISDIGIT(*p
)) r
->u
= ULONG_REG(p
);
197 else if (*p
== '+') r
->i
= LONG_REG(p
);
198 else if (*p
== '\'' && p
[2] == '\'' && !p
[3]) r
->u
= p
[1];
202 barf("bad regspec `%s'", p
);
209 static void dumpreg(const char *name
, const union reg
*r
,
210 const struct seg
*seg
, size_t nseg
)
214 #if ULONG_MAX == 0xffffffff
215 printf("%3s = 0x%08lx = %20ld = %20lu", name
, r
->u
, r
->i
, r
->u
);
217 printf("%3s = 0x%016lx = %20ld = %20lu", name
, r
->u
, r
->i
, r
->u
);
219 if (r
->u
>= ' ' && r
->u
<= '~') printf(" = '%c'", (int)r
->u
);
220 for (i
= 0; i
< nseg
; i
++) {
221 if (r
->p
== seg
[i
].p
)
222 printf(" = seg[%zu] base", i
);
223 else if (r
->p
== seg
[i
].p
+ seg
[i
].sz
)
224 printf(" = seg[%zu] limit", i
);
225 else if (seg
[i
].p
< r
->p
&& r
->p
< seg
[i
].p
+ seg
[i
].sz
)
226 printf(" = seg[%zu] + %zu", i
, (size_t)(r
->p
- seg
[i
].p
));
231 static void dumpseg(const struct seg
*seg
)
236 for (i
= 0; i
< seg
->sz
; i
+= 8) {
237 printf("\t%8zx :", i
);
238 for (j
= 0; j
< 8; j
++)
239 if (i
+ j
>= seg
->sz
) printf(" **");
240 else printf(" %02x", seg
->p
[i
+ j
]);
242 for (j
= 0; j
< 8; j
++)
243 if (i
+ j
>= seg
->sz
) putchar('*');
246 if (' ' <= ch
&& ch
<= '~') putchar(ch
);
253 int main(int argc
, char *argv
[])
256 struct seg seg
[16], *segp
= seg
;
264 prog
= strrchr(argv
[0], '/'); if (prog
) prog
++; else prog
= argv
[0];
267 barf("usage: %s I [REG...]",
270 j
= parse_long("program index", argv
[1], -1, N(x
) - 1);
272 #if ULONG_MAX == 0xffffffff
273 # define DEAD 0xdeadbeef
275 # define DEAD 0xdeadbeefdeadbeef
277 for (i
= 0; i
< NREGS
- 1; i
++) r
.r
[i
].u
= DEAD
;
286 l
= strtoul(p
, &q
, 10);
287 if (l
< NREGS
&& *q
== '=') { p
= q
+ 1; i
= l
; }
288 } else for (k
= 0; k
< NREGS
; k
++) {
289 n
= strlen(rname
[k
]);
290 if (STRNCMP(p
, ==, rname
[k
], n
) && p
[n
] == '=')
291 { i
= k
; p
+= n
+ 1; break; }
293 if (i
>= NREGS
) barf("too many registers");
294 setreg(&r
.r
[i
], &segp
, p
); i
++;
298 call_example(j
< 0 ?
&nop
: x
[j
], &r
);
300 for (i
= 0; i
< NREGS
; i
++) dumpreg(rname
[i
], &r
.r
[i
], seg
, nseg
);
304 #if defined(__i386__) || defined(__x86_64__)
312 printf("\tstatus: %ccf %cpf %caf %czf %csf %cdf %cof\n",
313 (f
>> 0)&1u ?
'+' : '-',
314 (f
>> 2)&1u ?
'+' : '-',
315 (f
>> 4)&1u ?
'+' : '-',
316 (f
>> 6)&1u ?
'+' : '-',
317 (f
>> 7)&1u ?
'+' : '-',
318 (f
>> 10)&1u ?
'+' : '-',
319 (f
>> 11)&1u ?
'+' : '-');
321 if (f
&CF
) printf(" c/b/nae"); else printf(" nc/ae/nb");
322 if (f
&ZF
) printf(" e/z"); else printf(" ne/nz");
323 if (f
&SF
) printf(" s"); else printf(" ns");
324 if (f
&OF
) printf(" o"); else printf(" no");
325 if (f
&PF
) printf(" p"); else printf(" np");
326 if ((f
&CF
) || (f
&ZF
)) printf(" be/na"); else printf(" a/nbe");
327 if (!(f
&OF
) == !(f
&SF
)) printf(" ge/nl"); else printf(" l/nge");
328 if (!(f
&OF
) == !(f
&SF
) && !(f
&ZF
))
329 printf(" g/nle"); else printf(" le/ng");
331 printf("\tsystem: %ctf %cif iopl=%d %cnt "
332 "%crf %cvm %cac %cvif %cvip %cid\n",
333 (f
>> 8)&1u ?
'+' : '-',
334 (f
>> 9)&1u ?
'+' : '-',
336 (f
>> 14)&1u ?
'+' : '-',
337 (f
>> 16)&1u ?
'+' : '-',
338 (f
>> 17)&1u ?
'+' : '-',
339 (f
>> 18)&1u ?
'+' : '-',
340 (f
>> 19)&1u ?
'+' : '-',
341 (f
>> 20)&1u ?
'+' : '-',
342 (f
>> 21)&1u ?
'+' : '-');
350 #elif defined(__arm__)
352 #define NF (1u << 31)
353 #define ZF (1u << 30)
354 #define CF (1u << 29)
355 #define VF (1u << 28)
359 *modetab
[] = { "?00", "?01", "?02", "?03", "?04", "?05", "?06", "?07",
360 "?08", "?09", "?10", "?11", "?12", "?13", "?14", "?15",
361 "usr", "fiq", "irq", "svc", "?20", "?21", "mon", "abt",
362 "?24", "?25", "hyp", "und", "?28", "?29", "?30", "sys" },
363 *condtab
[] = { "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
364 "hi", "ls", "ge", "lt", "gt", "le", "al", "nv" };
366 printf("\tuser: %cn %cz %cc %cv %cq ge=%c%c%c%c;",
367 (f
>> 31)&1u ?
'+' : '-',
368 (f
>> 30)&1u ?
'+' : '-',
369 (f
>> 29)&1u ?
'+' : '-',
370 (f
>> 28)&1u ?
'+' : '-',
371 (f
>> 27)&1u ?
'+' : '-',
372 (f
>> 19)&1u ?
'1' : '0',
373 (f
>> 18)&1u ?
'1' : '0',
374 (f
>> 17)&1u ?
'1' : '0',
375 (f
>> 16)&1u ?
'1' : '0');
376 if (f
&NF
) printf(" mi"); else printf(" pl");
377 if (f
&ZF
) printf(" eq"); else printf(" ne");
378 if (f
&CF
) printf(" cs/hs"); else printf(" cc/lo");
379 if (f
&VF
) printf(" vs"); else printf(" vc");
380 if ((f
&CF
) && !(f
&ZF
)) printf(" hi"); else printf(" ls");
381 if (!(f
&VF
) == !(f
&NF
)) printf(" ge"); else printf(" lt");
382 if (!(f
&VF
) == !(f
&NF
) && !(f
&ZF
)) printf(" gt"); else printf(" le");
384 printf("\tsystem: %cj it=%s:%c%c%c%c %ce %ca %ci %cf %ct m=%s\n",
385 (f
>> 24)&1u ?
'+' : '-',
386 condtab
[(f
>> 12)&15u],
387 (f
>> 11)&1u ?
'1' : '0',
388 (f
>> 10)&1u ?
'1' : '0',
389 (f
>> 26)&1u ?
'1' : '0',
390 (f
>> 25)&1u ?
'1' : '0',
391 (f
>> 9)&1u ?
'+' : '-',
392 (f
>> 8)&1u ?
'+' : '-',
393 (f
>> 7)&1u ?
'+' : '-',
394 (f
>> 6)&1u ?
'+' : '-',
395 (f
>> 5)&1u ?
'+' : '-',
396 modetab
[(f
>> 0)&31u]);
404 #elif defined(__aarch64__)
406 #define NF (1u << 31)
407 #define ZF (1u << 30)
408 #define CF (1u << 29)
409 #define VF (1u << 28)
411 printf("\tuser: %cn %cz %cc %cv;",
412 (f
>> 31)&1u ?
'+' : '-',
413 (f
>> 30)&1u ?
'+' : '-',
414 (f
>> 29)&1u ?
'+' : '-',
415 (f
>> 28)&1u ?
'+' : '-');
416 if (f
&NF
) printf(" mi"); else printf(" pl");
417 if (f
&ZF
) printf(" eq"); else printf(" ne");
418 if (f
&CF
) printf(" cs/hs"); else printf(" cc/lo");
419 if (f
&VF
) printf(" vs"); else printf(" vc");
420 if ((f
&CF
) && !(f
&ZF
)) printf(" hi"); else printf(" ls");
421 if (!(f
&VF
) == !(f
&NF
)) printf(" ge"); else printf(" lt");
422 if (!(f
&VF
) == !(f
&NF
) && !(f
&ZF
)) printf(" gt"); else printf(" le");
431 # error "not supported"
434 for (i
= 0; i
< nseg
; i
++)
435 { printf("seg[%d] (%p):\n", i
, seg
[i
].p
); dumpseg(&seg
[i
]); }