From 148d9a301fc92103935579372d9937ed71c3d33d Mon Sep 17 00:00:00 2001 From: pancake Date: Mon, 18 Mar 2024 12:39:23 +0100 Subject: [PATCH] Support arm64 type 1026 relocs ##bin --- libr/bin/format/elf/elf.c | 27 ++++++++++----- test/db/cmd/cmd_ie | 4 +++ test/db/formats/elf/reloc-arm64 | 58 +++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 8 deletions(-) create mode 100644 test/db/formats/elf/reloc-arm64 diff --git a/libr/bin/format/elf/elf.c b/libr/bin/format/elf/elf.c index 887bd0cd46..da3a8ff749 100644 --- a/libr/bin/format/elf/elf.c +++ b/libr/bin/format/elf/elf.c @@ -134,12 +134,10 @@ static bool __is_valid_ident(ut8 *e_ident) { } static bool init_ehdr(ELFOBJ *eo) { - ut8 *e_ident; ut8 ehdr[sizeof (Elf_(Ehdr))] = {0}; - int i, len; - - e_ident = (ut8*)&eo->ehdr.e_ident; + int i; + ut8 *e_ident = (ut8*)&eo->ehdr.e_ident; if (r_buf_read_at (eo->b, 0, e_ident, EI_NIDENT) != EI_NIDENT) { R_LOG_DEBUG ("read (magic)"); return false; @@ -151,7 +149,7 @@ static bool init_ehdr(ELFOBJ *eo) { eo->endian = (e_ident[EI_DATA] == ELFDATA2MSB)? 1: 0; - len = r_buf_read_at (eo->b, 0, ehdr, sizeof (ehdr)); + int len = r_buf_read_at (eo->b, 0, ehdr, sizeof (ehdr)); if (len < 32) { // tinyelf != sizeof (Elf_(Ehdr))) { R_LOG_DEBUG ("read (ehdr)"); return false; @@ -244,7 +242,6 @@ static bool read_phdr(ELFOBJ *eo) { break; } } - if (!load_header_found) { const ut64 load_addr = Elf_(get_baddr) (eo); eo->ehdr.e_phoff = Elf_(v2p) (eo, load_addr + eo->ehdr.e_phoff); @@ -5179,6 +5176,18 @@ typedef struct { ut64 plt_va; } GotPltBounds; +static bool is_important(RBinElfReloc *reloc) { + switch (reloc->type) { + case 21: + case 22: + case 1026: + return true; + } + + R_LOG_DEBUG ("Reloc type %d not used for imports", reloc->type); + return false; +} + static bool reloc_fill_local_address(ELFOBJ *eo) { RBinElfReloc *reloc; GotPltBounds ri = {0}; @@ -5225,8 +5234,7 @@ static bool reloc_fill_local_address(ELFOBJ *eo) { r_buf_read_at (eo->b, rvaddr, (ut8*)&n32, 4); pltptr = n32; #endif - bool ismagic = (reloc->type == 21 || reloc->type == 22); - // if (pltptr && pltptr != -1 && ismagic) { + bool ismagic = is_important (reloc); if (ismagic) { // text goes after the plt. so its possible that some symbols are pointed locally, thats all lsym is about if (pltptr > baddr) { @@ -5246,6 +5254,9 @@ static bool reloc_fill_local_address(ELFOBJ *eo) { #endif // TODO: if (reloc->type == 22) { // on arm! // extra check of bounds ut64 naddr = baddr + pltptr + (index * 12) + 0x20; + if (reloc->type == 1026) { + naddr = baddr + pltptr + (index * 16) + 64 - 16; + } if (naddr != UT64_MAX) { // this thing registers an 'rsym.${importname}' as a flag when loading the relocs from core/cbin.c reloc->laddr = naddr; diff --git a/test/db/cmd/cmd_ie b/test/db/cmd/cmd_ie index de93f21dae..3db84292f2 100644 --- a/test/db/cmd/cmd_ie +++ b/test/db/cmd/cmd_ie @@ -112,6 +112,10 @@ EOF EXPECT_ERR=<