From 75e4daaf29f10d2b31be4991507bfa0673b4e9e4 Mon Sep 17 00:00:00 2001 From: Breno Rodrigues Guimaraes Date: Fri, 17 Mar 2023 17:55:32 -0300 Subject: Add infrastructure to iterate on all objects that are string indexes --- src/patchelf.cc | 40 ++++++++++++++++++++++++++++++++++++++-- src/patchelf.h | 38 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/patchelf.cc b/src/patchelf.cc index 37e6479..f2f9043 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -2293,6 +2293,42 @@ void ElfFile::modifyExecstack(ExecstackMode op) printf("execstack: %c\n", result); } +template +template +void ElfFile::forAllStringReferences(Elf_Shdr& strTabHdr, StrIdxCallback&& fn) +{ + for (auto& sym : tryGetSectionSpan(".dynsym")) + fn(sym.st_name); + + for (auto& dyn : tryGetSectionSpan(".dynamic")) + switch (rdi(dyn.d_tag)) + { + case DT_NEEDED: + case DT_SONAME: + case DT_RPATH: + case DT_RUNPATH: fn(dyn.d_un.d_val); + default:; + } + + if (auto verdHdr = tryFindSectionHeader(".gnu.version_d")) + { + if (&shdrs.at(rdi(verdHdr->get().sh_link)) == &strTabHdr) + forAll_ElfVer(getSectionSpan(*verdHdr), + [] (auto& /*vd*/) {}, + [&] (auto& vda) { fn(vda.vda_name); } + ); + } + + if (auto vernHdr = tryFindSectionHeader(".gnu.version_r")) + { + if (&shdrs.at(rdi(vernHdr->get().sh_link)) == &strTabHdr) + forAll_ElfVer(getSectionSpan(*vernHdr), + [&] (auto& vn) { fn(vn.vn_file); }, + [&] (auto& vna) { fn(vna.vna_name); } + ); + } +} + static bool printInterpreter = false; static bool printOsAbi = false; static bool setOsAbi = false; @@ -2397,9 +2433,9 @@ static void patchElf() const std::string & outputFileName2 = outputFileName.empty() ? fileName : outputFileName; if (getElfType(fileContents).is32Bit) - patchElf2(ElfFile(fileContents), fileContents, outputFileName2); + patchElf2(ElfFile(fileContents), fileContents, outputFileName2); else - patchElf2(ElfFile(fileContents), fileContents, outputFileName2); + patchElf2(ElfFile(fileContents), fileContents, outputFileName2); } } diff --git a/src/patchelf.h b/src/patchelf.h index 9fab18c..4e229d6 100644 --- a/src/patchelf.h +++ b/src/patchelf.h @@ -10,8 +10,8 @@ using FileContents = std::shared_ptr>; -#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn, class Elf_Sym, class Elf_Verneed, class Elf_Versym, class Elf_Rel, class Elf_Rela, unsigned ElfClass -#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Verneed, Elf_Versym, Elf_Rel, Elf_Rela, ElfClass +#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn, class Elf_Sym, class Elf_Versym, class Elf_Verdef, class Elf_Verdaux, class Elf_Verneed, class Elf_Vernaux, class Elf_Rel, class Elf_Rela, unsigned ElfClass +#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Versym, Elf_Verdef, Elf_Verdaux, Elf_Verneed, Elf_Vernaux, Elf_Rel, Elf_Rela, ElfClass template struct span @@ -237,6 +237,40 @@ private: } } + template + void forAllStringReferences(const Elf_Shdr& strTabHdr, StrIdxCallback&& fn); + + template + auto follow(U* ptr, size_t offset) -> T* { + return offset ? (T*)(((char*)ptr)+offset) : nullptr; + }; + + template + void forAll_ElfVer(span vdspan, VdFn&& vdfn, VaFn&& vafn) + { + auto* vd = vdspan.begin(); + for (; vd; vd = follow(vd, rdi(vd->vd_next))) + { + vdfn(*vd); + auto va = follow(vd, rdi(vd->vd_aux)); + for (; va; va = follow(va, rdi(va->vda_next))) + vafn(*va); + } + } + + template + void forAll_ElfVer(span vnspan, VnFn&& vnfn, VaFn&& vafn) + { + auto* vn = vnspan.begin(); + for (; vn; vn = follow(vn, rdi(vn->vn_next))) + { + vnfn(*vn); + auto va = follow(vn, rdi(vn->vn_aux)); + for (; va; va = follow(va, rdi(va->vna_next))) + vafn(*va); + } + } + /* Convert an integer in big or little endian representation (as specified by the ELF header) to this platform's integer representation. */ -- cgit v1.2.1