From d688a05ac78517bcba09bae0f60bc76f3aa51ddb Mon Sep 17 00:00:00 2001 From: John Reiser Date: Sun, 9 Oct 2016 21:50:45 -0700 Subject: [PATCH] DT_JMPREL vanished (binutils-2.26.1); check all DT_RELA. modified: p_elf_enum.h modified: p_lx_elf.cpp --- src/p_elf_enum.h | 1 + src/p_lx_elf.cpp | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/p_elf_enum.h b/src/p_elf_enum.h index 63befd58..7d0913b6 100644 --- a/src/p_elf_enum.h +++ b/src/p_elf_enum.h @@ -146,6 +146,7 @@ DT_STRTAB = 5, /* String table */ DT_SYMTAB = 6, /* Symbol table */ DT_RELA = 7, /* Relocations which do contain an addend */ + DT_RELASZ = 8, /* Total size of Rela relocs */ DT_RELAENT = 9, /* Size of one RELA relocation */ DT_INIT = 12, /* Address of init function */ DT_REL = 17, /* Relocations which contain no addend */ diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index d7f4b242..024f21ff 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -1702,6 +1702,8 @@ PackLinuxElf64ppcle::canPack() // which references the symbol, because DT_GNU_HASH contains only // defined symbols, and there might be no DT_HASH. + Elf64_Rela const * + rela= (Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_RELA); Elf64_Rela const * jmprela= (Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_JMPREL); for ( int sz = elf_unsigned_dynamic(Elf64_Dyn::DT_PLTRELSZ); @@ -1716,6 +1718,19 @@ PackLinuxElf64ppcle::canPack() goto proceed; } + // 2016-10-09 DT_JMPREL is no more (binutils-2.26.1)? + // Check the general case, too. + for ( int sz = elf_unsigned_dynamic(Elf64_Dyn::DT_RELASZ); + 0 < sz; + (sz -= sizeof(Elf64_Rela)), ++rela + ) { + unsigned const symnum = get_te64(&rela->r_info) >> 32; + char const *const symnam = get_te32(&dynsym[symnum].st_name) + dynstr; + if (0==strcmp(symnam, "__libc_start_main") + || 0==strcmp(symnam, "__uClibc_main") + || 0==strcmp(symnam, "__uClibc_start_main")) + goto proceed; + } // Heuristic HACK for shared libraries (compare Darwin (MacOS) Dylib.) // If there is an existing DT_INIT, and if everything that the dynamic // linker ld-linux needs to perform relocations before calling DT_INIT @@ -1878,6 +1893,8 @@ PackLinuxElf64amd::canPack() // which references the symbol, because DT_GNU_HASH contains only // defined symbols, and there might be no DT_HASH. + Elf64_Rela const * + rela= (Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_RELA); Elf64_Rela const * jmprela= (Elf64_Rela const *)elf_find_dynamic(Elf64_Dyn::DT_JMPREL); for ( int sz = elf_unsigned_dynamic(Elf64_Dyn::DT_PLTRELSZ); @@ -1892,6 +1909,20 @@ PackLinuxElf64amd::canPack() goto proceed; } + // 2016-10-09 DT_JMPREL is no more (binutils-2.26.1)? + // Check the general case, too. + for ( int sz = elf_unsigned_dynamic(Elf64_Dyn::DT_RELASZ); + 0 < sz; + (sz -= sizeof(Elf64_Rela)), ++rela + ) { + unsigned const symnum = get_te64(&rela->r_info) >> 32; + char const *const symnam = get_te32(&dynsym[symnum].st_name) + dynstr; + if (0==strcmp(symnam, "__libc_start_main") + || 0==strcmp(symnam, "__uClibc_main") + || 0==strcmp(symnam, "__uClibc_start_main")) + goto proceed; + } + // Heuristic HACK for shared libraries (compare Darwin (MacOS) Dylib.) // If there is an existing DT_INIT, and if everything that the dynamic // linker ld-linux needs to perform relocations before calling DT_INIT