Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use RVec instead of RList as class storage #23625

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 50 additions & 4 deletions libr/bin/bfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
#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);
return ht_pp_find (bf->bo->classes_ht, name, NULL);
}
Expand Down Expand Up @@ -1094,20 +1094,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);
Expand All @@ -1116,13 +1145,30 @@ R_API RBinClass *r_bin_file_add_class(RBinFile *bf, const char *name, const char
}
return c;
}
#if R2_USE_NEW_ABI
c = R_NEW0 (RBinClass);
if (c) {
r_bin_class_init (c, name, super, attr);
c->index = RVecRBinClass_length (&bf->bo->classes);
RVecRBinClass_push_back (&bf->bo->classes, c);
ht_pp_insert (bf->bo->classes_ht, name, c);
}
// free (c);
// const int htidx = bc.index + 1;
// 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
c->index = r_list_length (bf->bo->classes);
r_list_append (bf->bo->classes, c);
ht_pp_insert (bf->bo->classes_ht, name, c);
}
#endif
return c;
}

Expand All @@ -1144,7 +1190,6 @@ 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);
// RBinSymbol *dsym = r_bin_symbol_clone (sym);
r_list_append (c->methods, sym);
free (name);
}
Expand Down Expand Up @@ -1222,6 +1267,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);
Expand Down
8 changes: 8 additions & 0 deletions libr/bin/bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,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);

Expand Down Expand Up @@ -273,6 +274,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);

Expand Down Expand Up @@ -321,10 +323,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);
Expand Down Expand Up @@ -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* /*<RBinClass>*/ 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) {
Expand Down
77 changes: 59 additions & 18 deletions libr/bin/bobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -172,7 +176,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
Expand All @@ -185,7 +189,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
Expand All @@ -202,7 +205,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;
Expand Down Expand Up @@ -262,19 +269,23 @@ R_IPI RBinObject *r_bin_object_new(RBinFile *bf, RBinPlugin *plugin, ut64 basead
return bo;
}

static bool filter_classes(RBinFile *bf, RList *list) {
bool rc = true;
static void filter_classes(RBinFile *bf) {
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)) {
R_LOG_INFO ("Corrupted class storage with nameless classes");
rc = false;
free (fname);
break;
}
Expand All @@ -291,7 +302,6 @@ static bool filter_classes(RBinFile *bf, RList *list) {
}
ht_su_free (db);
ht_pp_free (ht);
return rc;
}

static RRBTree *list2rbtree(RList *relocs) {
Expand All @@ -313,14 +323,22 @@ 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
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);
r_list_foreach (klass->methods, it2, method) {
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);
Expand Down Expand Up @@ -445,24 +463,47 @@ R_API int r_bin_object_set_items(RBinFile *bf, RBinObject *bo) {
RList *classes = p->classes (bf);
if (classes) {
// XXX we should probably merge them instead
#if R2_USE_NEW_ABI
RListIter *iter;
RBinClass *klass;
RVecRBinClass_fini (&bo->classes);
r_list_foreach (classes, iter, klass) {
RVecRBinClass_push_back (&bo->classes, klass);
}
#else
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
#endif
#if 0
// moved into libr/core/canal.c
// XXX SLOW on large binaries. only used when needed by getFunctionName from canal.c
Expand Down
4 changes: 4 additions & 0 deletions libr/bin/format/dex/dex.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading
Loading