Refactor and move get_targets_map_base to elf_map.c

This commit is contained in:
Alexis Ehret 2021-09-28 10:41:14 +02:00
parent 8f66775a0d
commit 988202fec4
6 changed files with 66 additions and 20 deletions

View file

@ -323,6 +323,7 @@ static bool init(ELFOBJ *bin, RzBinObjectLoadOptions *options) {
bin->boffset = Elf_(rz_bin_elf_get_boffset)(bin);
bin->relocs = Elf_(rz_bin_elf_relocs_new)(bin);
bin->reloc_targets_map_base = Elf_(rz_bin_elf_get_targets_map_base)(bin);
bin->notes = Elf_(rz_bin_elf_notes_new)(bin);

View file

@ -185,7 +185,10 @@ typedef struct rz_bin_elf_strtab RzBinElfStrtab;
struct Elf_(rz_bin_elf_obj_t) {
RzBuffer *b;
RzBuffer *buf_patched; ///< overlay over the original file with relocs patched
bool relocs_patched;
ut64 reloc_targets_map_base;
Sdb *kv;
@ -207,9 +210,6 @@ struct Elf_(rz_bin_elf_obj_t) {
RzBinElfStrtab *shstrtab; // should be use with elf_strtab.c
RzVector *relocs; // should be use with elf_relocs.c
bool reloc_targets_map_base_calculated;
bool relocs_patched;
ut64 reloc_targets_map_base;
// This is RzVector of note segment reprensented as RzVector<RzBinElfNote>
RzVector *notes; // RzVector<RzVector<RzBinElfNote>>
@ -273,6 +273,9 @@ RZ_BORROW RzBinElfSymbol *Elf_(rz_bin_elf_get_import)(RZ_NONNULL ELFOBJ *bin, ut
RZ_OWN RzVector *Elf_(rz_bin_elf_analyse_imports)(RZ_NONNULL ELFOBJ *bin);
bool Elf_(rz_bin_elf_has_imports)(RZ_NONNULL ELFOBJ *bin);
// elf_map.c
ut64 Elf_(rz_bin_elf_get_targets_map_base)(ELFOBJ *bin);
// elf_info.c
RZ_OWN RzList *Elf_(rz_bin_elf_get_libs)(RZ_NONNULL ELFOBJ *bin);
RZ_OWN Sdb *Elf_(rz_bin_elf_get_symbols_info)(RZ_NONNULL ELFOBJ *bin);

View file

@ -0,0 +1,6 @@
// SPDX-FileCopyrightText: 2021 08A <08A@riseup.net>
// SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
// SPDX-License-Identifier: LGPL-3.0-only
#define RZ_BIN_ELF64 1
#include "elf_map.c"

View file

@ -0,0 +1,45 @@
// SPDX-FileCopyrightText: 2021 08A <08A@riseup.net>
// SPDX-FileCopyrightText: 2021 RizinOrg <info@rizin.re>
// SPDX-License-Identifier: LGPL-3.0-only
#include "elf.h"
static ut64 get_targets_map_base_from_segments(ELFOBJ *bin) {
ut64 result = 0;
RzBinElfSegment *segment;
rz_bin_elf_foreach_segments(bin, segment) {
if (segment->data.p_type != PT_LOAD) {
continue;
}
result = RZ_MAX(result, segment->data.p_paddr + segment->data.p_memsz);
}
return result;
}
static ut64 get_targets_map_base_from_sections(ELFOBJ *bin) {
ut64 result = 0;
RzBinElfSection *section;
rz_bin_elf_foreach_sections(bin, section) {
result = RZ_MAX(result, section->rva + section->size);
}
return result;
}
static ut64 get_targets_map_base(ELFOBJ *bin) {
if (Elf_(rz_bin_elf_has_segments)(bin)) {
return get_targets_map_base_from_segments(bin);
}
return get_targets_map_base_from_sections(bin);
}
ut64 Elf_(rz_bin_elf_get_targets_map_base)(ELFOBJ *bin) {
ut64 result = get_targets_map_base(bin);
result += 0x8; // small additional shift to not overlap with symbols like _end
return result + rz_num_align_delta(result, sizeof(Elf_(Addr)));
}

View file

@ -85,6 +85,8 @@ rz_bin_sources = [
'format/elf/elf64_hash.c',
'format/elf/elf_imports.c',
'format/elf/elf64_imports.c',
'format/elf/elf_map.c',
'format/elf/elf64_map.c',
'format/elf/elf_info.c',
'format/elf/elf64_info.c',
'format/elf/elf_misc.c',

View file

@ -631,18 +631,6 @@ static ut64 reloc_target_size(ELFOBJ *obj) {
return obj->bits / 8;
}
/// base vaddr where to map the artificial reloc target vfile
static ut64 reloc_targets_map_base(RzBinFile *bf, struct Elf_(rz_bin_elf_obj_t) * obj) {
if (obj->reloc_targets_map_base_calculated) {
return obj->reloc_targets_map_base;
}
RzList *maps = maps_unpatched(bf);
obj->reloc_targets_map_base = rz_bin_relocs_patch_find_targets_map_base(maps, reloc_target_size(obj));
rz_list_free(maps);
obj->reloc_targets_map_base_calculated = true;
return obj->reloc_targets_map_base;
}
/// size of the artificial reloc target vfile
static ut64 reloc_targets_vfile_size(RzBinFile *bf, ELFOBJ *obj) {
if (!bf->o || !bf->o->opts.patch_relocs || !Elf_(rz_bin_elf_has_relocs)(obj)) {
@ -948,7 +936,7 @@ static void patch_relocs(RzBinFile *bf, ELFOBJ *bin) {
if (!size) {
return;
}
RzBinRelocTargetBuilder *targets = rz_bin_reloc_target_builder_new(cdsz, reloc_targets_map_base(bf, bin));
RzBinRelocTargetBuilder *targets = rz_bin_reloc_target_builder_new(cdsz, bin->reloc_targets_map_base);
if (!targets) {
return;
}
@ -1038,9 +1026,10 @@ static RzList *maps(RzBinFile *bf) {
// if relocs should be patched, use the patched vfile for everything from the file
patch_relocs(bf, obj);
rz_bin_relocs_patch_maps(ret, obj->buf_patched, 0,
reloc_targets_map_base(bf, obj), reloc_targets_vfile_size(bf, obj),
VFILE_NAME_PATCHED, VFILE_NAME_RELOC_TARGETS);
rz_bin_relocs_patch_maps(ret, obj->buf_patched, 0, obj->reloc_targets_map_base,
reloc_targets_vfile_size(bf, obj),
VFILE_NAME_PATCHED,
VFILE_NAME_RELOC_TARGETS);
return ret;
}
@ -1281,7 +1270,7 @@ static RzList *relocs(RzBinFile *bf) {
ut64 got_addr = get_got_addr(bin);
if (!got_addr) {
got_addr = reloc_targets_map_base(bf, bin);
got_addr = bin->reloc_targets_map_base;
}
RzBinElfReloc *reloc;