rizin/librz/bin/bobj_process_class.c
pelijah f2d8e0db3d
Add HtSP, HtSS, HtSU, SetS (#4415)
- All `ht_*_new0()` are removed
- `freefn` field of HT options was renamed to `finiKV`
- `finiKV_user` fields was added to HT options
- Added `ht_*_new_opt_size` API
- `HtSP` and `HtUP` are created with `ValueFree` callback  that allows to reduce extra LOC and prevent bugs
- `SetP` replaced with `SetS` (based on `HtSP`)
- `rz_th_ht_*_new0()` and `rz_th_ht_*_new_opt()` are replaced with `rz_th_ht_*_new(HtXX *)`
2024-04-16 20:27:48 +08:00

99 lines
2.9 KiB
C

// SPDX-FileCopyrightText: 2023 RizinOrg <info@rizin.re>
// SPDX-FileCopyrightText: 2023 deroad <wargio@libero.it>
// SPDX-License-Identifier: LGPL-3.0-only
#include <rz_bin.h>
#include "i/private.h"
static void process_class_method(RzBinObject *o, RzBinSymbol *method) {
// rebase physical address
method->paddr += o->opts.loadaddr;
char *key = rz_str_newf(RZ_BIN_FMT_CLASS_HT_GLUE, method->classname, method->name);
if (!key) {
RZ_LOG_ERROR("bin: failed to allocate class-method string\n");
return;
}
ht_sp_insert(o->glue_to_class_method, key, method);
free(key);
ht_up_insert(o->vaddr_to_class_method, method->vaddr, method);
}
static void process_class_field(RzBinObject *o, RzBinClassField *field) {
// rebase physical address
field->paddr += o->opts.loadaddr;
char *key = rz_str_newf(RZ_BIN_FMT_CLASS_HT_GLUE, field->classname, field->name);
if (!key) {
RZ_LOG_ERROR("bin: failed to allocate class-field string\n");
return;
}
ht_sp_insert(o->glue_to_class_field, key, field);
free(key);
}
static int bin_compare_method(RzBinSymbol *a, RzBinSymbol *b, void *user) {
return rz_bin_compare_method(a, b);
}
static int bin_compare_class_field(RzBinClassField *a, RzBinClassField *b, void *user) {
return rz_bin_compare_class_field(a, b);
}
static void process_handle_class(RzBinObject *o, RzBinClass *klass) {
if (!klass->name) {
klass->name = rz_str_dup("unknown_class");
}
RzBinClass *found = ht_sp_find(o->name_to_class_object, klass->name, NULL);
if (!found) {
ht_sp_insert(o->name_to_class_object, klass->name, klass);
found = klass;
} else {
RZ_LOG_WARN("Found duplicated class: %s\n", klass->name);
}
RzListIter *iter;
RzBinSymbol *method;
RzBinClassField *field;
rz_list_foreach (klass->methods, iter, method) {
process_class_method(o, method);
}
rz_list_foreach (klass->fields, iter, field) {
process_class_field(o, field);
}
rz_list_sort(klass->methods, (RzListComparator)bin_compare_method, NULL);
rz_list_sort(klass->fields, (RzListComparator)bin_compare_class_field, NULL);
}
RZ_IPI void rz_bin_set_and_process_classes(RzBinFile *bf, RzBinObject *o) {
RzBin *bin = bf->rbin;
RzBinPlugin *plugin = o->plugin;
rz_pvector_free(o->classes);
if (!(bin->filter_rules & (RZ_BIN_REQ_CLASSES | RZ_BIN_REQ_CLASSES_SOURCES)) ||
!plugin->classes || !(o->classes = plugin->classes(bf))) {
o->classes = rz_pvector_new((RzPVectorFree)rz_bin_class_free);
}
rz_warn_if_fail(o->classes->v.free_user);
ht_sp_free(o->name_to_class_object);
ht_sp_free(o->glue_to_class_method);
ht_sp_free(o->glue_to_class_field);
ht_up_free(o->vaddr_to_class_method);
o->name_to_class_object = ht_sp_new(HT_STR_DUP, NULL, NULL);
o->glue_to_class_method = ht_sp_new(HT_STR_DUP, NULL, NULL);
o->glue_to_class_field = ht_sp_new(HT_STR_DUP, NULL, NULL);
o->vaddr_to_class_method = ht_up_new(NULL, NULL);
void **it;
RzBinClass *element;
rz_pvector_foreach (o->classes, it) {
element = *it;
process_handle_class(o, element);
}
}