Followup-For: Bug #799880 Hi Felipe.
I have just picked some parts of commit 6900c and applied to the debian package. It built so I generated the debdiff. I also tested it in an amd64. The debdiff is attached. Thanks and regards.
diff -Nru patchelf-0.8/debian/changelog patchelf-0.8/debian/changelog --- patchelf-0.8/debian/changelog 2014-03-28 14:32:16.000000000 -0400 +++ patchelf-0.8/debian/changelog 2015-10-02 13:02:13.000000000 -0400 @@ -1,3 +1,10 @@ +patchelf (0.8-3) UNRELEASED; urgency=medium + + * Non-maintainer upload. + * Applied some changes from upstream to fix fbts on ppc64el + + -- Fernando Seiti Furusato <ferse...@br.ibm.com> Fri, 02 Oct 2015 12:51:08 -0400 + patchelf (0.8-2) unstable; urgency=medium * Document --remove-needed in manpage diff -Nru patchelf-0.8/debian/patches/changes-from-upstream.patch patchelf-0.8/debian/patches/changes-from-upstream.patch --- patchelf-0.8/debian/patches/changes-from-upstream.patch 1969-12-31 19:00:00.000000000 -0500 +++ patchelf-0.8/debian/patches/changes-from-upstream.patch 2015-10-02 13:02:01.000000000 -0400 @@ -0,0 +1,672 @@ +--- a/configure.ac ++++ b/configure.ac +@@ -1,4 +1,4 @@ +-AC_INIT([patchelf], m4_esyscmd([echo -n $(cat ./version)])) ++AC_INIT([patchelf], m4_esyscmd([printf $(cat ./version)])) + AC_CONFIG_SRCDIR([src/patchelf.cc]) + AC_CONFIG_AUX_DIR([build-aux]) + AM_INIT_AUTOMAKE([-Wall -Werror dist-bzip2 foreign color-tests parallel-tests]) +@@ -6,5 +6,7 @@ + AM_PROG_CC_C_O + AC_PROG_CXX + ++AC_CHECK_FUNCS([sysconf]) ++ + AC_CONFIG_FILES([Makefile src/Makefile tests/Makefile patchelf.spec]) + AC_OUTPUT +--- a/patchelf.1 ++++ b/patchelf.1 +@@ -51,6 +51,22 @@ + Removes a declared depency on LIBRARY (DT_NEEDED entry). This + option can be given multiple times. + ++.IP "--add-needed LIBRARY" ++Adds a declared dependency on a dynamic library (DT_NEEDED). ++This option can be give multiple times. ++ ++.IP "--replace-needed LIB_ORIG LIB_NEW" ++Replaces a declared dependency on a dynamic library with another one (DT_NEEDED). ++This option can be give multiple times. ++ ++.IP "--remove-needed LIBRARY" ++Removes a declared depency on LIBRARY (DT_NEEDED entry). This ++option can be given multiple times. ++ ++.IP "--no-default-lib" ++Marks the object that the search for dependencies of this object will ignore any ++default library search paths. ++ + .IP --debug + Prints details of the changes made to the input file. + +--- a/src/Makefile.am ++++ b/src/Makefile.am +@@ -1,3 +1,5 @@ ++AM_CXXFLAGS = -Wall ++ + bin_PROGRAMS = patchelf + + patchelf_SOURCES = patchelf.cc elf.h +--- a/src/patchelf.cc ++++ b/src/patchelf.cc +@@ -22,12 +22,6 @@ + using namespace std; + + +-#ifdef MIPSEL +-/* The lemote fuloong 2f kernel defconfig sets a page size of 16KB */ +-const unsigned int pageSize = 4096*4; +-#else +-const unsigned int pageSize = 4096; +-#endif + + + static bool debugMode = false; +@@ -45,6 +39,16 @@ + #define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym + + ++static unsigned int getPageSize(){ ++#if (defined HAVE_SYSCONF) ++ // if present, use sysconf to get kernel page size ++ return sysconf(_SC_PAGESIZE); ++#else ++ return 4096; ++#endif ++} ++ ++ + template<ElfFileParams> + class ElfFile + { +@@ -144,14 +148,24 @@ + + string getInterpreter(); + ++ string getSoname(); ++ ++ void setSoname(const string & newSoname); ++ + void setInterpreter(const string & newInterpreter); + + typedef enum { rpPrint, rpShrink, rpSet } RPathOp; + + void modifyRPath(RPathOp op, string newRPath); + ++ void addNeeded(set<string> libs); ++ + void removeNeeded(set<string> libs); + ++ void replaceNeeded(map<string, string>& libs); ++ ++ void noDefaultLib(); ++ + private: + + /* Convert an integer in big or little endian representation (as +@@ -205,7 +219,7 @@ + } + + +-static void error(string msg) ++__attribute__((noreturn)) static void error(string msg) + { + if (errno) perror(msg.c_str()); else fprintf(stderr, "%s\n", msg.c_str()); + exit(1); +@@ -228,7 +242,7 @@ + if (stat(fileName.c_str(), &st) != 0) error("stat"); + fileSize = st.st_size; + *fileMode = st.st_mode; +- maxSize = fileSize + 8 * 1024 * 1024; ++ maxSize = fileSize + 32 * 1024 * 1024; + + contents = (unsigned char *) malloc(fileSize + maxSize); + if (!contents) abort(); +@@ -358,21 +372,17 @@ + } + + +-static void writeFile(string fileName, mode_t fileMode) ++static void writeFile(string fileName) + { +- string fileName2 = fileName + "_patchelf_tmp"; +- +- int fd = open(fileName2.c_str(), +- O_CREAT | O_TRUNC | O_WRONLY, 0700); +- if (fd == -1) error("open"); +- +- if (write(fd, contents, fileSize) != fileSize) error("write"); ++ int fd = open(fileName.c_str(), O_TRUNC | O_WRONLY); ++ if (fd == -1) ++ error("open"); + +- if (close(fd) != 0) error("close"); ++ if (write(fd, contents, fileSize) != fileSize) ++ error("write"); + +- if (chmod(fileName2.c_str(), fileMode) != 0) error("chmod"); +- +- if (rename(fileName2.c_str(), fileName.c_str()) != 0) error("rename"); ++ if (close(fd) != 0) ++ error("close"); + } + + +@@ -388,9 +398,9 @@ + /* Move the entire contents of the file `extraPages' pages + further. */ + unsigned int oldSize = fileSize; +- unsigned int shift = extraPages * pageSize; +- growFile(fileSize + extraPages * pageSize); +- memmove(contents + extraPages * pageSize, contents, oldSize); ++ unsigned int shift = extraPages * getPageSize(); ++ growFile(fileSize + extraPages * getPageSize()); ++ memmove(contents + extraPages * getPageSize(), contents, oldSize); + memset(contents + sizeof(Elf_Ehdr), 0, shift - sizeof(Elf_Ehdr)); + + /* Adjust the ELF header. */ +@@ -407,8 +417,8 @@ + if (rdi(phdrs[i].p_align) != 0 && + (rdi(phdrs[i].p_vaddr) - rdi(phdrs[i].p_offset)) % rdi(phdrs[i].p_align) != 0) { + debug("changing alignment of program header %d from %d to %d\n", i, +- rdi(phdrs[i].p_align), pageSize); +- wri(phdrs[i].p_align, pageSize); ++ rdi(phdrs[i].p_align), getPageSize()); ++ wri(phdrs[i].p_align, getPageSize()); + } + } + +@@ -422,7 +432,7 @@ + wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage)); + wri(phdr.p_filesz, wri(phdr.p_memsz, shift)); + wri(phdr.p_flags, PF_R | PF_W); +- wri(phdr.p_align, pageSize); ++ wri(phdr.p_align, getPageSize()); + } + + +@@ -551,7 +561,7 @@ + page of other segments. */ + Elf_Addr startPage = 0; + for (unsigned int i = 0; i < phdrs.size(); ++i) { +- Elf_Addr thisPage = roundUp(rdi(phdrs[i].p_vaddr) + rdi(phdrs[i].p_memsz), pageSize); ++ Elf_Addr thisPage = roundUp(rdi(phdrs[i].p_vaddr) + rdi(phdrs[i].p_memsz), getPageSize()); + if (thisPage > startPage) startPage = thisPage; + } + +@@ -567,7 +577,7 @@ + debug("needed space is %d\n", neededSpace); + + +- size_t startOffset = roundUp(fileSize, pageSize); ++ size_t startOffset = roundUp(fileSize, getPageSize()); + + growFile(startOffset + neededSpace); + +@@ -591,7 +601,7 @@ + size_t hole = startPage - startOffset; + /* Print a warning, because the hole could be very big. */ + fprintf(stderr, "warning: working around a Linux kernel bug by creating a hole of %zu bytes in ā%sā\n", hole, fileName.c_str()); +- assert(hole % pageSize == 0); ++ assert(hole % getPageSize() == 0); + /* !!! We could create an actual hole in the file here, + but it's probably not worth the effort. */ + growFile(fileSize + hole); +@@ -611,7 +621,7 @@ + wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage)); + wri(phdr.p_filesz, wri(phdr.p_memsz, neededSpace)); + wri(phdr.p_flags, PF_R | PF_W); +- wri(phdr.p_align, pageSize); ++ wri(phdr.p_align, getPageSize()); + + + /* Write out the replaced sections. */ +@@ -682,7 +692,7 @@ + debug("first reserved offset/addr is 0x%x/0x%llx\n", + startOffset, (unsigned long long) startAddr); + +- assert(startAddr % pageSize == startOffset % pageSize); ++ assert(startAddr % getPageSize() == startOffset % getPageSize()); + Elf_Addr firstPage = startAddr - startOffset; + debug("first page is 0x%llx\n", (unsigned long long) firstPage); + +@@ -711,13 +721,13 @@ + neededSpace += sizeof(Elf_Phdr); + debug("needed space is %d\n", neededSpace); + +- unsigned int neededPages = roundUp(neededSpace - startOffset, pageSize) / pageSize; ++ unsigned int neededPages = roundUp(neededSpace - startOffset, getPageSize()) / getPageSize(); + debug("needed pages is %d\n", neededPages); +- if (neededPages * pageSize > firstPage) ++ if (neededPages * getPageSize() > firstPage) + error("virtual address space underrun!"); + +- firstPage -= neededPages * pageSize; +- startOffset += neededPages * pageSize; ++ firstPage -= neededPages * getPageSize(); ++ startOffset += neededPages * getPageSize(); + + shiftFile(neededPages, firstPage); + } +@@ -871,6 +881,88 @@ + return string((char *) contents + rdi(shdr.sh_offset), rdi(shdr.sh_size)); + } + ++template<ElfFileParams> ++string ElfFile<ElfFileParamNames>::getSoname() ++{ ++ Elf_Shdr & shdrDynamic = findSection(".dynamic"); ++ Elf_Shdr & shdrDynStr = findSection(".dynstr"); ++ char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset); ++ ++ /* Find the DT_STRTAB entry in the dynamic section. */ ++ Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); ++ Elf_Addr strTabAddr = 0; ++ for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) ++ if (rdi(dyn->d_tag) == DT_STRTAB) strTabAddr = rdi(dyn->d_un.d_ptr); ++ if (!strTabAddr) error("strange: no string table"); ++ ++ /* We assume that the virtual address in the DT_STRTAB entry ++ of the dynamic section corresponds to the .dynstr section. */ ++ assert(strTabAddr == rdi(shdrDynStr.sh_addr)); ++ ++ Elf_Dyn * dynSoname = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); ++ char * soname = 0; ++ for ( ; rdi(dynSoname->d_tag) != DT_NULL; dynSoname++) { ++ if (rdi(dynSoname->d_tag) == DT_SONAME) { ++ soname = strTab + rdi(dynSoname->d_un.d_val); ++ break; ++ } ++ } ++ ++ if (rdi(dynSoname->d_tag) == DT_NULL) ++ error("Specified ELF file does not contain any DT_SONAME entry in .dynamic section!"); ++ ++ return soname; ++} ++ ++template<ElfFileParams> ++void ElfFile<ElfFileParamNames>::setSoname(const string & newSoname) ++{ ++ Elf_Shdr & shdrDynamic = findSection(".dynamic"); ++ Elf_Shdr & shdrDynStr = findSection(".dynstr"); ++ char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset); ++ ++ /* Find the DT_STRTAB entry in the dynamic section. */ ++ Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); ++ Elf_Addr strTabAddr = 0; ++ for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) ++ if (rdi(dyn->d_tag) == DT_STRTAB) strTabAddr = rdi(dyn->d_un.d_ptr); ++ if (!strTabAddr) error("strange: no string table"); ++ ++ /* We assume that the virtual address in the DT_STRTAB entry ++ of the dynamic section corresponds to the .dynstr section. */ ++ assert(strTabAddr == rdi(shdrDynStr.sh_addr)); ++ ++ Elf_Dyn * dynSoname = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); ++ char * soname = 0; ++ for ( ; rdi(dynSoname->d_tag) != DT_NULL; dynSoname++) { ++ if (rdi(dynSoname->d_tag) == DT_SONAME) { ++ soname = strTab + rdi(dynSoname->d_un.d_val); ++ break; ++ } ++ } ++ if (rdi(dynSoname->d_tag) == DT_NULL) ++ error("Specified ELF file does not contain any DT_SONAME entry in .dynamic section!"); ++ ++ if (newSoname.size() <= strlen(soname)) { ++ debug("old soname: `%s', new soname: `%s'\n", soname, newSoname.c_str()); ++ strcpy(soname, newSoname.c_str()); ++ changed = true; ++ } ++ else { ++ /* Grow the .dynstr section to make room for the new DT_SONAME */ ++ debug("new soname is too long, resizing .dynstr section...\n"); ++ ++ string & newDynStr = replaceSection(".dynstr", ++ rdi(shdrDynStr.sh_size) + newSoname.size() + 1); ++ setSubstr(newDynStr, rdi(shdrDynStr.sh_size), newSoname + '\0'); ++ /* Update the DT_SONAME entry, if any */ ++ if (dynSoname) { ++ debug("old soname: `%s', new soname: `%s'\n", soname, newSoname.c_str()); ++ dynSoname->d_un.d_val = shdrDynStr.sh_size; ++ changed = true; ++ } ++ } ++} + + template<ElfFileParams> + void ElfFile<ElfFileParamNames>::setInterpreter(const string & newInterpreter) +@@ -1088,8 +1180,140 @@ + memset(last, 0, sizeof(Elf_Dyn) * (dyn - last)); + } + ++template<ElfFileParams> ++void ElfFile<ElfFileParamNames>::replaceNeeded(map<string, string>& libs) ++{ ++ if (libs.empty()) return; ++ ++ Elf_Shdr & shdrDynamic = findSection(".dynamic"); ++ Elf_Shdr & shdrDynStr = findSection(".dynstr"); ++ char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset); ++ ++ Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); ++ ++ unsigned int dynStrAddedBytes = 0; ++ ++ for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) { ++ if (rdi(dyn->d_tag) == DT_NEEDED) { ++ char * name = strTab + rdi(dyn->d_un.d_val); ++ if (libs.find(name) != libs.end()) { ++ const string & replacement = libs[name]; ++ ++ debug("replacing DT_NEEDED entry `%s' with `%s'\n", name, replacement.c_str()); ++ ++ // technically, the string referred by d_val could be used otherwise, too (although unlikely) ++ // we'll therefore add a new string ++ debug("resizing .dynstr ..."); ++ ++ string & newDynStr = replaceSection(".dynstr", ++ rdi(shdrDynStr.sh_size) + replacement.size() + 1 + dynStrAddedBytes); ++ setSubstr(newDynStr, rdi(shdrDynStr.sh_size) + dynStrAddedBytes, replacement + '\0'); ++ ++ dyn->d_un.d_val = shdrDynStr.sh_size + dynStrAddedBytes; ++ ++ dynStrAddedBytes += replacement.size() + 1; ++ ++ changed = true; ++ } else { ++ debug("keeping DT_NEEDED entry `%s'\n", name); ++ } ++ } ++ } ++} ++ ++template<ElfFileParams> ++void ElfFile<ElfFileParamNames>::addNeeded(set<string> libs) ++{ ++ if (libs.empty()) return; ++ ++ Elf_Shdr & shdrDynamic = findSection(".dynamic"); ++ Elf_Shdr & shdrDynStr = findSection(".dynstr"); ++ ++ /* add all new libs to the dynstr string table */ ++ unsigned int length = 0; ++ for (set<string>::iterator it = libs.begin(); it != libs.end(); it++) { ++ length += it->size() + 1; ++ } ++ ++ string & newDynStr = replaceSection(".dynstr", ++ rdi(shdrDynStr.sh_size) + length + 1); ++ set<Elf64_Xword> libStrings; ++ unsigned int pos = 0; ++ for (set<string>::iterator it = libs.begin(); it != libs.end(); it++) { ++ setSubstr(newDynStr, rdi(shdrDynStr.sh_size) + pos, *it + '\0'); ++ libStrings.insert(rdi(shdrDynStr.sh_size) + pos); ++ pos += it->size() + 1; ++ } ++ ++ /* add all new needed entries to the dynamic section */ ++ string & newDynamic = replaceSection(".dynamic", ++ rdi(shdrDynamic.sh_size) + sizeof(Elf_Dyn) * libs.size()); ++ ++ unsigned int idx = 0; ++ for ( ; rdi(((Elf_Dyn *) newDynamic.c_str())[idx].d_tag) != DT_NULL; idx++) ; ++ debug("DT_NULL index is %d\n", idx); ++ ++ /* Shift all entries down by the number of new entries. */ ++ setSubstr(newDynamic, sizeof(Elf_Dyn) * libs.size(), ++ string(newDynamic, 0, sizeof(Elf_Dyn) * (idx + 1))); ++ ++ /* Add the DT_NEEDED entries at the top. */ ++ unsigned int i = 0; ++ for (set<Elf64_Xword>::iterator it = libStrings.begin(); it != libStrings.end(); it++, i++) { ++ Elf_Dyn newDyn; ++ wri(newDyn.d_tag, DT_NEEDED); ++ wri(newDyn.d_un.d_val, *it); ++ setSubstr(newDynamic, i * sizeof(Elf_Dyn), string((char *) &newDyn, sizeof(Elf_Dyn))); ++ } ++ ++ changed = true; ++} ++ ++ ++template<ElfFileParams> ++void ElfFile<ElfFileParamNames>::noDefaultLib() ++{ ++ Elf_Shdr & shdrDynamic = findSection(".dynamic"); ++ ++ Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset)); ++ Elf_Dyn * dynFlags1 = 0; ++ for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) { ++ if (rdi(dyn->d_tag) == DT_FLAGS_1) { ++ dynFlags1 = dyn; ++ break; ++ } ++ } ++ if (dynFlags1) { ++ if (dynFlags1->d_un.d_val & DF_1_NODEFLIB) ++ return; ++ dynFlags1->d_un.d_val |= DF_1_NODEFLIB; ++ } else { ++ string & newDynamic = replaceSection(".dynamic", ++ rdi(shdrDynamic.sh_size) + sizeof(Elf_Dyn)); ++ ++ unsigned int idx = 0; ++ for ( ; rdi(((Elf_Dyn *) newDynamic.c_str())[idx].d_tag) != DT_NULL; idx++) ; ++ debug("DT_NULL index is %d\n", idx); ++ ++ /* Shift all entries down by one. */ ++ setSubstr(newDynamic, sizeof(Elf_Dyn), ++ string(newDynamic, 0, sizeof(Elf_Dyn) * (idx + 1))); ++ ++ /* Add the DT_FLAGS_1 entry at the top. */ ++ Elf_Dyn newDyn; ++ wri(newDyn.d_tag, DT_FLAGS_1); ++ newDyn.d_un.d_val = DF_1_NODEFLIB; ++ setSubstr(newDynamic, 0, string((char *) &newDyn, sizeof(Elf_Dyn))); ++ } ++ ++ changed = true; ++} ++ + + static bool printInterpreter = false; ++static bool printSoname = false; ++static bool setSoname = false; ++static string newSoname; + static string newInterpreter; + + static bool shrinkRPath = false; +@@ -1097,7 +1321,9 @@ + static bool printRPath = false; + static string newRPath; + static set<string> neededLibsToRemove; +- ++static map<string, string> neededLibsToReplace; ++static set<string> neededLibsToAdd; ++static bool noDefaultLib = false; + + template<class ElfFile> + static void patchElf2(ElfFile & elfFile, mode_t fileMode) +@@ -1107,6 +1333,12 @@ + if (printInterpreter) + printf("%s\n", elfFile.getInterpreter().c_str()); + ++ if (printSoname) ++ printf("%s\n", elfFile.getSoname().c_str()); ++ ++ if (setSoname) ++ elfFile.setSoname(newSoname); ++ + if (newInterpreter != "") + elfFile.setInterpreter(newInterpreter); + +@@ -1119,19 +1351,26 @@ + elfFile.modifyRPath(elfFile.rpSet, newRPath); + + elfFile.removeNeeded(neededLibsToRemove); ++ elfFile.replaceNeeded(neededLibsToReplace); ++ elfFile.addNeeded(neededLibsToAdd); ++ ++ if (noDefaultLib) ++ elfFile.noDefaultLib(); + + if (elfFile.isChanged()){ + elfFile.rewriteSections(); +- writeFile(fileName, fileMode); ++ writeFile(fileName); + } + } + + + static void patchElf() + { +- if (!printInterpreter && !printRPath) ++ if (!printInterpreter && !printRPath && !printSoname) + debug("patching ELF file `%s'\n", fileName.c_str()); + ++ debug("Kernel page size is %u bytes\n", getPageSize()); ++ + mode_t fileMode; + + readFile(fileName, &fileMode); +@@ -1166,11 +1405,16 @@ + fprintf(stderr, "syntax: %s\n\ + [--set-interpreter FILENAME]\n\ + [--print-interpreter]\n\ ++ [--print-soname]\t\tPrints 'DT_SONAME' entry of .dynamic section. Raises an error if DT_SONAME doesn't exist\n\ ++ [--set-soname SONAME]\t\tSets 'DT_SONAME' entry to SONAME. Raises an error if DT_SONAME doesn't exist\n\ + [--set-rpath RPATH]\n\ + [--shrink-rpath]\n\ + [--print-rpath]\n\ + [--force-rpath]\n\ ++ [--add-needed LIBRARY]\n\ + [--remove-needed LIBRARY]\n\ ++ [--replace-needed LIBRARY NEW_LIBRARY]\n\ ++ [--no-default-lib]\n\ + [--debug]\n\ + [--version]\n\ + FILENAME\n", progName.c_str()); +@@ -1196,6 +1440,14 @@ + else if (arg == "--print-interpreter") { + printInterpreter = true; + } ++ else if (arg == "--print-soname") { ++ printSoname = true; ++ } ++ else if (arg == "--set-soname") { ++ if (++i == argc) error("missing argument"); ++ setSoname = true; ++ newSoname = argv[i]; ++ } + else if (arg == "--shrink-rpath") { + shrinkRPath = true; + } +@@ -1221,14 +1473,26 @@ + added. */ + forceRPath = true; + } ++ else if (arg == "--add-needed") { ++ if (++i == argc) error("missing argument"); ++ neededLibsToAdd.insert(argv[i]); ++ } + else if (arg == "--remove-needed") { + if (++i == argc) error("missing argument"); + neededLibsToRemove.insert(argv[i]); + } ++ else if (arg == "--replace-needed") { ++ if (i+2 >= argc) error("missing argument(s)"); ++ neededLibsToReplace[ argv[i+1] ] = argv[i+2]; ++ i += 2; ++ } + else if (arg == "--debug") { + debugMode = true; + } +- else if (arg == "--help") { ++ else if (arg == "--no-default-lib") { ++ noDefaultLib = true; ++ } ++ else if (arg == "--help" || arg == "-h" ) { + showHelp(argv[0]); + return 0; + } +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -1,4 +1,4 @@ +-check_PROGRAMS = simple main main-scoped big-dynstr ++check_PROGRAMS = simple main main-scoped big-dynstr no-rpath + + TESTS = plain-fail.sh plain-run.sh shrink-rpath.sh set-interpreter-short.sh \ + set-interpreter-long.sh set-rpath.sh no-rpath.sh big-dynstr.sh \ +@@ -44,7 +44,7 @@ + # - without libtool, only archives (static libraries) can be built by automake + # - with libtool, it is difficult to control options + # - with libtool, it is not possible to compile convenience *dynamic* libraries :-( +-check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so ++check_PROGRAMS += libfoo.so libfoo-scoped.so libbar.so libbar-scoped.so libsimple.so + + libfoo_so_SOURCES = foo.c + libfoo_so_LDADD = -lbar $(AM_LDADD) +@@ -62,3 +62,9 @@ + libbar_scoped_so_SOURCES = bar.c + libbar_scoped_so_LDFLAGS = $(LDFLAGS_sharedlib) + ++libsimple_so_SOURCES = simple.c ++libsimple_so_LDFLAGS = $(LDFLAGS_sharedlib) -Wl,-soname,libsimple.so.1.0 ++ ++no_rpath_SOURCES = no-rpath.c ++# no -fpic for no-rpath.o ++no_rpath_CFLAGS = +--- /dev/null ++++ b/tests/no-rpath.c +@@ -0,0 +1,6 @@ ++#include <stdio.h> ++ ++int main() { ++ printf("Hello world\n"); ++ return 0; ++} +--- a/tests/no-rpath.sh ++++ b/tests/no-rpath.sh +@@ -4,7 +4,7 @@ + rm -rf ${SCRATCH} + mkdir -p ${SCRATCH} + +-cp ${srcdir}/no-rpath ${SCRATCH}/ ++cp no-rpath ${SCRATCH}/ + + oldRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath) + if test -n "$oldRPath"; then exit 1; fi +@@ -18,6 +18,4 @@ + exit 1 + fi + +-if [ "$(uname -m)" = i686 -a "$(uname -s)" = Linux ]; then +- cd ${SCRATCH} && ./no-rpath +-fi ++cd ${SCRATCH} && ./no-rpath +--- /dev/null ++++ b/tests/soname.sh +@@ -0,0 +1,21 @@ ++#! /bin/sh -e ++SCRATCH=scratch/$(basename $0 .sh) ++ ++rm -rf ${SCRATCH} ++mkdir -p ${SCRATCH} ++ ++cp libsimple.so ${SCRATCH}/ ++ ++# print and set DT_SONAME ++soname=$(../src/patchelf --print-soname ${SCRATCH}/libsimple.so) ++if test "$soname" != libsimple.so.1.0; then ++ echo "failed --print-soname test. Expected soname: libsimple.so.1.0, got: $soname" ++ exit 1 ++fi ++ ++../src/patchelf --set-soname libsimple.so.1.1 ${SCRATCH}/libsimple.so ++newSoname=$(../src/patchelf --print-soname ${SCRATCH}/libsimple.so) ++if test "$newSoname" != libsimple.so.1.1; then ++ echo "failed --set-soname test. Expected newSoname: libsimple.so.1.1, got: $newSoname" ++ exit 1 ++fi diff -Nru patchelf-0.8/debian/patches/series patchelf-0.8/debian/patches/series --- patchelf-0.8/debian/patches/series 2014-03-28 14:35:23.000000000 -0400 +++ patchelf-0.8/debian/patches/series 2015-10-02 12:52:39.000000000 -0400 @@ -1 +1,2 @@ debian-changes +changes-from-upstream.patch diff -Nru patchelf-0.8/debian/rules patchelf-0.8/debian/rules --- patchelf-0.8/debian/rules 2014-03-28 14:32:16.000000000 -0400 +++ patchelf-0.8/debian/rules 2015-10-02 12:50:01.000000000 -0400 @@ -17,8 +17,14 @@ rm -f configure rm -f aclocal.m4 +override_dh_auto_test: tests/soname.sh + dh_auto_test + src/elf.h.bak: mv src/elf.h src/elf.h.bak src/elf.h: mv src/elf.h.bak src/elf.h + +tests/soname.sh: + chmod a+x tests/soname.sh