diff --git a/libr/bin/bfile.c b/libr/bin/bfile.c index 37be0b32ebab5..e464112b1c10f 100644 --- a/libr/bin/bfile.c +++ b/libr/bin/bfile.c @@ -8,9 +8,15 @@ #define R_STRING_SCAN_BUFFER_SIZE 4096 #define R_STRING_MAX_UNI_BLOCKS 4 -static RBinClass *__getClass(RBinFile *bf, const char *name) { +static RBinClass *get_class(RBinFile *bf, const char *name) { R_RETURN_VAL_IF_FAIL (bf && bf->bo && bf->bo->classes_ht && name, NULL); +#if R2_USE_NEW_ABI + void *htidxptr = ht_pp_find (bf->bo->classes_ht, name, NULL); + int htidx = (int)(size_t)htidxptr; + return RVecRBinClass_at (&bf->bo->classes, htidx - 1); +#else return ht_pp_find (bf->bo->classes_ht, name, NULL); +#endif } static RBinSymbol *__getMethod(RBinFile *bf, const char *klass, const char *method) { @@ -1092,20 +1098,49 @@ R_API RBinClass *r_bin_class_new(const char *name, const char *super, ut64 attr) return c; } -R_API void r_bin_class_free(RBinClass *k) { +#if R2_USE_NEW_ABI +R_API void r_bin_class_init(RBinClass *c, const char *name, const char *super, ut64 attr) { + R_RETURN_IF_FAIL (c && name); + c->name = r_bin_name_new (name); + if (R_STR_ISNOTEMPTY (super)) { + c->super = r_list_newf (free); + r_list_append (c->super, r_bin_name_new (super)); + } + // TODO: use vectors! + c->methods = r_list_newf (r_bin_symbol_free); + c->fields = r_list_newf (r_bin_field_free); + c->attr = attr; +} + +R_API void r_bin_class_fini(RBinClass *k) { if (k) { free (k->name); r_list_free (k->super); free (k->visibility_str); r_list_free (k->methods); r_list_free (k->fields); + } +} +#else +static inline void r_bin_class_fini(RBinClass *k) { + free (k->name); + r_list_free (k->super); + free (k->visibility_str); + r_list_free (k->methods); + r_list_free (k->fields); +} +#endif + +R_API void r_bin_class_free(RBinClass *k) { + if (k) { + r_bin_class_fini (k), free (k); } } R_API RBinClass *r_bin_file_add_class(RBinFile *bf, const char *name, const char *super, ut64 attr) { R_RETURN_VAL_IF_FAIL (name && bf && bf->bo, NULL); - RBinClass *c = __getClass (bf, name); + RBinClass *c = get_class (bf, name); if (c) { if (R_STR_ISNOTEMPTY (super)) { r_list_free (c->super); @@ -1114,6 +1149,22 @@ R_API RBinClass *r_bin_file_add_class(RBinFile *bf, const char *name, const char } return c; } +#if R2_USE_NEW_ABI + RBinClass bc = {0}; + r_bin_class_init (&bc, name, super, attr); + bc.index = RVecRBinClass_length (&bf->bo->classes); + RVecRBinClass_push_back (&bf->bo->classes, &bc); + // free (c); + // const int htidx = bc.index + 1; + const int htidx = RVecRBinClass_length (&bf->bo->classes); // bc.index + 1; + ht_pp_update (bf->bo->classes_ht, name, (void*)(size_t)htidx); + // eprintf ("0-> %s (%s)\n", r_bin_name_tostring (c->name), name); + c = RVecRBinClass_last (&bf->bo->classes); + // eprintf ("1-> %s (%s)\n", r_bin_name_tostring (c->name), name); + // free (c); + // c = RVecRBinClass_at (&bf->bo->classes, 0); + // return c; +#else c = r_bin_class_new (name, super, attr); if (c) { // XXX. no need for a list, the ht is iterable too @@ -1121,6 +1172,7 @@ R_API RBinClass *r_bin_file_add_class(RBinFile *bf, const char *name, const char r_list_append (bf->bo->classes, c); ht_pp_insert (bf->bo->classes_ht, name, c); } +#endif return c; } @@ -1142,8 +1194,11 @@ R_API RBinSymbol *r_bin_file_add_method(RBinFile *bf, const char *klass, const c sym->lang = lang; char *name = r_str_newf ("%s::%s", klass, method); ht_pp_insert (bf->bo->methods_ht, name, sym); +#if R2_USE_NEW_ABI +#else // RBinSymbol *dsym = r_bin_symbol_clone (sym); r_list_append (c->methods, sym); +#endif free (name); } } @@ -1220,6 +1275,7 @@ R_API RBinFile *r_bin_file_open(RBin *bin, const char *file, RBinFileOptions *op // TODO Improve this API R_API void r_bin_file_merge(RBinFile *dst, RBinFile *src) { + R_RETURN_IF_FAIL (dst && src); // merge imports // merge dbginfo sdb_merge (dst->bo->kv, src->bo->kv); diff --git a/libr/bin/bin.c b/libr/bin/bin.c index ad8287a37932e..30cf3dd315b88 100644 --- a/libr/bin/bin.c +++ b/libr/bin/bin.c @@ -234,6 +234,7 @@ R_API void r_bin_string_free(void *_str) { } } +// R2_600 - return RBinFile instead of bool. avoid toctou R_API bool r_bin_open(RBin *bin, const char *file, RBinFileOptions *opt) { R_RETURN_VAL_IF_FAIL (bin && bin->iob.io && opt, false); @@ -270,6 +271,7 @@ R_API bool r_bin_reload(RBin *bin, ut32 bf_id, ut64 baseaddr) { return res; } +// R2_600 - return RBinFile instead of bool. avoid toctou R_API bool r_bin_open_buf(RBin *bin, RBuffer *buf, RBinFileOptions *opt) { R_RETURN_VAL_IF_FAIL (bin && opt, false); @@ -318,10 +320,12 @@ R_API bool r_bin_open_buf(RBin *bin, RBuffer *buf, RBinFileOptions *opt) { return false; } // r_ref (bf); + // return bf instead of bool! bin->cur = bf; return res; } +// R2_600 - return RBinFile instead of bool. avoid toctou R_API bool r_bin_open_io(RBin *bin, RBinFileOptions *opt) { R_RETURN_VAL_IF_FAIL (bin && opt && bin->iob.io, false); R_RETURN_VAL_IF_FAIL (opt->fd >= 0 && (st64)opt->sz >= 0, false); @@ -1303,11 +1307,15 @@ R_API RBuffer *r_bin_package(RBin *bin, const char *type, const char *file, RLis return NULL; } +#if R2_USE_NEW_ABI +// this api is deprecated. just access the binobject instead +#else R_API RList* /**/ r_bin_get_classes(RBin *bin) { R_RETURN_VAL_IF_FAIL (bin, NULL); RBinObject *bo = r_bin_cur_object (bin); return bo ? bo->classes : NULL; } +#endif /* returns vaddr, rebased with the baseaddr of bin, if va is enabled for bin, * paddr otherwise */ R_API ut64 r_bin_get_vaddr(RBin *bin, ut64 paddr, ut64 vaddr) { diff --git a/libr/bin/bobj.c b/libr/bin/bobj.c index 638f536f0d9b7..2ac0ec2af2d0a 100644 --- a/libr/bin/bobj.c +++ b/libr/bin/bobj.c @@ -51,7 +51,11 @@ static void object_delete_items(RBinObject *o) { } r_list_free (o->symbols); +#if R2_USE_NEW_ABI + RVecRBinClass_fini (&o->classes); +#else r_list_free (o->classes); +#endif ht_pp_free (o->classes_ht); ht_pp_free (o->methods_ht); r_list_free (o->lines); @@ -168,7 +172,7 @@ static void classes_from_symbols2(RBinFile *bf, RBinSymbol *sym) { } } -static RList *classes_from_symbols(RBinFile *bf) { +static void classes_from_symbols(RBinFile *bf) { RBinSymbol *sym; RListIter *iter; // TODO: Use rvec here @@ -181,7 +185,6 @@ static RList *classes_from_symbols(RBinFile *bf) { classes_from_symbols2 (bf, sym); } } - return bf->bo->classes; } // TODO: kill offset and sz, because those should be inferred from binfile->buf @@ -198,7 +201,11 @@ R_IPI RBinObject *r_bin_object_new(RBinFile *bf, RBinPlugin *plugin, ut64 basead bo->regstate = NULL; bo->kv = sdb_new0 (); // XXX bf->sdb bf->bo->sdb wtf bo->baddr = baseaddr; +#if R2_USE_NEW_ABI + RVecRBinClass_init (&bo->classes); +#else bo->classes = r_list_newf ((RListFree)r_bin_class_free); +#endif bo->classes_ht = ht_pp_new0 (); bo->methods_ht = ht_pp_new0 (); bo->baddr_shift = 0; @@ -258,14 +265,20 @@ R_IPI RBinObject *r_bin_object_new(RBinFile *bf, RBinPlugin *plugin, ut64 basead return bo; } -static bool filter_classes(RBinFile *bf, RList *list) { +static void filter_classes(RBinFile *bf) { bool rc = true; HtSU *db = ht_su_new0 (); HtPP *ht = ht_pp_new0 (); - RListIter *iter, *iter2; RBinClass *cls; RBinSymbol *sym; - r_list_foreach (list, iter, cls) { +#if R2_USE_NEW_ABI + RListIter *iter2; + R_VEC_FOREACH (&bf->bo->classes, cls) +#else + RListIter *iter, *iter2; + r_list_foreach (bf->bo->classes, iter, cls) +#endif + { const char *kname = r_bin_name_tostring (cls->name); char *fname = r_bin_filter_name (bf, db, cls->index, kname); if (R_STR_ISEMPTY (fname)) { @@ -308,14 +321,32 @@ static void r_bin_object_rebuild_classes_ht(RBinObject *bo) { ht_pp_free (bo->methods_ht); bo->methods_ht = ht_pp_new0 (); +#if R2_USE_NEW_ABI + RListIter *it2; +#else RListIter *it, *it2; +#endif RBinClass *klass; RBinSymbol *method; - r_list_foreach (bo->classes, it, klass) { +#if R2_USE_NEW_ABI + int klass_idx = 0; + R_VEC_FOREACH (&bo->classes, klass) +#else + r_list_foreach (bo->classes, it, klass) +#endif + { if (klass->name) { - ht_pp_insert (bo->classes_ht, klass->name, klass); + const char *klass_name = r_bin_name_tostring (klass->name); +#if R2_USE_NEW_ABI + void *htidxptr = (void*)(size_t)klass_idx; + ht_pp_insert (bo->classes_ht, klass_name, htidxptr); + klass_idx++; + /// TODO +#else + ht_pp_insert (bo->classes_ht, klass_name, klass); +#endif r_list_foreach (klass->methods, it2, method) { - const char *klass_name = r_bin_name_tostring (klass->name); + // const char *klass_name = r_bin_name_tostring (klass->name); const char *method_name = r_bin_name_tostring (method->name); char *name = r_str_newf ("%s::%s", klass_name, method_name); ht_pp_insert (bo->methods_ht, name, method); @@ -437,26 +468,43 @@ R_API int r_bin_object_set_items(RBinFile *bf, RBinObject *bo) { } if (bin->filter_rules & R_BIN_REQ_CLASSES) { if (p->classes) { +#if R2_USE_NEW_ABI + p->classes (bf); +#else RList *classes = p->classes (bf); if (classes) { // XXX we should probably merge them instead r_list_free (bo->classes); bo->classes = classes; - r_bin_object_rebuild_classes_ht (bo); } +#endif + r_bin_object_rebuild_classes_ht (bo); isSwift = r_bin_lang_swift (bf); if (isSwift) { - bo->classes = classes_from_symbols (bf); + classes_from_symbols (bf); + bo->classes = bf->bo->classes; // XXX unnecessary i think } } else { - RList *classes = classes_from_symbols (bf); - if (classes) { - bo->classes = classes; - } + classes_from_symbols (bf); + bo->classes = bf->bo->classes; } if (bin->filter) { - filter_classes (bf, bo->classes); + filter_classes (bf); } +#if R2_USE_NEW_ABI + if (RVecRBinClass_length (&bo->classes) > 0 && !bo->addr2klassmethod) { + RListIter *iter; + RBinClass *klass; + RBinSymbol *method; + bo->addr2klassmethod = ht_up_new0 (); + R_VEC_FOREACH (&bo->classes, klass) { + // this is slow. must be optimized, but at least its cached + r_list_foreach (klass->methods, iter, method) { + ht_up_insert (bo->addr2klassmethod, method->vaddr, method); + } + } + } +#else // cache addr=class+method #if 0 // moved into libr/core/canal.c diff --git a/libr/bin/format/dex/dex.h b/libr/bin/format/dex/dex.h index 5723b6f2cfd7d..6c4540dc69a38 100644 --- a/libr/bin/format/dex/dex.h +++ b/libr/bin/format/dex/dex.h @@ -142,7 +142,11 @@ typedef struct r_bin_dex_obj_t { RList *methods_list; RList *trycatch_list; RList *imports_list; +#if R2_USE_NEW_ABI + // it's stored in RBinObject +#else RList *classes_list; +#endif RList *lines_list; ut64 code_from; ut64 code_to; diff --git a/libr/bin/format/objc/mach0_classes.c b/libr/bin/format/objc/mach0_classes.c index 0bb840acfcb82..30e9c258e6c83 100644 --- a/libr/bin/format/objc/mach0_classes.c +++ b/libr/bin/format/objc/mach0_classes.c @@ -1225,25 +1225,22 @@ static char *get_class_name(RBinFile *bf, mach0_ut p) { /////////////////////////////////////////////////////////////////////////////// static void get_class_ro_t(RBinFile *bf, bool *is_meta_class, RBinClass *klass, objc_cache_opt_info *oi, mach0_ut p) { - struct MACH0_(obj_t) *bin; struct MACH0_(SClassRoT) cro = {0}; ut32 offset, left, i; ut64 r, s; int len; - bool bigendian; ut8 scro[sizeof (struct MACH0_(SClassRoT))] = {0}; if (!bf || !bf->bo || !bf->bo->bin_obj || !bf->bo->info) { R_LOG_WARN ("Invalid RBinFile pointer"); return; } - bigendian = bf->bo->info->big_endian; - bin = (struct MACH0_(obj_t) *)bf->bo->bin_obj; + const bool bigendian = bf->bo->info->big_endian; + struct MACH0_(obj_t) *bin = (struct MACH0_(obj_t) *)bf->bo->bin_obj; if (!(r = va2pa (bf, p, &offset, &left))) { // eprintf ("No pointer\n"); return; } - if (r + left < r || r + sizeof (cro) < r) { return; } @@ -1329,7 +1326,6 @@ static void get_class_ro_t(RBinFile *bf, bool *is_meta_class, RBinClass *klass, #else sdb_set (bin->kv, "objc_class.format", "xxxxx isa super cache vtable data", 0); #endif - if (cro.baseMethods > 0) { const char *klass_name = r_bin_name_tostring2 (klass->name, 'd'); if (cro.baseMethods & 1) { @@ -1670,7 +1666,14 @@ static void parse_type(RBinFile *bf, RList *list, SwiftType st, HtUP *symbols_ht free (method_name); } } +#if R2_USE_NEW_ABI +// eprintf ("PPP %s\n", r_bin_name_tostring (klass->name)); + RVecRBinClass_push_back (&bf->bo->classes, klass); + free (klass); + klass = RVecRBinClass_last (&bf->bo->classes); +#else r_list_append (list, klass); +#endif if (st.fields != UT64_MAX) { int i; @@ -1760,8 +1763,11 @@ static void *read_section(RBinFile *bf, MetaSection *ms, ut64 *asize) { } RList *MACH0_(parse_classes)(RBinFile *bf, objc_cache_opt_info *oi) { - r_return_val_if_fail (bf && bf->bo, NULL); + R_RETURN_VAL_IF_FAIL (bf && bf->bo, NULL); +#if R2_USE_NEW_ABI + RBinObject *bo = bf->bo; +#endif ut64 num_of_unnamed_class = 0; ut32 size = 0; RList *sctns = NULL; @@ -1789,6 +1795,12 @@ RList *MACH0_(parse_classes)(RBinFile *bf, objc_cache_opt_info *oi) { goto get_classes_error; } } +#if R2_USE_NEW_ABI + RListIter *iter; + r_list_foreach (ret, iter, klass) { + RVecRBinClass_push_back (&bo->classes, klass); + } +#endif const bool want_swift = !r_sys_getenv_asbool ("RABIN2_MACHO_NOSWIFT"); // 2s / 16s @@ -1851,6 +1863,7 @@ RList *MACH0_(parse_classes)(RBinFile *bf, objc_cache_opt_info *oi) { } RBinClass *klass = r_bin_class_new ("", "", R_BIN_ATTR_PUBLIC); R_FREE (klass->name); // allow NULL name in rbinclass? + // TODO r_bin_name_free (klass->name); klass->lang = R_BIN_LANG_OBJC; size = sizeof (mach0_ut); if (ms.clslist.addr > bf->size || ms.clslist.addr + size > bf->size) { @@ -1877,7 +1890,12 @@ RList *MACH0_(parse_classes)(RBinFile *bf, objc_cache_opt_info *oi) { free (klass_name); num_of_unnamed_class++; } +#if R2_USE_NEW_ABI + RVecRBinClass_push_back (&bo->classes, klass); + free (klass); +#else r_list_append (ret, klass); +#endif } metadata_sections_fini (&ms); return ret; @@ -1891,18 +1909,21 @@ RList *MACH0_(parse_classes)(RBinFile *bf, objc_cache_opt_info *oi) { } static RList *MACH0_(parse_categories)(RBinFile *bf, MetaSections *ms, const RSkipList *relocs, objc_cache_opt_info *oi) { - r_return_val_if_fail (bf && bf->bo && bf->bo->bin_obj && bf->bo->info, NULL); + R_RETURN_VAL_IF_FAIL (bf && bf->bo && bf->bo->bin_obj && bf->bo->info, NULL); R_LOG_DEBUG ("parse objc categories"); const size_t ptr_size = sizeof (mach0_ut); - if (!ms->catlist.have) { + if (!ms->catlist.have || !relocs) { return NULL; } - +#if R2_USE_NEW_ABI + RBinObject *bo = bf->bo; + RList *ret = NULL; +#else RList *ret = r_list_newf ((RListFree)r_bin_class_free); if (!ret || !relocs) { goto error; } - +#endif ut32 i; for (i = 0; i < ms->catlist.size; i += ptr_size) { mach0_ut p; @@ -1943,7 +1964,12 @@ static RList *MACH0_(parse_categories)(RBinFile *bf, MetaSections *ms, const RSk // free (klass->name); // klass->name = name; } +#if R2_USE_NEW_ABI + // eprintf ("PPP %s\n", r_bin_name_tostring (klass->name)); + RVecRBinClass_push_back (&bo->classes, klass); +#else r_list_append (ret, klass); +#endif } return ret; diff --git a/libr/bin/mangling/objc.c b/libr/bin/mangling/objc.c index 7fb50d0ab333e..93a5bff3450b8 100644 --- a/libr/bin/mangling/objc.c +++ b/libr/bin/mangling/objc.c @@ -4,16 +4,24 @@ #include "../i/private.h" R_API char *r_bin_demangle_objc(RBinFile *bf, const char *sym) { +#if R2_USE_NEW_ABI + r_return_val_if_fail ((!bf || (bf && bf->bo)) && sym, NULL); +#else r_return_val_if_fail ((!bf || (bf && bf->bo && bf->bo->classes)) && sym, NULL); +#endif char *clas = NULL; char *name = NULL; char *args = NULL; int i, nargs = 0; const char *type = NULL; +#if R2_USE_NEW_ABI + // no need to check +#else if (bf && bf->bo && bf->bo->classes) { bf = NULL; } +#endif /* classes */ if (r_str_startswith (sym, "_OBJC_")) { const char *sym2 = sym + strlen ("_OBJC_"); diff --git a/libr/bin/p/bin_dex.c b/libr/bin/p/bin_dex.c index d42534bfc8494..a56fef94cacea 100644 --- a/libr/bin/p/bin_dex.c +++ b/libr/bin/p/bin_dex.c @@ -1474,7 +1474,11 @@ static void parse_class(RBinFile *bf, RBinDexClass *c, int class_index, int *met goto beach; } cls->visibility_str = createAccessFlagStr (c->access_flags, kAccessForClass); +#if R2_USE_NEW_ABI + RVecRBinClass_push_back (&bf->bo->classes, cls); +#else r_list_append (dex->classes_list, cls); +#endif if (dex->dexdump) { rbin->cb_printf (" Class descriptor : '%s;'\n", cls_name); rbin->cb_printf (" Access flags : 0x%04x (%s)\n", c->access_flags, @@ -1618,6 +1622,9 @@ static bool dex_loadcode(RBinFile *bf) { if (!dex->lines_list) { return false; } +#if R2_USE_NEW_ABI + RVecRBinClass_init (&bf->bo->classes); +#else dex->classes_list = r_list_newf ((RListFree)r_bin_class_free); if (!dex->classes_list) { r_list_free (dex->methods_list); @@ -1625,7 +1632,7 @@ static bool dex_loadcode(RBinFile *bf) { r_list_free (dex->imports_list); return false; } - +#endif if (dex->header.method_size > dex->size) { dex->header.method_size = 0; return false; @@ -1770,12 +1777,19 @@ static RList *methods(RBinFile *bf) { } static RList *classes(RBinFile *bf) { - r_return_val_if_fail (bf && bf->bo && bf->bo->bin_obj, NULL); - RBinDexObj *bin = (RBinDexObj*) bf->bo->bin_obj; - if (!bin->classes_list) { + R_RETURN_VAL_IF_FAIL (bf && bf->bo && bf->bo->bin_obj, NULL); +#if R2_USE_NEW_ABI + if (RVecRBinClass_length (&bf->bo->classes) == 0) { dex_loadcode (bf); } - return bin->classes_list; + return NULL; +#else + RBinDexObj *dex = (RBinDexObj*) bf->bo->bin_obj; + if (!dex->classes_list) { + dex_loadcode (bf); + } + return dex->classes_list; +#endif } static bool already_entry(RList *entries, ut64 vaddr) { diff --git a/libr/bin/p/bin_java.c b/libr/bin/p/bin_java.c index 321a74d45bf5d..f4ca1cef21793 100644 --- a/libr/bin/p/bin_java.c +++ b/libr/bin/p/bin_java.c @@ -54,7 +54,20 @@ static RList *entries(RBinFile *bf) { } static RList *classes(RBinFile *bf) { +#if R2_USE_NEW_ABI + // R2_600 - java is duping classes, we need to use bf->bo directly + RList *klasses = r_bin_java_get_classes ((struct r_bin_java_obj_t *) bf->bo->bin_obj); + RBinClass *klass; + RVecRBinClass *vec = &bf->bo->classes; + RListIter *iter; + r_list_foreach (klasses, iter, klass) { + RVecRBinClass_push_back (vec, klass); + } + // r_list_free (klasses); + return NULL; +#else return r_bin_java_get_classes ((struct r_bin_java_obj_t *) bf->bo->bin_obj); +#endif } static RList *symbols(RBinFile *bf) { diff --git a/libr/core/cbin.c b/libr/core/cbin.c index 8d8176c4b55f9..69b7fd5358394 100644 --- a/libr/core/cbin.c +++ b/libr/core/cbin.c @@ -3881,10 +3881,19 @@ static bool is_javaish(RBinFile *bf) { static bool bin_classes(RCore *r, PJ *pj, int mode) { const int pref = r_config_get_b (r->config, "asm.demangle")? 'd': 0; - RListIter *iter, *iter2, *iter3; RBinSymbol *sym; RBinClass *c; RBinField *f; +#if R2_USE_NEW_ABI + RListIter *iter2, *iter3; + RBinObject *bo = R_UNWRAP4 (r, bin, cur, bo); + if (!bo) { + return false; + } +#define CLASSES_FOREACH R_VEC_FOREACH (&bo->classes, c) +#else + RListIter *iter, *iter2, *iter3; +#define CLASSES_FOREACH r_list_foreach (cs, iter, c) RList *cs = r_bin_get_classes (r->bin); if (!cs) { if (IS_MODE_JSON (mode)) { @@ -3894,6 +3903,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) { } return false; } +#endif // XXX: support for classes is broken and needs more love if (IS_MODE_JSON (mode)) { pj_a (pj); @@ -3906,7 +3916,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) { r_cons_println ("fs classes"); } const bool bin_filter = r_config_get_b (r->config, "bin.filter"); - r_list_foreach (cs, iter, c) { + CLASSES_FOREACH { const char *cname = r_bin_name_tostring2 (c->name, pref); const char *rname = r_bin_name_tostring2 (c->name, 'o'); if (!c || R_STR_ISEMPTY (cname)) { diff --git a/libr/core/cmd_info.inc.c b/libr/core/cmd_info.inc.c index 672325115e54b..6907db7322f77 100644 --- a/libr/core/cmd_info.inc.c +++ b/libr/core/cmd_info.inc.c @@ -149,8 +149,14 @@ static void classdump_keys(RCore *core, RBinObject *bo) { RBinClass *k; RBinField *f; RBinSymbol *m; +#if R2_USE_NEW_ABI + RListIter *iter2; + R_VEC_FOREACH (&bo->classes, k) +#else RListIter *iter, *iter2; - r_list_foreach (bo->classes, iter, k) { + r_list_foreach (bo->classes, iter, k) +#endif + { const char *kname = r_bin_name_tostring2 (k->name, pref); r_list_foreach (k->fields, iter2, f) { const char *kind = r_bin_field_kindstr (f); @@ -632,8 +638,26 @@ static void cmd_ic_comma(RCore *core, const char *input) { r_list_foreach (bfiles, objs_iter, bf) { RBinObject *obj = bf->bo; RBinClass *klass; - RListIter *iter, *iter2; core->bin->cur = bf; +#if R2_USE_NEW_ABI + RListIter *iter2; + R_VEC_FOREACH (&obj->classes, klass) { + const char *kname = r_bin_name_tostring (klass->name); + RBinSymbol *method; + r_list_foreach (klass->methods, iter2, method) { + char *addr = r_str_newf ("0x%08"PFMT64x, iova? method->vaddr: method->paddr); + r_table_add_row (t, addr, "method", kname, method->name, NULL); + free (addr); + } + RBinField *field; + r_list_foreach (klass->fields, iter2, field) { + char *addr = r_str_newf ("0x%08"PFMT64x, iova? field->vaddr: field->paddr); + r_table_add_row (t, addr, "field", kname, field->name, NULL); + free (addr); + } + } +#else + RListIter *iter, *iter2; r_list_foreach (obj->classes, iter, klass) { const char *kname = r_bin_name_tostring (klass->name); RBinSymbol *method; @@ -649,6 +673,7 @@ static void cmd_ic_comma(RCore *core, const char *input) { free (addr); } } +#endif } core->bin->cur = cur; r_list_free (bfiles); @@ -680,15 +705,25 @@ static void cmd_ic_sub(RCore *core, const char *input) { char *klass_name = strdup (input); char *method_name = r_str_after (klass_name, '.'); RBinClass *klass = NULL; +#if R2_USE_NEW_ABI + RBinObject *bo = R_UNWRAP4 (core, bin, cur, bo); + R_VEC_FOREACH (&bo->classes, k) +#else RList *klasses = r_bin_get_classes (core->bin); - r_list_foreach (klasses, iter, k) { + r_list_foreach (klasses, iter, k) +#endif + { const char *kname = r_bin_name_tostring2 (k->name, pref); if (!strcmp (kname, klass_name)) { if (method_name) { klass = k; } else { // delete class! +#if R2_USE_NEW_ABI + R_LOG_WARN ("TODO: delete class"); +#else r_list_delete (klasses, iter); +#endif return; } break; @@ -712,13 +747,19 @@ void cmd_ic_add(RCore *core, const char *input) { R_LOG_INFO ("Usage: ic+[klassname][.methodname]"); return; } - RList *klasses = r_bin_get_classes (core->bin); RListIter *iter; RBinClass *k; char *klass_name = strdup (input); char *method_name = r_str_after (klass_name, '.'); RBinClass *klass = NULL; - r_list_foreach (klasses, iter, k) { +#if R2_USE_NEW_ABI + RBinObject *bo = R_UNWRAP4 (core, bin, cur, bo); + R_VEC_FOREACH (&bo->classes, k) +#else + RList *klasses = r_bin_get_classes (core->bin); + r_list_foreach (klasses, iter, k) +#endif + { const char *kname = r_bin_name_tostring (k->name); if (!strcmp (kname, klass_name)) { klass = k; @@ -728,7 +769,11 @@ void cmd_ic_add(RCore *core, const char *input) { if (!klass) { klass = R_NEW0 (RBinClass); klass->name = r_bin_name_new (klass_name); +#if R2_USE_NEW_ABI + RVecRBinClass_push_back (&bo->classes, klass); +#else r_list_append (klasses, klass); +#endif } if (method_name == NULL) { klass->addr = core->offset; @@ -757,14 +802,20 @@ void cmd_ic_add(RCore *core, const char *input) { static void cmd_icg(RCore *core, RBinObject *obj, const char *arg) { // "icg" const int pref = r_config_get_b (core->config, "asm.demangle")? 0: 'o'; RBinClass *cls; - RListIter *iter, *iter2; if (!obj) { return; } bool fullGraph = true; const char *match = r_str_trim_head_ro (arg); +#if R2_USE_NEW_ABI + RListIter *iter2; +#define CLASSES_FOREACH R_VEC_FOREACH (&obj->classes, cls) +#else + RListIter *iter, *iter2; +#define CLASSES_FOREACH r_list_foreach (obj->classes, iter, cls) +#endif if (R_STR_ISNOTEMPTY (match)) { - r_list_foreach (obj->classes, iter, cls) { + CLASSES_FOREACH { const char *kname = r_bin_name_tostring2 (cls->name, pref); if (!match || !strstr (kname, match)) { continue; @@ -782,7 +833,7 @@ static void cmd_icg(RCore *core, RBinObject *obj, const char *arg) { // "icg" } } } else if (fullGraph) { - r_list_foreach (obj->classes, iter, cls) { + CLASSES_FOREACH { const char *kname = r_bin_name_tostring2 (cls->name, pref); RBinName *bn; r_cons_printf ("agn %s\n", kname); @@ -793,7 +844,7 @@ static void cmd_icg(RCore *core, RBinObject *obj, const char *arg) { // "icg" } } } else { - r_list_foreach (obj->classes, iter, cls) { + CLASSES_FOREACH { const char *kname = r_bin_name_tostring2 (cls->name, pref); char *sk; RListIter *iter; @@ -836,7 +887,14 @@ static void cmd_ic0(RCore *core, RBinObject *obj, int mode, PJ *pj, bool is_arra RListIter *iter, *iter2; RBinSymbol *sym; RBinClass *cls; - r_list_foreach (obj->classes, iter, cls) { +#if R2_USE_NEW_ABI + int classes_length = RVecRBinClass_length (&obj->classes); + R_VEC_FOREACH (&obj->classes, cls) +#else + int classes_length = r_list_length (obj->classes); + r_list_foreach (obj->classes, iter, cls) +#endif + { const char *kname = r_bin_name_tostring2 (cls->name, pref); if ((idx >= 0 && idx != (*count)++) || (R_STR_ISNOTEMPTY (cls_name) && strcmp (cls_name, kname))) { continue; @@ -857,7 +915,7 @@ static void cmd_ic0(RCore *core, RBinObject *obj, int mode, PJ *pj, bool is_arra { listed_classes = true; int mode = R_MODE_RADARE; - RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes)); + RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, classes_length); } #if 0 r_list_foreach (cls->methods, iter2, sym) { @@ -876,16 +934,14 @@ static void cmd_ic0(RCore *core, RBinObject *obj, int mode, PJ *pj, bool is_arra case 'j': { int mode = R_MODE_JSON; // (oldmode == 'q')? R_MODE_SIMPLE: 0; - int len = r_list_length (obj->classes); listed_classes = true; - RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, len); + RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, classes_length); } break; case 0: if (idx == -1 && R_STR_ISEMPTY (cls_name)) { - size_t len = r_list_length (obj->classes); int mode = 0; - RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, len); + RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, classes_length); listed_classes = true; } else { r_cons_printf ("class %s\n", kname); @@ -901,9 +957,9 @@ static void cmd_ic0(RCore *core, RBinObject *obj, int mode, PJ *pj, bool is_arra break; case 'q': { - size_t len = r_list_length (obj->classes); - int mode = R_MODE_SIMPLE; - RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, len); + int oldmode = mode; + int mode = (oldmode == 'q')? R_MODE_SIMPLE: 0; + RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, classes_length); listed_classes = true; } break; @@ -1016,7 +1072,14 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, bool is_array, bool v } r_list_foreach (objs, objs_iter, bf) { RBinObject *obj = bf->bo; - if (!obj || !obj->classes || r_list_empty (obj->classes)) { +#if R2_USE_NEW_ABI + int classes_length = RVecRBinClass_length (&obj->classes); + RListIter *iter2; +#else + int classes_length = r_list_length (obj->classes); + RListIter *iter, *iter2; +#endif + if (!obj || classes_length == 0) { if (mode == 'j') { r_cons_printf ("%s[]", first? "": ","); } @@ -1026,11 +1089,15 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, bool is_array, bool v first = false; RBinClass *cls; RBinSymbol *sym; - RListIter *iter, *iter2; core->bin->cur = bf; if (is_superquiet && is_jvm) { - r_list_foreach (obj->classes, iter, cls) { +#if R2_USE_NEW_ABI + R_VEC_FOREACH (&obj->classes, cls) +#else + r_list_foreach (obj->classes, iter, cls) +#endif + { const char *kname = r_bin_name_tostring (cls->name); if (!isKnownAndroidPackage (kname)) { r_cons_printf ("%s\n", kname); @@ -1038,13 +1105,18 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, bool is_array, bool v } break; } - tts_say (core, "classes", r_list_length (obj->classes)); + tts_say (core, "classes", classes_length); switch (cmd) { case 'g': cmd_icg (core, obj, arg); break; case 's': // "ics" - r_list_foreach (obj->classes, iter, cls) { +#if R2_USE_NEW_ABI + R_VEC_FOREACH (&obj->classes, cls) +#else + r_list_foreach (obj->classes, iter, cls) +#endif + { const char *kname = r_bin_name_tostring (cls->name); r_list_foreach (cls->methods, iter2, sym) { ut64 addr = iova? sym->vaddr: sym->paddr; @@ -1060,7 +1132,12 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, bool is_array, bool v classdump_keys (core, obj); return; case 'l': // "icl" - r_list_foreach (obj->classes, iter, cls) { +#if R2_USE_NEW_ABI + R_VEC_FOREACH (&obj->classes, cls) +#else + r_list_foreach (obj->classes, iter, cls) +#endif + { r_list_foreach (cls->methods, iter2, sym) { const char *comma = iter2->p? " ": ""; r_cons_printf ("%s0x%"PFMT64x, comma, @@ -1077,7 +1154,12 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, bool is_array, bool v ut64 min = UT64_MAX; const char *method = NULL; ut64 max = 0LL; - r_list_foreach (obj->classes, iter, cls) { +#if R2_USE_NEW_ABI + R_VEC_FOREACH (&obj->classes, cls) +#else + r_list_foreach (obj->classes, iter, cls) +#endif + { method = NULL; r_list_foreach (cls->methods, iter2, sym) { ut64 at = iova? sym->vaddr: sym->paddr; @@ -1118,7 +1200,7 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, bool is_array, bool v olang = strdup (r_config_get (core->config, "bin.lang")); r_config_set (core->config, "bin.lang", lang + 1); } - RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes)); + RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, classes_length); if (olang) { r_config_set (core->config, "bin.lang", olang); free (olang); @@ -1130,7 +1212,7 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, bool is_array, bool v mode = R_MODE_JSON; } // TODO add the ability to filter by name - RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes)); + RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, classes_length); break; case ' ': // "ic" case 0: // "ic" diff --git a/libr/core/cmd_print.inc.c b/libr/core/cmd_print.inc.c index d38fc1a959247..a86d7788294c1 100644 --- a/libr/core/cmd_print.inc.c +++ b/libr/core/cmd_print.inc.c @@ -1098,10 +1098,16 @@ static void findMethodBounds(RList *methods, ut64 *min, ut64 *max) { static ut64 findClassBounds(RCore *core, const char *input, int *len) { ut64 min = 0, max = 0; - RListIter *iter; RBinClass *c; +#if R2_USE_NEW_ABI + RBinObject *bo = R_UNWRAP4 (core, bin, cur, bo); + R_VEC_FOREACH (&bo->classes, c) +#else + RListIter *iter; RList *cs = r_bin_get_classes (core->bin); - r_list_foreach (cs, iter, c) { + r_list_foreach (cs, iter, c) +#endif + { findMethodBounds (c->methods, &min, &max); if (len) { *len = (max - min); diff --git a/libr/core/dmh_glibc.inc.c b/libr/core/dmh_glibc.inc.c index 63492a843490a..5b737471470d3 100644 --- a/libr/core/dmh_glibc.inc.c +++ b/libr/core/dmh_glibc.inc.c @@ -43,6 +43,7 @@ static GHT GH(get_va_symbol)(RCore *core, const char *path, const char *sym_name GHT vaddr = GHT_MAX; RBin *bin = core->bin; RBinFile *bf = r_bin_cur (bin); + int bfid = bf? bf->id: -1; RBinFileOptions opt; r_bin_file_options_init (&opt, -1, 0, 0, false); @@ -57,8 +58,17 @@ static GHT GH(get_va_symbol)(RCore *core, const char *path, const char *sym_name } } RBinFile *libc_bf = r_bin_cur (bin); - r_bin_file_delete (bin, libc_bf->id); - r_bin_file_set_cur_binfile (bin, bf); + if (libc_bf) { + r_bin_file_delete (bin, libc_bf->id); + if (bfid != -1) { + r_bin_file_set_cur_by_id (bin, bfid); + // r_bin_file_set_cur_binfile (bin, bf); + } else { + R_LOG_ERROR ("Cannot revert back to the previous binfile"); + } + } else { + R_LOG_ERROR ("Cannot find current binfile for libc"); + } } return vaddr; } @@ -581,6 +591,9 @@ static GHT GH (get_main_arena_offset_with_relocs) (RCore *core, const char *libc R_LOG_WARN ("get_main_arena_with_relocs: Failed to open libc %s", libc_path); return GHT_MAX; } +#if R2_USE_NEW_ABI + int bfid = bf? bf->id: -1; +#endif RRBTree *relocs = r_bin_get_relocs (bin); if (!relocs) { R_LOG_WARN ("get_main_arena_with_relocs: Failed to get relocs from libc %s", libc_path); @@ -660,7 +673,14 @@ static GHT GH (get_main_arena_offset_with_relocs) (RCore *core, const char *libc RBinFile *libc_bf = r_bin_cur (bin); r_bin_file_delete (bin, libc_bf->id); +#if R2_USE_NEW_ABI + if (bfid != -1) { + // r_bin_file_set_cur_binfile (bin, bf); + r_bin_file_set_cur_by_id (bin, bfid); + } +#else r_bin_file_set_cur_binfile (bin, bf); +#endif return main_arena; } diff --git a/libr/core/vmenus.c b/libr/core/vmenus.c index 90ca3bb447986..63a732d65827f 100644 --- a/libr/core/vmenus.c +++ b/libr/core/vmenus.c @@ -1050,7 +1050,6 @@ R_API int r_core_visual_types(RCore *core) { } R_API bool r_core_visual_hudclasses(RCore *core) { - RListIter *iter, *iter2; RBinClass *c; RBinField *f; RBinSymbol *m; @@ -1062,8 +1061,16 @@ R_API bool r_core_visual_hudclasses(RCore *core) { } const int pref = r_config_get_b (core->config, "asm.demangle")? 'd': 0; list->free = free; +#if R2_USE_NEW_ABI + RListIter *iter2; + RBinObject *bo = R_UNWRAP4 (core, bin, cur, bo); + R_VEC_FOREACH (&bo->classes, c) +#else + RListIter *iter, *iter2; RList *classes = r_bin_get_classes (core->bin); - r_list_foreach (classes, iter, c) { + r_list_foreach (classes, iter, c) +#endif + { const char *cname = r_bin_name_tostring2 (c->name, pref); r_list_foreach (c->fields, iter2, f) { const char *fname = r_bin_name_tostring2 (f->name, pref); @@ -1362,11 +1369,18 @@ R_API int r_core_visual_classes(RCore *core) { int oldcur = 0; char *grep = NULL; bool grepmode = false; +#if R2_USE_NEW_ABI +#warning TODO not implemented the visual header classes with this vector thing + //RBinObject *bo = R_UNWRAP4 (core, bin, cur, bo); + // R_VEC_FOREACH (&bo->classes, c) + RList *list = NULL; +#else RList *list = r_bin_get_classes (core->bin); if (r_list_empty (list)) { r_cons_message ("No Classes"); return false; } +#endif for (;;) { int cols; r_cons_clear00 (); diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index 41aa009ef8750..e2fc909d2a24c 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -329,12 +329,43 @@ typedef struct r_bin_import_t { bool is_imported; } RBinImport; +// RBinClass +typedef struct r_bin_class_t { + RBinName *name; + RList *super; // list of RBinName + char *visibility_str; // XXX R2_590 - only used by dex+java should be ut32 or bitfield.. should be usable for swift too + int index; // should be unsigned? + ut64 addr; + char *ns; // namespace // maybe RBinName? +#if R2_USE_NEW_ABI + // Use RVec here + RList *methods; // + RList *fields; // +#else + RList *methods; // + RList *fields; // +#endif + // RList *interfaces; // + RBinAttribute attr; + ut64 lang; +} RBinClass; + +R_API RBinClass *r_bin_class_new(const char *name, const char *super, ut64 attr); +R_API void r_bin_class_free(RBinClass *); +#if R2_USE_NEW_ABI +R_API void r_bin_class_fini(RBinClass *k); +#endif + + #include // XXX only forward declare here for better compile times R_API void r_bin_symbol_fini(RBinSymbol *sym); R_API void r_bin_import_fini(RBinImport *sym); R_VEC_TYPE_WITH_FINI (RVecRBinImport, RBinImport, r_bin_import_fini); +#if R2_USE_NEW_ABI +R_VEC_TYPE_WITH_FINI (RVecRBinClass, RBinClass, r_bin_class_fini); +#endif R_VEC_TYPE_WITH_FINI (RVecRBinSymbol, RBinSymbol, r_bin_symbol_fini); R_VEC_TYPE(RVecRBinSection, RBinSection); R_VEC_TYPE(RVecRBinEntry, RBinSymbol); @@ -359,7 +390,11 @@ typedef struct r_bin_object_t { RList/**/ *libs; RRBTree/**/ *relocs; RList/**/ *strings; +#if R2_USE_NEW_ABI + RVecRBinClass classes; +#else RList/**/ *classes; +#endif HtPP *classes_ht; HtPP *methods_ht; RList/**/ *lines; @@ -594,25 +629,6 @@ typedef struct r_bin_plugin_t { typedef void (*RBinSymbollCallback)(RBinObject *obj, void *symbol); -typedef struct r_bin_class_t { - RBinName *name; - RList *super; // list of RBinName - char *visibility_str; // XXX R2_590 - only used by dex+java should be ut32 or bitfield.. should be usable for swift too - int index; // should be unsigned? - ut64 addr; - char *ns; // namespace // maybe RBinName? -#if R2_USE_NEW_ABI - // Use RVec here - RList *methods; // - RList *fields; // -#else - RList *methods; // - RList *fields; // -#endif - // RList *interfaces; // - RBinAttribute attr; - ut64 lang; -} RBinClass; #define RBinSectionName r_offsetof(RBinSection, name) #define RBinSectionOffset r_offsetof(RBinSection, offset) @@ -754,6 +770,8 @@ typedef void (*RBinSymbolCallback)(RBinObject *obj, RBinSymbol *symbol); // options functions R_API void r_bin_file_options_init(RBinFileOptions *opt, int fd, ut64 baseaddr, ut64 loadaddr, int rawstr); R_API void r_bin_arch_options_init(RBinArchOptions *opt, const char *arch, int bits); +// uhm should be tied used because we dont want bincur to change because of open +R_API RBinFile *r_bin_file_open(RBin *bin, const char *file, RBinFileOptions *opt); // R_API void r_bin_create_options_init(RBinCreateOptions *opt, const char *arch, int bits); // open/close/reload functions @@ -764,11 +782,6 @@ R_API bool r_bin_open_io(RBin *bin, RBinFileOptions *opt); R_API bool r_bin_open_buf(RBin *bin, RBuffer *buf, RBinFileOptions *opt); R_API bool r_bin_reload(RBin *bin, ut32 bf_id, ut64 baseaddr); -R_API RBinClass *r_bin_class_new(const char *name, const char *super, ut64 attr); -R_API void r_bin_class_free(RBinClass *); -// uhm should be tied used because we dont want bincur to change because of open -R_API RBinFile *r_bin_file_open(RBin *bin, const char *file, RBinFileOptions *opt); - // plugins/bind functions R_API void r_bin_bind(RBin *b, RBinBind *bnd); R_API bool r_bin_plugin_add(RBin *bin, RBinPlugin *plugin); diff --git a/libr/main/radiff2.c b/libr/main/radiff2.c index 63bad06533961..ac0b12281c1b8 100644 --- a/libr/main/radiff2.c +++ b/libr/main/radiff2.c @@ -759,16 +759,22 @@ static int import_cmp(const RBinImport *a, const RBinImport *b) { } static ut8 *get_classes(RCore *c, int *len) { - RListIter *iter; if (!c || !len) { return NULL; } RBinClass *klass; - const RList *list = r_bin_get_classes (c->bin); RList *reslist = r_list_newf (free); - r_list_foreach (list, iter, klass) { +#if R2_USE_NEW_ABI + RBinObject *bo = R_UNWRAP4 (c, bin, cur, bo); + R_VEC_FOREACH (&bo->classes, klass) +#else + RListIter *iter; + const RList *list = r_bin_get_classes (c->bin); + r_list_foreach (list, iter, klass) +#endif + { const char *kname = r_bin_name_tostring (klass->name); r_list_append (reslist, strdup (kname)); } @@ -789,10 +795,17 @@ static ut8 *get_fields(RCore *c, int *len) { } RBinClass *klass; - const RList *list = r_bin_get_classes (c->bin); RList *reslist = r_list_newf (free); +#if R2_USE_NEW_ABI + RListIter *iter2; + RBinObject *bo = R_UNWRAP4 (c, bin, cur, bo); + R_VEC_FOREACH (&bo->classes, klass) +#else RListIter *iter, *iter2; - r_list_foreach (list, iter, klass) { + const RList *list = r_bin_get_classes (c->bin); + r_list_foreach (list, iter, klass) +#endif + { const char *kname = r_bin_name_tostring (klass->name); RBinField *field; r_list_foreach (klass->fields, iter2, field) { @@ -808,17 +821,23 @@ static ut8 *get_fields(RCore *c, int *len) { } static ut8 *get_methods(RCore *c, int *len) { - RListIter *iter, *iter2; - if (!c || !len) { return NULL; } RBinClass *klass; RBinSymbol *sym; - const RList *list = r_bin_get_classes (c->bin); RList *reslist = r_list_newf (free); - r_list_foreach (list, iter, klass) { +#if R2_USE_NEW_ABI + RListIter *iter2; + RBinObject *bo = R_UNWRAP4 (c, bin, cur, bo); + R_VEC_FOREACH (&bo->classes, klass) +#else + RListIter *iter, *iter2; + const RList *list = r_bin_get_classes (c->bin); + r_list_foreach (list, iter, klass) +#endif + { const char *kname = r_bin_name_tostring (klass->name); r_list_foreach (klass->methods, iter2, sym) { const char *name = r_bin_name_tostring (sym->name); diff --git a/test/unit/test_anal_block.c b/test/unit/test_anal_block.c index 14628c4f3f832..a4bbfbbc8b595 100644 --- a/test/unit/test_anal_block.c +++ b/test/unit/test_anal_block.c @@ -10,7 +10,7 @@ static size_t blocks_count(RAnal *anal) { size_t count = 0; RBIter iter; RAnalBlock *block; - r_rbtree_foreach(anal->bb_tree, iter, block, RAnalBlock, _rb) { + r_rbtree_foreach (anal->bb_tree, iter, block, RAnalBlock, _rb) { count++; } return count; @@ -77,6 +77,8 @@ bool test_r_anal_block_split(void) { block->jump = 0xdeadbeef; block->fail = 0xc0ffee; block->ninstr = 5; + free (block->op_pos); + block->op_pos = calloc (block->ninstr, sizeof (ut16)); r_anal_bb_set_offset (block, 0, 0); r_anal_bb_set_offset (block, 1, 1); r_anal_bb_set_offset (block, 2, 2);