Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package patchelf for openSUSE:Factory 
checked in at 2021-10-19 23:03:33
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/patchelf (Old)
 and      /work/SRC/openSUSE:Factory/.patchelf.new.1890 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "patchelf"

Tue Oct 19 23:03:33 2021 rev:14 rq:925683 version:0.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/patchelf/patchelf.changes        2020-09-21 
17:12:46.587426574 +0200
+++ /work/SRC/openSUSE:Factory/.patchelf.new.1890/patchelf.changes      
2021-10-19 23:03:35.993266751 +0200
@@ -1,0 +2,15 @@
+Sat Oct 16 12:24:20 UTC 2021 - Dirk M??ller <dmuel...@suse.com>
+
+- update to 0.13:
+  * mark phdrs synced with sections, avoid rechecking it when syncing not
+  * fix roundUp() to not truncate 64 bit values
+  * Use sh_offset instead of sh_addr when checking already replaced libs 
+  * Add ELF test case with invalid string table index
+  * Gracefully handle ELF files with invalid string table indices in header
+  * clang-tidy fixes
+  * avoid needless memory allocation when replacing sections
+  * silence compiler warning because of different signedness
+  * avoid needless copies of std::string
+  * patchelf: Fix alignment issues with contiguous note sections
+
+-------------------------------------------------------------------

Old:
----
  patchelf-0.12.tar.bz2

New:
----
  patchelf-0.13.tar.bz2

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ patchelf.spec ++++++
--- /var/tmp/diff_new_pack.ewfvxC/_old  2021-10-19 23:03:36.425266947 +0200
+++ /var/tmp/diff_new_pack.ewfvxC/_new  2021-10-19 23:03:36.425266947 +0200
@@ -1,7 +1,7 @@
 #
 # spec file for package patchelf
 #
-# Copyright (c) 2020 SUSE LLC
+# Copyright (c) 2021 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.12
+Version:        0.13
 Release:        0
 Summary:        A utility for patching ELF binaries
 License:        GPL-3.0-only
@@ -32,14 +32,14 @@
 executables and change the RPATH of executables and libraries.
 
 %prep
-%setup -q -n %{name}-0.12.20200827.8d3a16e
+%setup -q -n %{name}-0.13.20210805.a949ff2
 
 %build
 %configure
-make %{?_smp_mflags}
+%make_build
 
 %check
-make %{?_smp_mflags} check
+%make_build check
 
 %install
 %make_install

++++++ patchelf-0.12.tar.bz2 -> patchelf-0.13.tar.bz2 ++++++
++++ 2097 lines of diff (skipped)
++++    retrying with extended exclude list
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/README.md 
new/patchelf-0.13.20210805.a949ff2/README.md
--- old/patchelf-0.12.20200827.8d3a16e/README.md        1970-01-01 
01:00:01.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/README.md        1970-01-01 
01:00:01.000000000 +0100
@@ -99,6 +99,12 @@
 
 ## Release History
 
+0.13 (August 5, 2021):
+
+* New `--add-rpath` flag.
+
+* Bug fixes.
+
 0.12 (August 27, 2020):
 
 * New `--clear-symbol-version` flag.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/build-aux/compile 
new/patchelf-0.13.20210805.a949ff2/build-aux/compile
--- old/patchelf-0.12.20200827.8d3a16e/build-aux/compile        2020-08-27 
14:12:58.000000000 +0200
+++ new/patchelf-0.13.20210805.a949ff2/build-aux/compile        2021-08-05 
14:55:32.000000000 +0200
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 # Written by Tom Tromey <tro...@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@
          MINGW*)
            file_conv=mingw
            ;;
-         CYGWIN*)
+         CYGWIN* | MSYS*)
            file_conv=cygwin
            ;;
          *)
@@ -67,7 +67,7 @@
        mingw/*)
          file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
          ;;
-       cygwin/*)
+       cygwin/* | msys/*)
          file=`cygpath -m "$file" || echo "$file"`
          ;;
        wine/*)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/build-aux/missing 
new/patchelf-0.13.20210805.a949ff2/build-aux/missing
--- old/patchelf-0.12.20200827.8d3a16e/build-aux/missing        2020-08-27 
14:12:58.000000000 +0200
+++ new/patchelf-0.13.20210805.a949ff2/build-aux/missing        2021-08-05 
14:55:32.000000000 +0200
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pin...@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/build-aux/test-driver 
new/patchelf-0.13.20210805.a949ff2/build-aux/test-driver
--- old/patchelf-0.12.20200827.8d3a16e/build-aux/test-driver    2020-08-27 
14:12:59.000000000 +0200
+++ new/patchelf-0.13.20210805.a949ff2/build-aux/test-driver    2021-08-05 
14:55:32.000000000 +0200
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2020 Free Software Foundation, Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/configure.ac 
new/patchelf-0.13.20210805.a949ff2/configure.ac
--- old/patchelf-0.12.20200827.8d3a16e/configure.ac     1970-01-01 
01:00:01.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/configure.ac     1970-01-01 
01:00:01.000000000 +0100
@@ -6,6 +6,7 @@
 
 AM_PROG_CC_C_O
 AC_PROG_CXX
+AM_PROG_AS
 
 DEFAULT_PAGESIZE=auto
 AC_ARG_WITH([page-size],
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/patchelf.1 
new/patchelf-0.13.20210805.a949ff2/patchelf.1
--- old/patchelf-0.12.20200827.8d3a16e/patchelf.1       1970-01-01 
01:00:01.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/patchelf.1       1970-01-01 
01:00:01.000000000 +0100
@@ -43,6 +43,9 @@
 .IP "--set-rpath RPATH"
 Change the RPATH of the executable or library to RPATH.
 
+.IP "--add-rpath RPATH"
+Add RPATH to the existing RPATH of the executable or library.
+
 .IP --remove-rpath
 Removes the DT_RPATH or DT_RUNPATH entry of the executable or library.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/patchelf.spec 
new/patchelf-0.13.20210805.a949ff2/patchelf.spec
--- old/patchelf-0.12.20200827.8d3a16e/patchelf.spec    2020-08-27 
14:13:00.000000000 +0200
+++ new/patchelf-0.13.20210805.a949ff2/patchelf.spec    2021-08-05 
14:55:33.000000000 +0200
@@ -1,7 +1,7 @@
 Summary: A utility for patching ELF binaries
 
 Name: patchelf
-Version: 0.12.20200827.8d3a16e
+Version: 0.13.20210805.a949ff2
 Release: 1
 License: GPL
 Group: Development/Tools
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/src/elf.h 
new/patchelf-0.13.20210805.a949ff2/src/elf.h
--- old/patchelf-0.12.20200827.8d3a16e/src/elf.h        1970-01-01 
01:00:01.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/src/elf.h        1970-01-01 
01:00:01.000000000 +0100
@@ -366,7 +366,9 @@
                                           required */
 #define SHF_GROUP           (1 << 9)   /* Section is member of a group.  */
 #define SHF_TLS                     (1 << 10)  /* Section hold thread-local 
data.  */
+#define SHF_COMPRESSED      (1 << 11)  /* Section with compressed data */
 #define SHF_MASKOS          0x0ff00000 /* OS-specific.  */
+#define SHF_GNU_BUILD_NOTE   (1 << 20) /* Section contains GNU BUILD ATTRIBUTE 
notes.  */
 #define SHF_MASKPROC        0xf0000000 /* Processor-specific */
 #define SHF_ORDERED         (1 << 30)  /* Special ordering requirement
                                           (Solaris).  */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/src/patchelf.cc 
new/patchelf-0.13.20210805.a949ff2/src/patchelf.cc
--- old/patchelf-0.12.20200827.8d3a16e/src/patchelf.cc  1970-01-01 
01:00:01.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/src/patchelf.cc  1970-01-01 
01:00:01.000000000 +0100
@@ -16,27 +16,27 @@
  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include <string>
-#include <vector>
-#include <set>
-#include <map>
 #include <algorithm>
+#include <limits>
+#include <map>
 #include <memory>
+#include <set>
 #include <sstream>
-#include <limits>
 #include <stdexcept>
+#include <string>
+#include <vector>
 
-#include <cstdlib>
-#include <cstdio>
-#include <cstdarg>
 #include <cassert>
-#include <cstring>
 #include <cerrno>
+#include <cstdarg>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
 
-#include <sys/types.h>
+#include <fcntl.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 #include <unistd.h>
-#include <fcntl.h>
 
 #include "elf.h"
 
@@ -54,8 +54,7 @@
 static int forcedPageSize = -1;
 #endif
 
-typedef std::shared_ptr<std::vector<unsigned char>> FileContents;
-
+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
@@ -79,9 +78,7 @@
 
 static bool hasAllowedPrefix(const std::string & s, const 
std::vector<std::string> & allowedPrefixes)
 {
-    for (auto & i : allowedPrefixes)
-        if (!s.compare(0, i.size(), i)) return true;
-    return false;
+    return std::any_of(allowedPrefixes.begin(), allowedPrefixes.end(), 
[&](const std::string & i) { return !s.compare(0, i.size(), i); });
 }
 
 
@@ -106,8 +103,8 @@
 
     bool isExecutable = false;
 
-    typedef std::string SectionName;
-    typedef std::map<SectionName, std::string> ReplacedSections;
+    using SectionName = std::string;
+    using ReplacedSections = std::map<SectionName, std::string>;
 
     ReplacedSections replacedSections;
 
@@ -120,8 +117,7 @@
     std::vector<SectionName> sectionsByOldIndex;
 
 public:
-
-    ElfFile(FileContents fileContents);
+    explicit ElfFile(FileContents fileContents);
 
     bool isChanged()
     {
@@ -136,8 +132,8 @@
         bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y)
         {
             // A PHDR comes before everything else.
-            if (y.p_type == PT_PHDR) return false;
-            if (x.p_type == PT_PHDR) return true;
+            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);
@@ -201,7 +197,7 @@
 
     void setInterpreter(const std::string & newInterpreter);
 
-    typedef enum { rpPrint, rpShrink, rpSet, rpRemove } RPathOp;
+    typedef enum { rpPrint, rpShrink, rpSet, rpAdd, rpRemove } RPathOp;
 
     void modifyRPath(RPathOp op, const std::vector<std::string> & 
allowedRpathPrefixes, std::string newRPath);
 
@@ -291,41 +287,37 @@
 struct SysError : std::runtime_error
 {
     int errNo;
-    SysError(const std::string & msg)
+    explicit SysError(const std::string & msg)
         : std::runtime_error(fmt(msg + ": " + strerror(errno)))
         , errNo(errno)
     { }
 };
 
-
-__attribute__((noreturn)) static void error(std::string msg)
+__attribute__((noreturn)) static void error(const std::string & msg)
 {
     if (errno)
         throw SysError(msg);
-    else
-        throw std::runtime_error(msg);
+    throw std::runtime_error(msg);
 }
 
-
-static void growFile(FileContents contents, size_t newSize)
+static void growFile(const FileContents & contents, size_t newSize)
 {
     if (newSize > contents->capacity()) error("maximum file size exceeded");
     if (newSize <= contents->size()) return;
     contents->resize(newSize, 0);
 }
 
-
-static FileContents readFile(std::string fileName,
+static FileContents readFile(const std::string & fileName,
     size_t cutOff = std::numeric_limits<size_t>::max())
 {
     struct stat st;
     if (stat(fileName.c_str(), &st) != 0)
         throw SysError(fmt("getting info about '", fileName, "'"));
 
-    if ((uint64_t) st.st_size > (uint64_t) std::numeric_limits<size_t>::max())
+    if (static_cast<uint64_t>(st.st_size) > 
static_cast<uint64_t>(std::numeric_limits<size_t>::max()))
         throw SysError(fmt("cannot read file of size ", st.st_size, " into 
memory"));
 
-    size_t size = std::min(cutOff, (size_t) st.st_size);
+    size_t size = std::min(cutOff, static_cast<size_t>(st.st_size));
 
     FileContents contents = std::make_shared<std::vector<unsigned char>>();
     contents->reserve(size + 32 * 1024 * 1024);
@@ -358,7 +350,8 @@
 ElfType getElfType(const FileContents & fileContents)
 {
     /* Check the ELF header for basic validity. */
-    if (fileContents->size() < (off_t) sizeof(Elf32_Ehdr)) error("missing ELF 
header");
+    if (fileContents->size() < static_cast<off_t>(sizeof(Elf32_Ehdr)))
+        error("missing ELF header");
 
     auto contents = fileContents->data();
 
@@ -374,20 +367,21 @@
     bool is32Bit = contents[EI_CLASS] == ELFCLASS32;
 
     // FIXME: endianness
-    return ElfType{is32Bit, is32Bit ? ((Elf32_Ehdr *) contents)->e_machine : 
((Elf64_Ehdr *) contents)->e_machine};
+    return ElfType { is32Bit, is32Bit ? (reinterpret_cast<Elf32_Ehdr 
*>(contents))->e_machine : (reinterpret_cast<Elf64_Ehdr 
*>(contents))->e_machine };
 }
 
 
 static void checkPointer(const FileContents & contents, void * p, unsigned int 
size)
 {
-    unsigned char * q = (unsigned char *) p;
-    assert(q >= contents->data() && q + size <= contents->data() + 
contents->size());
+    auto q = static_cast<unsigned char *>(p);
+    if (!(q >= contents->data() && q + size <= contents->data() + 
contents->size()))
+        error("data region extends past file end");
 }
 
 
 template<ElfFileParams>
-ElfFile<ElfFileParamNames>::ElfFile(FileContents fileContents)
-    : fileContents(fileContents)
+ElfFile<ElfFileParamNames>::ElfFile(FileContents fContents)
+    : fileContents(fContents)
     , contents(fileContents->data())
 {
     /* Check the ELF header for basic validity. */
@@ -403,13 +397,13 @@
     if (rdi(hdr->e_type) != ET_EXEC && rdi(hdr->e_type) != ET_DYN)
         error("wrong ELF type");
 
-    if ((size_t) (rdi(hdr->e_phoff) + rdi(hdr->e_phnum) * 
rdi(hdr->e_phentsize)) > fileContents->size())
+    if (rdi(hdr->e_phoff) + size_t(rdi(hdr->e_phnum) * rdi(hdr->e_phentsize)) 
> fileContents->size())
         error("program header table out of bounds");
 
     if (rdi(hdr->e_shnum) == 0)
         error("no section headers. The input file is probably a statically 
linked, self-decompressing binary");
 
-    if ((size_t) (rdi(hdr->e_shoff) + rdi(hdr->e_shnum) * 
rdi(hdr->e_shentsize)) > fileContents->size())
+    if (rdi(hdr->e_shoff) + size_t(rdi(hdr->e_shnum) * rdi(hdr->e_shentsize)) 
> fileContents->size())
         error("section header table out of bounds");
 
     if (rdi(hdr->e_phentsize) != sizeof(Elf_Phdr))
@@ -417,29 +411,41 @@
 
     /* Copy the program and section headers. */
     for (int i = 0; i < rdi(hdr->e_phnum); ++i) {
-        phdrs.push_back(* ((Elf_Phdr *) (contents + rdi(hdr->e_phoff)) + i));
+        Elf_Phdr *phdr = (Elf_Phdr *) (contents + rdi(hdr->e_phoff)) + i;
+
+        checkPointer(fileContents, phdr, sizeof(*phdr));
+        phdrs.push_back(*phdr);
         if (rdi(phdrs[i].p_type) == PT_INTERP) isExecutable = true;
     }
 
-    for (int i = 0; i < rdi(hdr->e_shnum); ++i)
-        shdrs.push_back(* ((Elf_Shdr *) (contents + rdi(hdr->e_shoff)) + i));
+    for (int i = 0; i < rdi(hdr->e_shnum); ++i) {
+        Elf_Shdr *shdr = (Elf_Shdr *) (contents + rdi(hdr->e_shoff)) + i;
+
+        checkPointer(fileContents, shdr, sizeof(*shdr));
+        shdrs.push_back(*shdr);
+    }
 
     /* Get the section header string table section (".shstrtab").  Its
        index in the section header table is given by e_shstrndx field
        of the ELF header. */
     unsigned int shstrtabIndex = rdi(hdr->e_shstrndx);
-    assert(shstrtabIndex < shdrs.size());
+    if (shstrtabIndex >= shdrs.size())
+        error("string table index out of bounds");
+
     unsigned int shstrtabSize = rdi(shdrs[shstrtabIndex].sh_size);
     char * shstrtab = (char * ) contents + rdi(shdrs[shstrtabIndex].sh_offset);
     checkPointer(fileContents, shstrtab, shstrtabSize);
 
-    assert(shstrtabSize > 0);
-    assert(shstrtab[shstrtabSize - 1] == 0);
+    if (shstrtabSize == 0)
+        error("string table size is zero");
+
+    if (shstrtab[shstrtabSize - 1] != 0)
+        error("string table is not zero terminated");
 
     sectionNames = std::string(shstrtab, shstrtabSize);
 
-    sectionsByOldIndex.resize(hdr->e_shnum);
-    for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
+    sectionsByOldIndex.resize(shdrs.size());
+    for (size_t i = 1; i < shdrs.size(); ++i)
         sectionsByOldIndex[i] = getSectionName(shdrs[i]);
 }
 
@@ -453,7 +459,7 @@
     // Architectures (and ABIs) can have different minimum section alignment
     // requirements. There is no authoritative list of these values. The
     // current list is extracted from GNU gold's source code (abi_pagesize).
-    switch (hdr->e_machine) {
+    switch (rdi(hdr->e_machine)) {
       case EM_SPARC:
       case EM_MIPS:
       case EM_PPC:
@@ -519,8 +525,7 @@
     wri(hdr->e_shstrndx, findSection3(shstrtabName));
 }
 
-
-static void writeFile(std::string fileName, FileContents contents)
+static void writeFile(const std::string & fileName, const FileContents & 
contents)
 {
     debug("writing %s\n", fileName.c_str());
 
@@ -541,7 +546,7 @@
 }
 
 
-static unsigned int roundUp(unsigned int n, unsigned int m)
+static uint64_t roundUp(uint64_t n, uint64_t m)
 {
     return ((n - 1) / m + 1) * m;
 }
@@ -594,7 +599,12 @@
 template<ElfFileParams>
 std::string ElfFile<ElfFileParamNames>::getSectionName(const Elf_Shdr & shdr) 
const
 {
-    return std::string(sectionNames.c_str() + rdi(shdr.sh_name));
+    const size_t name_off = rdi(shdr.sh_name);
+
+    if (name_off >= sectionNames.size())
+        error("section name offset out of bounds");
+
+    return std::string(sectionNames.c_str() + name_off);
 }
 
 
@@ -603,7 +613,7 @@
 {
     auto shdr = findSection2(sectionName);
     if (!shdr) {
-        std::string extraMsg = "";
+        std::string extraMsg;
         if (sectionName == ".interp" || sectionName == ".dynamic" || 
sectionName == ".dynstr")
             extraMsg = ". The input file is most likely statically linked";
         error("cannot find section '" + sectionName + "'" + extraMsg);
@@ -616,7 +626,7 @@
 Elf_Shdr * ElfFile<ElfFileParamNames>::findSection2(const SectionName & 
sectionName)
 {
     auto i = findSection3(sectionName);
-    return i ? &shdrs[i] : 0;
+    return i ? &shdrs[i] : nullptr;
 }
 
 
@@ -631,14 +641,14 @@
 template<ElfFileParams>
 bool ElfFile<ElfFileParamNames>::haveReplacedSection(const SectionName & 
sectionName) const
 {
-    return (replacedSections.find(sectionName) != replacedSections.end());
+    return replacedSections.count(sectionName);
 }
 
 template<ElfFileParams>
 std::string & ElfFile<ElfFileParamNames>::replaceSection(const SectionName & 
sectionName,
     unsigned int size)
 {
-    ReplacedSections::iterator i = replacedSections.find(sectionName);
+    auto i = replacedSections.find(sectionName);
     std::string s;
 
     if (i != replacedSections.end()) {
@@ -663,14 +673,15 @@
        *before* writing the new section contents (below) to prevent
        clobbering previously written new section contents. */
     for (auto & i : replacedSections) {
-        std::string sectionName = i.first;
+        const std::string & sectionName = i.first;
         Elf_Shdr & shdr = findSection(sectionName);
-        if (shdr.sh_type != SHT_NOBITS)
+        if (rdi(shdr.sh_type) != SHT_NOBITS)
             memset(contents + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size));
     }
 
+    std::set<unsigned int> noted_phdrs = {};
     for (auto & i : replacedSections) {
-        std::string sectionName = i.first;
+        const std::string & sectionName = i.first;
         auto & shdr = findSection(sectionName);
         Elf_Shdr orig_shdr = shdr;
         debug("rewriting section '%s' from offset 0x%x (size %d) to offset 
0x%x (size %d)\n",
@@ -688,23 +699,25 @@
         /* If this is the .interp section, then the PT_INTERP segment
            must be sync'ed with it. */
         if (sectionName == ".interp") {
-            for (unsigned int j = 0; j < phdrs.size(); ++j)
-                if (rdi(phdrs[j].p_type) == PT_INTERP) {
-                    phdrs[j].p_offset = shdr.sh_offset;
-                    phdrs[j].p_vaddr = phdrs[j].p_paddr = shdr.sh_addr;
-                    phdrs[j].p_filesz = phdrs[j].p_memsz = shdr.sh_size;
+            for (auto & phdr : phdrs) {
+                if (rdi(phdr.p_type) == PT_INTERP) {
+                    phdr.p_offset = shdr.sh_offset;
+                    phdr.p_vaddr = phdr.p_paddr = shdr.sh_addr;
+                    phdr.p_filesz = phdr.p_memsz = shdr.sh_size;
                 }
+            }
         }
 
         /* If this is the .dynamic section, then the PT_DYNAMIC segment
            must be sync'ed with it. */
-        if (sectionName == ".dynamic") {
-            for (unsigned int j = 0; j < phdrs.size(); ++j)
-                if (rdi(phdrs[j].p_type) == PT_DYNAMIC) {
-                    phdrs[j].p_offset = shdr.sh_offset;
-                    phdrs[j].p_vaddr = phdrs[j].p_paddr = shdr.sh_addr;
-                    phdrs[j].p_filesz = phdrs[j].p_memsz = shdr.sh_size;
+        else if (sectionName == ".dynamic") {
+            for (auto & phdr : phdrs) {
+                if (rdi(phdr.p_type) == PT_DYNAMIC) {
+                    phdr.p_offset = shdr.sh_offset;
+                    phdr.p_vaddr = phdr.p_paddr = shdr.sh_addr;
+                    phdr.p_filesz = phdr.p_memsz = shdr.sh_size;
                 }
+            }
         }
 
         /* If this is a note section, there might be a PT_NOTE segment that
@@ -721,7 +734,7 @@
                 shdr.sh_addralign = orig_shdr.sh_addralign;
 
             for (unsigned int j = 0; j < phdrs.size(); ++j)
-                if (rdi(phdrs[j].p_type) == PT_NOTE) {
+                if (rdi(phdrs[j].p_type) == PT_NOTE && !noted_phdrs.count(j)) {
                     Elf_Off p_start = rdi(phdrs[j].p_offset);
                     Elf_Off p_end = p_start + rdi(phdrs[j].p_filesz);
                     Elf_Off s_start = rdi(orig_shdr.sh_offset);
@@ -739,6 +752,8 @@
                     phdrs[j].p_offset = shdr.sh_offset;
                     phdrs[j].p_vaddr = phdrs[j].p_paddr = shdr.sh_addr;
                     phdrs[j].p_filesz = phdrs[j].p_memsz = shdr.sh_size;
+
+                    noted_phdrs.insert(j);
                 }
         }
 
@@ -757,19 +772,20 @@
        PT_LOAD segment located directly after the last virtual address
        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), getPageSize());
+    Elf_Addr firstPage = 0;
+    for (auto & phdr : phdrs) {
+        Elf_Addr thisPage = roundUp(rdi(phdr.p_vaddr) + rdi(phdr.p_memsz), 
getPageSize());
         if (thisPage > startPage) startPage = thisPage;
+        if (rdi(phdr.p_type) == PT_PHDR) firstPage = rdi(phdr.p_vaddr) - 
rdi(phdr.p_offset);
     }
 
     debug("last page is 0x%llx\n", (unsigned long long) startPage);
+    debug("first page is 0x%llx\n", (unsigned long long) firstPage);
 
     /* When normalizing note segments we will in the worst case be adding
        1 program header for each SHT_NOTE section. */
-    unsigned int num_notes = 0;
-    for (const auto & shdr : shdrs)
-        if (rdi(shdr.sh_type) == SHT_NOTE)
-            num_notes++;
+    unsigned int num_notes = std::count_if(shdrs.begin(), shdrs.end(),
+        [this](Elf_Shdr shdr) { return rdi(shdr.sh_type) == SHT_NOTE; });
 
     /* Because we're adding a new section header, we're necessarily increasing
        the size of the program header table.  This can cause the first section
@@ -778,19 +794,19 @@
     /* Some sections may already be replaced so account for that */
     unsigned int i = 1;
     Elf_Addr pht_size = sizeof(Elf_Ehdr) + (phdrs.size() + num_notes + 
1)*sizeof(Elf_Phdr);
-    while( shdrs[i].sh_addr <= pht_size && i < rdi(hdr->e_shnum) ) {
+    while( rdi(shdrs[i].sh_offset) <= pht_size && i < rdi(hdr->e_shnum) ) {
         if (not haveReplacedSection(getSectionName(shdrs[i])))
-            replaceSection(getSectionName(shdrs[i]), shdrs[i].sh_size);
+            replaceSection(getSectionName(shdrs[i]), rdi(shdrs[i].sh_size));
         i++;
     }
 
     /* Compute the total space needed for the replaced sections */
     off_t neededSpace = 0;
-    for (auto & i : replacedSections)
-        neededSpace += roundUp(i.second.size(), sectionAlignment);
+    for (auto & s : replacedSections)
+        neededSpace += roundUp(s.second.size(), sectionAlignment);
     debug("needed space is %d\n", neededSpace);
 
-    size_t startOffset = roundUp(fileContents->size(), getPageSize());
+    Elf_Off startOffset = roundUp(fileContents->size(), getPageSize());
 
     growFile(fileContents, startOffset + neededSpace);
 
@@ -835,7 +851,7 @@
     assert(curOff == startOffset + neededSpace);
 
     /* Write out the updated program and section headers */
-    rewriteHeaders(hdr->e_phoff);
+    rewriteHeaders(firstPage + rdi(hdr->e_phoff));
 }
 
 
@@ -851,7 +867,7 @@
     unsigned int lastReplaced = 0;
     for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) {
         std::string sectionName = getSectionName(shdrs[i]);
-        if (replacedSections.find(sectionName) != replacedSections.end()) {
+        if (replacedSections.count(sectionName)) {
             debug("using replaced section '%s'\n", sectionName.c_str());
             lastReplaced = i;
         }
@@ -882,13 +898,12 @@
             startAddr = rdi(shdr.sh_addr);
             lastReplaced = i - 1;
             break;
-        } else {
-            if (replacedSections.find(sectionName) == replacedSections.end()) {
-                debug("replacing section '%s' which is in the way\n", 
sectionName.c_str());
-                replaceSection(sectionName, rdi(shdr.sh_size));
-            }
         }
-        prevSection = sectionName;
+        if (!replacedSections.count(sectionName)) {
+            debug("replacing section '%s' which is in the way\n", 
sectionName.c_str());
+            replaceSection(sectionName, rdi(shdr.sh_size));
+        }
+        prevSection = std::move(sectionName);
     }
 
     debug("first reserved offset/addr is 0x%x/0x%llx\n",
@@ -971,16 +986,11 @@
        one of them has to be replaced. */
 
     /* We don't need to do anything if no note segments were replaced. */
-    bool replaced_note = false;
-    for (const auto & i : replacedSections) {
-        if (rdi(findSection(i.first).sh_type) == SHT_NOTE)
-            replaced_note = true;
-    }
+    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; });
     if (!replaced_note) return;
 
-    size_t orig_count = phdrs.size();
-    for (size_t i = 0; i < orig_count; ++i) {
-        auto & phdr = phdrs[i];
+    for (auto & phdr : phdrs) {
         if (rdi(phdr.p_type) != PT_NOTE) continue;
 
         size_t start_off = rdi(phdr.p_offset);
@@ -993,8 +1003,9 @@
             size_t size = 0;
             for (const auto & shdr : shdrs) {
                 if (rdi(shdr.sh_type) != SHT_NOTE) continue;
-                if (rdi(shdr.sh_offset) != curr_off) continue;
+                if (rdi(shdr.sh_offset) != roundUp(curr_off, 
rdi(shdr.sh_addralign))) continue;
                 size = rdi(shdr.sh_size);
+                curr_off = roundUp(curr_off, rdi(shdr.sh_addralign));
                 break;
             }
             if (size == 0)
@@ -1050,11 +1061,11 @@
 
     /* If there is a segment for the program header table, update it.
        (According to the ELF spec, there can only be one.) */
-    for (unsigned int i = 0; i < phdrs.size(); ++i) {
-        if (rdi(phdrs[i].p_type) == PT_PHDR) {
-            phdrs[i].p_offset = hdr->e_phoff;
-            wri(phdrs[i].p_vaddr, wri(phdrs[i].p_paddr, phdrAddress));
-            wri(phdrs[i].p_filesz, wri(phdrs[i].p_memsz, phdrs.size() * 
sizeof(Elf_Phdr)));
+    for (auto & phdr : phdrs) {
+        if (rdi(phdr.p_type) == PT_PHDR) {
+            phdr.p_offset = hdr->e_phoff;
+            wri(phdr.p_vaddr, wri(phdr.p_paddr, phdrAddress));
+            wri(phdr.p_filesz, wri(phdr.p_memsz, phdrs.size() * 
sizeof(Elf_Phdr)));
             break;
         }
     }
@@ -1078,7 +1089,7 @@
        (e.g., those produced by klibc's klcc). */
     auto shdrDynamic = findSection2(".dynamic");
     if (shdrDynamic) {
-        Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic->sh_offset));
+        auto dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic->sh_offset));
         unsigned int d_tag;
         for ( ; (d_tag = rdi(dyn->d_tag)) != DT_NULL; dyn++)
             if (d_tag == DT_STRTAB)
@@ -1129,14 +1140,14 @@
         if (rdi(shdrs[i].sh_type) != SHT_SYMTAB && rdi(shdrs[i].sh_type) != 
SHT_DYNSYM) continue;
         debug("rewriting symbol table section %d\n", i);
         for (size_t entry = 0; (entry + 1) * sizeof(Elf_Sym) <= 
rdi(shdrs[i].sh_size); entry++) {
-            Elf_Sym * sym = (Elf_Sym *) (contents + rdi(shdrs[i].sh_offset) + 
entry * sizeof(Elf_Sym));
+            auto sym = (Elf_Sym *)(contents + rdi(shdrs[i].sh_offset) + entry 
* sizeof(Elf_Sym));
             unsigned int shndx = rdi(sym->st_shndx);
             if (shndx != SHN_UNDEF && shndx < SHN_LORESERVE) {
                 if (shndx >= sectionsByOldIndex.size()) {
                     fprintf(stderr, "warning: entry %d in symbol table refers 
to a non-existent section, skipping\n", shndx);
                     continue;
                 }
-                std::string section = sectionsByOldIndex.at(shndx);
+                const std::string & section = sectionsByOldIndex.at(shndx);
                 assert(!section.empty());
                 auto newIndex = findSection3(section); // inefficient
                 //debug("rewriting symbol %d: index = %d (%s) -> %d\n", entry, 
shndx, section.c_str(), newIndex);
@@ -1179,9 +1190,9 @@
     char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset);
 
     /* Walk through the dynamic section, look for the DT_SONAME entry. */
-    Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
-    Elf_Dyn * dynSoname = 0;
-    char * soname = 0;
+    auto dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic.sh_offset));
+    Elf_Dyn * dynSoname = nullptr;
+    char * soname = nullptr;
     for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
         if (rdi(dyn->d_tag) == DT_SONAME) {
             dynSoname = dyn;
@@ -1191,7 +1202,7 @@
 
     if (op == printSoname) {
         if (soname) {
-            if (std::string(soname ? soname : "") == "")
+            if (strlen(soname) == 0)
                 debug("DT_SONAME is empty\n");
             else
                 printf("%s\n", soname);
@@ -1201,7 +1212,7 @@
         return;
     }
 
-    if (std::string(soname ? soname : "") == newSoname) {
+    if (soname && soname == newSoname) {
         debug("current and proposed new SONAMEs are equal keeping DT_SONAME 
entry\n");
         return;
     }
@@ -1280,9 +1291,9 @@
        generates a DT_RPATH and DT_RUNPATH pointing at the same
        string. */
     std::vector<std::string> neededLibs;
-    Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
-    Elf_Dyn * dynRPath = 0, * dynRunPath = 0;
-    char * rpath = 0;
+    auto dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic.sh_offset));
+    Elf_Dyn *dynRPath = nullptr, *dynRunPath = nullptr;
+    char * rpath = nullptr;
     for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
         if (rdi(dyn->d_tag) == DT_RPATH) {
             dynRPath = dyn;
@@ -1339,7 +1350,8 @@
                 if (!neededLibFound[j]) {
                     std::string libName = dirName + "/" + neededLibs[j];
                     try {
-                        if (getElfType(readFile(libName, 
sizeof(Elf32_Ehdr))).machine == rdi(hdr->e_machine)) {
+                        Elf32_Half library_e_machine = 
getElfType(readFile(libName, sizeof(Elf32_Ehdr))).machine;
+                        if (rdi(library_e_machine) == rdi(hdr->e_machine)) {
                             neededLibFound[j] = true;
                             libFound = true;
                         } else
@@ -1362,7 +1374,7 @@
             return;
         }
 
-        Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
+        dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic.sh_offset));
         Elf_Dyn * last = dyn;
         for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
             if (rdi(dyn->d_tag) == DT_RPATH) {
@@ -1383,19 +1395,23 @@
     if (!forceRPath && dynRPath && !dynRunPath) { /* convert DT_RPATH to 
DT_RUNPATH */
         wri(dynRPath->d_tag, DT_RUNPATH);
         dynRunPath = dynRPath;
-        dynRPath = 0;
+        dynRPath = nullptr;
         changed = true;
     } else if (forceRPath && dynRunPath) { /* convert DT_RUNPATH to DT_RPATH */
         wri(dynRunPath->d_tag, DT_RPATH);
         dynRPath = dynRunPath;
-        dynRunPath = 0;
+        dynRunPath = nullptr;
         changed = true;
     }
 
-    if (std::string(rpath ? rpath : "") == newRPath) {
+    if (rpath && rpath == newRPath) {
         return;
     }
 
+    if (op == rpAdd) {
+        newRPath = std::string(rpath ? rpath : "") + ":" + newRPath; 
+    }
+
     changed = true;
 
     /* Zero out the previous rpath to prevent retained dependencies in
@@ -1459,12 +1475,12 @@
     auto shdrDynStr = findSection(".dynstr");
     char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset);
 
-    Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
+    auto dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic.sh_offset));
     Elf_Dyn * last = dyn;
     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()) {
+            if (libs.count(name)) {
                 debug("removing DT_NEEDED entry '%s'\n", name);
                 changed = true;
             } else {
@@ -1487,7 +1503,7 @@
     auto shdrDynStr = findSection(".dynstr");
     char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset);
 
-    Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
+    auto dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic.sh_offset));
 
     unsigned int verNeedNum = 0;
 
@@ -1497,7 +1513,7 @@
         if (rdi(dyn->d_tag) == DT_NEEDED) {
             char * name = strTab + rdi(dyn->d_un.d_val);
             auto i = libs.find(name);
-            if (i != libs.end()) {
+            if (i != libs.end() && name != i->second) {
                 auto replacement = i->second;
 
                 debug("replacing DT_NEEDED entry '%s' with '%s'\n", name, 
replacement.c_str());
@@ -1545,11 +1561,11 @@
 
         unsigned int verStrAddedBytes = 0;
 
-        Elf_Verneed * need = (Elf_Verneed *) (contents + 
rdi(shdrVersionR.sh_offset));
+        auto need = (Elf_Verneed *)(contents + rdi(shdrVersionR.sh_offset));
         while (verNeedNum > 0) {
             char * file = verStrTab + rdi(need->vn_file);
             auto i = libs.find(file);
-            if (i != libs.end()) {
+            if (i != libs.end() && file != i->second) {
                 auto replacement = i->second;
 
                 debug("replacing .gnu.version_r entry '%s' with '%s'\n", file, 
replacement.c_str());
@@ -1582,12 +1598,15 @@
     auto shdrDynamic = findSection(".dynamic");
     auto shdrDynStr = findSection(".dynstr");
 
-    /* add all new libs to the dynstr string table */
     unsigned int length = 0;
-    for (auto & i : libs) length += i.size() + 1;
+
+    /* add all new libs to the dynstr string table */
+    for (auto &lib : libs)
+        length += lib.size() + 1;
 
     std::string & newDynStr = replaceSection(".dynstr",
         rdi(shdrDynStr.sh_size) + length + 1);
+
     std::set<Elf64_Xword> libStrings;
     unsigned int pos = 0;
     for (auto & i : libs) {
@@ -1644,8 +1663,8 @@
 {
     auto shdrDynamic = findSection(".dynamic");
 
-    Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
-    Elf_Dyn * dynFlags1 = 0;
+    auto dyn = (Elf_Dyn *)(contents + rdi(shdrDynamic.sh_offset));
+    auto dynFlags1 = (Elf_Dyn *)nullptr;
     for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
         if (rdi(dyn->d_tag) == DT_FLAGS_1) {
             dynFlags1 = dyn;
@@ -1687,9 +1706,9 @@
     auto shdrDynsym = findSection(".dynsym");
     auto shdrVersym = findSection(".gnu.version");
 
-    char * strTab = (char *) contents + rdi(shdrDynStr.sh_offset);
-    Elf_Sym * dynsyms = (Elf_Sym *) (contents + rdi(shdrDynsym.sh_offset));
-    Elf_Versym * versyms = (Elf_Versym *) (contents + 
rdi(shdrVersym.sh_offset));
+    auto strTab = (char *)contents + rdi(shdrDynStr.sh_offset);
+    auto dynsyms = (Elf_Sym *)(contents + rdi(shdrDynsym.sh_offset));
+    auto versyms = (Elf_Versym *)(contents + rdi(shdrVersym.sh_offset));
     size_t count = rdi(shdrDynsym.sh_size) / sizeof(Elf_Sym);
 
     if (count != rdi(shdrVersym.sh_size) / sizeof(Elf_Versym))
@@ -1698,7 +1717,7 @@
     for (size_t i = 0; i < count; i++) {
         auto dynsym = dynsyms[i];
         auto name = strTab + rdi(dynsym.st_name);
-        if (syms.find(name) != syms.end()) {
+        if (syms.count(name)) {
             debug("clearing symbol version for %s\n", name);
             wri(versyms[i], 1);
         }
@@ -1715,6 +1734,7 @@
 static std::vector<std::string> allowedRpathPrefixes;
 static bool removeRPath = false;
 static bool setRPath = false;
+static bool addRPath = false;
 static bool printRPath = false;
 static std::string newRPath;
 static std::set<std::string> neededLibsToRemove;
@@ -1725,7 +1745,7 @@
 static bool noDefaultLib = false;
 
 template<class ElfFile>
-static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, 
std::string fileName)
+static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, 
const std::string & fileName)
 {
     if (printInterpreter)
         printf("%s\n", elfFile.getInterpreter().c_str());
@@ -1736,7 +1756,7 @@
     if (setSoname)
         elfFile.modifySoname(elfFile.replaceSoname, newSoname);
 
-    if (newInterpreter != "")
+    if (!newInterpreter.empty())
         elfFile.setInterpreter(newInterpreter);
 
     if (printRPath)
@@ -1748,6 +1768,8 @@
         elfFile.modifyRPath(elfFile.rpRemove, {}, "");
     else if (setRPath)
         elfFile.modifyRPath(elfFile.rpSet, {}, newRPath);
+    else if (addRPath)
+        elfFile.modifyRPath(elfFile.rpAdd, {}, newRPath);
 
     if (printNeeded) elfFile.printNeededLibs();
 
@@ -1771,12 +1793,12 @@
 
 static void patchElf()
 {
-    for (auto fileName : fileNames) {
+    for (const auto & fileName : fileNames) {
         if (!printInterpreter && !printRPath && !printSoname && !printNeeded)
             debug("patching ELF file '%s'\n", fileName.c_str());
 
         auto fileContents = readFile(fileName);
-        std::string outputFileName2 = outputFileName.empty() ? fileName : 
outputFileName;
+        const std::string & outputFileName2 = outputFileName.empty() ? 
fileName : outputFileName;
 
         if (getElfType(fileContents).is32Bit)
             patchElf2(ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, 
Elf32_Off, Elf32_Dyn, Elf32_Sym, Elf32_Verneed, Elf32_Versym>(fileContents), 
fileContents, outputFileName2);
@@ -1795,6 +1817,7 @@
   [--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.\n\
   [--set-rpath RPATH]\n\
+  [--add-rpath RPATH]\n\
   [--remove-rpath]\n\
   [--shrink-rpath]\n\
   [--allowed-rpath-prefixes PREFIXES]\t\tWith '--shrink-rpath', reject rpath 
entries not starting with the allowed prefix\n\
@@ -1820,7 +1843,8 @@
         return 1;
     }
 
-    if (getenv("PATCHELF_DEBUG") != 0) debugMode = true;
+    if (getenv("PATCHELF_DEBUG") != nullptr)
+        debugMode = true;
 
     int i;
     for (i = 1; i < argc; ++i) {
@@ -1860,6 +1884,11 @@
             setRPath = true;
             newRPath = argv[i];
         }
+        else if (arg == "--add-rpath") {
+            if (++i == argc) error("missing argument");
+            addRPath = true;
+            newRPath = argv[i];
+        }
         else if (arg == "--print-rpath") {
             printRPath = true;
         }
@@ -1926,6 +1955,9 @@
     if (!outputFileName.empty() && fileNames.size() != 1)
         error("--output option only allowed with single input file");
 
+    if (setRPath && addRPath)
+        error("--set-rpath option not allowed with --add-rpath");
+
     patchElf();
 
     return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/Makefile.am 
new/patchelf-0.13.20210805.a949ff2/tests/Makefile.am
--- old/patchelf-0.12.20200827.8d3a16e/tests/Makefile.am        1970-01-01 
01:00:01.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/Makefile.am        1970-01-01 
01:00:01.000000000 +0100
@@ -1,6 +1,6 @@
 LIBS =
 
-check_PROGRAMS = simple main main-scoped big-dynstr no-rpath
+check_PROGRAMS = simple main main-scoped big-dynstr no-rpath 
contiguous_note_sections
 
 no_rpath_arch_TESTS = \
   no-rpath-amd64.sh \
@@ -20,19 +20,23 @@
 
 src_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 \
+  set-interpreter-long.sh set-rpath.sh add-rpath.sh no-rpath.sh big-dynstr.sh \
   set-rpath-library.sh soname.sh shrink-rpath-with-allowed-prefixes.sh \
   force-rpath.sh \
   plain-needed.sh \
   output-flag.sh \
-  build-id.sh
+  no-rpath-pie-powerpc.sh \
+  build-id.sh \
+  invalid-elf.sh \
+  endianness.sh \
+  contiguous_note_sections.sh
 
 build_TESTS = \
   $(no_rpath_arch_TESTS)
 
 TESTS = $(src_TESTS) $(build_TESTS)
 
-EXTRA_DIST = no-rpath-prebuild $(src_TESTS) no-rpath-prebuild.sh
+EXTRA_DIST = no-rpath-prebuild $(src_TESTS) no-rpath-prebuild.sh invalid-elf 
endianness
 
 TESTS_ENVIRONMENT = PATCHELF_DEBUG=1
 
@@ -104,3 +108,7 @@
 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_CFLAGS = -pie
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/add-rpath.sh 
new/patchelf-0.13.20210805.a949ff2/tests/add-rpath.sh
--- old/patchelf-0.12.20200827.8d3a16e/tests/add-rpath.sh       1970-01-01 
01:00:00.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/add-rpath.sh       1970-01-01 
01:00:01.000000000 +0100
@@ -0,0 +1,26 @@
+#! /bin/sh -e
+SCRATCH=scratch/$(basename $0 .sh)
+
+rm -rf ${SCRATCH}
+mkdir -p ${SCRATCH}
+mkdir -p ${SCRATCH}/libsA
+mkdir -p ${SCRATCH}/libsB
+
+cp main ${SCRATCH}/
+cp libfoo.so ${SCRATCH}/libsA/
+cp libbar.so ${SCRATCH}/libsB/
+
+../src/patchelf --force-rpath --add-rpath $(pwd)/${SCRATCH}/libsA 
${SCRATCH}/main
+../src/patchelf --force-rpath --add-rpath $(pwd)/${SCRATCH}/libsB 
${SCRATCH}/main
+
+if test "$(uname)" = FreeBSD; then
+    export LD_LIBRARY_PATH=$(pwd)/${SCRATCH}/libsB
+fi
+
+exitCode=0
+(cd ${SCRATCH} && ./main) || exitCode=$?
+
+if test "$exitCode" != 46; then
+    echo "bad exit code!"
+    exit 1
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/contiguous_note_sections.ld 
new/patchelf-0.13.20210805.a949ff2/tests/contiguous_note_sections.ld
--- old/patchelf-0.12.20200827.8d3a16e/tests/contiguous_note_sections.ld        
1970-01-01 01:00:00.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/contiguous_note_sections.ld        
1970-01-01 01:00:01.000000000 +0100
@@ -0,0 +1,24 @@
+PHDRS
+{
+  headers PT_PHDR PHDRS ;
+  notes PT_NOTE;
+  text PT_LOAD FILEHDR PHDRS ;
+  data PT_LOAD ;
+  interp PT_INTERP ;
+  dynamic PT_DYNAMIC ;
+}
+
+SECTIONS
+{
+  . = SIZEOF_HEADERS;
+  . = ALIGN(4);
+
+  .note.my-section0 : { *(.note.my-section0) } :notes :text
+  .note.my-section1 : { *(.note.my-section1) } :notes :text
+
+  .interp : { *(.interp) } :text :interp
+  .text : { *(.text) } :text
+  .rodata : { *(.rodata) } /* defaults to :text */
+
+  .data : { *(.data) } :data
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/contiguous_note_sections.s 
new/patchelf-0.13.20210805.a949ff2/tests/contiguous_note_sections.s
--- old/patchelf-0.12.20200827.8d3a16e/tests/contiguous_note_sections.s 
1970-01-01 01:00:00.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/contiguous_note_sections.s 
1970-01-01 01:00:01.000000000 +0100
@@ -0,0 +1,23 @@
+/*
+ * Testcase for error:
+ * patchelf: cannot normalize PT_NOTE segment: non-contiguous SHT_NOTE sections
+ */
+.section ".note.my-section0", "a", @note
+    .align 4
+    .long 1f - 0f              /* name length (not including padding) */
+    .long 3f - 2f              /* desc length (not including padding) */
+    .long 1                    /* type = NT_VERSION */
+0:  .asciz "my-version-12345" /* name */
+1:  .align 4
+2:  .long 1                    /* desc - toolchain version number, 32-bit LE */
+3:  .align 4
+
+.section ".note.my-section1", "a", @note
+    .align 8
+    .long 1f - 0f              /* name length (not including padding) */
+    .long 3f - 2f              /* desc length (not including padding) */
+    .long 1                    /* type = NT_VERSION */
+0:  .asciz "my-version-1" /* name */
+1:  .align 4
+2:  .long 1                    /* desc - toolchain version number, 32-bit LE */
+3:  .align 4
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/contiguous_note_sections.sh 
new/patchelf-0.13.20210805.a949ff2/tests/contiguous_note_sections.sh
--- old/patchelf-0.12.20200827.8d3a16e/tests/contiguous_note_sections.sh        
1970-01-01 01:00:00.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/contiguous_note_sections.sh        
1970-01-01 01:00:01.000000000 +0100
@@ -0,0 +1,6 @@
+#! /bin/sh -e
+
+# Running --set-interpreter on this binary should not produce the following
+# error:
+# patchelf: cannot normalize PT_NOTE segment: non-contiguous SHT_NOTE sections
+../src/patchelf --set-interpreter ld-linux-x86-64.so.2 contiguous_note_sections
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/endianness/Makefile 
new/patchelf-0.13.20210805.a949ff2/tests/endianness/Makefile
--- old/patchelf-0.12.20200827.8d3a16e/tests/endianness/Makefile        
1970-01-01 01:00:00.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/endianness/Makefile        
1970-01-01 01:00:01.000000000 +0100
@@ -0,0 +1,3 @@
+all:
+       $(CC) -xc -nostdlib -shared -o libtest.so - <<< 'void test() {}'
+       $(CC) -xc -nostdlib -L. -ltest -o main - <<< 'void _start() {}'
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/endianness/ppc64/libtest.so and 
new/patchelf-0.13.20210805.a949ff2/tests/endianness/ppc64/libtest.so differ
Binary files old/patchelf-0.12.20200827.8d3a16e/tests/endianness/ppc64/main and 
new/patchelf-0.13.20210805.a949ff2/tests/endianness/ppc64/main differ
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/endianness/ppc64le/libtest.so and 
new/patchelf-0.13.20210805.a949ff2/tests/endianness/ppc64le/libtest.so differ
Binary files old/patchelf-0.12.20200827.8d3a16e/tests/endianness/ppc64le/main 
and new/patchelf-0.13.20210805.a949ff2/tests/endianness/ppc64le/main differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/endianness.sh 
new/patchelf-0.13.20210805.a949ff2/tests/endianness.sh
--- old/patchelf-0.12.20200827.8d3a16e/tests/endianness.sh      1970-01-01 
01:00:00.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/endianness.sh      1970-01-01 
01:00:01.000000000 +0100
@@ -0,0 +1,24 @@
+#! /bin/sh -e
+SCRATCH=scratch/$(basename $0 .sh)
+PATCHELF="../src/patchelf"
+
+for arch in ppc64 ppc64le; do
+    rm -rf ${SCRATCH}
+    mkdir -p ${SCRATCH}
+
+    cp endianness/${arch}/main endianness/${arch}/libtest.so ${SCRATCH}/
+
+    rpath="${PWD}/${SCRATCH}"
+
+    # set rpath to scratch dir
+    ${PATCHELF} --output ${SCRATCH}/main-rpath --set-rpath $rpath 
${SCRATCH}/main
+
+    # attempt to shrink rpath, should not result in empty rpath
+    ${PATCHELF} --output ${SCRATCH}/main-shrunk --shrink-rpath --debug 
${SCRATCH}/main-rpath 
+
+    # 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
+    fi
+done
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/invalid-elf/invalid-phdr-offset and 
new/patchelf-0.13.20210805.a949ff2/tests/invalid-elf/invalid-phdr-offset differ
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/invalid-elf/invalid-shdr-name and 
new/patchelf-0.13.20210805.a949ff2/tests/invalid-elf/invalid-shdr-name differ
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/invalid-elf/invalid-shrstrtab-idx and 
new/patchelf-0.13.20210805.a949ff2/tests/invalid-elf/invalid-shrstrtab-idx 
differ
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/invalid-elf/invalid-shrstrtab-nonterm 
and 
new/patchelf-0.13.20210805.a949ff2/tests/invalid-elf/invalid-shrstrtab-nonterm 
differ
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/invalid-elf/invalid-shrstrtab-size and 
new/patchelf-0.13.20210805.a949ff2/tests/invalid-elf/invalid-shrstrtab-size 
differ
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/invalid-elf/invalid-shrstrtab-zero and 
new/patchelf-0.13.20210805.a949ff2/tests/invalid-elf/invalid-shrstrtab-zero 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/invalid-elf.sh 
new/patchelf-0.13.20210805.a949ff2/tests/invalid-elf.sh
--- old/patchelf-0.12.20200827.8d3a16e/tests/invalid-elf.sh     1970-01-01 
01:00:00.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/invalid-elf.sh     1970-01-01 
01:00:01.000000000 +0100
@@ -0,0 +1,40 @@
+#! /bin/sh -u
+
+# Usage: killed_by_signal $?
+#
+# Returns true if the exit code indicates that the program was killed
+# by a signal. This works because the exit code of processes that were
+# killed by a signal is 128 plus the signal number.
+killed_by_signal() {
+    [ $1 -ge 128 ]
+}
+
+
+# The directory containing all our input files.
+TEST_DIR=$(dirname $(readlink -f $0))/invalid-elf
+
+# Each test case is listed here. The names should roughly indicate
+# what makes the given ELF file invalid.
+TEST_CASES="invalid-shrstrtab-idx invalid-shrstrtab-size invalid-shrstrtab-zero
+            invalid-shrstrtab-nonterm invalid-shdr-name invalid-phdr-offset"
+
+FAILED_TESTS=""
+
+for tcase in $TEST_CASES; do
+    if [ ! -r "$TEST_DIR/$tcase" ]; then
+       echo "Cannot read test case: $tcase"
+       exit 1
+    fi
+
+    ../src/patchelf --output /dev/null "$TEST_DIR/$tcase"
+    if killed_by_signal $?; then
+       FAILED_TESTS="$FAILED_TESTS $tcase"
+    fi
+done
+
+if [ -z "$FAILED_TESTS" ]; then
+    exit 0
+else
+    echo "Failed tests: $FAILED_TESTS"
+    exit 1
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/no-rpath-pie-powerpc.sh 
new/patchelf-0.13.20210805.a949ff2/tests/no-rpath-pie-powerpc.sh
--- old/patchelf-0.12.20200827.8d3a16e/tests/no-rpath-pie-powerpc.sh    
1970-01-01 01:00:00.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/no-rpath-pie-powerpc.sh    
1970-01-01 01:00:01.000000000 +0100
@@ -0,0 +1,54 @@
+#! /bin/sh -e
+set -x
+SCRATCH=scratch/no-rpath-pie-powerpc
+
+no_rpath_bin="${srcdir}/no-rpath-prebuild/no-rpath-pie-powerpc"
+
+if [ ! -f $no_rpath_bin ]; then
+  echo "no 'no-rpath' binary for '$ARCH' in '${srcdir}/no-rpath-prebuild'"
+  exit 1
+fi
+
+rm -rf ${SCRATCH}
+mkdir -p ${SCRATCH}
+
+cp $no_rpath_bin ${SCRATCH}/no-rpath
+
+oldRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath)
+if test -n "$oldRPath"; then exit 1; fi
+../src/patchelf \
+  --set-interpreter "$(../src/patchelf --print-interpreter ../src/patchelf)" \
+  --set-rpath /foo:/bar:/xxxxxxxxxxxxxxx ${SCRATCH}/no-rpath
+
+newRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath)
+if ! echo "$newRPath" | grep -q '/foo:/bar'; then
+    echo "incomplete RPATH"
+    exit 1
+fi
+
+# Tests for powerpc PIE endianness regressions
+readelfData=$(readelf -l ${SCRATCH}/no-rpath 2>&1)
+
+if [ $(echo "$readelfData" | grep --count "PHDR") != 1 ]; then
+  # Triggered if PHDR errors appear on stderr
+  echo "Unexpected number of occurences of PHDR in readelf results"
+  exit 1
+fi
+
+virtAddr=$(echo "$readelfData" | grep "PHDR" | awk '{print $3}')
+if [ "$virtAddr" != "0x00000034" ]; then
+  # Triggered if the virtual address is the incorrect endianness
+  echo "Unexpected virt addr, expected [0x00000034] got [$virtAddr]"
+  exit 1
+fi
+
+echo "$readelfData" | grep "LOAD" | while read -r line ; do
+  align=$(echo "$line" | awk '{print $NF}')
+  if [ "$align" != "0x10000" ]; then
+    # Triggered if the target arch was not detected properly
+    echo "Unexpected Align for LOAD segment, expected [0x10000] got [$align]"
+    echo "Load segment: [$line]"
+    exit 1
+  fi
+done
+
Binary files 
old/patchelf-0.12.20200827.8d3a16e/tests/no-rpath-prebuild/no-rpath-pie-powerpc 
and 
new/patchelf-0.13.20210805.a949ff2/tests/no-rpath-prebuild/no-rpath-pie-powerpc 
differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/tests/plain-needed.sh 
new/patchelf-0.13.20210805.a949ff2/tests/plain-needed.sh
--- old/patchelf-0.12.20200827.8d3a16e/tests/plain-needed.sh    1970-01-01 
01:00:01.000000000 +0100
+++ new/patchelf-0.13.20210805.a949ff2/tests/plain-needed.sh    1970-01-01 
01:00:01.000000000 +0100
@@ -1,4 +1,25 @@
 #! /bin/sh
 set -e
+
+SCRATCH=scratch/$(basename $0 .sh)
+MAIN_ELF="${SCRATCH}/main"
+
+PATCHELF="../src/patchelf"
+
+rm -rf ${SCRATCH}
+mkdir -p ${SCRATCH}
+cp main ${SCRATCH}/
+
 echo "Confirming main requires libfoo"
-../src/patchelf --print-needed main | grep -q libfoo.so
+${PATCHELF} --print-needed "${MAIN_ELF}" | grep -q libfoo.so
+
+echo "Testing --add-needed functionality"
+${PATCHELF} --add-needed bar.so "${MAIN_ELF}"
+${PATCHELF} --print-needed "${MAIN_ELF}" | grep -q bar.so
+
+echo "Testing --remove-needed functionality"
+${PATCHELF} --remove-needed bar.so "${MAIN_ELF}"
+if ${PATCHELF} --print-needed "${MAIN_ELF}" | grep -q bar.so; then
+       echo "ERROR: --remove-needed did not eliminate bar.so!"
+       exit 1
+fi
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' --exclude Makefile.in --exclude configure --exclude 
config.guess --exclude '*.pot' --exclude mkinstalldirs --exclude aclocal.m4 
--exclude config.sub --exclude depcomp --exclude install-sh --exclude ltmain.sh 
old/patchelf-0.12.20200827.8d3a16e/version 
new/patchelf-0.13.20210805.a949ff2/version
--- old/patchelf-0.12.20200827.8d3a16e/version  2020-08-27 14:12:55.000000000 
+0200
+++ new/patchelf-0.13.20210805.a949ff2/version  2021-08-05 14:55:29.000000000 
+0200
@@ -1 +1 @@
-0.12.20200827.8d3a16e
+0.13.20210805.a949ff2

Reply via email to