From c1d6bf436620f7063dc265eb4eab1817a744ff94 Mon Sep 17 00:00:00 2001 From: John Reiser Date: Thu, 24 Feb 2011 09:38:17 -0800 Subject: [PATCH] avoid .so with DT_TEXTREL; SourceForge bug 3190915 --- src/p_elf_enum.h | 1 + src/p_lx_elf.cpp | 28 ++++++++++++++++++++++++++-- src/p_lx_elf.h | 2 ++ 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/p_elf_enum.h b/src/p_elf_enum.h index d08dd68b..1c84a72a 100644 --- a/src/p_elf_enum.h +++ b/src/p_elf_enum.h @@ -152,6 +152,7 @@ DT_RELENT = 19, /* Size of one Rel relocation */ DT_STRSZ = 10, /* Sizeof string table */ DT_PLTREL = 20, /* Type of reloc in PLT */ + DT_TEXTREL = 22, /* Reloc might modify .text */ DT_JMPREL = 23, /* Address of PLT relocs */ DT_CHECKSUM = 0x6ffffdf8, /* Only for prelink? */ DT_GNU_HASH = 0x6ffffef5, /* GNU-style hash table */ diff --git a/src/p_lx_elf.cpp b/src/p_lx_elf.cpp index 1da57c67..5ad8daa7 100644 --- a/src/p_lx_elf.cpp +++ b/src/p_lx_elf.cpp @@ -1296,6 +1296,8 @@ bool PackLinuxElf32::canPack() // and also requires ld-linux to behave. if (elf_find_dynamic(Elf32_Dyn::DT_INIT)) { + if (elf_has_dynamic(Elf32_Dyn::DT_TEXTREL)) + goto abandon; Elf32_Shdr const *shdr = shdri; xct_va = ~0u; for (j= n_elf_shnum; --j>=0; ++shdr) { @@ -1326,7 +1328,6 @@ bool PackLinuxElf32::canPack() break; } } - // FIXME: DT_TEXTREL xct_off = elf_get_offset_from_address(xct_va); goto proceed; // But proper packing depends on checking xct_va. } @@ -1467,6 +1468,8 @@ PackLinuxElf64amd::canPack() // and also requires ld-linux to behave. if (elf_find_dynamic(Elf64_Dyn::DT_INIT)) { + if (elf_has_dynamic(Elf64_Dyn::DT_TEXTREL)) + goto abandon; Elf64_Shdr const *shdr = shdri; xct_va = ~0ull; for (j= n_elf_shnum; --j>=0; ++shdr) { @@ -1497,7 +1500,6 @@ PackLinuxElf64amd::canPack() break; } } - // FIXME: DT_TEXTREL xct_off = elf_get_offset_from_address(xct_va); goto proceed; // But proper packing depends on checking xct_va. } @@ -2872,6 +2874,17 @@ PackLinuxElf32::elf_get_offset_from_address(acc_uint64l_t const addr) const return 0; } +Elf32_Dyn const * +PackLinuxElf32::elf_has_dynamic(unsigned int const key) const +{ + Elf32_Dyn const *dynp= dynseg; + if (dynp) + for (; Elf32_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te32(&dynp->d_tag)==key) { + return dynp; + } + return 0; +} + void const * PackLinuxElf32::elf_find_dynamic(unsigned int const key) const { @@ -2912,6 +2925,17 @@ PackLinuxElf64::elf_get_offset_from_address(acc_uint64l_t const addr) const return 0; } +Elf64_Dyn const * +PackLinuxElf64::elf_has_dynamic(unsigned int const key) const +{ + Elf64_Dyn const *dynp= dynseg; + if (dynp) + for (; Elf64_Dyn::DT_NULL!=dynp->d_tag; ++dynp) if (get_te64(&dynp->d_tag)==key) { + return dynp; + } + return 0; +} + void const * PackLinuxElf64::elf_find_dynamic(unsigned int const key) const { diff --git a/src/p_lx_elf.h b/src/p_lx_elf.h index 30d22afe..8d4aa321 100644 --- a/src/p_lx_elf.h +++ b/src/p_lx_elf.h @@ -136,6 +136,7 @@ protected: Elf32_Shdr const *elf_find_section_name(char const *) const; Elf32_Shdr const *elf_find_section_type(unsigned) const; void const *elf_find_dynamic(unsigned) const; + Elf32_Dyn const *elf_has_dynamic(unsigned) const; acc_uint64l_t elf_unsigned_dynamic(unsigned) const; protected: @@ -242,6 +243,7 @@ protected: Elf64_Shdr const *elf_find_section_name(char const *) const; Elf64_Shdr const *elf_find_section_type(unsigned) const; void const *elf_find_dynamic(unsigned) const; + Elf64_Dyn const *elf_has_dynamic(unsigned) const; acc_uint64l_t elf_unsigned_dynamic(unsigned) const; protected: