diff --git a/librz/analysis/arch_profile.c b/librz/analysis/arch_profile.c index e064f6aa80..8dde2728d1 100644 --- a/librz/analysis/arch_profile.c +++ b/librz/analysis/arch_profile.c @@ -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; diff --git a/librz/analysis/op.c b/librz/analysis/op.c index 40602bb28c..03fcdf3ea2 100644 --- a/librz/analysis/op.c +++ b/librz/analysis/op.c @@ -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; } } diff --git a/librz/analysis/p/analysis_avr.c b/librz/analysis/p/analysis_avr.c index 74224bc95b..53f96a8a75 100644 --- a/librz/analysis/p/analysis_avr.c +++ b/librz/analysis/p/analysis_avr.c @@ -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); diff --git a/librz/core/disasm.c b/librz/core/disasm.c index 14043db57a..9c2b009b05 100644 --- a/librz/core/disasm.c +++ b/librz/core/disasm.c @@ -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); diff --git a/librz/include/rz_analysis.h b/librz/include/rz_analysis.h index 1c6114f853..7ff0143b84 100644 --- a/librz/include/rz_analysis.h +++ b/librz/include/rz_analysis.h @@ -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 */ diff --git a/librz/include/rz_arch.h b/librz/include/rz_arch.h index 02141ff1c1..38fa127a0f 100644 --- a/librz/include/rz_arch.h +++ b/librz/include/rz_arch.h @@ -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(); diff --git a/test/db/analysis/avr b/test/db/analysis/avr index b83686334f..e582ebe0a1 100644 --- a/test/db/analysis/avr +++ b/test/db/analysis/avr @@ -908,3 +908,80 @@ EXPECT=<