From 988202fec4e45ccb3a7c2e2a255837cbddcaa748 Mon Sep 17 00:00:00 2001 From: Alexis Ehret <08a@riseup.net> Date: Tue, 28 Sep 2021 10:41:14 +0200 Subject: [PATCH] Refactor and move get_targets_map_base to elf_map.c --- librz/bin/format/elf/elf.c | 1 + librz/bin/format/elf/elf.h | 9 ++++--- librz/bin/format/elf/elf64_map.c | 6 +++++ librz/bin/format/elf/elf_map.c | 45 ++++++++++++++++++++++++++++++++ librz/bin/meson.build | 2 ++ librz/bin/p/bin_elf.inc | 23 +++++----------- 6 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 librz/bin/format/elf/elf64_map.c create mode 100644 librz/bin/format/elf/elf_map.c diff --git a/librz/bin/format/elf/elf.c b/librz/bin/format/elf/elf.c index d95a439f76..155d7a37a6 100644 --- a/librz/bin/format/elf/elf.c +++ b/librz/bin/format/elf/elf.c @@ -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); diff --git a/librz/bin/format/elf/elf.h b/librz/bin/format/elf/elf.h index 2e82441fe7..7aa7fa2ebc 100644 --- a/librz/bin/format/elf/elf.h +++ b/librz/bin/format/elf/elf.h @@ -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 RzVector *notes; // RzVector> @@ -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); diff --git a/librz/bin/format/elf/elf64_map.c b/librz/bin/format/elf/elf64_map.c new file mode 100644 index 0000000000..c9dc70f273 --- /dev/null +++ b/librz/bin/format/elf/elf64_map.c @@ -0,0 +1,6 @@ +// SPDX-FileCopyrightText: 2021 08A <08A@riseup.net> +// SPDX-FileCopyrightText: 2021 RizinOrg +// SPDX-License-Identifier: LGPL-3.0-only + +#define RZ_BIN_ELF64 1 +#include "elf_map.c" diff --git a/librz/bin/format/elf/elf_map.c b/librz/bin/format/elf/elf_map.c new file mode 100644 index 0000000000..1add4b155d --- /dev/null +++ b/librz/bin/format/elf/elf_map.c @@ -0,0 +1,45 @@ +// SPDX-FileCopyrightText: 2021 08A <08A@riseup.net> +// SPDX-FileCopyrightText: 2021 RizinOrg +// 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))); +} diff --git a/librz/bin/meson.build b/librz/bin/meson.build index 75b02c99a7..0a0d28b60d 100644 --- a/librz/bin/meson.build +++ b/librz/bin/meson.build @@ -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', diff --git a/librz/bin/p/bin_elf.inc b/librz/bin/p/bin_elf.inc index ee8eeb4c8c..8117b3070f 100644 --- a/librz/bin/p/bin_elf.inc +++ b/librz/bin/p/bin_elf.inc @@ -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;