Skip to content

Commit

Permalink
Unify the relocations loading (#16705)
Browse files Browse the repository at this point in the history
* Mov init rel_cache inside the bin init
* Introduce array cache
* Use bin->relocs after loading all relocs
* Handle bin->relocs == NULL
* Remove last free
* Use cache to get relocations
  • Loading branch information
Alexis Ehret committed Apr 24, 2020
1 parent c90b2fa commit 78de31f
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 33 deletions.
54 changes: 26 additions & 28 deletions libr/bin/format/elf/elf.c
Expand Up @@ -1259,6 +1259,23 @@ static bool init_dynstr(ELFOBJ *bin) {
return false;
}

static HtUP *rel_cache_new(RBinElfReloc *relocs, ut32 reloc_num) {
if (!relocs || reloc_num == 0) {
return NULL;
}

const int htsize = R_MIN (reloc_num, 1024);
HtUP *rel_cache = ht_up_new_size (htsize, NULL, NULL, NULL);
ut32 i;

for (i = 0; i < reloc_num; i++) {
RBinElfReloc *tmp = relocs + i;
ht_up_insert (rel_cache, tmp->sym, tmp);
}

return rel_cache;
}

static bool elf_init(ELFOBJ *bin) {
/* bin is not an ELF */
if (!init_ehdr (bin)) {
Expand Down Expand Up @@ -1289,6 +1306,8 @@ static bool elf_init(ELFOBJ *bin) {
bin->symbols_by_ord = NULL;
bin->g_sections = Elf_(r_bin_elf_get_sections) (bin);
bin->boffset = Elf_(r_bin_elf_get_boffset) (bin);
bin->relocs = Elf_(r_bin_elf_get_relocs) (bin);
bin->rel_cache = rel_cache_new (bin->relocs, bin->reloc_num);
sdb_ns_set (bin->kv, "versioninfo", store_versioninfo (bin));
return true;
}
Expand All @@ -1311,28 +1330,6 @@ ut64 Elf_(r_bin_elf_get_section_addr_end)(ELFOBJ *bin, const char *section_name)
return section? section->rva + section->size: UT64_MAX;
}


static void rel_cache_free(HtUPKv *kv) {
free (kv->value);
}

static HtUP *rel_cache_new(ELFOBJ *bin) {
RBinElfReloc *relocs = Elf_(r_bin_elf_get_relocs) (bin);
const int htsize = R_MIN (bin->reloc_num, 1024);
HtUP *rel_cache = ht_up_new_size (htsize, NULL, rel_cache_free, NULL);
size_t i;

for (i = 0; i < bin->reloc_num; i++) {
RBinElfReloc *tmp = R_NEW (RBinElfReloc);
memcpy (tmp, relocs + i, sizeof (RBinElfReloc));
if (!ht_up_insert (rel_cache, tmp->sym, tmp)) {
free (tmp);
}
}
free (relocs);
return rel_cache;
}

static ut64 get_got_entry(ELFOBJ *bin, RBinElfReloc *rel) {
if (!rel->rva) {
return UT64_MAX;
Expand Down Expand Up @@ -1549,12 +1546,8 @@ static ut64 get_import_addr(ELFOBJ *bin, int sym) {
return UT64_MAX;
}

// create rel/rela cache if not already there
if (!bin->rel_cache) {
bin->rel_cache = rel_cache_new (bin);
if (!bin->rel_cache) {
return UT64_MAX;
}
return UT64_MAX;
}

// lookup the right rel/rela entry
Expand Down Expand Up @@ -2715,10 +2708,14 @@ static RBinElfReloc *populate_relocs_record(ELFOBJ *bin) {
}

RBinElfReloc* Elf_(r_bin_elf_get_relocs) (ELFOBJ *bin) {
if (!bin || !bin->g_sections) {
if (!bin) {
return NULL;
}

if (bin->relocs) {
return bin->relocs;
}

return populate_relocs_record (bin);
}

Expand Down Expand Up @@ -3700,6 +3697,7 @@ void Elf_(r_bin_elf_free)(ELFOBJ* bin) {
R_FREE (bin->g_sections);
R_FREE (bin->g_symbols);
R_FREE (bin->g_imports);
R_FREE (bin->relocs);
ht_up_free (bin->rel_cache);
bin->rel_cache = NULL;
free (bin);
Expand Down
3 changes: 2 additions & 1 deletion libr/bin/format/elf/elf.h
Expand Up @@ -110,8 +110,9 @@ struct Elf_(r_bin_elf_obj_t) {
char *shstrtab;

Elf_(Dyn) *dyn_buf;
RBinElfDynamicInfo dyn_info;
int dyn_entries;
RBinElfDynamicInfo dyn_info;
RBinElfReloc *relocs;
ut32 reloc_num;

ut64 version_info[DT_VERSIONTAGNUM];
Expand Down
4 changes: 0 additions & 4 deletions libr/bin/p/bin_elf.inc
Expand Up @@ -697,7 +697,6 @@ static RList* relocs(RBinFile *bf) {
}
r_list_append (ret, ptr);
}
free (relocs);
}
return ret;
}
Expand Down Expand Up @@ -908,13 +907,11 @@ static RList* patch_relocs(RBin *b) {
return NULL;
}
if (!(ret = r_list_newf ((RListFree)free))) {
free (relcs);
return NULL;
}
HtUUOptions opt = { 0 };
if (!(relocs_by_sym = ht_uu_new_opt (&opt))) {
r_list_free (ret);
free (relcs);
return NULL;
}
vaddr = n_vaddr;
Expand Down Expand Up @@ -944,7 +941,6 @@ static RList* patch_relocs(RBin *b) {
r_list_append (ret, ptr);
}
ht_uu_free (relocs_by_sym);
free (relcs);
return ret;
}

Expand Down

0 comments on commit 78de31f

Please sign in to comment.