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

Reply via email to