Resolve MMIO and extended registers (#1631)

This commit is contained in:
Giovanni 2021-09-09 02:19:02 +02:00 committed by GitHub
parent eb262e4df9
commit 5c9f93fe23
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 127 additions and 2 deletions

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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 */

View file

@ -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();

View file

@ -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