Skip to content

Commit

Permalink
Allow bin plugins to set custom relocs free
Browse files Browse the repository at this point in the history
  • Loading branch information
kazarmy committed May 18, 2024
1 parent 58a3b7c commit dbadc71
Show file tree
Hide file tree
Showing 10 changed files with 16 additions and 30 deletions.
25 changes: 6 additions & 19 deletions librz/bin/bobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ static int reloc_target_cmp(const void *a, const void *b, void *user) {

#undef CMP_CHECK

RZ_API RzBinRelocStorage *rz_bin_reloc_storage_new(RZ_OWN RzPVector /*<RzBinReloc *>*/ *relocs, RzBinPlugin *plugin) {
RZ_API RzBinRelocStorage *rz_bin_reloc_storage_new(RZ_OWN RzPVector /*<RzBinReloc *>*/ *relocs) {
RzBinRelocStorage *ret = RZ_NEW0(RzBinRelocStorage);
if (!ret) {
return NULL;
Expand All @@ -115,6 +115,7 @@ RZ_API RzBinRelocStorage *rz_bin_reloc_storage_new(RZ_OWN RzPVector /*<RzBinRelo
rz_pvector_push(&target_sorter, reloc);
}
}
ret->relocs_free = relocs->v.free_user;
relocs->v.free = NULL; // ownership of relocs transferred
rz_pvector_free(relocs);
rz_pvector_sort(&sorter, reloc_cmp, NULL);
Expand All @@ -125,30 +126,16 @@ RZ_API RzBinRelocStorage *rz_bin_reloc_storage_new(RZ_OWN RzPVector /*<RzBinRelo
ret->target_relocs_count = rz_pvector_len(&target_sorter);
ret->target_relocs = (RzBinReloc **)rz_pvector_flush(&target_sorter);
rz_pvector_fini(&target_sorter);
if (plugin) {
if (!strcmp(plugin->name, "coff")) {
ret->imp_shared = true;
ret->sym_shared = true;
} else if (rz_str_cmp_list("le mach0 mach064 mdmp pe", plugin->name, ' ')) {
ret->imp_shared = true;
}
}
return ret;
}

RZ_API void rz_bin_reloc_storage_free(RzBinRelocStorage *storage) {
if (!storage) {
return;
}
for (size_t i = 0; i < storage->relocs_count; i++) {
if (storage->relocs[i]) {
if (!storage->imp_shared) {
rz_bin_import_free(storage->relocs[i]->import);
}
if (!storage->sym_shared) {
rz_bin_symbol_free(storage->relocs[i]->symbol);
}
free(storage->relocs[i]);
if (storage->relocs_free) {
for (size_t i = 0; i < storage->relocs_count; i++) {
storage->relocs_free(storage->relocs[i]);
}
}
free(storage->relocs);
Expand Down Expand Up @@ -570,7 +557,7 @@ RZ_API RzBinRelocStorage *rz_bin_object_patch_relocs(RzBinFile *bf, RzBinObject
}
rz_bin_reloc_storage_free(o->relocs);
REBASE_PADDR(o, tmp, RzBinReloc);
o->relocs = rz_bin_reloc_storage_new(tmp, o->plugin);
o->relocs = rz_bin_reloc_storage_new(tmp);
bf->rbin->is_reloc_patched = true;
}
return o->relocs;
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/bobj_process_reloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ RZ_IPI void rz_bin_set_and_process_relocs(RzBinFile *bf, RzBinObject *o, const R
process_handle_reloc(element, o, demangler, flags, imp_cb, sym_cb);
}

o->relocs = rz_bin_reloc_storage_new(relocs, plugin);
o->relocs = rz_bin_reloc_storage_new(relocs);
}

RZ_IPI void rz_bin_demangle_relocs_with_flags(RzBinObject *o, const RzDemanglerPlugin *demangler, RzDemanglerFlag flags) {
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/format/le/le.c
Original file line number Diff line number Diff line change
Expand Up @@ -1765,7 +1765,7 @@ RZ_OWN RzPVector /*<RzBinVirtualFile *>*/ *rz_bin_le_get_virtual_files(RzBinFile
RZ_OWN RzPVector /*<RzBinReloc *>*/ *rz_bin_le_get_relocs(RzBinFile *bf) {
rz_bin_le_obj_t *bin = bf->o->bin_obj;
RzList /*<LE_reloc *>*/ *le_relocs = bin->le_relocs;
RzPVector /*<RzBinReloc *>*/ *relocs = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free);
RzPVector /*<RzBinReloc *>*/ *relocs = rz_pvector_new(free);
RzBinReloc *reloc = NULL;
if (!relocs) {
fail_cleanup:
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/format/ne/ne.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ RzPVector /*<RzBinReloc *>*/ *rz_bin_ne_get_relocs(rz_bin_ne_obj_t *bin) {
}
rz_buf_read_at(bin->buf, (ut64)bin->ne_header->ModRefTable + bin->header_offset, (ut8 *)modref, bin->ne_header->ModRefs * sizeof(ut16));

RzPVector *relocs = rz_pvector_new(free);
RzPVector *relocs = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free);
if (!relocs) {
free(modref);
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/p/bin_bflt.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ static void convert_relocs(RzBfltObj *bin, RzPVector /*<RzBinReloc *>*/ *out, Rz

static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
RzBfltObj *obj = (RzBfltObj *)bf->o->bin_obj;
RzPVector *vec = rz_pvector_new((RzPVectorFree)free);
RzPVector *vec = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free);
if (!vec || !obj) {
rz_pvector_free(vec);
return NULL;
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/p/bin_elf.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1858,7 +1858,7 @@ static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {

patch_relocs(bf, bin);

if (!(ret = rz_pvector_new((RzPVectorFree)free))) {
if (!(ret = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free))) {
return NULL;
}

Expand Down
2 changes: 1 addition & 1 deletion librz/bin/p/bin_mz.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
if (!bf || !bf->o || !bf->o->bin_obj) {
return NULL;
}
if (!(ret = rz_pvector_new(free))) {
if (!(ret = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free))) {
return NULL;
}
if (!(relocs = rz_bin_mz_get_relocs(bf->o->bin_obj))) {
Expand Down
2 changes: 1 addition & 1 deletion librz/bin/p/bin_qnx.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ static RzPVector /*<RzBinReloc *>*/ *relocs(RzBinFile *bf) {
QnxObj *qo = bf->o->bin_obj;
RzBinReloc *reloc = NULL;
RzListIter *it = NULL;
RzPVector *relocs = rz_pvector_new(free);
RzPVector *relocs = rz_pvector_new((RzPVectorFree)rz_bin_reloc_free);
if (!relocs) {
return NULL;
}
Expand Down
5 changes: 2 additions & 3 deletions librz/include/rz_bin.h
Original file line number Diff line number Diff line change
Expand Up @@ -680,13 +680,12 @@ RZ_API ut64 rz_bin_reloc_size(RzBinReloc *reloc);
struct rz_bin_reloc_storage_t {
RzBinReloc **relocs; ///< all relocs, ordered by their vaddr
size_t relocs_count;
RzPVectorFree relocs_free;
RzBinReloc **target_relocs; ///< all relocs that have a valid target_vaddr, ordered by their target_vaddr. size is target_relocs_count!
size_t target_relocs_count;
bool imp_shared; // plugin frees reloc imports
bool sym_shared; // plugin frees reloc symbols
}; // RzBinRelocStorage

RZ_API RzBinRelocStorage *rz_bin_reloc_storage_new(RZ_OWN RzPVector /*<RzBinReloc *>*/ *relocs, RzBinPlugin *plugin);
RZ_API RzBinRelocStorage *rz_bin_reloc_storage_new(RZ_OWN RzPVector /*<RzBinReloc *>*/ *relocs);
RZ_API void rz_bin_reloc_storage_free(RzBinRelocStorage *storage);
RZ_API RzBinReloc *rz_bin_reloc_storage_get_reloc_in(RzBinRelocStorage *storage, ut64 vaddr, ut64 size);

Expand Down
2 changes: 1 addition & 1 deletion test/integration/test_bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ bool test_rz_bin_reloc_storage(void) {
mu_assert_notnull(rz, "reloc");
RzBinReloc *r3 = add_reloc(l, 0x1003, 0x1006, 0x200c);
mu_assert_notnull(r3, "reloc");
RzBinRelocStorage *relocs = rz_bin_reloc_storage_new(l, NULL);
RzBinRelocStorage *relocs = rz_bin_reloc_storage_new(l);

RzBinReloc *r = rz_bin_reloc_storage_get_reloc_in(relocs, 0xfff, 1);
mu_assert_null(r, "reloc in");
Expand Down

0 comments on commit dbadc71

Please sign in to comment.