Resolve MMIO and extended registers (#1631)
This commit is contained in:
parent
eb262e4df9
commit
5c9f93fe23
7 changed files with 127 additions and 2 deletions
|
|
@ -70,6 +70,24 @@ RZ_API void rz_arch_target_free(RzArchTarget *t) {
|
|||
free(t);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resolves an address and returns the linked mmio
|
||||
*/
|
||||
RZ_API RZ_BORROW const char *rz_arch_profile_resolve_mmio(RZ_NONNULL RzArchProfile *profile, ut64 address) {
|
||||
rz_return_val_if_fail(profile, NULL);
|
||||
|
||||
return ht_up_find(profile->registers_mmio, (ut64)address, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resolves an address and returns the linked extended register
|
||||
*/
|
||||
RZ_API RZ_BORROW const char *rz_arch_profile_resolve_extended_register(RZ_NONNULL RzArchProfile *profile, ut64 address) {
|
||||
rz_return_val_if_fail(profile, NULL);
|
||||
|
||||
return ht_up_find(profile->registers_extended, (ut64)address, NULL);
|
||||
}
|
||||
|
||||
static inline bool cpu_reload_needed(RzArchTarget *c, const char *cpu, const char *arch) {
|
||||
if (!c->arch || strcmp(c->arch, arch)) {
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ RZ_API void rz_analysis_op_init(RzAnalysisOp *op) {
|
|||
op->refptr = 0;
|
||||
op->val = UT64_MAX;
|
||||
op->disp = UT64_MAX;
|
||||
op->mmio_address = UT64_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -735,6 +735,7 @@ INST_HANDLER(in) { // IN Rd, A
|
|||
RzStrBuf *io_src = __generic_io_dest(a, 0, cpu);
|
||||
op->type2 = 0;
|
||||
op->val = a;
|
||||
op->mmio_address = a;
|
||||
op->family = RZ_ANALYSIS_OP_FAMILY_IO;
|
||||
ESIL_A("%s,r%d,=,", rz_strbuf_get(io_src), r);
|
||||
rz_strbuf_free(io_src);
|
||||
|
|
@ -1077,6 +1078,7 @@ INST_HANDLER(out) { // OUT A, Rr
|
|||
RzStrBuf *io_dst = __generic_io_dest(a, 1, cpu);
|
||||
op->type2 = 1;
|
||||
op->val = a;
|
||||
op->mmio_address = a;
|
||||
op->family = RZ_ANALYSIS_OP_FAMILY_IO;
|
||||
ESIL_A("r%d,%s,", r, rz_strbuf_get(io_dst));
|
||||
rz_strbuf_free(io_dst);
|
||||
|
|
|
|||
|
|
@ -1036,6 +1036,7 @@ static const char *get_reg_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr) {
|
|||
|
||||
static void ds_build_op_str(RDisasmState *ds, bool print_color) {
|
||||
RzCore *core = ds->core;
|
||||
|
||||
if (ds->use_esil) {
|
||||
free(ds->opstr);
|
||||
if (*RZ_STRBUF_SAFEGET(&ds->analop.esil)) {
|
||||
|
|
@ -1074,6 +1075,30 @@ static void ds_build_op_str(RDisasmState *ds, bool print_color) {
|
|||
}
|
||||
}
|
||||
|
||||
if (ds->analop.mmio_address != UT64_MAX) {
|
||||
char number[32];
|
||||
rz_strf(number, "0x%" PFMT64x, ds->analop.mmio_address);
|
||||
|
||||
RzArchTarget *arch_target = core->analysis->arch_target;
|
||||
|
||||
const char *resolved = rz_arch_profile_resolve_mmio(arch_target->profile, ds->analop.mmio_address);
|
||||
if (resolved) {
|
||||
ds->opstr = rz_str_replace(ds->opstr, number, resolved, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (ds->analop.ptr != UT64_MAX) {
|
||||
char number[32];
|
||||
rz_strf(number, "0x%" PFMT64x, ds->analop.ptr);
|
||||
|
||||
RzArchTarget *arch_target = core->analysis->arch_target;
|
||||
|
||||
const char *resolved = rz_arch_profile_resolve_extended_register(arch_target->profile, ds->analop.ptr);
|
||||
if (resolved) {
|
||||
ds->opstr = rz_str_replace(ds->opstr, number, resolved, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize */
|
||||
core->parser->subrel = rz_config_get_b(core->config, "asm.sub.rel");
|
||||
core->parser->subreg = rz_config_get_b(core->config, "asm.sub.reg");
|
||||
|
|
@ -1087,8 +1112,7 @@ static void ds_build_op_str(RDisasmState *ds, bool print_color) {
|
|||
core->parser->get_op_ireg = get_op_ireg;
|
||||
core->parser->get_ptr_at = get_ptr_at;
|
||||
core->parser->get_reg_at = get_reg_at;
|
||||
rz_parse_subvar(core->parser, f, at, ds->analop.size,
|
||||
ds->opstr, ds->strsub, sizeof(ds->strsub));
|
||||
rz_parse_subvar(core->parser, f, at, ds->analop.size, ds->opstr, ds->strsub, sizeof(ds->strsub));
|
||||
if (*ds->strsub) {
|
||||
free(ds->opstr);
|
||||
ds->opstr = strdup(ds->strsub);
|
||||
|
|
|
|||
|
|
@ -833,6 +833,7 @@ typedef struct rz_analysis_op_t {
|
|||
int ptrsize; /* f.ex: zero extends for 8, 16 or 32 bits only */
|
||||
st64 stackptr; /* stack pointer */
|
||||
int refptr; /* if (0) ptr = "reference" else ptr = "load memory of refptr bytes" */
|
||||
ut64 mmio_address; // mmio address
|
||||
RzAnalysisValue *src[3];
|
||||
RzAnalysisValue *dst;
|
||||
RzList *access; /* RzAnalysisValue access information */
|
||||
|
|
|
|||
|
|
@ -48,6 +48,8 @@ RZ_API void rz_arch_target_free(RzArchTarget *target);
|
|||
RZ_API bool rz_arch_profiles_init(RzArchTarget *c, const char *cpu, const char *arch, const char *dir_prefix);
|
||||
RZ_API void rz_arch_profile_add_flag_every_io(RzArchProfile *profile, RzFlag *flags);
|
||||
RZ_API bool rz_arch_load_profile_sdb(RzArchTarget *t, const char *path);
|
||||
RZ_API RZ_BORROW const char *rz_arch_profile_resolve_mmio(RZ_NONNULL RzArchProfile *profile, ut64 address);
|
||||
RZ_API RZ_BORROW const char *rz_arch_profile_resolve_extended_register(RZ_NONNULL RzArchProfile *profile, ut64 address);
|
||||
|
||||
RZ_API RZ_OWN RzArchPlatformItem *rz_arch_platform_item_new(RZ_NULLABLE const char *name);
|
||||
RZ_API RZ_OWN RzArchPlatformTarget *rz_arch_platform_target_new();
|
||||
|
|
|
|||
|
|
@ -908,3 +908,80 @@ EXPECT=<<EOF
|
|||
0x00008000 2 sp
|
||||
EOF
|
||||
RUN
|
||||
|
||||
NAME=avr resolve mmio and ext_reg (TCCR0B & OCR1BH)
|
||||
FILE=bins/firmware/arduino_avr.bin
|
||||
CMDS=<<EOF
|
||||
e asm.arch=avr
|
||||
e asm.cpu=ATmega168
|
||||
aaa
|
||||
s fcn.000005a2
|
||||
pdr
|
||||
EOF
|
||||
EXPECT=<<EOF
|
||||
; CALL XREF from fcn.00000662 @ 0x696
|
||||
; CALL XREF from fcn.00000662 @ +0x92
|
||||
/ fcn.000005a2 ();
|
||||
| 0x000005a2 cpi r24, 0x05
|
||||
| 0x000005a4 breq 0x5d4
|
||||
| ----------- true: 0x000005d4 false: 0x000005a6
|
||||
| 0x000005a6 brcc 0x5b2
|
||||
| ----------- true: 0x000005b2 false: 0x000005a8
|
||||
| 0x000005a8 cpi r24, 0x03
|
||||
| 0x000005aa breq 0x5c6
|
||||
| ----------- true: 0x000005c6 false: 0x000005ac
|
||||
| 0x000005ac cpi r24, 0x04
|
||||
| 0x000005ae breq 0x5cc
|
||||
| ----------- true: 0x000005cc false: 0x000005b0
|
||||
| 0x000005b0 ret
|
||||
|
||||
| ; CODE XREF from fcn.000005a2 @ 0x5a6
|
||||
| 0x000005b2 cpi r24, 0x09
|
||||
| 0x000005b4 breq 0x5dc
|
||||
| ----------- true: 0x000005dc false: 0x000005b6
|
||||
| 0x000005b6 cpi r24, 0x0a
|
||||
| 0x000005b8 breq 0x5e4
|
||||
| ----------- true: 0x000005e4 false: 0x000005ba
|
||||
| 0x000005ba cpi r24, 0x08
|
||||
| 0x000005bc brne 0x5ee
|
||||
| ----------- true: 0x000005ee false: 0x000005be
|
||||
| 0x000005be lds r24, OCR1BH ; 0x8b
|
||||
| 0x000005c2 andi r24, 0x7f
|
||||
| 0x000005c4 rjmp 0x5ea
|
||||
| ----------- true: 0x000005ea
|
||||
| ; CODE XREF from fcn.000005a2 @ 0x5aa
|
||||
| 0x000005c6 in r24, 0x2f
|
||||
| 0x000005c8 andi r24, 0x7f
|
||||
| 0x000005ca rjmp 0x5d0
|
||||
| ----------- true: 0x000005d0
|
||||
| ; CODE XREF from fcn.000005a2 @ 0x5ae
|
||||
| 0x000005cc in r24, 0x2f
|
||||
| 0x000005ce andi r24, 0xdf
|
||||
| ----------- true: 0x000005d0
|
||||
| ; CODE XREF from fcn.000005a2 @ 0x5ca
|
||||
| 0x000005d0 out 0x2f, r24
|
||||
| 0x000005d2 ret
|
||||
|
||||
| ; CODE XREF from fcn.000005a2 @ 0x5a4
|
||||
| 0x000005d4 in r24, TCCR0B
|
||||
| 0x000005d6 andi r24, 0xdf
|
||||
| 0x000005d8 out TCCR0B, r24
|
||||
| 0x000005da ret
|
||||
|
||||
| ; CODE XREF from fcn.000005a2 @ 0x5b4
|
||||
| 0x000005dc lds r24, OCR1BH ; 0x8b
|
||||
| 0x000005e0 andi r24, 0xdf
|
||||
| 0x000005e2 rjmp 0x5ea
|
||||
| ----------- true: 0x000005ea
|
||||
| ; CODE XREF from fcn.000005a2 @ 0x5b8
|
||||
| 0x000005e4 lds r24, OCR1BH ; 0x8b
|
||||
| 0x000005e8 andi r24, 0xf7
|
||||
| ----------- true: 0x000005ea
|
||||
| ; CODE XREFS from fcn.000005a2 @ 0x5c4, 0x5e2
|
||||
| 0x000005ea sts OCR1BH, r24 ; 0x8b
|
||||
| ----------- true: 0x000005ee
|
||||
| ; CODE XREF from fcn.000005a2 @ 0x5bc
|
||||
\ 0x000005ee ret
|
||||
|
||||
EOF
|
||||
RUN
|
||||
|
|
|
|||
Loading…
Reference in a new issue