17 a
, b
, c
, d
, si
, di
, bp
, f
,
18 r8
, r9
, r10
, r11
, r12
, r13
, r14
, r15
;
26 #define N(v) (sizeof(v)/sizeof((v)[0]))
28 #define CTYPE_HACK(func, ch) func((unsigned char)(ch))
29 #define ISDIGIT(ch) CTYPE_HACK(isdigit, ch)
30 #define ISSPACE(ch) CTYPE_HACK(isspace, ch)
33 _(x00) _(x01) _(x02) _(x03) _(x04) _(x05) _(x06) _(x07) \
34 _(x08) _(x09) _(x0a) _(x0b) _(x0c) _(x0d) _(x0e) _(x0f) \
35 _(x10) _(x11) _(x12) _(x13) _(x14) _(x15) _(x16) _(x17) \
36 _(x18) _(x19) _(x1a) _(x1b) _(x1c) _(x1d) _(x1e) _(x1f) \
37 _(x20) _(x21) _(x22) _(x23) _(x24) _(x25) _(x26) _(x27) \
38 _(x28) _(x29) _(x2a) _(x2b) _(x2c) _(x2d) _(x2e) _(x2f) \
39 _(x30) _(x31) _(x32) _(x33) _(x34) _(x35) _(x36) _(x37) \
40 _(x38) _(x39) _(x3a) _(x3b) _(x3c) _(x3d) _(x3e) _(x3f)
42 #define DECL(x) extern const int x;
46 static const int *x
[] = {
51 extern void call_example(const int *f
, struct regs
*r
);
53 static const char *prog
= "???";
55 __attribute__((format(printf
, 1, 2), noreturn
))
56 static void barf(const char *m
, ...)
61 fprintf(stderr
, "%s: ", prog
);
62 vfprintf(stderr
, m
, ap
);
68 static void *xmalloc(size_t sz
)
74 if (!p
) barf("malloc failed");
78 #define DEF_PARSEINT(name, ty, strto) \
79 static ty parse_##name(const char *what, const char *p, ty min, ty max) \
86 if (ISSPACE(*p)) goto bad; \
87 err = errno; errno = 0; \
88 i = strto(p, &q, 0); \
89 if (errno) goto bad; \
91 if (i < min || i > max) goto bad; \
96 barf("bad %s `%s'", what, pp); \
98 DEF_PARSEINT(long, long, strtol
)
99 DEF_PARSEINT(ulong
, unsigned long, strtoul
)
101 static int hex_digit(char ch
)
103 if ('0' <= ch
&& ch
<= '9') return (ch
- '0');
104 else if ('A' <= ch
&& ch
<= 'F') return (ch
- 'A' + 10);
105 else if ('a' <= ch
&& ch
<= 'f') return (ch
- 'a' + 10);
109 static void setreg(union reg
*r
,
110 struct seg
**seg_inout
,
111 int *i_inout
, int argc
, char *argv
[])
119 #define LONG_REG(p) (parse_long("signed register", (p), LONG_MIN, LONG_MAX))
120 #define ULONG_REG(p) (parse_ulong("unsigned register", (p), 0, ULONG_MAX))
122 p
= *i_inout
>= argc ?
"-" : argv
[(*i_inout
)++];
125 if (p
[1]) r
->i
= LONG_REG(p
);
126 else r
->u
= 0xdeadbeefdeadbeef;
129 if (p
[1] != ':') goto bad
;
130 r
->i
= LONG_REG(p
+ 2);
133 if (p
[1] != ':') goto bad
;
134 r
->u
= ULONG_REG(p
+ 2);
137 if (p
[1] != ':' || p
[3]) goto bad
;
141 if (p
[1] != ':') goto bad
;
142 pp
= p
+ 2; n
= strlen(pp
) + 1;
143 seg
= (*seg_inout
)++; seg
->p
= xmalloc(n
); seg
->sz
= n
;
144 memcpy(seg
->p
, pp
, n
); r
->p
= seg
->p
;
147 if (p
[1] != ':') goto bad
;
148 pp
= p
+ 2; n
= strlen(pp
); if (n
%2) goto bad
;
149 seg
= (*seg_inout
)++; seg
->p
= q
= xmalloc(n
/2); seg
->sz
= n
/2;
151 hi
= hex_digit(pp
[0]); lo
= hex_digit(pp
[1]);
152 if (hi
< 0 || lo
< 0) goto bad
;
153 *q
++ = 16*hi
+ lo
; n
-= 2; pp
+= 2;
158 if (ISDIGIT(*p
)) r
->u
= ULONG_REG(p
);
159 else if (*p
== '+') r
->i
= LONG_REG(p
);
160 else if (*p
== '\'' && p
[2] == '\'' && !p
[3]) r
->u
= p
[1];
164 barf("bad regspec `%s'", p
);
171 static void dumpreg(const char *name
, const union reg
*r
,
172 const struct seg
*seg
, size_t nseg
)
176 printf("%3s = 0x%016lx = %20ld = %20lu", name
, r
->u
, r
->i
, r
->u
);
177 if (r
->u
>= ' ' && r
->u
<= '~') printf(" = '%c'", (int)r
->u
);
178 for (i
= 0; i
< nseg
; i
++) {
179 if (r
->p
== seg
[i
].p
)
180 printf(" = seg[%zu] base", i
);
181 else if (r
->p
== seg
[i
].p
+ seg
[i
].sz
)
182 printf(" = seg[%zu] limit", i
);
183 else if (seg
[i
].p
< r
->p
&& r
->p
< seg
[i
].p
+ seg
[i
].sz
)
184 printf(" = seg[%zu] + %zu", i
, (size_t)(r
->p
- seg
[i
].p
));
189 static void dumpseg(const struct seg
*seg
)
194 for (i
= 0; i
< seg
->sz
; i
+= 8) {
195 printf("\t%8zx :", i
);
196 for (j
= 0; j
< 8; j
++)
197 if (i
+ j
>= seg
->sz
) printf(" **");
198 else printf(" %02x", seg
->p
[i
+ j
]);
200 for (j
= 0; j
< 8; j
++)
201 if (i
+ j
>= seg
->sz
) putchar('*');
204 if (' ' <= ch
&& ch
<= '~') putchar(ch
);
211 int main(int argc
, char *argv
[])
214 struct seg seg
[16], *segp
= seg
;
218 prog
= strrchr(argv
[0], '/'); if (prog
) prog
++; else prog
= argv
[0];
221 barf("usage: %s I [A B C D SI DI BP R8 R9 R10 R11 R12 R13 R14 R15 F]",
224 j
= parse_long("program index", argv
[1], -1, N(x
) - 1);
227 setreg(&r
.a
, &segp
, &i
, argc
, argv
);
228 setreg(&r
.b
, &segp
, &i
, argc
, argv
);
229 setreg(&r
.c
, &segp
, &i
, argc
, argv
);
230 setreg(&r
.d
, &segp
, &i
, argc
, argv
);
231 setreg(&r
.si
, &segp
, &i
, argc
, argv
);
232 setreg(&r
.di
, &segp
, &i
, argc
, argv
);
233 setreg(&r
.bp
, &segp
, &i
, argc
, argv
);
234 setreg(&r
.r8
, &segp
, &i
, argc
, argv
);
235 setreg(&r
.r9
, &segp
, &i
, argc
, argv
);
236 setreg(&r
.r10
, &segp
, &i
, argc
, argv
);
237 setreg(&r
.r11
, &segp
, &i
, argc
, argv
);
238 setreg(&r
.r12
, &segp
, &i
, argc
, argv
);
239 setreg(&r
.r13
, &segp
, &i
, argc
, argv
);
240 setreg(&r
.r14
, &segp
, &i
, argc
, argv
);
241 setreg(&r
.r15
, &segp
, &i
, argc
, argv
);
242 setreg(&r
.f
, &segp
, &i
, argc
, argv
);
245 call_example(j
< 0 ?
&nop
: x
[j
], &r
);
247 dumpreg("rax", &r
.a
, seg
, nseg
);
248 dumpreg("rbx", &r
.b
, seg
, nseg
);
249 dumpreg("rcx", &r
.c
, seg
, nseg
);
250 dumpreg("rdx", &r
.d
, seg
, nseg
);
251 dumpreg("rsi", &r
.si
, seg
, nseg
);
252 dumpreg("rdi", &r
.di
, seg
, nseg
);
253 dumpreg("rbp", &r
.bp
, seg
, nseg
);
254 dumpreg("rbp", &r
.bp
, seg
, nseg
);
255 dumpreg("r8", &r
.r8
, seg
, nseg
);
256 dumpreg("r9", &r
.r9
, seg
, nseg
);
257 dumpreg("r10", &r
.r10
, seg
, nseg
);
258 dumpreg("r11", &r
.r11
, seg
, nseg
);
259 dumpreg("r12", &r
.r12
, seg
, nseg
);
260 dumpreg("r13", &r
.r13
, seg
, nseg
);
261 dumpreg("r14", &r
.r14
, seg
, nseg
);
262 dumpreg("r15", &r
.r15
, seg
, nseg
);
270 dumpreg("f", &r
.f
, seg
, nseg
);
271 printf("\tstatus: %ccf %cpf %caf %czf %csf %cdf %cof\n",
272 (r
.f
.u
>> 0)&1u ?
'+' : '-',
273 (r
.f
.u
>> 2)&1u ?
'+' : '-',
274 (r
.f
.u
>> 4)&1u ?
'+' : '-',
275 (r
.f
.u
>> 6)&1u ?
'+' : '-',
276 (r
.f
.u
>> 7)&1u ?
'+' : '-',
277 (r
.f
.u
>> 10)&1u ?
'+' : '-',
278 (r
.f
.u
>> 11)&1u ?
'+' : '-');
280 if (r
.f
.u
&CF
) printf(" c/b/nae"); else printf(" nc/ae/nb");
281 if (r
.f
.u
&ZF
) printf(" e/z"); else printf(" ne/nz");
282 if (r
.f
.u
&SF
) printf(" s"); else printf(" ns");
283 if (r
.f
.u
&OF
) printf(" o"); else printf(" no");
284 if (r
.f
.u
&PF
) printf(" p"); else printf(" np");
285 if ((r
.f
.u
&CF
) || (r
.f
.u
&ZF
)) printf(" be/na"); else printf(" a/nbe");
286 if (!(r
.f
.u
&OF
) == !(r
.f
.u
&SF
)) printf(" ge/nl"); else printf(" l/nge");
287 if (!(r
.f
.u
&OF
) == !(r
.f
.u
&SF
) && !(r
.f
.u
&ZF
))
288 printf(" g/nle"); else printf(" le/ng");
290 printf("\tsystem: %ctf %cif iopl=%d %cnt "
291 "%crf %cvm %cac %cvif %cvip %cid\n",
292 (r
.f
.u
>> 8)&1u ?
'+' : '-',
293 (r
.f
.u
>> 9)&1u ?
'+' : '-',
294 (int)((r
.f
.u
>> 12)&1u),
295 (r
.f
.u
>> 14)&1u ?
'+' : '-',
296 (r
.f
.u
>> 16)&1u ?
'+' : '-',
297 (r
.f
.u
>> 17)&1u ?
'+' : '-',
298 (r
.f
.u
>> 18)&1u ?
'+' : '-',
299 (r
.f
.u
>> 19)&1u ?
'+' : '-',
300 (r
.f
.u
>> 20)&1u ?
'+' : '-',
301 (r
.f
.u
>> 21)&1u ?
'+' : '-');
309 for (i
= 0; i
< nseg
; i
++)
310 { printf("seg[%d] (%p):\n", i
, seg
[i
].p
); dumpseg(&seg
[i
]); }