2 * Copyright (C) 2009-2011 Marcelina KoĆcielnicka <mwk@0x04.net>
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
25 #include "dis-intern.h"
30 const struct disisa
*isa
;
31 struct varinfo
*varinfo
;
39 static inline ull
bf_(int s
, int l
, ull
*a
, ull
*m
) {
43 ull m0
= (((1ull << l
) - 1) << bit
);
45 res
|= (a
[idx
] & m0
) >> bit
;
47 ull m1
= (((1ull << l
) - 1) >> (0x40 - bit
));
49 res
|= (a
[idx
+1] & m1
) << (0x40 - bit
);
53 #define BF(s, l) bf_(s, l, a, m)
55 ull
getbf(const struct bitfield
*bf
, ull
*a
, ull
*m
) {
59 for (i
= 0; i
< sizeof(bf
->sbf
) / sizeof(bf
->sbf
[0]); i
++) {
60 res
|= BF(bf
->sbf
[i
].pos
, bf
->sbf
[i
].len
) << pos
;
61 pos
+= bf
->sbf
[i
].len
;
67 if (res
& 1ull << (pos
- 1))
70 case BF_SLIGHTLY_SIGNED
:
71 if (res
& 1ull << (pos
- 1) && res
& 1ull << (pos
- 2))
86 struct easm_expr
*getrbf(const struct rbitfield
*bf
, ull
*a
, ull
*m
) {
90 for (i
= 0; i
< sizeof(bf
->sbf
) / sizeof(bf
->sbf
[0]); i
++) {
91 res
|= BF(bf
->sbf
[i
].pos
, bf
->sbf
[i
].len
) << pos
;
92 pos
+= bf
->sbf
[i
].len
;
98 if (res
& 1ull << (pos
- 1))
101 case RBF_SLIGHTLY_SIGNED
:
102 if (res
& 1ull << (pos
- 1) && res
& 1ull << (pos
- 2))
105 case RBF_ULTRASIGNED
:
110 struct easm_expr
*expr
= easm_expr_simple(EASM_EXPR_POS
);
112 expr
= easm_expr_bin(EASM_EXPR_ADD
, expr
, easm_expr_num(EASM_EXPR_NUM
, bf
->pospreadd
));
114 expr
= easm_expr_bin(EASM_EXPR_AND
, expr
, easm_expr_num(EASM_EXPR_NUM
, -(1ull << bf
->shr
)));
115 expr
= easm_expr_bin(EASM_EXPR_ADD
, expr
, easm_expr_num(EASM_EXPR_NUM
, res
));
117 expr
= easm_expr_bin(EASM_EXPR_ADD
, expr
, easm_expr_num(EASM_EXPR_NUM
, bf
->addend
));
121 return easm_expr_num(EASM_EXPR_NUM
, res
);
125 #define GETBF(bf) getbf(bf, a, m)
126 #define GETRBF(bf) getrbf(bf, a, m)
128 static inline struct litem
*makeli(struct easm_expr
*e
) {
129 struct litem
*li
= calloc(sizeof *li
, 1);
130 li
->type
= LITEM_EXPR
;
135 void atomtab_d DPROTO
{
136 const struct insn
*tab
= v
;
138 while ((a
[0]&tab
->mask
) != tab
->val
|| !var_ok(tab
->fmask
, tab
->ptype
, ctx
->varinfo
))
141 for (i
= 0; i
< ARRAY_SIZE(tab
->atoms
); i
++)
142 if (tab
->atoms
[i
].fun_dis
)
143 tab
->atoms
[i
].fun_dis (ctx
, a
, m
, tab
->atoms
[i
].arg
);
146 void atomopl_d DPROTO
{
147 ctx
->oplen
= *(int*)v
;
150 void atomendmark_d DPROTO
{
154 void atomsestart_d DPROTO
{
155 struct litem
*li
= calloc(sizeof *li
, 1);
156 li
->type
= LITEM_SESTART
;
157 ADDARRAY(ctx
->atoms
, li
);
160 void atomseend_d DPROTO
{
161 struct litem
*li
= calloc(sizeof *li
, 1);
162 li
->type
= LITEM_SEEND
;
163 ADDARRAY(ctx
->atoms
, li
);
166 void atomname_d DPROTO
{
167 struct litem
*li
= calloc(sizeof *li
, 1);
168 li
->type
= LITEM_NAME
;
170 ADDARRAY(ctx
->atoms
, li
);
173 void atomcmd_d DPROTO
{
174 struct litem
*li
= makeli(easm_expr_str(EASM_EXPR_LABEL
, strdup(v
)));
175 ADDARRAY(ctx
->atoms
, li
);
178 void atomunk_d DPROTO
{
179 struct litem
*li
= calloc(sizeof *li
, 1);
180 li
->type
= LITEM_NAME
;
183 ADDARRAY(ctx
->atoms
, li
);
186 void atomimm_d DPROTO
{
187 const struct bitfield
*bf
= v
;
188 struct easm_expr
*expr
= easm_expr_num(EASM_EXPR_NUM
, GETBF(bf
));
189 ADDARRAY(ctx
->atoms
, makeli(expr
));
192 void atomrimm_d DPROTO
{
193 const struct rbitfield
*bf
= v
;
194 struct easm_expr
*expr
= GETRBF(bf
);
195 ADDARRAY(ctx
->atoms
, makeli(expr
));
198 void atomctarg_d DPROTO
{
199 const struct rbitfield
*bf
= v
;
200 struct easm_expr
*expr
= GETRBF(bf
);
201 expr
->special
= EASM_SPEC_CTARG
;
202 ADDARRAY(ctx
->atoms
, makeli(expr
));
205 void atombtarg_d DPROTO
{
206 const struct rbitfield
*bf
= v
;
207 struct easm_expr
*expr
= GETRBF(bf
);
208 expr
->special
= EASM_SPEC_BTARG
;
209 ADDARRAY(ctx
->atoms
, makeli(expr
));
212 void atomign_d DPROTO
{
214 (void)BF(n
[0], n
[1]);
217 // print reg if non-0, ignore otherwise. return 1 if printed anything.
218 static struct easm_expr
*printreg (struct disctx
*ctx
, ull
*a
, ull
*m
, const struct reg
*reg
) {
219 struct easm_expr
*expr
;
222 num
= GETBF(reg
->bf
);
225 for (i
= 0; reg
->specials
[i
].num
!= -1; i
++) {
226 if (!var_ok(reg
->specials
[i
].fmask
, 0, ctx
->varinfo
))
228 if (num
== reg
->specials
[i
].num
) {
229 switch (reg
->specials
[i
].mode
) {
231 expr
= easm_expr_str(EASM_EXPR_REG
, strdup(reg
->specials
[i
].name
));
232 expr
->special
= EASM_SPEC_REGSP
;
237 return easm_expr_num(EASM_EXPR_NUM
, 1);
239 return easm_expr_simple(EASM_EXPR_DISCARD
);
244 const char *suf
= "";
256 str
= aprintf("%s%lld%s", reg
->name
, num
, suf
);
258 str
= aprintf("%s%s", reg
->name
, suf
);
259 expr
= easm_expr_str(EASM_EXPR_REG
, str
);
261 expr
->special
= EASM_SPEC_REGSP
;
262 if (reg
->always_special
)
263 expr
->special
= EASM_SPEC_ERR
;
267 void atomreg_d DPROTO
{
268 const struct reg
*reg
= v
;
269 struct easm_expr
*expr
= printreg(ctx
, a
, m
, reg
);
270 if (!expr
) expr
= easm_expr_num(EASM_EXPR_NUM
, 0);
271 ADDARRAY(ctx
->atoms
, makeli(expr
));
274 void atomdiscard_d DPROTO
{
275 struct easm_expr
*expr
= easm_expr_simple(EASM_EXPR_DISCARD
);
276 ADDARRAY(ctx
->atoms
, makeli(expr
));
279 void atommem_d DPROTO
{
280 const struct mem
*mem
= v
;
281 int type
= EASM_EXPR_MEM
;
282 struct easm_expr
*expr
= 0;
283 struct easm_expr
*pexpr
= 0;
285 expr
= printreg(ctx
, a
, m
, mem
->reg
);
287 struct easm_expr
*imm
= GETRBF(mem
->imm
);
289 type
= EASM_EXPR_MEMPP
;
293 expr
= easm_expr_bin(EASM_EXPR_ADD
, expr
, imm
);
300 struct easm_expr
*sexpr
= printreg(ctx
, a
, m
, mem
->reg2
);
303 uint64_t num
= 1ull << mem
->reg2shr
;
304 struct easm_expr
*ssexpr
= easm_expr_num(EASM_EXPR_NUM
, num
);
305 sexpr
= easm_expr_bin(EASM_EXPR_MUL
, sexpr
, ssexpr
);
308 expr
= easm_expr_bin(EASM_EXPR_ADD
, expr
, sexpr
);
313 if (!expr
) expr
= easm_expr_num(EASM_EXPR_NUM
, 0);
315 struct easm_expr
*nex
;
317 nex
= easm_expr_bin(type
, expr
, pexpr
);
319 nex
= easm_expr_un(type
, expr
);
321 nex
->str
= aprintf("%s%lld", mem
->name
, GETBF(mem
->idx
));
323 nex
->str
= strdup(mem
->name
);
324 nex
->mods
= calloc(sizeof *nex
->mods
, 1);
326 } else if (type
!= EASM_EXPR_MEM
) {
329 if (mem
->literal
&& expr
->type
== EASM_EXPR_MEM
)
330 expr
->special
= EASM_SPEC_LITERAL
;
331 ADDARRAY(ctx
->atoms
, makeli(expr
));
334 void atomvec_d DPROTO
{
335 const struct vec
*vec
= v
;
336 struct easm_expr
*expr
= 0;
337 ull base
= GETBF(vec
->bf
);
338 ull cnt
= GETBF(vec
->cnt
);
341 mask
= GETBF(vec
->mask
);
343 for (i
= 0; i
< cnt
; i
++) {
344 struct easm_expr
*sexpr
;
345 if (mask
& 1ull<<i
) {
346 char *name
= aprintf("%s%lld", vec
->name
, base
+ k
++);
347 sexpr
= easm_expr_str(EASM_EXPR_REG
, name
);
349 sexpr
->special
= EASM_SPEC_REGSP
;
351 sexpr
= easm_expr_simple(EASM_EXPR_DISCARD
);
354 expr
= easm_expr_bin(EASM_EXPR_VEC
, expr
, sexpr
);
359 expr
= easm_expr_simple(EASM_EXPR_ZVEC
);
360 ADDARRAY(ctx
->atoms
, makeli(expr
));
363 void atombf_d DPROTO
{
364 const struct bitfield
*bf
= v
;
365 uint64_t num1
= GETBF(&bf
[0]);
366 uint64_t num2
= num1
+ GETBF(&bf
[1]);
367 struct easm_expr
*expr
= easm_expr_bin(EASM_EXPR_VEC
,
368 easm_expr_num(EASM_EXPR_NUM
, num1
),
369 easm_expr_num(EASM_EXPR_NUM
, num2
));
370 ADDARRAY(ctx
->atoms
, makeli(expr
));
373 struct dis_op_chunk
{
381 DIS_STATUS_EOF
= 0x1, /* EOF in the middle of an opcode */
382 DIS_STATUS_UNK_FORM
= 0x2, /* failed to determine instruction format - opcode length uncertain */
383 DIS_STATUS_UNK_INSN
= 0x4, /* failed to determine instruction name - unknown opcode or due to one of the above errors */
384 DIS_STATUS_UNK_OPERAND
= 0x8, /* failed to determine instruction operands */
385 DIS_STATUS_UNUSED_BITS
= 0x10, /* instruction decoded, but unused bitfields have non-default values */
388 struct dis_op_chunk
*chunks
;
393 ull a
[MAXOPLEN
], m
[MAXOPLEN
];
394 struct easm_insn
*insn
;
399 static void dis_del_res(struct dis_res
*dres
)
401 easm_del_insn(dres
->insn
);
406 static struct easm_sinsn
*dis_parse_sinsn(struct disctx
*ctx
, enum dis_status
*status
, int *spos
);
408 static struct easm_expr
*dis_parse_expr(struct disctx
*ctx
, enum dis_status
*status
, int *spos
) {
409 if (*spos
>= ctx
->atomsnum
)
411 if (ctx
->atoms
[*spos
]->type
== LITEM_EXPR
)
412 return ctx
->atoms
[(*spos
)++]->expr
;
413 if (ctx
->atoms
[(*spos
)++]->type
!= LITEM_SESTART
)
415 struct easm_expr
*res
= easm_expr_sinsn(dis_parse_sinsn(ctx
, status
, spos
));
416 if (ctx
->atoms
[(*spos
)++]->type
!= LITEM_SEEND
)
421 static struct easm_sinsn
*dis_parse_sinsn(struct disctx
*ctx
, enum dis_status
*status
, int *spos
) {
422 struct easm_sinsn
*res
= calloc(sizeof *res
, 1);
423 res
->str
= ctx
->atoms
[*spos
]->str
;
424 res
->isunk
= ctx
->atoms
[*spos
]->isunk
;
426 *status
|= DIS_STATUS_UNK_INSN
;
427 if (ctx
->atoms
[(*spos
)++]->type
!= LITEM_NAME
)
429 struct easm_mods
*mods
= calloc (sizeof *mods
, 1);
430 while (*spos
< ctx
->atomsnum
&& ctx
->atoms
[*spos
]->type
!= LITEM_SEEND
) {
431 if (ctx
->atoms
[*spos
]->type
== LITEM_NAME
) {
432 struct easm_mod
*mod
= calloc(sizeof *mod
, 1);
433 mod
->str
= ctx
->atoms
[*spos
]->str
;
434 mod
->isunk
= ctx
->atoms
[*spos
]->isunk
;
436 *status
|= DIS_STATUS_UNK_OPERAND
;
437 ADDARRAY(mods
->mods
, mod
);
440 struct easm_operand
*op
= calloc (sizeof *op
, 1);
442 mods
= calloc (sizeof *mods
, 1);
443 ADDARRAY(op
->exprs
, dis_parse_expr(ctx
, status
, spos
));
444 ADDARRAY(res
->operands
, op
);
451 static struct easm_subinsn
*dis_parse_subinsn(struct disctx
*ctx
, enum dis_status
*status
, int *spos
) {
452 struct easm_subinsn
*res
= calloc(sizeof *res
, 1);
453 while (ctx
->atoms
[*spos
]->type
!= LITEM_NAME
)
454 ADDARRAY(res
->prefs
, dis_parse_expr(ctx
, status
, spos
));
455 res
->sinsn
= dis_parse_sinsn(ctx
, status
, spos
);
459 static struct easm_insn
*dis_parse_insn(struct disctx
*ctx
, enum dis_status
*status
) {
461 struct easm_insn
*res
= calloc(sizeof *res
, 1);
462 ADDARRAY(res
->subinsns
, dis_parse_subinsn(ctx
, status
, &spos
));
463 if (spos
!= ctx
->atomsnum
)
469 const struct disisa
*isa
;
470 struct varinfo
*varinfo
;
476 struct label
*labels
;
481 struct dis_res
*do_dis(struct decoctx
*deco
, uint32_t cur
) {
482 struct disctx c
= { 0 };
483 struct disctx
*ctx
= &c
;
484 struct dis_res
*res
= calloc(sizeof *res
, 1);
486 int stride
= ed_getcstride(deco
->isa
, deco
->varinfo
);
487 for (i
= 0; i
< MAXOPLEN
*8 && cur
+ i
/stride
< deco
->codesz
; i
++) {
488 res
->a
[i
/8] |= (ull
)deco
->code
[cur
*stride
+ i
] << (i
&7)*8;
490 ctx
->isa
= deco
->isa
;
491 ctx
->varinfo
= deco
->varinfo
;
492 if (deco
->isa
->tsched
&& (cur
% deco
->isa
->schedpos
) == 0)
493 atomtab_d (ctx
, res
->a
, res
->m
, deco
->isa
->tsched
);
495 atomtab_d (ctx
, res
->a
, res
->m
, deco
->isa
->troot
);
496 res
->oplen
= ctx
->oplen
;
497 if (res
->oplen
+ cur
> deco
->codesz
)
498 res
->status
|= DIS_STATUS_EOF
;
499 if (res
->oplen
== 0) {
500 res
->status
|= DIS_STATUS_UNK_FORM
;
501 res
->oplen
= ctx
->isa
->opunit
;
503 res
->endmark
= ctx
->endmark
;
504 /* XXX unused status */
505 res
->insn
= dis_parse_insn(ctx
, &res
->status
);
507 for (i
= 0; i
< ctx
->atomsnum
; ++i
)
514 static void mark(struct decoctx
*ctx
, uint32_t ptr
, int m
) {
515 if (ptr
< ctx
->codebase
|| ptr
>= ctx
->codebase
+ ctx
->codesz
)
517 ctx
->marks
[ptr
- ctx
->codebase
] |= m
;
520 static int is_nr_mark(struct decoctx
*ctx
, uint32_t ptr
) {
521 if (ptr
< ctx
->codebase
|| ptr
>= ctx
->codebase
+ ctx
->codesz
)
523 return ctx
->marks
[ptr
- ctx
->codebase
] & 0x40;
526 char *deco_label(struct decoctx
*ctx
, uint64_t val
) {
528 for (i
= 0; i
< ctx
->labelsnum
; i
++)
529 if (ctx
->labels
[i
].val
== val
&& ctx
->labels
[i
].name
)
530 return strdup(ctx
->labels
[i
].name
);
534 static void dis_pp_sinsn(struct decoctx
*deco
, struct dis_res
*dres
, struct easm_sinsn
*sinsn
, uint64_t pos
);
536 static void dis_pp_expr(struct decoctx
*deco
, struct dis_res
*dres
, struct easm_expr
*expr
, uint64_t pos
) {
538 dis_pp_expr(deco
, dres
, expr
->e1
, pos
);
540 dis_pp_expr(deco
, dres
, expr
->e2
, pos
);
542 dis_pp_sinsn(deco
, dres
, expr
->sinsn
, pos
);
543 easm_substpos_expr(expr
, pos
);
544 if (easm_cfold_expr(expr
)) {
545 if (expr
->special
== EASM_SPEC_CTARG
) {
546 mark(deco
, expr
->num
, 2);
547 expr
->alabel
= deco_label(deco
, expr
->num
);
548 if (is_nr_mark(deco
, expr
->num
))
550 } else if (expr
->special
== EASM_SPEC_BTARG
) {
551 mark(deco
, expr
->num
, 1);
552 expr
->alabel
= deco_label(deco
, expr
->num
);
554 if (expr
->num
& 1ull << 63 && !expr
->special
) {
555 expr
->type
= EASM_EXPR_NEG
;
556 expr
->e1
= easm_expr_num(EASM_EXPR_NUM
, -expr
->num
);
560 if (expr
->type
== EASM_EXPR_ADD
&& expr
->e1
->type
== EASM_EXPR_NUM
&& expr
->e1
->num
== 0) {
561 struct easm_expr
*oe2
= expr
->e2
;
566 if ((expr
->type
== EASM_EXPR_ADD
|| expr
->type
== EASM_EXPR_SUB
) && expr
->e2
->type
== EASM_EXPR_NUM
&& expr
->e2
->num
== 0) {
567 struct easm_expr
*oe1
= expr
->e1
;
572 if (expr
->type
== EASM_EXPR_ADD
&& expr
->e2
->type
== EASM_EXPR_NUM
&& expr
->e2
->num
& 1ull << 63) {
573 expr
->e2
->num
= -expr
->e2
->num
;
574 expr
->type
= EASM_EXPR_SUB
;
576 if (expr
->type
== EASM_EXPR_MEM
&& expr
->special
== EASM_SPEC_LITERAL
) {
577 if (expr
->e1
->type
!= EASM_EXPR_NUM
) {
578 expr
->special
= EASM_SPEC_NONE
;
580 ull ptr
= expr
->e1
->num
;
581 mark(deco
, ptr
, 0x10);
582 if (ptr
< deco
->codebase
|| ptr
> deco
->codebase
+ deco
->codesz
) {
583 expr
->special
= EASM_SPEC_NONE
;
585 if (ed_getcbsz(deco
->isa
, deco
->varinfo
) != 8)
589 for (j
= 0; j
< 4; j
++)
590 num
|= deco
->code
[ptr
- deco
->codebase
+ j
] << j
*8;
597 static void dis_pp_sinsn(struct decoctx
*deco
, struct dis_res
*dres
, struct easm_sinsn
*sinsn
, uint64_t pos
) {
599 for (i
= 0; i
< sinsn
->operandsnum
; i
++)
600 for (j
= 0; j
< sinsn
->operands
[i
]->exprsnum
; j
++)
601 dis_pp_expr(deco
, dres
, sinsn
->operands
[i
]->exprs
[j
], pos
);
604 static void dis_pp_subinsn(struct decoctx
*deco
, struct dis_res
*dres
, struct easm_subinsn
*subinsn
, uint64_t pos
) {
606 for (i
= 0; i
< subinsn
->prefsnum
; i
++)
607 dis_pp_expr(deco
, dres
, subinsn
->prefs
[i
], pos
);
608 dis_pp_sinsn(deco
, dres
, subinsn
->sinsn
, pos
);
611 static void dis_pp_insn(struct decoctx
*deco
, struct dis_res
*dres
, struct easm_insn
*insn
, uint64_t pos
) {
613 for (i
= 0; i
< insn
->subinsnsnum
; i
++)
614 dis_pp_subinsn(deco
, dres
, insn
->subinsns
[i
], pos
);
617 void dis_dopp(struct decoctx
*deco
, struct dis_res
*dres
, uint64_t pos
) {
618 dis_pp_insn(deco
, dres
, dres
->insn
, pos
);
622 * Disassembler driver
624 * You pass a block of memory to this function, disassembly goes out to given
628 void envydis (const struct disisa
*isa
, FILE *out
, uint8_t *code
, uint32_t start
, int num
, struct varinfo
*varinfo
, int quiet
, struct label
*labels
, int labelsnum
, const struct envy_colors
*cols
)
630 struct decoctx c
= { 0 };
631 struct decoctx
*ctx
= &c
;
635 ctx
->marks
= calloc(num
, sizeof *ctx
->marks
);
636 ctx
->names
= calloc(num
, sizeof *ctx
->names
);
637 ctx
->codebase
= start
;
638 ctx
->varinfo
= varinfo
;
640 ctx
->labels
= labels
;
641 ctx
->labelsnum
= labelsnum
;
642 int stride
= ed_getcstride(ctx
->isa
, ctx
->varinfo
);
643 int cbsz
= ed_getcbsz(ctx
->isa
, ctx
->varinfo
);
645 for (i
= 0; i
< labelsnum
; i
++) {
646 mark(ctx
, labels
[i
].val
, labels
[i
].type
);
647 if (labels
[i
].val
>= ctx
->codebase
&& labels
[i
].val
< ctx
->codebase
+ ctx
->codesz
) {
649 ctx
->names
[labels
[i
].val
- ctx
->codebase
] = labels
[i
].name
;
651 if (labels
[i
].size
) {
652 for (j
= 0; j
< labels
[i
].size
; j
+=4)
653 mark(ctx
, labels
[i
].val
+ j
, labels
[i
].type
);
662 if (!active
&& (ctx
->marks
[cur
] & 3) && !(ctx
->marks
[cur
] & 8)) {
665 ctx
->marks
[cur
] |= 8;
668 struct dis_res
*dres
= do_dis(ctx
, cur
);
669 dis_dopp(ctx
, dres
, cur
+ start
);
670 if (dres
->oplen
&& !dres
->endmark
&& !(ctx
->marks
[cur
] & 4))
682 struct dis_res
*dres
= do_dis(ctx
, cur
);
683 dis_dopp(ctx
, dres
, cur
+ start
);
693 int skip
= 0, nonzero
= 0;
695 int mark
= ctx
->marks
[cur
];
696 if (ctx
->names
[cur
]) {
699 fprintf(out
, "%s[%x bytes skipped]\n", cols
->err
, skip
);
701 fprintf(out
, "%s[%x zero bytes skipped]\n", cols
->reset
, skip
);
706 fprintf (out
, "%s%s:\n", cols
->reset
, ctx
->names
[cur
]);
708 fprintf (out
, "\n%s%s:\n", cols
->ctarg
, ctx
->names
[cur
]);
710 fprintf (out
, "%s%s:\n", cols
->btarg
, ctx
->names
[cur
]);
712 fprintf (out
, "%s%s:\n", cols
->reset
, ctx
->names
[cur
]);
714 if (mark
& 0x1b0 && !active
) {
717 fprintf(out
, "%s[%x bytes skipped]\n", cols
->err
, skip
);
719 fprintf(out
, "%s[%x zero bytes skipped]\n", cols
->reset
, skip
);
725 fprintf (out
, "%s%08x:%s", cols
->mem
, cur
+ start
, cols
->reset
);
727 uint8_t val
= code
[cur
];
728 fprintf (out
, " %s%02x\n", cols
->num
, val
);
730 } else if (mark
& 0x100) {
732 for (i
= 0; i
< 2 && cur
+ i
< num
; i
++) {
733 val
|= code
[cur
+ i
] << i
*8;
735 fprintf (out
, " %s%04x\n", cols
->num
, val
);
737 } else if (mark
& 0x10) {
739 for (i
= 0; i
< 4 && cur
+ i
< num
; i
++) {
740 val
|= code
[cur
+ i
] << i
*8;
742 fprintf (out
, " %s%08x\n", cols
->num
, val
);
745 fprintf (out
, " %s\"", cols
->num
);
749 fprintf (out
, "\\n");
752 fprintf (out
, "\\\\");
755 fprintf (out
, "\\\"");
758 fprintf (out
, "%c", code
[cur
]);
764 fprintf (out
, "\"\n");
768 if (!active
&& mark
& 7)
770 if (!active
&& labels
) {
771 for (i
= 0; i
< stride
; i
++)
772 if (code
[cur
*stride
+i
])
780 fprintf(out
, "%s[%x bytes skipped]\n", cols
->err
, skip
);
782 fprintf(out
, "%s[%x zero bytes skipped]\n", cols
->reset
, skip
);
786 struct dis_res
*dres
= do_dis(ctx
, cur
);
787 dis_dopp(ctx
, dres
, cur
+ start
);
789 if (dres
->endmark
|| mark
& 4)
792 if (mark
& 2 && !ctx
->names
[cur
])
797 fprintf (out
, "%s%08x:%s", cols
->reset
, cur
+ start
, cols
->reset
);
800 fprintf (out
, "%s%08x:%s", cols
->btarg
, cur
+ start
, cols
->reset
);
803 fprintf (out
, "%s%08x:%s", cols
->ctarg
, cur
+ start
, cols
->reset
);
806 fprintf (out
, "%s%08x:%s", cols
->bctarg
, cur
+ start
, cols
->reset
);
811 for (i
= 0; i
< isa
->maxoplen
; i
+= isa
->opunit
) {
813 for (j
= isa
->opunit
*stride
- 1; j
>= 0; j
--)
814 if (i
+j
/stride
&& i
+j
/stride
>= dres
->oplen
) {
816 } else if (cur
+i
+j
/stride
>= num
) {
817 fprintf (out
, "%s??", cols
->err
);
819 fprintf (out
, "%s%02x", cols
->reset
, code
[(cur
+ i
)*stride
+ j
]);
825 fprintf (out
, "%sC", cols
->ctarg
);
829 fprintf (out
, "%sB", cols
->btarg
);
833 } else if (quiet
== 1) {
838 easm_print_insn(out
, cols
, dres
->insn
);
840 if (dres
->status
& DIS_STATUS_UNK_FORM
) {
841 fprintf (out
, " %s[unknown op length]%s", cols
->err
, cols
->reset
);
844 for (i
= dres
->oplen
; i
< MAXOPLEN
* 8; i
++)
845 dres
->a
[i
/8] &= ~(0xffull
<< (i
& 7) * 8);
846 for (i
= 0; i
< MAXOPLEN
; i
++) {
847 dres
->a
[i
] &= ~dres
->m
[i
];
852 fprintf (out
, " %s[unknown:", cols
->err
);
853 for (i
= 0; i
< dres
->oplen
|| i
== 0; i
+= isa
->opunit
) {
855 for (j
= isa
->opunit
*stride
- 1; j
>= 0; j
--)
859 fprintf (out
, "%02llx", (dres
->a
[(i
+j
)/8] >> ((i
+ j
)&7) * 8) & 0xff);
864 if (dres
->status
& DIS_STATUS_EOF
) {
865 fprintf (out
, " %s[incomplete]%s", cols
->err
, cols
->reset
);
867 if (dres
->status
& DIS_STATUS_UNK_INSN
) {
868 fprintf (out
, " %s[unknown instruction]%s", cols
->err
, cols
->reset
);
870 if (dres
->status
& DIS_STATUS_UNK_OPERAND
) {
871 fprintf (out
, " %s[unknown operand]%s", cols
->err
, cols
->reset
);
873 fprintf (out
, "%s\n", cols
->reset
);