Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package patchelf for openSUSE:Factory checked in at 2022-03-28 16:58:41 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/patchelf (Old) and /work/SRC/openSUSE:Factory/.patchelf.new.1900 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "patchelf" Mon Mar 28 16:58:41 2022 rev:16 rq:964678 version:0.14.5 Changes: -------- --- /work/SRC/openSUSE:Factory/patchelf/patchelf.changes 2021-12-22 20:18:27.651858138 +0100 +++ /work/SRC/openSUSE:Factory/.patchelf.new.1900/patchelf.changes 2022-03-28 16:59:11.892858278 +0200 @@ -1,0 +2,11 @@ +Sun Mar 20 21:02:53 UTC 2022 - Dirk M??ller <dmuel...@suse.com> + +- update to 0.14.5: + * fix faulty version in 0.14.4 + * Several test fixes to fix patchelf test suite on openbsd + * Allow multiple modifications in same call + * Add support to build with musl + * Fix typo: s/folllow/follow/ + * mips: fix incorrect polarity on dyn_offset + +------------------------------------------------------------------- Old: ---- patchelf-0.14.3.tar.bz2 New: ---- patchelf-0.14.5.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ patchelf.spec ++++++ --- /var/tmp/diff_new_pack.T8Ym5B/_old 2022-03-28 16:59:12.360858914 +0200 +++ /var/tmp/diff_new_pack.T8Ym5B/_new 2022-03-28 16:59:12.364858920 +0200 @@ -1,7 +1,7 @@ # # spec file for package patchelf # -# Copyright (c) 2021 SUSE LLC +# Copyright (c) 2022 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: patchelf -Version: 0.14.3 +Version: 0.14.5 Release: 0 Summary: A utility for patching ELF binaries License: GPL-3.0-only ++++++ patchelf-0.14.3.tar.bz2 -> patchelf-0.14.5.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/README.md new/patchelf-0.14.5/README.md --- old/patchelf-0.14.3/README.md 1970-01-01 01:00:01.000000000 +0100 +++ new/patchelf-0.14.5/README.md 1970-01-01 01:00:01.000000000 +0100 @@ -70,6 +70,7 @@ ## Compiling and Testing +### Via Autotools ```console ./bootstrap.sh ./configure @@ -77,6 +78,13 @@ make check sudo make install ``` +### Via Nix + +You can build with Nix in several ways. + +1. Building via `nix build` will produce the result in `./result/bin/patchelf`. If you would like to build _patchelf_ with _musl_ try `nix build .#patchelf-musl` + +2. You can launch a development environment with `nix develop` and follow the autotools steps above. If you would like to develop with _musl_ try `nix develop .#musl` ## Author @@ -99,6 +107,18 @@ ## Release History +0.14.5 (February 21, 2022): + +* fix faulty version in 0.14.4 + +0.14.4 (February 21, 2022): + +* Several test fixes to fix patchelf test suite on openbsd by @klemensn +* Allow multiple modifications in same call by @fzakaria in https://github.com/NixOS/patchelf/pull/361 +* Add support to build with musl by @fzakaria in https://github.com/NixOS/patchelf/pull/362 +* Fix typo: s/folllow/follow/ by @bjornfor in https://github.com/NixOS/patchelf/pull/366 +* mips: fix incorrect polarity on dyn_offset; closes #364 by @a-m-joseph in https://github.com/NixOS/patchelf/pull/365 + 0.14.3 (December 05, 2021): * this release adds support for static, pre-compiled patchelf binaries diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/configure new/patchelf-0.14.5/configure --- old/patchelf-0.14.3/configure 2021-12-05 15:41:13.000000000 +0100 +++ new/patchelf-0.14.5/configure 2022-02-21 14:27:37.000000000 +0100 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for patchelf 0.14.3. +# Generated by GNU Autoconf 2.71 for patchelf 0.14.5. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, @@ -607,8 +607,8 @@ # Identity of this package. PACKAGE_NAME='patchelf' PACKAGE_TARNAME='patchelf' -PACKAGE_VERSION='0.14.3' -PACKAGE_STRING='patchelf 0.14.3' +PACKAGE_VERSION='0.14.5' +PACKAGE_STRING='patchelf 0.14.5' PACKAGE_BUGREPORT='' PACKAGE_URL='' @@ -1285,7 +1285,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures patchelf 0.14.3 to adapt to many kinds of systems. +\`configure' configures patchelf 0.14.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1352,7 +1352,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of patchelf 0.14.3:";; + short | recursive ) echo "Configuration of patchelf 0.14.5:";; esac cat <<\_ACEOF @@ -1456,7 +1456,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -patchelf configure 0.14.3 +patchelf configure 0.14.5 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1571,7 +1571,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by patchelf $as_me 0.14.3, which was +It was created by patchelf $as_me 0.14.5, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3049,7 +3049,7 @@ # Define the identity of the package. PACKAGE='patchelf' - VERSION='0.14.3' + VERSION='0.14.5' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -5757,7 +5757,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by patchelf $as_me 0.14.3, which was +This file was extended by patchelf $as_me 0.14.5, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5816,7 +5816,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -patchelf config.status 0.14.3 +patchelf config.status 0.14.5 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/patchelf.spec new/patchelf-0.14.5/patchelf.spec --- old/patchelf-0.14.3/patchelf.spec 2021-12-05 15:41:15.000000000 +0100 +++ new/patchelf-0.14.5/patchelf.spec 2022-02-21 14:27:39.000000000 +0100 @@ -1,7 +1,7 @@ Summary: A utility for patching ELF binaries Name: patchelf -Version: 0.14.3 +Version: 0.14.5 Release: 1 License: GPL Group: Development/Tools diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/src/Makefile.am new/patchelf-0.14.5/src/Makefile.am --- old/patchelf-0.14.3/src/Makefile.am 1970-01-01 01:00:01.000000000 +0100 +++ new/patchelf-0.14.5/src/Makefile.am 1970-01-01 01:00:01.000000000 +0100 @@ -19,4 +19,4 @@ bin_PROGRAMS = patchelf -patchelf_SOURCES = patchelf.cc elf.h +patchelf_SOURCES = patchelf.cc elf.h patchelf.h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/src/Makefile.in new/patchelf-0.14.5/src/Makefile.in --- old/patchelf-0.14.3/src/Makefile.in 2021-12-05 15:41:14.000000000 +0100 +++ new/patchelf-0.14.5/src/Makefile.in 2022-02-21 14:27:38.000000000 +0100 @@ -271,7 +271,7 @@ AM_CXXFLAGS = -Wall -std=c++17 -D_FILE_OFFSET_BITS=64 $(am__append_1) \ $(am__append_2) $(am__append_3) $(am__append_4) SAN_FLAGS = -fno-optimize-sibling-calls -fno-omit-frame-pointer -patchelf_SOURCES = patchelf.cc elf.h +patchelf_SOURCES = patchelf.cc elf.h patchelf.h all: all-am .SUFFIXES: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/src/patchelf.cc new/patchelf-0.14.5/src/patchelf.cc --- old/patchelf-0.14.3/src/patchelf.cc 1970-01-01 01:00:01.000000000 +0100 +++ new/patchelf-0.14.5/src/patchelf.cc 1970-01-01 01:00:01.000000000 +0100 @@ -41,6 +41,7 @@ #include <unistd.h> #include "elf.h" +#include "patchelf.h" #ifndef PACKAGE_STRING #define PACKAGE_STRING "patchelf" @@ -63,11 +64,6 @@ #define EM_LOONGARCH 258 #endif -using FileContents = std::shared_ptr<std::vector<unsigned char>>; - -#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 -#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Verneed, Elf_Versym - static std::vector<std::string> splitColonDelimitedString(const char * s) { @@ -85,163 +81,6 @@ return std::any_of(allowedPrefixes.begin(), allowedPrefixes.end(), [&](const std::string & i) { return !s.compare(0, i.size(), i); }); } - -template<ElfFileParams> -class ElfFile -{ -public: - - const FileContents fileContents; - -private: - - std::vector<Elf_Phdr> phdrs; - std::vector<Elf_Shdr> shdrs; - - bool littleEndian; - - bool changed = false; - - bool isExecutable = false; - - using SectionName = std::string; - using ReplacedSections = std::map<SectionName, std::string>; - - ReplacedSections replacedSections; - - std::string sectionNames; /* content of the .shstrtab section */ - - /* Align on 4 or 8 bytes boundaries on 32- or 64-bit platforms - respectively. */ - size_t sectionAlignment = sizeof(Elf_Off); - - std::vector<SectionName> sectionsByOldIndex; - -public: - explicit ElfFile(FileContents fileContents); - - bool isChanged() - { - return changed; - } - -private: - - struct CompPhdr - { - ElfFile * elfFile; - bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y) - { - // A PHDR comes before everything else. - if (elfFile->rdi(y.p_type) == PT_PHDR) return false; - if (elfFile->rdi(x.p_type) == PT_PHDR) return true; - - // Sort non-PHDRs by address. - return elfFile->rdi(x.p_paddr) < elfFile->rdi(y.p_paddr); - } - }; - - friend struct CompPhdr; - - void sortPhdrs(); - - struct CompShdr - { - ElfFile * elfFile; - bool operator ()(const Elf_Shdr & x, const Elf_Shdr & y) - { - return elfFile->rdi(x.sh_offset) < elfFile->rdi(y.sh_offset); - } - }; - - friend struct CompShdr; - - unsigned int getPageSize() const; - - void sortShdrs(); - - void shiftFile(unsigned int extraPages, Elf_Addr startPage); - - std::string getSectionName(const Elf_Shdr & shdr) const; - - Elf_Shdr & findSection(const SectionName & sectionName); - - std::optional<std::reference_wrapper<Elf_Shdr>> findSection2(const SectionName & sectionName); - - unsigned int findSection3(const SectionName & sectionName); - - std::string & replaceSection(const SectionName & sectionName, - unsigned int size); - - bool haveReplacedSection(const SectionName & sectionName) const; - - void writeReplacedSections(Elf_Off & curOff, - Elf_Addr startAddr, Elf_Off startOffset); - - void rewriteHeaders(Elf_Addr phdrAddress); - - void rewriteSectionsLibrary(); - - void rewriteSectionsExecutable(); - - void normalizeNoteSegments(); - -public: - - void rewriteSections(); - - std::string getInterpreter(); - - typedef enum { printSoname, replaceSoname } sonameMode; - - void modifySoname(sonameMode op, const std::string & newSoname); - - void setInterpreter(const std::string & newInterpreter); - - typedef enum { rpPrint, rpShrink, rpSet, rpAdd, rpRemove } RPathOp; - - void modifyRPath(RPathOp op, const std::vector<std::string> & allowedRpathPrefixes, std::string newRPath); - std::string shrinkRPath(char* rpath, std::vector<std::string> &neededLibs, const std::vector<std::string> & allowedRpathPrefixes); - void removeRPath(Elf_Shdr & shdrDynamic); - - void addNeeded(const std::set<std::string> & libs); - - void removeNeeded(const std::set<std::string> & libs); - - void replaceNeeded(const std::map<std::string, std::string> & libs); - - void printNeededLibs() /* should be const */; - - void noDefaultLib(); - - void clearSymbolVersions(const std::set<std::string> & syms); - -private: - - /* Convert an integer in big or little endian representation (as - specified by the ELF header) to this platform's integer - representation. */ - template<class I> - I rdi(I i) const; - - /* Convert back to the ELF representation. */ - template<class I> - I wri(I & t, unsigned long long i) const - { - t = rdi((I) i); - return i; - } - - Elf_Ehdr *hdr() { - return (Elf_Ehdr *)fileContents->data(); - } - - const Elf_Ehdr *hdr() const { - return (const Elf_Ehdr *)fileContents->data(); - } -}; - - /* !!! G++ creates broken code if this function is inlined, don't know why... */ template<ElfFileParams> @@ -513,14 +352,14 @@ for (unsigned int i = 1; i < rdi(hdr()->e_shnum); ++i) if (rdi(shdrs[i].sh_link) != 0) wri(shdrs[i].sh_link, - findSection3(linkage[getSectionName(shdrs[i])])); + getSectionIndex(linkage[getSectionName(shdrs[i])])); /* And the st_info mappings. */ for (unsigned int i = 1; i < rdi(hdr()->e_shnum); ++i) if (rdi(shdrs.at(i).sh_info) != 0 && (rdi(shdrs.at(i).sh_type) == SHT_REL || rdi(shdrs.at(i).sh_type) == SHT_RELA)) wri(shdrs.at(i).sh_info, - findSection3(info.at(getSectionName(shdrs.at(i))))); + getSectionIndex(info.at(getSectionName(shdrs.at(i))))); /* And the .shstrtab index. Note: the match here is done by checking the offset as searching * by name can yield incorrect results in case there are multiple sections with the same @@ -630,9 +469,9 @@ template<ElfFileParams> -Elf_Shdr & ElfFile<ElfFileParamNames>::findSection(const SectionName & sectionName) +Elf_Shdr & ElfFile<ElfFileParamNames>::findSectionHeader(const SectionName & sectionName) { - auto shdr = findSection2(sectionName); + auto shdr = tryFindSectionHeader(sectionName); if (!shdr) { std::string extraMsg; if (sectionName == ".interp" || sectionName == ".dynamic" || sectionName == ".dynstr") @@ -644,9 +483,9 @@ template<ElfFileParams> -std::optional<std::reference_wrapper<Elf_Shdr>> ElfFile<ElfFileParamNames>::findSection2(const SectionName & sectionName) +std::optional<std::reference_wrapper<Elf_Shdr>> ElfFile<ElfFileParamNames>::tryFindSectionHeader(const SectionName & sectionName) { - auto i = findSection3(sectionName); + auto i = getSectionIndex(sectionName); if (i) return shdrs.at(i); return {}; @@ -654,7 +493,7 @@ template<ElfFileParams> -unsigned int ElfFile<ElfFileParamNames>::findSection3(const SectionName & sectionName) +unsigned int ElfFile<ElfFileParamNames>::getSectionIndex(const SectionName & sectionName) { for (unsigned int i = 1; i < rdi(hdr()->e_shnum); ++i) if (getSectionName(shdrs.at(i)) == sectionName) return i; @@ -677,7 +516,7 @@ if (i != replacedSections.end()) { s = std::string(i->second); } else { - auto shdr = findSection(sectionName); + auto shdr = findSectionHeader(sectionName); s = std::string((char *) fileContents->data() + rdi(shdr.sh_offset), rdi(shdr.sh_size)); } @@ -697,7 +536,7 @@ clobbering previously written new section contents. */ for (auto & i : replacedSections) { const std::string & sectionName = i.first; - Elf_Shdr & shdr = findSection(sectionName); + Elf_Shdr & shdr = findSectionHeader(sectionName); if (rdi(shdr.sh_type) != SHT_NOBITS) memset(fileContents->data() + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size)); } @@ -705,7 +544,7 @@ std::set<unsigned int> noted_phdrs = {}; for (auto & i : replacedSections) { const std::string & sectionName = i.first; - auto & shdr = findSection(sectionName); + auto & shdr = findSectionHeader(sectionName); Elf_Shdr orig_shdr = shdr; debug("rewriting section '%s' from offset 0x%x (size %d) to offset 0x%x (size %d)\n", sectionName.c_str(), rdi(shdr.sh_offset), rdi(shdr.sh_size), curOff, i.second.size()); @@ -1024,7 +863,7 @@ /* We don't need to do anything if no note segments were replaced. */ bool replaced_note = std::any_of(replacedSections.begin(), replacedSections.end(), - [this](std::pair<const std::string, std::string> & i) { return rdi(findSection(i.first).sh_type) == SHT_NOTE; }); + [this](std::pair<const std::string, std::string> & i) { return rdi(findSectionHeader(i.first).sh_type) == SHT_NOTE; }); if (!replaced_note) return; std::vector<Elf_Phdr> newPhdrs; @@ -1128,61 +967,61 @@ /* Update all those nasty virtual addresses in the .dynamic section. Note that not all executables have .dynamic sections (e.g., those produced by klibc's klcc). */ - auto shdrDynamic = findSection2(".dynamic"); + auto shdrDynamic = tryFindSectionHeader(".dynamic"); if (shdrDynamic) { auto dyn_table = (Elf_Dyn *) (fileContents->data() + rdi((*shdrDynamic).get().sh_offset)); unsigned int d_tag; for (auto dyn = dyn_table; (d_tag = rdi(dyn->d_tag)) != DT_NULL; dyn++) if (d_tag == DT_STRTAB) - dyn->d_un.d_ptr = findSection(".dynstr").sh_addr; + dyn->d_un.d_ptr = findSectionHeader(".dynstr").sh_addr; else if (d_tag == DT_STRSZ) - dyn->d_un.d_val = findSection(".dynstr").sh_size; + dyn->d_un.d_val = findSectionHeader(".dynstr").sh_size; else if (d_tag == DT_SYMTAB) - dyn->d_un.d_ptr = findSection(".dynsym").sh_addr; + dyn->d_un.d_ptr = findSectionHeader(".dynsym").sh_addr; else if (d_tag == DT_HASH) - dyn->d_un.d_ptr = findSection(".hash").sh_addr; + dyn->d_un.d_ptr = findSectionHeader(".hash").sh_addr; else if (d_tag == DT_GNU_HASH) { - auto shdr = findSection2(".gnu.hash"); + auto shdr = tryFindSectionHeader(".gnu.hash"); // some binaries might this section stripped // in which case we just ignore the value. if (shdr) dyn->d_un.d_ptr = (*shdr).get().sh_addr; } else if (d_tag == DT_JMPREL) { - auto shdr = findSection2(".rel.plt"); - if (!shdr) shdr = findSection2(".rela.plt"); + auto shdr = tryFindSectionHeader(".rel.plt"); + if (!shdr) shdr = tryFindSectionHeader(".rela.plt"); /* 64-bit Linux, x86-64 */ - if (!shdr) shdr = findSection2(".rela.IA_64.pltoff"); /* 64-bit Linux, IA-64 */ + if (!shdr) shdr = tryFindSectionHeader(".rela.IA_64.pltoff"); /* 64-bit Linux, IA-64 */ if (!shdr) error("cannot find section corresponding to DT_JMPREL"); dyn->d_un.d_ptr = (*shdr).get().sh_addr; } else if (d_tag == DT_REL) { /* !!! hack! */ - auto shdr = findSection2(".rel.dyn"); + auto shdr = tryFindSectionHeader(".rel.dyn"); /* no idea if this makes sense, but it was needed for some program */ - if (!shdr) shdr = findSection2(".rel.got"); + if (!shdr) shdr = tryFindSectionHeader(".rel.got"); /* some programs have neither section, but this doesn't seem to be a problem */ if (!shdr) continue; dyn->d_un.d_ptr = (*shdr).get().sh_addr; } else if (d_tag == DT_RELA) { - auto shdr = findSection2(".rela.dyn"); + auto shdr = tryFindSectionHeader(".rela.dyn"); /* some programs lack this section, but it doesn't seem to be a problem */ if (!shdr) continue; dyn->d_un.d_ptr = (*shdr).get().sh_addr; } else if (d_tag == DT_VERNEED) - dyn->d_un.d_ptr = findSection(".gnu.version_r").sh_addr; + dyn->d_un.d_ptr = findSectionHeader(".gnu.version_r").sh_addr; else if (d_tag == DT_VERSYM) - dyn->d_un.d_ptr = findSection(".gnu.version").sh_addr; + dyn->d_un.d_ptr = findSectionHeader(".gnu.version").sh_addr; else if (d_tag == DT_MIPS_RLD_MAP_REL) { /* the MIPS_RLD_MAP_REL tag stores the offset to the debug pointer, relative to the address of the tag */ - auto shdr = findSection2(".rld_map"); + auto shdr = tryFindSectionHeader(".rld_map"); if (shdr) { - auto rld_map_addr = findSection(".rld_map").sh_addr; + auto rld_map_addr = findSectionHeader(".rld_map").sh_addr; auto dyn_offset = ((char*)dyn) - ((char*)dyn_table); - dyn->d_un.d_ptr = rld_map_addr + dyn_offset - (*shdrDynamic).get().sh_addr; + dyn->d_un.d_ptr = rld_map_addr - dyn_offset - (*shdrDynamic).get().sh_addr; } else { /* ELF file with DT_MIPS_RLD_MAP_REL but without .rld_map is broken, and it's not our job to fix it; yet, we have @@ -1212,7 +1051,7 @@ } const std::string & section = sectionsByOldIndex.at(shndx); assert(!section.empty()); - auto newIndex = findSection3(section); // inefficient + auto newIndex = getSectionIndex(section); // inefficient //debug("rewriting symbol %d: index = %d (%s) -> %d\n", entry, shndx, section.c_str(), newIndex); wri(sym->st_shndx, newIndex); /* Rewrite st_value. FIXME: we should do this for all @@ -1236,8 +1075,8 @@ template<ElfFileParams> std::string ElfFile<ElfFileParamNames>::getInterpreter() { - auto shdr = findSection(".interp"); - return std::string((char *) fileContents->data() + rdi(shdr.sh_offset), rdi(shdr.sh_size)); + auto shdr = findSectionHeader(".interp"); + return std::string((char *) fileContents->data() + rdi(shdr.sh_offset), rdi(shdr.sh_size) - 1); } template<ElfFileParams> @@ -1248,8 +1087,8 @@ return; } - auto shdrDynamic = findSection(".dynamic"); - auto shdrDynStr = findSection(".dynstr"); + auto shdrDynamic = findSectionHeader(".dynamic"); + auto shdrDynStr = findSectionHeader(".dynstr"); char * strTab = (char *) fileContents->data() + rdi(shdrDynStr.sh_offset); /* Walk through the dynamic section, look for the DT_SONAME entry. */ @@ -1311,6 +1150,7 @@ } changed = true; + this->rewriteSections(); } template<ElfFileParams> @@ -1319,6 +1159,7 @@ std::string & section = replaceSection(".interp", newInterpreter.size() + 1); setSubstr(section, 0, newInterpreter + '\0'); changed = true; + this->rewriteSections(); } @@ -1395,13 +1236,14 @@ } } memset(last, 0, sizeof(Elf_Dyn) * (dyn - last)); + this->rewriteSections(); } template<ElfFileParams> void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, const std::vector<std::string> & allowedRpathPrefixes, std::string newRPath) { - auto shdrDynamic = findSection(".dynamic"); + auto shdrDynamic = findSectionHeader(".dynamic"); if (rdi(shdrDynamic.sh_type) == SHT_NOBITS) { debug("no dynamic section\n"); @@ -1410,7 +1252,7 @@ /* !!! We assume that the virtual address in the DT_STRTAB entry of the dynamic section corresponds to the .dynstr section. */ - auto shdrDynStr = findSection(".dynstr"); + auto shdrDynStr = findSectionHeader(".dynstr"); char * strTab = (char *) fileContents->data() + rdi(shdrDynStr.sh_offset); @@ -1541,6 +1383,7 @@ newDyn.d_un.d_val = shdrDynStr.sh_size; setSubstr(newDynamic, 0, std::string((char *) &newDyn, sizeof(Elf_Dyn))); } + this->rewriteSections(); } @@ -1549,8 +1392,8 @@ { if (libs.empty()) return; - auto shdrDynamic = findSection(".dynamic"); - auto shdrDynStr = findSection(".dynstr"); + auto shdrDynamic = findSectionHeader(".dynamic"); + auto shdrDynStr = findSectionHeader(".dynstr"); char * strTab = (char *) fileContents->data() + rdi(shdrDynStr.sh_offset); auto dyn = (Elf_Dyn *)(fileContents->data() + rdi(shdrDynamic.sh_offset)); @@ -1570,6 +1413,8 @@ } memset(last, 0, sizeof(Elf_Dyn) * (dyn - last)); + + this->rewriteSections(); } template<ElfFileParams> @@ -1577,8 +1422,8 @@ { if (libs.empty()) return; - auto shdrDynamic = findSection(".dynamic"); - auto shdrDynStr = findSection(".dynstr"); + auto shdrDynamic = findSectionHeader(".dynamic"); + auto shdrDynStr = findSectionHeader(".dynstr"); char * strTab = (char *) fileContents->data() + rdi(shdrDynStr.sh_offset); auto dyn = (Elf_Dyn *)(fileContents->data() + rdi(shdrDynamic.sh_offset)); @@ -1634,7 +1479,7 @@ // be replaced. if (verNeedNum) { - auto shdrVersionR = findSection(".gnu.version_r"); + auto shdrVersionR = findSectionHeader(".gnu.version_r"); // The filename strings in the .gnu.version_r are different from the // ones in .dynamic: instead of being in .dynstr, they're in some // arbitrary section and we have to look in ->sh_link to figure out @@ -1693,6 +1538,8 @@ --verNeedNum; } } + + this->rewriteSections(); } template<ElfFileParams> @@ -1700,8 +1547,8 @@ { if (libs.empty()) return; - auto shdrDynamic = findSection(".dynamic"); - auto shdrDynStr = findSection(".dynstr"); + auto shdrDynamic = findSectionHeader(".dynamic"); + auto shdrDynStr = findSectionHeader(".dynstr"); unsigned int length = 0; @@ -1743,13 +1590,15 @@ } changed = true; + + this->rewriteSections(); } template<ElfFileParams> void ElfFile<ElfFileParamNames>::printNeededLibs() // const { - const auto shdrDynamic = findSection(".dynamic"); - const auto shdrDynStr = findSection(".dynstr"); + const auto shdrDynamic = findSectionHeader(".dynamic"); + const auto shdrDynStr = findSectionHeader(".dynstr"); const char *strTab = (char *)fileContents->data() + rdi(shdrDynStr.sh_offset); const Elf_Dyn *dyn = (Elf_Dyn *) (fileContents->data() + rdi(shdrDynamic.sh_offset)); @@ -1766,7 +1615,7 @@ template<ElfFileParams> void ElfFile<ElfFileParamNames>::noDefaultLib() { - auto shdrDynamic = findSection(".dynamic"); + auto shdrDynamic = findSectionHeader(".dynamic"); auto dyn = (Elf_Dyn *)(fileContents->data() + rdi(shdrDynamic.sh_offset)); auto dynFlags1 = (Elf_Dyn *)nullptr; @@ -1799,6 +1648,7 @@ setSubstr(newDynamic, 0, std::string((char *) &newDyn, sizeof(Elf_Dyn))); } + this->rewriteSections(); changed = true; } @@ -1807,9 +1657,9 @@ { if (syms.empty()) return; - auto shdrDynStr = findSection(".dynstr"); - auto shdrDynsym = findSection(".dynsym"); - auto shdrVersym = findSection(".gnu.version"); + auto shdrDynStr = findSectionHeader(".dynstr"); + auto shdrDynsym = findSectionHeader(".dynsym"); + auto shdrVersym = findSectionHeader(".gnu.version"); auto strTab = (char *)fileContents->data() + rdi(shdrDynStr.sh_offset); auto dynsyms = (Elf_Sym *)(fileContents->data() + rdi(shdrDynsym.sh_offset)); @@ -1828,6 +1678,7 @@ } } changed = true; + this->rewriteSections(); } static bool printInterpreter = false; @@ -1887,7 +1738,6 @@ elfFile.noDefaultLib(); if (elfFile.isChanged()){ - elfFile.rewriteSections(); writeFile(fileName, elfFile.fileContents); } else if (alwaysWrite) { debug("not modified, but alwaysWrite=true\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/src/patchelf.h new/patchelf-0.14.5/src/patchelf.h --- old/patchelf-0.14.3/src/patchelf.h 1970-01-01 01:00:00.000000000 +0100 +++ new/patchelf-0.14.5/src/patchelf.h 1970-01-01 01:00:01.000000000 +0100 @@ -0,0 +1,159 @@ +using FileContents = std::shared_ptr<std::vector<unsigned char>>; + +#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 +#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Verneed, Elf_Versym + +template<ElfFileParams> +class ElfFile +{ +public: + + const FileContents fileContents; + +private: + + std::vector<Elf_Phdr> phdrs; + std::vector<Elf_Shdr> shdrs; + + bool littleEndian; + + bool changed = false; + + bool isExecutable = false; + + using SectionName = std::string; + using ReplacedSections = std::map<SectionName, std::string>; + + ReplacedSections replacedSections; + + std::string sectionNames; /* content of the .shstrtab section */ + + /* Align on 4 or 8 bytes boundaries on 32- or 64-bit platforms + respectively. */ + size_t sectionAlignment = sizeof(Elf_Off); + + std::vector<SectionName> sectionsByOldIndex; + +public: + explicit ElfFile(FileContents fileContents); + + bool isChanged() + { + return changed; + } + +private: + + struct CompPhdr + { + ElfFile * elfFile; + bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y) + { + // A PHDR comes before everything else. + if (elfFile->rdi(y.p_type) == PT_PHDR) return false; + if (elfFile->rdi(x.p_type) == PT_PHDR) return true; + + // Sort non-PHDRs by address. + return elfFile->rdi(x.p_paddr) < elfFile->rdi(y.p_paddr); + } + }; + + friend struct CompPhdr; + + void sortPhdrs(); + + struct CompShdr + { + ElfFile * elfFile; + bool operator ()(const Elf_Shdr & x, const Elf_Shdr & y) + { + return elfFile->rdi(x.sh_offset) < elfFile->rdi(y.sh_offset); + } + }; + + friend struct CompShdr; + + unsigned int getPageSize() const; + + void sortShdrs(); + + void shiftFile(unsigned int extraPages, Elf_Addr startPage); + + std::string getSectionName(const Elf_Shdr & shdr) const; + + Elf_Shdr & findSectionHeader(const SectionName & sectionName); + + std::optional<std::reference_wrapper<Elf_Shdr>> tryFindSectionHeader(const SectionName & sectionName); + + unsigned int getSectionIndex(const SectionName & sectionName); + + std::string & replaceSection(const SectionName & sectionName, + unsigned int size); + + bool haveReplacedSection(const SectionName & sectionName) const; + + void writeReplacedSections(Elf_Off & curOff, + Elf_Addr startAddr, Elf_Off startOffset); + + void rewriteHeaders(Elf_Addr phdrAddress); + + void rewriteSectionsLibrary(); + + void rewriteSectionsExecutable(); + + void normalizeNoteSegments(); + +public: + + void rewriteSections(); + + std::string getInterpreter(); + + typedef enum { printSoname, replaceSoname } sonameMode; + + void modifySoname(sonameMode op, const std::string & newSoname); + + void setInterpreter(const std::string & newInterpreter); + + typedef enum { rpPrint, rpShrink, rpSet, rpAdd, rpRemove } RPathOp; + + void modifyRPath(RPathOp op, const std::vector<std::string> & allowedRpathPrefixes, std::string newRPath); + std::string shrinkRPath(char* rpath, std::vector<std::string> &neededLibs, const std::vector<std::string> & allowedRpathPrefixes); + void removeRPath(Elf_Shdr & shdrDynamic); + + void addNeeded(const std::set<std::string> & libs); + + void removeNeeded(const std::set<std::string> & libs); + + void replaceNeeded(const std::map<std::string, std::string> & libs); + + void printNeededLibs() /* should be const */; + + void noDefaultLib(); + + void clearSymbolVersions(const std::set<std::string> & syms); + +private: + + /* Convert an integer in big or little endian representation (as + specified by the ELF header) to this platform's integer + representation. */ + template<class I> + I rdi(I i) const; + + /* Convert back to the ELF representation. */ + template<class I> + I wri(I & t, unsigned long long i) const + { + t = rdi((I) i); + return i; + } + + Elf_Ehdr *hdr() { + return (Elf_Ehdr *)fileContents->data(); + } + + const Elf_Ehdr *hdr() const { + return (const Elf_Ehdr *)fileContents->data(); + } +}; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/tests/Makefile.am new/patchelf-0.14.5/tests/Makefile.am --- old/patchelf-0.14.3/tests/Makefile.am 1970-01-01 01:00:01.000000000 +0100 +++ new/patchelf-0.14.5/tests/Makefile.am 1970-01-01 01:00:01.000000000 +0100 @@ -39,7 +39,8 @@ basic-flags.sh \ set-empty-rpath.sh \ phdr-corruption.sh \ - replace-needed.sh + replace-needed.sh \ + replace-add-needed.sh build_TESTS = \ $(no_rpath_arch_TESTS) @@ -83,7 +84,7 @@ big-dynstr.c: main.c cat $< > big-dynstr.c - for i in $$(seq 1 2000); do echo "void f$$i(void) { };"; done >> big-dynstr.c + i=1; while [ $$i -le 2000 ]; do echo "void f$$i(void) { };"; i=$$(($$i + 1)); done >> big-dynstr.c nodist_big_dynstr_SOURCES = big-dynstr.c big_dynstr_LDADD = -lfoo $(AM_LDADD) @@ -108,7 +109,7 @@ phdr-corruption.so libbuildid_so_SOURCES = simple.c -libbuildid_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-build-id +libbuildid_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,--build-id libfoo_so_SOURCES = foo.c libfoo_so_LDADD = -lbar $(AM_LDADD) @@ -129,7 +130,8 @@ libsimple_so_SOURCES = simple.c libsimple_so_LDFLAGS = $(LDFLAGS_sharedlib) -libtoomanystrtab_so_SOURCES = too-many-strtab.c +too_many_strtab_SOURCES = too-many-strtab.c too-many-strtab2.s +libtoomanystrtab_so_SOURCES = too-many-strtab.c too-many-strtab2.s libtoomanystrtab_so_LDFLAGS = $(LDFLAGS_sharedlib) no_rpath_SOURCES = no-rpath.c @@ -137,9 +139,9 @@ no_rpath_CFLAGS = contiguous_note_sections_SOURCES = contiguous-note-sections.s contiguous-note-sections.ld -contiguous_note_sections_LDFLAGS = -nostdlib -T contiguous-note-sections.ld +contiguous_note_sections_LDFLAGS = -nostdlib -T $(srcdir)/contiguous-note-sections.ld contiguous_note_sections_CFLAGS = -pie phdr_corruption_so_SOURCES = void.c phdr-corruption.ld -phdr_corruption_so_LDFLAGS = -nostdlib -shared -Wl,-Tphdr-corruption.ld +phdr_corruption_so_LDFLAGS = -nostdlib -shared -Wl,-T$(srcdir)/phdr-corruption.ld phdr_corruption_so_CFLAGS = diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/tests/Makefile.in new/patchelf-0.14.5/tests/Makefile.in --- old/patchelf-0.14.3/tests/Makefile.in 2021-12-05 15:41:14.000000000 +0100 +++ new/patchelf-0.14.5/tests/Makefile.in 2022-02-21 14:27:38.000000000 +0100 @@ -142,7 +142,8 @@ libsimple_so_LDADD = $(LDADD) libsimple_so_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libsimple_so_LDFLAGS) $(LDFLAGS) -o $@ -am_libtoomanystrtab_so_OBJECTS = too-many-strtab.$(OBJEXT) +am_libtoomanystrtab_so_OBJECTS = too-many-strtab.$(OBJEXT) \ + too-many-strtab2.$(OBJEXT) libtoomanystrtab_so_OBJECTS = $(am_libtoomanystrtab_so_OBJECTS) libtoomanystrtab_so_LDADD = $(LDADD) libtoomanystrtab_so_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ @@ -175,8 +176,9 @@ simple_pie_LDADD = $(LDADD) simple_pie_LINK = $(CCLD) $(simple_pie_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -too_many_strtab_SOURCES = too-many-strtab.c -too_many_strtab_OBJECTS = too-many-strtab.$(OBJEXT) +am_too_many_strtab_OBJECTS = too-many-strtab.$(OBJEXT) \ + too-many-strtab2.$(OBJEXT) +too_many_strtab_OBJECTS = $(am_too_many_strtab_OBJECTS) too_many_strtab_LDADD = $(LDADD) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) @@ -230,7 +232,7 @@ $(libtoomanystrtab_so_SOURCES) $(main_SOURCES) \ $(main_scoped_SOURCES) $(no_rpath_SOURCES) \ $(phdr_corruption_so_SOURCES) $(simple_SOURCES) \ - $(simple_pie_SOURCES) too-many-strtab.c + $(simple_pie_SOURCES) $(too_many_strtab_SOURCES) DIST_SOURCES = $(contiguous_note_sections_SOURCES) \ $(libbar_scoped_so_SOURCES) $(libbar_so_SOURCES) \ $(libbuildid_so_SOURCES) $(libfoo_scoped_so_SOURCES) \ @@ -238,7 +240,7 @@ $(libtoomanystrtab_so_SOURCES) $(main_SOURCES) \ $(main_scoped_SOURCES) $(no_rpath_SOURCES) \ $(phdr_corruption_so_SOURCES) $(simple_SOURCES) \ - $(simple_pie_SOURCES) too-many-strtab.c + $(simple_pie_SOURCES) $(too_many_strtab_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -601,7 +603,8 @@ basic-flags.sh \ set-empty-rpath.sh \ phdr-corruption.sh \ - replace-needed.sh + replace-needed.sh \ + replace-add-needed.sh build_TESTS = \ $(no_rpath_arch_TESTS) @@ -634,7 +637,7 @@ big_dynstr_LDFLAGS = $(LDFLAGS_local) check_DATA = libbig-dynstr.debug libbuildid_so_SOURCES = simple.c -libbuildid_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-build-id +libbuildid_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,--build-id libfoo_so_SOURCES = foo.c libfoo_so_LDADD = -lbar $(AM_LDADD) libfoo_so_DEPENDENCIES = libbar.so @@ -649,16 +652,17 @@ libbar_scoped_so_LDFLAGS = $(LDFLAGS_sharedlib) libsimple_so_SOURCES = simple.c libsimple_so_LDFLAGS = $(LDFLAGS_sharedlib) -libtoomanystrtab_so_SOURCES = too-many-strtab.c +too_many_strtab_SOURCES = too-many-strtab.c too-many-strtab2.s +libtoomanystrtab_so_SOURCES = too-many-strtab.c too-many-strtab2.s libtoomanystrtab_so_LDFLAGS = $(LDFLAGS_sharedlib) no_rpath_SOURCES = no-rpath.c # no -fpic for no-rpath.o no_rpath_CFLAGS = contiguous_note_sections_SOURCES = contiguous-note-sections.s contiguous-note-sections.ld -contiguous_note_sections_LDFLAGS = -nostdlib -T contiguous-note-sections.ld +contiguous_note_sections_LDFLAGS = -nostdlib -T $(srcdir)/contiguous-note-sections.ld contiguous_note_sections_CFLAGS = -pie phdr_corruption_so_SOURCES = void.c phdr-corruption.ld -phdr_corruption_so_LDFLAGS = -nostdlib -shared -Wl,-Tphdr-corruption.ld +phdr_corruption_so_LDFLAGS = -nostdlib -shared -Wl,-T$(srcdir)/phdr-corruption.ld phdr_corruption_so_CFLAGS = all: all-am @@ -1263,6 +1267,13 @@ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +replace-add-needed.sh.log: replace-add-needed.sh + @p='replace-add-needed.sh'; \ + b='replace-add-needed.sh'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) no-rpath-amd64.sh.log: no-rpath-amd64.sh @p='no-rpath-amd64.sh'; \ b='no-rpath-amd64.sh'; \ @@ -1564,7 +1575,7 @@ big-dynstr.c: main.c cat $< > big-dynstr.c - for i in $$(seq 1 2000); do echo "void f$$i(void) { };"; done >> big-dynstr.c + i=1; while [ $$i -le 2000 ]; do echo "void f$$i(void) { };"; i=$$(($$i + 1)); done >> big-dynstr.c # somehow bug does not trigger if we use # normal autotools rules to build the program: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/tests/build-id.sh new/patchelf-0.14.5/tests/build-id.sh --- old/patchelf-0.14.3/tests/build-id.sh 1970-01-01 01:00:01.000000000 +0100 +++ new/patchelf-0.14.5/tests/build-id.sh 1970-01-01 01:00:01.000000000 +0100 @@ -16,4 +16,5 @@ ../src/patchelf \ --set-rpath "$long_rpath" "${SCRATCH}/libbuildid.so" -readelf -n "${SCRATCH}/libbuildid.so" | grep -q "Build ID" +# older readelf versions do not recognize build id, but we can grep by constant +readelf -n "${SCRATCH}/libbuildid.so" | grep -q -F -e 'Build ID' -e 'Unknown note type: (0x00000003)' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/tests/endianness.sh new/patchelf-0.14.5/tests/endianness.sh --- old/patchelf-0.14.3/tests/endianness.sh 1970-01-01 01:00:01.000000000 +0100 +++ new/patchelf-0.14.5/tests/endianness.sh 1970-01-01 01:00:01.000000000 +0100 @@ -6,7 +6,7 @@ rm -rf ${SCRATCH} mkdir -p ${SCRATCH} - cp endianness/${arch}/main endianness/${arch}/libtest.so ${SCRATCH}/ + cp ${srcdir}/endianness/${arch}/main ${srcdir}/endianness/${arch}/libtest.so ${SCRATCH}/ rpath="${PWD}/${SCRATCH}" @@ -19,6 +19,6 @@ # check whether rpath is still present if ! ${PATCHELF} --print-rpath ${SCRATCH}/main-shrunk | grep -q "$rpath"; then echo "rpath was removed for ${arch}" - exit 1 + exit 1 fi done diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/tests/grow-file.sh new/patchelf-0.14.5/tests/grow-file.sh --- old/patchelf-0.14.3/tests/grow-file.sh 1970-01-01 01:00:01.000000000 +0100 +++ new/patchelf-0.14.5/tests/grow-file.sh 1970-01-01 01:00:01.000000000 +0100 @@ -8,7 +8,7 @@ cp simple-pie ${SCRATCH}/simple-pie # Add a 40MB rpath -head -c 40000000 /dev/urandom > ${SCRATCH}/foo.bin +tr -cd 'a-z0-9' < /dev/urandom | dd count=40 bs=1000000 > ${SCRATCH}/foo.bin # Grow the file ../src/patchelf --add-rpath @${SCRATCH}/foo.bin ${SCRATCH}/simple-pie diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/tests/replace-add-needed.sh new/patchelf-0.14.5/tests/replace-add-needed.sh --- old/patchelf-0.14.3/tests/replace-add-needed.sh 1970-01-01 01:00:00.000000000 +0100 +++ new/patchelf-0.14.5/tests/replace-add-needed.sh 1970-01-01 01:00:01.000000000 +0100 @@ -0,0 +1,38 @@ +#! /bin/sh -e +SCRATCH=scratch/$(basename $0 .sh) +PATCHELF=$(readlink -f "../src/patchelf") + +rm -rf ${SCRATCH} +mkdir -p ${SCRATCH} + +cp simple ${SCRATCH}/ +cp libfoo.so ${SCRATCH}/ +cp libbar.so ${SCRATCH}/ + +cd ${SCRATCH} + +libcldd=$(ldd ./simple | awk '/ => / { print $3 }' | grep -E "(libc.so|ld-musl)") + +# We have to set the soname on these libraries +${PATCHELF} --set-soname libbar.so ./libbar.so + +# Add a libbar.so so we can rewrite it later +${PATCHELF} --add-needed libbar.so ./simple + +# Make the NEEDED in libfoo the same as simple +# This is a current "bug" in musl +# https://www.openwall.com/lists/musl/2021/12/21/1 +${PATCHELF} --replace-needed libbar.so $(readlink -f ./libbar.so) ./libfoo.so + +${PATCHELF} --replace-needed libc.so.6 ${libcldd} \ + --replace-needed libbar.so $(readlink -f ./libbar.so) \ + --add-needed $(readlink -f ./libfoo.so) \ + ./simple + +exitCode=0 +./simple || exitCode=$? + +if test "$exitCode" != 0; then + ldd ./simple + exit 1 +fi \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/tests/too-many-strtab.c new/patchelf-0.14.5/tests/too-many-strtab.c --- old/patchelf-0.14.3/tests/too-many-strtab.c 1970-01-01 01:00:01.000000000 +0100 +++ new/patchelf-0.14.5/tests/too-many-strtab.c 1970-01-01 01:00:01.000000000 +0100 @@ -1,3 +1 @@ -const int __attribute__((section (".shstrtab"))) lel = 42; - -int main(){return 0;} +int main(){ return 0; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/tests/too-many-strtab2.s new/patchelf-0.14.5/tests/too-many-strtab2.s --- old/patchelf-0.14.3/tests/too-many-strtab2.s 1970-01-01 01:00:00.000000000 +0100 +++ new/patchelf-0.14.5/tests/too-many-strtab2.s 1970-01-01 01:00:01.000000000 +0100 @@ -0,0 +1,5 @@ +/* + * Create additional .shstrtab section + */ +.section ".shstrtab", "", %3 +.byte 0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/patchelf-0.14.3/version new/patchelf-0.14.5/version --- old/patchelf-0.14.3/version 2021-12-05 15:41:12.000000000 +0100 +++ new/patchelf-0.14.5/version 2022-02-21 14:27:35.000000000 +0100 @@ -1 +1 @@ -0.14.3 +0.14.5