[neon/qt/pyside2/Neon/release] debian: Do not use patchelf to change RPATH, not needed in Debian.

Dmitry Shachnev null at kde.org
Thu Jul 25 03:06:04 BST 2024


Git commit db83fe3d93a9d419f69cfc6991c3bd5b68f4833a by Dmitry Shachnev.
Committed on 25/01/2024 at 11:23.
Pushed by carlosdem into branch 'Neon/release'.

Do not use patchelf to change RPATH, not needed in Debian.

M  +1    -0    debian/changelog
M  +0    -1    debian/control
A  +37   -0    debian/patches/Do-not-change-RPATH.patch
M  +1    -1    debian/patches/series
D  +0    -3117 debian/patches/update-patchelf.patch

https://invent.kde.org/neon/qt/pyside2/-/commit/db83fe3d93a9d419f69cfc6991c3bd5b68f4833a

diff --git a/debian/changelog b/debian/changelog
index 40b7254c..162c3071 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -2,6 +2,7 @@ pyside2 (5.15.12-3) UNRELEASED; urgency=medium
 
   [ Dmitry Shachnev ]
   * Backport upstream change to stop using imp module.
+  * Do not use patchelf to change RPATH, not needed in Debian.
 
  -- Debian Qt/KDE Maintainers <debian-qt-kde at lists.debian.org>  Thu, 25 Jan 2024 13:48:45 +0300
 
diff --git a/debian/control b/debian/control
index 706b3310..717b9835 100644
--- a/debian/control
+++ b/debian/control
@@ -27,7 +27,6 @@ Build-Depends: chrpath,
                libxml2-dev,
                libxslt1-dev,
                llvm-15-dev,
-               patchelf [!mips64el],
                python3-dev,
                python3-distro,
                python3-setuptools,
diff --git a/debian/patches/Do-not-change-RPATH.patch b/debian/patches/Do-not-change-RPATH.patch
new file mode 100644
index 00000000..2e3dc190
--- /dev/null
+++ b/debian/patches/Do-not-change-RPATH.patch
@@ -0,0 +1,37 @@
+From: Dmitry Shachnev <mitya57 at debian.org>
+Date: Thu, 25 Jan 2024 14:21:09 +0300
+Subject: Do not change RPATH
+
+Forwarded: not-needed
+---
+ build_scripts/main.py           | 3 ---
+ build_scripts/platforms/unix.py | 5 -----
+ 2 files changed, 8 deletions(-)
+
+diff --git a/build_scripts/main.py b/build_scripts/main.py
+index 23b37c5..25c0cf3 100644
+--- a/build_scripts/main.py
++++ b/build_scripts/main.py
+@@ -631,9 +631,6 @@ class PysideBuild(_build, DistUtilsCommandMixin):
+                 log.info("Created {}".format(build_history))
+ 
+         if not OPTION["SKIP_PACKAGING"]:
+-            # Build patchelf if needed
+-            self.build_patchelf()
+-
+             # Prepare packages
+             self.prepare_packages()
+ 
+diff --git a/build_scripts/platforms/unix.py b/build_scripts/platforms/unix.py
+index b842510..8df0e73 100644
+--- a/build_scripts/platforms/unix.py
++++ b/build_scripts/platforms/unix.py
+@@ -220,8 +220,3 @@ def prepare_packages_posix(self, vars):
+         if config.is_internal_shiboken_generator_build():
+             # Copy over clang before rpath patching.
+             self.prepare_standalone_clang(is_win=False)
+-
+-    # Update rpath to $ORIGIN
+-    if sys.platform.startswith('linux') or sys.platform.startswith('darwin'):
+-        rpath_path = "{st_build_dir}/{st_package_name}".format(**vars)
+-        self.update_rpath(rpath_path, executables)
diff --git a/debian/patches/series b/debian/patches/series
index f5ce1f26..8e07fce3 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,6 +1,5 @@
 update-sip-import.patch
 fix-spelling-errors.patch
-update-patchelf.patch
 blacklist-failing-tests.patch
 test-with-current-interpreter.patch
 Shiboken-Fix-the-oldest-shiboken-bug-ever.patch
@@ -10,3 +9,4 @@ Python-3.12-Fix-the-structure-of-class-property.patch
 Support-running-PySide-on-Python-3.12.patch
 Final-details-to-enable-3.12-wheel-compatibility.patch
 Stop-using-imp-module.patch
+Do-not-change-RPATH.patch
diff --git a/debian/patches/update-patchelf.patch b/debian/patches/update-patchelf.patch
deleted file mode 100644
index b46fe05e..00000000
--- a/debian/patches/update-patchelf.patch
+++ /dev/null
@@ -1,3117 +0,0 @@
-From: Debian Qt/KDE Maintainers <debian-qt-kde at lists.debian.org>
-Date: Tue, 5 Nov 2019 10:39:14 +0100
-Subject: update-patchelf
-MIME-Version: 1.0
-Content-Type: text/plain; charset="utf-8"
-Content-Transfer-Encoding: 8bit
-
-Update patchelf to current git version
-
-The current version fixes a bug which broke the ability to strip
-binaries with debug symbols:
-https://github.com/NixOS/patchelf/pull/117
-
-With the former version of patchelf, I would get "not enough room for
-program headers, try linking with -N" when trying to strip the binaries.
-
-This patch brings patchelf in sync with the commit
-27ffe8ae871e7a186018d66020ef3f6162c12c69 of patchelf's git
-repository.
-
-Also update patchelf's build process to match the logic in upstream's
-automake files (thanks to Frédéric Bonnard for the patch to properly use
-getconf PAGESIZE).
-
-Bug: https://bugreports.qt.io/browse/PYSIDE-740
-Last-Update: 2018-07-09
----
- build_scripts/main.py        |   13 +-
- sources/patchelf/elf.h       | 1064 +++++++++++++++++++++++++++++++---------
- sources/patchelf/patchelf.cc | 1101 +++++++++++++++++++++++++++++++-----------
- 3 files changed, 1673 insertions(+), 505 deletions(-)
-
-diff --git a/build_scripts/main.py b/build_scripts/main.py
-index f748455..23b37c5 100644
---- a/build_scripts/main.py
-+++ b/build_scripts/main.py
-@@ -715,7 +715,18 @@ class PysideBuild(_build, DistUtilsCommandMixin):
-             return
-         log.info("Building patchelf...")
-         module_src_dir = os.path.join(self.sources_dir, "patchelf")
--        build_cmd = ["g++", "{}/patchelf.cc".format(module_src_dir), "-o", "patchelf"]
-+        import subprocess
-+        pagesize = subprocess.check_output("getconf PAGESIZE", shell=True).decode('utf-8').rstrip()
-+        build_cmd = [
-+            "g++",
-+            "-std=c++11",
-+            "-DPAGESIZE=%s" % (pagesize),
-+            '-DPACKAGE_STRING="patchelf"',
-+            "-D_FILE_OFFSET_BITS=64",
-+            "{}/patchelf.cc".format(module_src_dir),
-+            "-o",
-+            "patchelf",
-+        ]
-         if run_process(build_cmd) != 0:
-             raise DistutilsSetupError("Error building patchelf")
-         self._patchelf_path = os.path.join(self.script_dir, "patchelf")
-diff --git a/sources/patchelf/elf.h b/sources/patchelf/elf.h
-index b897f5b..87cb141 100644
---- a/sources/patchelf/elf.h
-+++ b/sources/patchelf/elf.h
-@@ -1,6 +1,5 @@
- /* This file defines standard ELF types, structures, and macros.
--   Copyright (C) 1995-2003,2004,2005,2006,2007,2008
--	Free Software Foundation, Inc.
-+   Copyright (C) 1995-2014 Free Software Foundation, Inc.
-    This file is part of the GNU C Library.
- 
-    The GNU C Library is free software; you can redistribute it and/or
-@@ -14,13 +13,16 @@
-    Lesser General Public License for more details.
- 
-    You should have received a copy of the GNU Lesser General Public
--   License along with the GNU C Library; if not, write to the Free
--   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
--   02111-1307 USA.  */
-+   License along with the GNU C Library; if not, see
-+   <http://www.gnu.org/licenses/>.  */
- 
- #ifndef _ELF_H
- #define	_ELF_H 1
- 
-+/* #include <features.h> */
-+
-+/* __BEGIN_DECLS */
-+
- /* Standard ELF types.  */
- 
- #include <stdint.h>
-@@ -138,7 +140,8 @@ typedef struct
- #define ELFOSABI_SYSV		0	/* Alias.  */
- #define ELFOSABI_HPUX		1	/* HP-UX */
- #define ELFOSABI_NETBSD		2	/* NetBSD.  */
--#define ELFOSABI_LINUX		3	/* Linux.  */
-+#define ELFOSABI_GNU		3	/* Object uses GNU ELF extensions.  */
-+#define ELFOSABI_LINUX		ELFOSABI_GNU /* Compatibility alias.  */
- #define ELFOSABI_SOLARIS	6	/* Sun Solaris.  */
- #define ELFOSABI_AIX		7	/* IBM AIX.  */
- #define ELFOSABI_IRIX		8	/* SGI Irix.  */
-@@ -146,6 +149,7 @@ typedef struct
- #define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX.  */
- #define ELFOSABI_MODESTO	11	/* Novell Modesto.  */
- #define ELFOSABI_OPENBSD	12	/* OpenBSD.  */
-+#define ELFOSABI_ARM_AEABI	64	/* ARM EABI */
- #define ELFOSABI_ARM		97	/* ARM */
- #define ELFOSABI_STANDALONE	255	/* Standalone (embedded) application */
- 
-@@ -245,7 +249,11 @@ typedef struct
- #define EM_OPENRISC	92		/* OpenRISC 32-bit embedded processor */
- #define EM_ARC_A5	93		/* ARC Cores Tangent-A5 */
- #define EM_XTENSA	94		/* Tensilica Xtensa Architecture */
--#define EM_NUM		95
-+#define EM_AARCH64	183		/* ARM AARCH64 */
-+#define EM_TILEPRO	188		/* Tilera TILEPro */
-+#define EM_MICROBLAZE	189		/* Xilinx MicroBlaze */
-+#define EM_TILEGX	191		/* Tilera TILE-Gx */
-+#define EM_NUM		192
- 
- /* If it is necessary to assign new unofficial EM_* values, please
-    pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the
-@@ -440,6 +448,7 @@ typedef struct
- #define STB_WEAK	2		/* Weak symbol */
- #define	STB_NUM		3		/* Number of defined types.  */
- #define STB_LOOS	10		/* Start of OS-specific */
-+#define STB_GNU_UNIQUE	10		/* Unique symbol.  */
- #define STB_HIOS	12		/* End of OS-specific */
- #define STB_LOPROC	13		/* Start of processor-specific */
- #define STB_HIPROC	15		/* End of processor-specific */
-@@ -455,6 +464,7 @@ typedef struct
- #define STT_TLS		6		/* Symbol is thread-local data object*/
- #define	STT_NUM		7		/* Number of defined types.  */
- #define STT_LOOS	10		/* Start of OS-specific */
-+#define STT_GNU_IFUNC	10		/* Symbol is indirect code object */
- #define STT_HIOS	12		/* End of OS-specific */
- #define STT_LOPROC	13		/* Start of processor-specific */
- #define STT_HIPROC	15		/* End of processor-specific */
-@@ -552,6 +562,12 @@ typedef struct
-   Elf64_Xword	p_align;		/* Segment alignment */
- } Elf64_Phdr;
- 
-+/* Special value for e_phnum.  This indicates that the real number of
-+   program headers is too large to fit into e_phnum.  Instead the real
-+   value is in the field sh_info of section 0.  */
-+
-+#define PN_XNUM		0xffff
-+
- /* Legal values for p_type (segment type).  */
- 
- #define	PT_NULL		0		/* Program header table entry unused */
-@@ -601,10 +617,30 @@ typedef struct
- #define NT_LWPSTATUS	16		/* Contains copy of lwpstatus struct */
- #define NT_LWPSINFO	17		/* Contains copy of lwpinfo struct */
- #define NT_PRFPXREG	20		/* Contains copy of fprxregset struct */
-+#define NT_SIGINFO	0x53494749	/* Contains copy of siginfo_t,
-+					   size might increase */
-+#define NT_FILE		0x46494c45	/* Contains information about mapped
-+					   files */
- #define NT_PRXFPREG	0x46e62b7f	/* Contains copy of user_fxsr_struct */
- #define NT_PPC_VMX	0x100		/* PowerPC Altivec/VMX registers */
- #define NT_PPC_SPE	0x101		/* PowerPC SPE/EVR registers */
-+#define NT_PPC_VSX	0x102		/* PowerPC VSX registers */
- #define NT_386_TLS	0x200		/* i386 TLS slots (struct user_desc) */
-+#define NT_386_IOPERM	0x201		/* x86 io permission bitmap (1=deny) */
-+#define NT_X86_XSTATE	0x202		/* x86 extended state using xsave */
-+#define NT_S390_HIGH_GPRS	0x300	/* s390 upper register halves */
-+#define NT_S390_TIMER	0x301		/* s390 timer register */
-+#define NT_S390_TODCMP	0x302		/* s390 TOD clock comparator register */
-+#define NT_S390_TODPREG	0x303		/* s390 TOD programmable register */
-+#define NT_S390_CTRS	0x304		/* s390 control registers */
-+#define NT_S390_PREFIX	0x305		/* s390 prefix register */
-+#define NT_S390_LAST_BREAK	0x306	/* s390 breaking event address */
-+#define NT_S390_SYSTEM_CALL	0x307	/* s390 system call restart data */
-+#define NT_S390_TDB	0x308		/* s390 transaction diagnostic block */
-+#define NT_ARM_VFP	0x400		/* ARM VFP/NEON registers */
-+#define NT_ARM_TLS	0x401		/* ARM TLS register */
-+#define NT_ARM_HW_BREAK	0x402		/* ARM hardware breakpoint registers */
-+#define NT_ARM_HW_WATCH	0x403		/* ARM hardware watchpoint registers */
- 
- /* Legal values for the note segment descriptor types for object files.  */
- 
-@@ -768,6 +804,15 @@ typedef struct
- #define DF_1_ENDFILTEE	0x00004000	/* Filtee terminates filters search. */
- #define	DF_1_DISPRELDNE	0x00008000	/* Disp reloc applied at build time. */
- #define	DF_1_DISPRELPND	0x00010000	/* Disp reloc applied at run-time.  */
-+#define	DF_1_NODIRECT	0x00020000	/* Object has no-direct binding. */
-+#define	DF_1_IGNMULDEF	0x00040000
-+#define	DF_1_NOKSYMS	0x00080000
-+#define	DF_1_NOHDR	0x00100000
-+#define	DF_1_EDITED	0x00200000	/* Object is modified after built.  */
-+#define	DF_1_NORELOC	0x00400000
-+#define	DF_1_SYMINTPOSE	0x00800000	/* Object has individual interposers.  */
-+#define	DF_1_GLOBAUDIT	0x01000000	/* Global auditing required.  */
-+#define	DF_1_SINGLETON	0x02000000	/* Singleton symbols are used.  */
- 
- /* Flags for the feature selection in DT_FEATURE_1.  */
- #define DTF_1_PARINIT	0x00000001
-@@ -927,59 +972,7 @@ typedef struct
-     } a_un;
- } Elf64_auxv_t;
- 
--/* Legal values for a_type (entry type).  */
--
--#define AT_NULL		0		/* End of vector */
--#define AT_IGNORE	1		/* Entry should be ignored */
--#define AT_EXECFD	2		/* File descriptor of program */
--#define AT_PHDR		3		/* Program headers for program */
--#define AT_PHENT	4		/* Size of program header entry */
--#define AT_PHNUM	5		/* Number of program headers */
--#define AT_PAGESZ	6		/* System page size */
--#define AT_BASE		7		/* Base address of interpreter */
--#define AT_FLAGS	8		/* Flags */
--#define AT_ENTRY	9		/* Entry point of program */
--#define AT_NOTELF	10		/* Program is not ELF */
--#define AT_UID		11		/* Real uid */
--#define AT_EUID		12		/* Effective uid */
--#define AT_GID		13		/* Real gid */
--#define AT_EGID		14		/* Effective gid */
--#define AT_CLKTCK	17		/* Frequency of times() */
--
--/* Some more special a_type values describing the hardware.  */
--#define AT_PLATFORM	15		/* String identifying platform.  */
--#define AT_HWCAP	16		/* Machine dependent hints about
--					   processor capabilities.  */
--
--/* This entry gives some information about the FPU initialization
--   performed by the kernel.  */
--#define AT_FPUCW	18		/* Used FPU control word.  */
--
--/* Cache block sizes.  */
--#define AT_DCACHEBSIZE	19		/* Data cache block size.  */
--#define AT_ICACHEBSIZE	20		/* Instruction cache block size.  */
--#define AT_UCACHEBSIZE	21		/* Unified cache block size.  */
--
--/* A special ignored value for PPC, used by the kernel to control the
--   interpretation of the AUXV. Must be > 16.  */
--#define AT_IGNOREPPC	22		/* Entry should be ignored.  */
--
--#define	AT_SECURE	23		/* Boolean, was exec setuid-like?  */
--
--#define AT_EXECFN	31		/* Filename of executable.  */
--
--/* Pointer to the global system page used for system calls and other
--   nice things.  */
--#define AT_SYSINFO	32
--#define AT_SYSINFO_EHDR	33
--
--/* Shapes of the caches.  Bits 0-3 contains associativity; bits 4-7 contains
--   log2 of line size; mask those to get cache size.  */
--#define AT_L1I_CACHESHAPE	34
--#define AT_L1D_CACHESHAPE	35
--#define AT_L2_CACHESHAPE	36
--#define AT_L3_CACHESHAPE	37
--
-+/* #include <bits/auxv.h> */
- /* Note section contents.  Each entry in the note section begins with
-    a header of a fixed form.  */
- 
-@@ -1042,6 +1035,9 @@ typedef struct
-    The descriptor consists of any nonzero number of bytes.  */
- #define NT_GNU_BUILD_ID	3
- 
-+/* Version note generated by GNU gold containing a version string.  */
-+#define NT_GNU_GOLD_VERSION	4
-+
- 
- /* Move records.  */
- typedef struct
-@@ -1102,8 +1098,29 @@ typedef struct
- #define R_68K_GLOB_DAT	20		/* Create GOT entry */
- #define R_68K_JMP_SLOT	21		/* Create PLT entry */
- #define R_68K_RELATIVE	22		/* Adjust by program base */
-+#define R_68K_TLS_GD32      25          /* 32 bit GOT offset for GD */
-+#define R_68K_TLS_GD16      26          /* 16 bit GOT offset for GD */
-+#define R_68K_TLS_GD8       27          /* 8 bit GOT offset for GD */
-+#define R_68K_TLS_LDM32     28          /* 32 bit GOT offset for LDM */
-+#define R_68K_TLS_LDM16     29          /* 16 bit GOT offset for LDM */
-+#define R_68K_TLS_LDM8      30          /* 8 bit GOT offset for LDM */
-+#define R_68K_TLS_LDO32     31          /* 32 bit module-relative offset */
-+#define R_68K_TLS_LDO16     32          /* 16 bit module-relative offset */
-+#define R_68K_TLS_LDO8      33          /* 8 bit module-relative offset */
-+#define R_68K_TLS_IE32      34          /* 32 bit GOT offset for IE */
-+#define R_68K_TLS_IE16      35          /* 16 bit GOT offset for IE */
-+#define R_68K_TLS_IE8       36          /* 8 bit GOT offset for IE */
-+#define R_68K_TLS_LE32      37          /* 32 bit offset relative to
-+					   static TLS block */
-+#define R_68K_TLS_LE16      38          /* 16 bit offset relative to
-+					   static TLS block */
-+#define R_68K_TLS_LE8       39          /* 8 bit offset relative to
-+					   static TLS block */
-+#define R_68K_TLS_DTPMOD32  40          /* 32 bit module number */
-+#define R_68K_TLS_DTPREL32  41          /* 32 bit module-relative offset */
-+#define R_68K_TLS_TPREL32   42          /* 32 bit TP-relative offset */
- /* Keep this the last entry.  */
--#define R_68K_NUM	23
-+#define R_68K_NUM	43
- 
- /* Intel 80386 specific definitions.  */
- 
-@@ -1157,7 +1174,7 @@ typedef struct
- #define R_386_TLS_DTPMOD32 35		/* ID of module containing symbol */
- #define R_386_TLS_DTPOFF32 36		/* Offset in TLS block */
- #define R_386_TLS_TPOFF32  37		/* Negated offset in static TLS block */
--/* 38? */
-+#define R_386_SIZE32	   38 		/* 32-bit symbol size */
- #define R_386_TLS_GOTDESC  39		/* GOT offset for TLS descriptor.  */
- #define R_386_TLS_DESC_CALL 40		/* Marker of call through TLS
- 					   descriptor for
-@@ -1166,8 +1183,9 @@ typedef struct
- 					   pointer to code and to
- 					   argument, returning the TLS
- 					   offset for the symbol.  */
-+#define R_386_IRELATIVE	   42		/* Adjust indirectly by program base */
- /* Keep this the last entry.  */
--#define R_386_NUM	   42
-+#define R_386_NUM	   43
- 
- /* SUN SPARC specific definitions.  */
- 
-@@ -1235,6 +1253,7 @@ typedef struct
- #define R_SPARC_PC_LM22		39	/* Low miggle 22 bits of ... */
- #define R_SPARC_WDISP16		40	/* PC relative 16 bit shifted */
- #define R_SPARC_WDISP19		41	/* PC relative 19 bit shifted */
-+#define R_SPARC_GLOB_JMP	42	/* was part of v9 ABI but was removed */
- #define R_SPARC_7		43	/* Direct 7 bit */
- #define R_SPARC_5		44	/* Direct 5 bit */
- #define R_SPARC_6		45	/* Direct 6 bit */
-@@ -1272,118 +1291,124 @@ typedef struct
- #define R_SPARC_TLS_DTPOFF64	77
- #define R_SPARC_TLS_TPOFF32	78
- #define R_SPARC_TLS_TPOFF64	79
-+#define R_SPARC_GOTDATA_HIX22	80
-+#define R_SPARC_GOTDATA_LOX10	81
-+#define R_SPARC_GOTDATA_OP_HIX22	82
-+#define R_SPARC_GOTDATA_OP_LOX10	83
-+#define R_SPARC_GOTDATA_OP	84
-+#define R_SPARC_H34		85
-+#define R_SPARC_SIZE32		86
-+#define R_SPARC_SIZE64		87
-+#define R_SPARC_WDISP10		88
-+#define R_SPARC_JMP_IREL	248
-+#define R_SPARC_IRELATIVE	249
-+#define R_SPARC_GNU_VTINHERIT	250
-+#define R_SPARC_GNU_VTENTRY	251
-+#define R_SPARC_REV32		252
- /* Keep this the last entry.  */
--#define R_SPARC_NUM		80
-+#define R_SPARC_NUM		253
- 
- /* For Sparc64, legal values for d_tag of Elf64_Dyn.  */
- 
--#define DT_SPARC_REGISTER 0x70000001
--#define DT_SPARC_NUM	2
--
--/* Bits present in AT_HWCAP on SPARC.  */
--
--#define HWCAP_SPARC_FLUSH	1	/* The CPU supports flush insn.  */
--#define HWCAP_SPARC_STBAR	2
--#define HWCAP_SPARC_SWAP	4
--#define HWCAP_SPARC_MULDIV	8
--#define HWCAP_SPARC_V9		16	/* The CPU is v9, so v8plus is ok.  */
--#define HWCAP_SPARC_ULTRA3	32
--#define HWCAP_SPARC_BLKINIT	64	/* Sun4v with block-init/load-twin.  */
--#define HWCAP_SPARC_N2		128
-+#define DT_SPARC_REGISTER	0x70000001
-+#define DT_SPARC_NUM		2
- 
- /* MIPS R3000 specific definitions.  */
- 
- /* Legal values for e_flags field of Elf32_Ehdr.  */
- 
--#define EF_MIPS_NOREORDER   1		/* A .noreorder directive was used */
--#define EF_MIPS_PIC	    2		/* Contains PIC code */
--#define EF_MIPS_CPIC	    4		/* Uses PIC calling sequence */
--#define EF_MIPS_XGOT	    8
--#define EF_MIPS_64BIT_WHIRL 16
--#define EF_MIPS_ABI2	    32
--#define EF_MIPS_ABI_ON32    64
--#define EF_MIPS_ARCH	    0xf0000000	/* MIPS architecture level */
-+#define EF_MIPS_NOREORDER	1     /* A .noreorder directive was used.  */
-+#define EF_MIPS_PIC		2     /* Contains PIC code.  */
-+#define EF_MIPS_CPIC		4     /* Uses PIC calling sequence.  */
-+#define EF_MIPS_XGOT		8
-+#define EF_MIPS_64BIT_WHIRL	16
-+#define EF_MIPS_ABI2		32
-+#define EF_MIPS_ABI_ON32	64
-+#define EF_MIPS_NAN2008	1024  /* Uses IEEE 754-2008 NaN encoding.  */
-+#define EF_MIPS_ARCH		0xf0000000 /* MIPS architecture level.  */
- 
- /* Legal values for MIPS architecture level.  */
- 
--#define EF_MIPS_ARCH_1	    0x00000000	/* -mips1 code.  */
--#define EF_MIPS_ARCH_2	    0x10000000	/* -mips2 code.  */
--#define EF_MIPS_ARCH_3	    0x20000000	/* -mips3 code.  */
--#define EF_MIPS_ARCH_4	    0x30000000	/* -mips4 code.  */
--#define EF_MIPS_ARCH_5	    0x40000000	/* -mips5 code.  */
--#define EF_MIPS_ARCH_32	    0x60000000	/* MIPS32 code.  */
--#define EF_MIPS_ARCH_64	    0x70000000	/* MIPS64 code.  */
--
--/* The following are non-official names and should not be used.  */
--
--#define E_MIPS_ARCH_1	  0x00000000	/* -mips1 code.  */
--#define E_MIPS_ARCH_2	  0x10000000	/* -mips2 code.  */
--#define E_MIPS_ARCH_3	  0x20000000	/* -mips3 code.  */
--#define E_MIPS_ARCH_4	  0x30000000	/* -mips4 code.  */
--#define E_MIPS_ARCH_5	  0x40000000	/* -mips5 code.  */
--#define E_MIPS_ARCH_32	  0x60000000	/* MIPS32 code.  */
--#define E_MIPS_ARCH_64	  0x70000000	/* MIPS64 code.  */
-+#define EF_MIPS_ARCH_1		0x00000000 /* -mips1 code.  */
-+#define EF_MIPS_ARCH_2		0x10000000 /* -mips2 code.  */
-+#define EF_MIPS_ARCH_3		0x20000000 /* -mips3 code.  */
-+#define EF_MIPS_ARCH_4		0x30000000 /* -mips4 code.  */
-+#define EF_MIPS_ARCH_5		0x40000000 /* -mips5 code.  */
-+#define EF_MIPS_ARCH_32		0x50000000 /* MIPS32 code.  */
-+#define EF_MIPS_ARCH_64		0x60000000 /* MIPS64 code.  */
-+#define EF_MIPS_ARCH_32R2	0x70000000 /* MIPS32r2 code.  */
-+#define EF_MIPS_ARCH_64R2	0x80000000 /* MIPS64r2 code.  */
-+
-+/* The following are unofficial names and should not be used.  */
-+
-+#define E_MIPS_ARCH_1		EF_MIPS_ARCH_1
-+#define E_MIPS_ARCH_2		EF_MIPS_ARCH_2
-+#define E_MIPS_ARCH_3		EF_MIPS_ARCH_3
-+#define E_MIPS_ARCH_4		EF_MIPS_ARCH_4
-+#define E_MIPS_ARCH_5		EF_MIPS_ARCH_5
-+#define E_MIPS_ARCH_32		EF_MIPS_ARCH_32
-+#define E_MIPS_ARCH_64		EF_MIPS_ARCH_64
- 
- /* Special section indices.  */
- 
--#define SHN_MIPS_ACOMMON    0xff00	/* Allocated common symbols */
--#define SHN_MIPS_TEXT	    0xff01	/* Allocated test symbols.  */
--#define SHN_MIPS_DATA	    0xff02	/* Allocated data symbols.  */
--#define SHN_MIPS_SCOMMON    0xff03	/* Small common symbols */
--#define SHN_MIPS_SUNDEFINED 0xff04	/* Small undefined symbols */
-+#define SHN_MIPS_ACOMMON	0xff00	/* Allocated common symbols.  */
-+#define SHN_MIPS_TEXT		0xff01	/* Allocated test symbols.  */
-+#define SHN_MIPS_DATA		0xff02	/* Allocated data symbols.  */
-+#define SHN_MIPS_SCOMMON 	0xff03	/* Small common symbols.  */
-+#define SHN_MIPS_SUNDEFINED	0xff04	/* Small undefined symbols.  */
- 
- /* Legal values for sh_type field of Elf32_Shdr.  */
- 
--#define SHT_MIPS_LIBLIST       0x70000000 /* Shared objects used in link */
--#define SHT_MIPS_MSYM	       0x70000001
--#define SHT_MIPS_CONFLICT      0x70000002 /* Conflicting symbols */
--#define SHT_MIPS_GPTAB	       0x70000003 /* Global data area sizes */
--#define SHT_MIPS_UCODE	       0x70000004 /* Reserved for SGI/MIPS compilers */
--#define SHT_MIPS_DEBUG	       0x70000005 /* MIPS ECOFF debugging information*/
--#define SHT_MIPS_REGINFO       0x70000006 /* Register usage information */
--#define SHT_MIPS_PACKAGE       0x70000007
--#define SHT_MIPS_PACKSYM       0x70000008
--#define SHT_MIPS_RELD	       0x70000009
--#define SHT_MIPS_IFACE         0x7000000b
--#define SHT_MIPS_CONTENT       0x7000000c
--#define SHT_MIPS_OPTIONS       0x7000000d /* Miscellaneous options.  */
--#define SHT_MIPS_SHDR	       0x70000010
--#define SHT_MIPS_FDESC	       0x70000011
--#define SHT_MIPS_EXTSYM	       0x70000012
--#define SHT_MIPS_DENSE	       0x70000013
--#define SHT_MIPS_PDESC	       0x70000014
--#define SHT_MIPS_LOCSYM	       0x70000015
--#define SHT_MIPS_AUXSYM	       0x70000016
--#define SHT_MIPS_OPTSYM	       0x70000017
--#define SHT_MIPS_LOCSTR	       0x70000018
--#define SHT_MIPS_LINE	       0x70000019
--#define SHT_MIPS_RFDESC	       0x7000001a
--#define SHT_MIPS_DELTASYM      0x7000001b
--#define SHT_MIPS_DELTAINST     0x7000001c
--#define SHT_MIPS_DELTACLASS    0x7000001d
--#define SHT_MIPS_DWARF         0x7000001e /* DWARF debugging information.  */
--#define SHT_MIPS_DELTADECL     0x7000001f
--#define SHT_MIPS_SYMBOL_LIB    0x70000020
--#define SHT_MIPS_EVENTS	       0x70000021 /* Event section.  */
--#define SHT_MIPS_TRANSLATE     0x70000022
--#define SHT_MIPS_PIXIE	       0x70000023
--#define SHT_MIPS_XLATE	       0x70000024
--#define SHT_MIPS_XLATE_DEBUG   0x70000025
--#define SHT_MIPS_WHIRL	       0x70000026
--#define SHT_MIPS_EH_REGION     0x70000027
--#define SHT_MIPS_XLATE_OLD     0x70000028
--#define SHT_MIPS_PDR_EXCEPTION 0x70000029
-+#define SHT_MIPS_LIBLIST	0x70000000 /* Shared objects used in link.  */
-+#define SHT_MIPS_MSYM		0x70000001
-+#define SHT_MIPS_CONFLICT	0x70000002 /* Conflicting symbols.  */
-+#define SHT_MIPS_GPTAB		0x70000003 /* Global data area sizes.  */
-+#define SHT_MIPS_UCODE		0x70000004 /* Reserved for SGI/MIPS compilers */
-+#define SHT_MIPS_DEBUG		0x70000005 /* MIPS ECOFF debugging info.  */
-+#define SHT_MIPS_REGINFO	0x70000006 /* Register usage information.  */
-+#define SHT_MIPS_PACKAGE	0x70000007
-+#define SHT_MIPS_PACKSYM	0x70000008
-+#define SHT_MIPS_RELD		0x70000009
-+#define SHT_MIPS_IFACE		0x7000000b
-+#define SHT_MIPS_CONTENT	0x7000000c
-+#define SHT_MIPS_OPTIONS	0x7000000d /* Miscellaneous options.  */
-+#define SHT_MIPS_SHDR		0x70000010
-+#define SHT_MIPS_FDESC		0x70000011
-+#define SHT_MIPS_EXTSYM		0x70000012
-+#define SHT_MIPS_DENSE		0x70000013
-+#define SHT_MIPS_PDESC		0x70000014
-+#define SHT_MIPS_LOCSYM		0x70000015
-+#define SHT_MIPS_AUXSYM		0x70000016
-+#define SHT_MIPS_OPTSYM		0x70000017
-+#define SHT_MIPS_LOCSTR		0x70000018
-+#define SHT_MIPS_LINE		0x70000019
-+#define SHT_MIPS_RFDESC		0x7000001a
-+#define SHT_MIPS_DELTASYM	0x7000001b
-+#define SHT_MIPS_DELTAINST	0x7000001c
-+#define SHT_MIPS_DELTACLASS	0x7000001d
-+#define SHT_MIPS_DWARF		0x7000001e /* DWARF debugging information.  */
-+#define SHT_MIPS_DELTADECL	0x7000001f
-+#define SHT_MIPS_SYMBOL_LIB	0x70000020
-+#define SHT_MIPS_EVENTS		0x70000021 /* Event section.  */
-+#define SHT_MIPS_TRANSLATE	0x70000022
-+#define SHT_MIPS_PIXIE		0x70000023
-+#define SHT_MIPS_XLATE		0x70000024
-+#define SHT_MIPS_XLATE_DEBUG	0x70000025
-+#define SHT_MIPS_WHIRL		0x70000026
-+#define SHT_MIPS_EH_REGION	0x70000027
-+#define SHT_MIPS_XLATE_OLD	0x70000028
-+#define SHT_MIPS_PDR_EXCEPTION	0x70000029
- 
- /* Legal values for sh_flags field of Elf32_Shdr.  */
- 
--#define SHF_MIPS_GPREL	 0x10000000	/* Must be part of global data area */
--#define SHF_MIPS_MERGE	 0x20000000
--#define SHF_MIPS_ADDR	 0x40000000
--#define SHF_MIPS_STRINGS 0x80000000
--#define SHF_MIPS_NOSTRIP 0x08000000
--#define SHF_MIPS_LOCAL	 0x04000000
--#define SHF_MIPS_NAMES	 0x02000000
--#define SHF_MIPS_NODUPE	 0x01000000
-+#define SHF_MIPS_GPREL		0x10000000 /* Must be in global data area.  */
-+#define SHF_MIPS_MERGE		0x20000000
-+#define SHF_MIPS_ADDR		0x40000000
-+#define SHF_MIPS_STRINGS	0x80000000
-+#define SHF_MIPS_NOSTRIP	0x08000000
-+#define SHF_MIPS_LOCAL		0x04000000
-+#define SHF_MIPS_NAMES		0x02000000
-+#define SHF_MIPS_NODUPE		0x01000000
- 
- 
- /* Symbol tables.  */
-@@ -1405,23 +1430,23 @@ typedef union
- {
-   struct
-     {
--      Elf32_Word gt_current_g_value;	/* -G value used for compilation */
--      Elf32_Word gt_unused;		/* Not used */
--    } gt_header;			/* First entry in section */
-+      Elf32_Word gt_current_g_value;	/* -G value used for compilation.  */
-+      Elf32_Word gt_unused;		/* Not used.  */
-+    } gt_header;			/* First entry in section.  */
-   struct
-     {
--      Elf32_Word gt_g_value;		/* If this value were used for -G */
--      Elf32_Word gt_bytes;		/* This many bytes would be used */
--    } gt_entry;				/* Subsequent entries in section */
-+      Elf32_Word gt_g_value;		/* If this value were used for -G.  */
-+      Elf32_Word gt_bytes;		/* This many bytes would be used.  */
-+    } gt_entry;				/* Subsequent entries in section.  */
- } Elf32_gptab;
- 
- /* Entry found in sections of type SHT_MIPS_REGINFO.  */
- 
- typedef struct
- {
--  Elf32_Word	ri_gprmask;		/* General registers used */
--  Elf32_Word	ri_cprmask[4];		/* Coprocessor registers used */
--  Elf32_Sword	ri_gp_value;		/* $gp register value */
-+  Elf32_Word ri_gprmask;		/* General registers used.  */
-+  Elf32_Word ri_cprmask[4];		/* Coprocessor registers used.  */
-+  Elf32_Sword ri_gp_value;		/* $gp register value.  */
- } Elf32_RegInfo;
- 
- /* Entries found in sections of type SHT_MIPS_OPTIONS.  */
-@@ -2013,9 +2038,6 @@ typedef Elf32_Addr Elf32_Conflict;
- #define R_PPC_GOT_DTPREL16_HI	93 /* half16*	(sym+add)@got at dtprel@h */
- #define R_PPC_GOT_DTPREL16_HA	94 /* half16*	(sym+add)@got at dtprel@ha */
- 
--/* Keep this the last entry.  */
--#define R_PPC_NUM		95
--
- /* The remaining relocs are from the Embedded ELF ABI, and are not
-    in the SVR4 ELF ABI.  */
- #define R_PPC_EMB_NADDR32	101
-@@ -2043,11 +2065,14 @@ typedef Elf32_Addr Elf32_Conflict;
- #define R_PPC_DIAB_RELSDA_HI	184	/* like EMB_RELSDA, but high 16 bit */
- #define R_PPC_DIAB_RELSDA_HA	185	/* like EMB_RELSDA, adjusted high 16 */
- 
-+/* GNU extension to support local ifunc.  */
-+#define R_PPC_IRELATIVE		248
-+
- /* GNU relocs used in PIC code sequences.  */
--#define R_PPC_REL16		249	/* word32   (sym-.) */
--#define R_PPC_REL16_LO		250	/* half16   (sym-.)@l */
--#define R_PPC_REL16_HI		251	/* half16   (sym-.)@h */
--#define R_PPC_REL16_HA		252	/* half16   (sym-.)@ha */
-+#define R_PPC_REL16		249	/* half16   (sym+add-.) */
-+#define R_PPC_REL16_LO		250	/* half16   (sym+add-.)@l */
-+#define R_PPC_REL16_HI		251	/* half16   (sym+add-.)@h */
-+#define R_PPC_REL16_HA		252	/* half16   (sym+add-.)@ha */
- 
- /* This is a phony reloc to handle any old fashioned TOC16 references
-    that may still be in object files.  */
-@@ -2168,76 +2193,261 @@ typedef Elf32_Addr Elf32_Conflict;
- #define R_PPC64_DTPREL16_HIGHERA 104 /* half16	(sym+add)@dtprel at highera */
- #define R_PPC64_DTPREL16_HIGHEST 105 /* half16	(sym+add)@dtprel at highest */
- #define R_PPC64_DTPREL16_HIGHESTA 106 /* half16	(sym+add)@dtprel at highesta */
--
--/* Keep this the last entry.  */
--#define R_PPC64_NUM		107
-+#define R_PPC64_TLSGD		107 /* none	(sym+add)@tlsgd */
-+#define R_PPC64_TLSLD		108 /* none	(sym+add)@tlsld */
-+#define R_PPC64_TOCSAVE		109 /* none */
-+
-+/* Added when HA and HI relocs were changed to report overflows.  */
-+#define R_PPC64_ADDR16_HIGH	110
-+#define R_PPC64_ADDR16_HIGHA	111
-+#define R_PPC64_TPREL16_HIGH	112
-+#define R_PPC64_TPREL16_HIGHA	113
-+#define R_PPC64_DTPREL16_HIGH	114
-+#define R_PPC64_DTPREL16_HIGHA	115
-+
-+/* GNU extension to support local ifunc.  */
-+#define R_PPC64_JMP_IREL	247
-+#define R_PPC64_IRELATIVE	248
-+#define R_PPC64_REL16		249	/* half16   (sym+add-.) */
-+#define R_PPC64_REL16_LO	250	/* half16   (sym+add-.)@l */
-+#define R_PPC64_REL16_HI	251	/* half16   (sym+add-.)@h */
-+#define R_PPC64_REL16_HA	252	/* half16   (sym+add-.)@ha */
-+
-+/* e_flags bits specifying ABI.
-+   1 for original function descriptor using ABI,
-+   2 for revised ABI without function descriptors,
-+   0 for unspecified or not using any features affected by the differences.  */
-+#define EF_PPC64_ABI	3
- 
- /* PowerPC64 specific values for the Dyn d_tag field.  */
- #define DT_PPC64_GLINK  (DT_LOPROC + 0)
- #define DT_PPC64_OPD	(DT_LOPROC + 1)
- #define DT_PPC64_OPDSZ	(DT_LOPROC + 2)
-+#define DT_PPC64_OPT	(DT_LOPROC + 3)
- #define DT_PPC64_NUM    3
- 
-+/* PowerPC64 specific values for the DT_PPC64_OPT Dyn entry.  */
-+#define PPC64_OPT_TLS		1
-+#define PPC64_OPT_MULTI_TOC	2
-+
-+/* PowerPC64 specific values for the Elf64_Sym st_other field.  */
-+#define STO_PPC64_LOCAL_BIT	5
-+#define STO_PPC64_LOCAL_MASK	(7 << STO_PPC64_LOCAL_BIT)
-+#define PPC64_LOCAL_ENTRY_OFFSET(other)				\
-+ (((1 << (((other) & STO_PPC64_LOCAL_MASK) >> STO_PPC64_LOCAL_BIT)) >> 2) << 2)
-+
- 
- /* ARM specific declarations */
- 
- /* Processor specific flags for the ELF header e_flags field.  */
--#define EF_ARM_RELEXEC     0x01
--#define EF_ARM_HASENTRY    0x02
--#define EF_ARM_INTERWORK   0x04
--#define EF_ARM_APCS_26     0x08
--#define EF_ARM_APCS_FLOAT  0x10
--#define EF_ARM_PIC         0x20
--#define EF_ARM_ALIGN8      0x40		/* 8-bit structure alignment is in use */
--#define EF_ARM_NEW_ABI     0x80
--#define EF_ARM_OLD_ABI     0x100
-+#define EF_ARM_RELEXEC		0x01
-+#define EF_ARM_HASENTRY		0x02
-+#define EF_ARM_INTERWORK	0x04
-+#define EF_ARM_APCS_26		0x08
-+#define EF_ARM_APCS_FLOAT	0x10
-+#define EF_ARM_PIC		0x20
-+#define EF_ARM_ALIGN8		0x40 /* 8-bit structure alignment is in use */
-+#define EF_ARM_NEW_ABI		0x80
-+#define EF_ARM_OLD_ABI		0x100
-+#define EF_ARM_SOFT_FLOAT	0x200
-+#define EF_ARM_VFP_FLOAT	0x400
-+#define EF_ARM_MAVERICK_FLOAT	0x800
-+
-+#define EF_ARM_ABI_FLOAT_SOFT	0x200   /* NB conflicts with EF_ARM_SOFT_FLOAT */
-+#define EF_ARM_ABI_FLOAT_HARD	0x400   /* NB conflicts with EF_ARM_VFP_FLOAT */
-+
- 
- /* Other constants defined in the ARM ELF spec. version B-01.  */
- /* NB. These conflict with values defined above.  */
- #define EF_ARM_SYMSARESORTED	0x04
--#define EF_ARM_DYNSYMSUSESEGIDX 0x08
-+#define EF_ARM_DYNSYMSUSESEGIDX	0x08
- #define EF_ARM_MAPSYMSFIRST	0x10
- #define EF_ARM_EABIMASK		0XFF000000
- 
--#define EF_ARM_EABI_VERSION(flags) ((flags) & EF_ARM_EABIMASK)
--#define EF_ARM_EABI_UNKNOWN  0x00000000
--#define EF_ARM_EABI_VER1     0x01000000
--#define EF_ARM_EABI_VER2     0x02000000
-+/* Constants defined in AAELF.  */
-+#define EF_ARM_BE8	    0x00800000
-+#define EF_ARM_LE8	    0x00400000
-+
-+#define EF_ARM_EABI_VERSION(flags)	((flags) & EF_ARM_EABIMASK)
-+#define EF_ARM_EABI_UNKNOWN	0x00000000
-+#define EF_ARM_EABI_VER1	0x01000000
-+#define EF_ARM_EABI_VER2	0x02000000
-+#define EF_ARM_EABI_VER3	0x03000000
-+#define EF_ARM_EABI_VER4	0x04000000
-+#define EF_ARM_EABI_VER5	0x05000000
- 
--/* Additional symbol types for Thumb */
--#define STT_ARM_TFUNC      0xd
-+/* Additional symbol types for Thumb.  */
-+#define STT_ARM_TFUNC		STT_LOPROC /* A Thumb function.  */
-+#define STT_ARM_16BIT		STT_HIPROC /* A Thumb label.  */
- 
- /* ARM-specific values for sh_flags */
--#define SHF_ARM_ENTRYSECT  0x10000000   /* Section contains an entry point */
--#define SHF_ARM_COMDEF     0x80000000   /* Section may be multiply defined
--					   in the input to a link step */
-+#define SHF_ARM_ENTRYSECT	0x10000000 /* Section contains an entry point */
-+#define SHF_ARM_COMDEF		0x80000000 /* Section may be multiply defined
-+					      in the input to a link step.  */
- 
- /* ARM-specific program header flags */
--#define PF_ARM_SB          0x10000000   /* Segment contains the location
--					   addressed by the static base */
-+#define PF_ARM_SB		0x10000000 /* Segment contains the location
-+					      addressed by the static base. */
-+#define PF_ARM_PI		0x20000000 /* Position-independent segment.  */
-+#define PF_ARM_ABS		0x40000000 /* Absolute segment.  */
- 
- /* Processor specific values for the Phdr p_type field.  */
--#define PT_ARM_EXIDX	0x70000001	/* .ARM.exidx segment */
-+#define PT_ARM_EXIDX		(PT_LOPROC + 1)	/* ARM unwind segment.  */
-+
-+/* Processor specific values for the Shdr sh_type field.  */
-+#define SHT_ARM_EXIDX		(SHT_LOPROC + 1) /* ARM unwind section.  */
-+#define SHT_ARM_PREEMPTMAP	(SHT_LOPROC + 2) /* Preemption details.  */
-+#define SHT_ARM_ATTRIBUTES	(SHT_LOPROC + 3) /* ARM attributes section.  */
-+
-+
-+/* AArch64 relocs.  */
-+
-+#define R_AARCH64_NONE            0	/* No relocation.  */
-+#define R_AARCH64_ABS64         257	/* Direct 64 bit. */
-+#define R_AARCH64_ABS32         258	/* Direct 32 bit.  */
-+#define R_AARCH64_ABS16		259	/* Direct 16-bit.  */
-+#define R_AARCH64_PREL64	260	/* PC-relative 64-bit.	*/
-+#define R_AARCH64_PREL32	261	/* PC-relative 32-bit.	*/
-+#define R_AARCH64_PREL16	262	/* PC-relative 16-bit.	*/
-+#define R_AARCH64_MOVW_UABS_G0	263	/* Dir. MOVZ imm. from bits 15:0.  */
-+#define R_AARCH64_MOVW_UABS_G0_NC 264	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_UABS_G1	265	/* Dir. MOVZ imm. from bits 31:16.  */
-+#define R_AARCH64_MOVW_UABS_G1_NC 266	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_UABS_G2	267	/* Dir. MOVZ imm. from bits 47:32.  */
-+#define R_AARCH64_MOVW_UABS_G2_NC 268	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_UABS_G3	269	/* Dir. MOV{K,Z} imm. from 63:48.  */
-+#define R_AARCH64_MOVW_SABS_G0	270	/* Dir. MOV{N,Z} imm. from 15:0.  */
-+#define R_AARCH64_MOVW_SABS_G1	271	/* Dir. MOV{N,Z} imm. from 31:16.  */
-+#define R_AARCH64_MOVW_SABS_G2	272	/* Dir. MOV{N,Z} imm. from 47:32.  */
-+#define R_AARCH64_LD_PREL_LO19	273	/* PC-rel. LD imm. from bits 20:2.  */
-+#define R_AARCH64_ADR_PREL_LO21	274	/* PC-rel. ADR imm. from bits 20:0.  */
-+#define R_AARCH64_ADR_PREL_PG_HI21 275	/* Page-rel. ADRP imm. from 32:12.  */
-+#define R_AARCH64_ADR_PREL_PG_HI21_NC 276 /* Likewise; no overflow check.  */
-+#define R_AARCH64_ADD_ABS_LO12_NC 277	/* Dir. ADD imm. from bits 11:0.  */
-+#define R_AARCH64_LDST8_ABS_LO12_NC 278	/* Likewise for LD/ST; no check. */
-+#define R_AARCH64_TSTBR14	279	/* PC-rel. TBZ/TBNZ imm. from 15:2.  */
-+#define R_AARCH64_CONDBR19	280	/* PC-rel. cond. br. imm. from 20:2. */
-+#define R_AARCH64_JUMP26	282	/* PC-rel. B imm. from bits 27:2.  */
-+#define R_AARCH64_CALL26	283	/* Likewise for CALL.  */
-+#define R_AARCH64_LDST16_ABS_LO12_NC 284 /* Dir. ADD imm. from bits 11:1.  */
-+#define R_AARCH64_LDST32_ABS_LO12_NC 285 /* Likewise for bits 11:2.  */
-+#define R_AARCH64_LDST64_ABS_LO12_NC 286 /* Likewise for bits 11:3.  */
-+#define R_AARCH64_MOVW_PREL_G0	287	/* PC-rel. MOV{N,Z} imm. from 15:0.  */
-+#define R_AARCH64_MOVW_PREL_G0_NC 288	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_PREL_G1	289	/* PC-rel. MOV{N,Z} imm. from 31:16. */
-+#define R_AARCH64_MOVW_PREL_G1_NC 290	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_PREL_G2	291	/* PC-rel. MOV{N,Z} imm. from 47:32. */
-+#define R_AARCH64_MOVW_PREL_G2_NC 292	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_PREL_G3	293	/* PC-rel. MOV{N,Z} imm. from 63:48. */
-+#define R_AARCH64_LDST128_ABS_LO12_NC 299 /* Dir. ADD imm. from bits 11:4.  */
-+#define R_AARCH64_MOVW_GOTOFF_G0 300	/* GOT-rel. off. MOV{N,Z} imm. 15:0. */
-+#define R_AARCH64_MOVW_GOTOFF_G0_NC 301	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_GOTOFF_G1 302	/* GOT-rel. o. MOV{N,Z} imm. 31:16.  */
-+#define R_AARCH64_MOVW_GOTOFF_G1_NC 303	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_GOTOFF_G2 304	/* GOT-rel. o. MOV{N,Z} imm. 47:32.  */
-+#define R_AARCH64_MOVW_GOTOFF_G2_NC 305	/* Likewise for MOVK; no check.  */
-+#define R_AARCH64_MOVW_GOTOFF_G3 306	/* GOT-rel. o. MOV{N,Z} imm. 63:48.  */
-+#define R_AARCH64_GOTREL64	307	/* GOT-relative 64-bit.  */
-+#define R_AARCH64_GOTREL32	308	/* GOT-relative 32-bit.  */
-+#define R_AARCH64_GOT_LD_PREL19	309	/* PC-rel. GOT off. load imm. 20:2.  */
-+#define R_AARCH64_LD64_GOTOFF_LO15 310	/* GOT-rel. off. LD/ST imm. 14:3.  */
-+#define R_AARCH64_ADR_GOT_PAGE	311	/* P-page-rel. GOT off. ADRP 32:12.  */
-+#define R_AARCH64_LD64_GOT_LO12_NC 312	/* Dir. GOT off. LD/ST imm. 11:3.  */
-+#define R_AARCH64_LD64_GOTPAGE_LO15 313	/* GOT-page-rel. GOT off. LD/ST 14:3 */
-+#define R_AARCH64_TLSGD_ADR_PREL21 512	/* PC-relative ADR imm. 20:0.  */
-+#define R_AARCH64_TLSGD_ADR_PAGE21 513	/* page-rel. ADRP imm. 32:12.  */
-+#define R_AARCH64_TLSGD_ADD_LO12_NC 514	/* direct ADD imm. from 11:0.  */
-+#define R_AARCH64_TLSGD_MOVW_G1	515	/* GOT-rel. MOV{N,Z} 31:16.  */
-+#define R_AARCH64_TLSGD_MOVW_G0_NC 516	/* GOT-rel. MOVK imm. 15:0.  */
-+#define R_AARCH64_TLSLD_ADR_PREL21 517	/* Like 512; local dynamic model.  */
-+#define R_AARCH64_TLSLD_ADR_PAGE21 518	/* Like 513; local dynamic model.  */
-+#define R_AARCH64_TLSLD_ADD_LO12_NC 519	/* Like 514; local dynamic model.  */
-+#define R_AARCH64_TLSLD_MOVW_G1	520	/* Like 515; local dynamic model.  */
-+#define R_AARCH64_TLSLD_MOVW_G0_NC 521	/* Like 516; local dynamic model.  */
-+#define R_AARCH64_TLSLD_LD_PREL19 522	/* TLS PC-rel. load imm. 20:2.  */
-+#define R_AARCH64_TLSLD_MOVW_DTPREL_G2 523 /* TLS DTP-rel. MOV{N,Z} 47:32.  */
-+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1 524 /* TLS DTP-rel. MOV{N,Z} 31:16.  */
-+#define R_AARCH64_TLSLD_MOVW_DTPREL_G1_NC 525 /* Likewise; MOVK; no check.  */
-+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0 526 /* TLS DTP-rel. MOV{N,Z} 15:0.  */
-+#define R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC 527 /* Likewise; MOVK; no check.  */
-+#define R_AARCH64_TLSLD_ADD_DTPREL_HI12 528 /* DTP-rel. ADD imm. from 23:12. */
-+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12 529 /* DTP-rel. ADD imm. from 11:0.  */
-+#define R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC 530 /* Likewise; no ovfl. check.  */
-+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12 531 /* DTP-rel. LD/ST imm. 11:0.  */
-+#define R_AARCH64_TLSLD_LDST8_DTPREL_LO12_NC 532 /* Likewise; no check.  */
-+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12 533 /* DTP-rel. LD/ST imm. 11:1.  */
-+#define R_AARCH64_TLSLD_LDST16_DTPREL_LO12_NC 534 /* Likewise; no check.  */
-+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12 535 /* DTP-rel. LD/ST imm. 11:2.  */
-+#define R_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC 536 /* Likewise; no check.  */
-+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12 537 /* DTP-rel. LD/ST imm. 11:3.  */
-+#define R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC 538 /* Likewise; no check.  */
-+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G1 539 /* GOT-rel. MOV{N,Z} 31:16.  */
-+#define R_AARCH64_TLSIE_MOVW_GOTTPREL_G0_NC 540 /* GOT-rel. MOVK 15:0.  */
-+#define R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21 541 /* Page-rel. ADRP 32:12.  */
-+#define R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC 542 /* Direct LD off. 11:3.  */
-+#define R_AARCH64_TLSIE_LD_GOTTPREL_PREL19 543 /* PC-rel. load imm. 20:2.  */
-+#define R_AARCH64_TLSLE_MOVW_TPREL_G2 544 /* TLS TP-rel. MOV{N,Z} 47:32.  */
-+#define R_AARCH64_TLSLE_MOVW_TPREL_G1 545 /* TLS TP-rel. MOV{N,Z} 31:16.  */
-+#define R_AARCH64_TLSLE_MOVW_TPREL_G1_NC 546 /* Likewise; MOVK; no check.  */
-+#define R_AARCH64_TLSLE_MOVW_TPREL_G0 547 /* TLS TP-rel. MOV{N,Z} 15:0.  */
-+#define R_AARCH64_TLSLE_MOVW_TPREL_G0_NC 548 /* Likewise; MOVK; no check.  */
-+#define R_AARCH64_TLSLE_ADD_TPREL_HI12 549 /* TP-rel. ADD imm. 23:12.  */
-+#define R_AARCH64_TLSLE_ADD_TPREL_LO12 550 /* TP-rel. ADD imm. 11:0.  */
-+#define R_AARCH64_TLSLE_ADD_TPREL_LO12_NC 551 /* Likewise; no ovfl. check.  */
-+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12 552 /* TP-rel. LD/ST off. 11:0.  */
-+#define R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC 553 /* Likewise; no ovfl. check. */
-+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12 554 /* TP-rel. LD/ST off. 11:1.  */
-+#define R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC 555 /* Likewise; no check.  */
-+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12 556 /* TP-rel. LD/ST off. 11:2.  */
-+#define R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC 557 /* Likewise; no check.  */
-+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12 558 /* TP-rel. LD/ST off. 11:3.  */
-+#define R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC 559 /* Likewise; no check.  */
-+#define R_AARCH64_TLSDESC_LD_PREL19 560	/* PC-rel. load immediate 20:2.  */
-+#define R_AARCH64_TLSDESC_ADR_PREL21 561 /* PC-rel. ADR immediate 20:0.  */
-+#define R_AARCH64_TLSDESC_ADR_PAGE21 562 /* Page-rel. ADRP imm. 32:12.  */
-+#define R_AARCH64_TLSDESC_LD64_LO12 563	/* Direct LD off. from 11:3.  */
-+#define R_AARCH64_TLSDESC_ADD_LO12 564	/* Direct ADD imm. from 11:0.  */
-+#define R_AARCH64_TLSDESC_OFF_G1 565	/* GOT-rel. MOV{N,Z} imm. 31:16.  */
-+#define R_AARCH64_TLSDESC_OFF_G0_NC 566	/* GOT-rel. MOVK imm. 15:0; no ck.  */
-+#define R_AARCH64_TLSDESC_LDR	567	/* Relax LDR.  */
-+#define R_AARCH64_TLSDESC_ADD	568	/* Relax ADD.  */
-+#define R_AARCH64_TLSDESC_CALL	569	/* Relax BLR.  */
-+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12 570 /* TP-rel. LD/ST off. 11:4.  */
-+#define R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC 571 /* Likewise; no check.  */
-+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12 572 /* DTP-rel. LD/ST imm. 11:4. */
-+#define R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC 573 /* Likewise; no check.  */
-+#define R_AARCH64_COPY         1024	/* Copy symbol at runtime.  */
-+#define R_AARCH64_GLOB_DAT     1025	/* Create GOT entry.  */
-+#define R_AARCH64_JUMP_SLOT    1026	/* Create PLT entry.  */
-+#define R_AARCH64_RELATIVE     1027	/* Adjust by program base.  */
-+#define R_AARCH64_TLS_DTPMOD64 1028	/* Module number, 64 bit.  */
-+#define R_AARCH64_TLS_DTPREL64 1029	/* Module-relative offset, 64 bit.  */
-+#define R_AARCH64_TLS_TPREL64  1030	/* TP-relative offset, 64 bit.  */
-+#define R_AARCH64_TLSDESC      1031	/* TLS Descriptor.  */
-+#define R_AARCH64_IRELATIVE	1032	/* STT_GNU_IFUNC relocation.  */
- 
- /* ARM relocs.  */
- 
- #define R_ARM_NONE		0	/* No reloc */
--#define R_ARM_PC24		1	/* PC relative 26 bit branch */
-+#define R_ARM_PC24		1	/* Deprecated PC relative 26
-+					   bit branch.  */
- #define R_ARM_ABS32		2	/* Direct 32 bit  */
- #define R_ARM_REL32		3	/* PC relative 32 bit */
- #define R_ARM_PC13		4
- #define R_ARM_ABS16		5	/* Direct 16 bit */
- #define R_ARM_ABS12		6	/* Direct 12 bit */
--#define R_ARM_THM_ABS5		7
-+#define R_ARM_THM_ABS5		7	/* Direct & 0x7C (LDR, STR).  */
- #define R_ARM_ABS8		8	/* Direct 8 bit */
- #define R_ARM_SBREL32		9
--#define R_ARM_THM_PC22		10
--#define R_ARM_THM_PC8		11
-+#define R_ARM_THM_PC22		10	/* PC relative 24 bit (Thumb32 BL).  */
-+#define R_ARM_THM_PC8		11	/* PC relative & 0x3FC
-+					   (Thumb16 LDR, ADD, ADR).  */
- #define R_ARM_AMP_VCALL9	12
--#define R_ARM_SWI24		13
--#define R_ARM_THM_SWI8		14
--#define R_ARM_XPC25		15
--#define R_ARM_THM_XPC22		16
-+#define R_ARM_SWI24		13	/* Obsolete static relocation.  */
-+#define R_ARM_TLS_DESC		13      /* Dynamic relocation.  */
-+#define R_ARM_THM_SWI8		14	/* Reserved.  */
-+#define R_ARM_XPC25		15	/* Reserved.  */
-+#define R_ARM_THM_XPC22		16	/* Reserved.  */
- #define R_ARM_TLS_DTPMOD32	17	/* ID of module containing symbol */
- #define R_ARM_TLS_DTPOFF32	18	/* Offset in TLS block */
- #define R_ARM_TLS_TPOFF32	19	/* Offset in static TLS block */
-@@ -2248,17 +2458,109 @@ typedef Elf32_Addr Elf32_Conflict;
- #define R_ARM_GOTOFF		24	/* 32 bit offset to GOT */
- #define R_ARM_GOTPC		25	/* 32 bit PC relative offset to GOT */
- #define R_ARM_GOT32		26	/* 32 bit GOT entry */
--#define R_ARM_PLT32		27	/* 32 bit PLT address */
--#define R_ARM_ALU_PCREL_7_0	32
--#define R_ARM_ALU_PCREL_15_8	33
--#define R_ARM_ALU_PCREL_23_15	34
--#define R_ARM_LDR_SBREL_11_0	35
--#define R_ARM_ALU_SBREL_19_12	36
--#define R_ARM_ALU_SBREL_27_20	37
-+#define R_ARM_PLT32		27	/* Deprecated, 32 bit PLT address.  */
-+#define R_ARM_CALL		28	/* PC relative 24 bit (BL, BLX).  */
-+#define R_ARM_JUMP24		29	/* PC relative 24 bit
-+					   (B, BL<cond>).  */
-+#define R_ARM_THM_JUMP24	30	/* PC relative 24 bit (Thumb32 B.W).  */
-+#define R_ARM_BASE_ABS		31	/* Adjust by program base.  */
-+#define R_ARM_ALU_PCREL_7_0	32	/* Obsolete.  */
-+#define R_ARM_ALU_PCREL_15_8	33	/* Obsolete.  */
-+#define R_ARM_ALU_PCREL_23_15	34	/* Obsolete.  */
-+#define R_ARM_LDR_SBREL_11_0	35	/* Deprecated, prog. base relative.  */
-+#define R_ARM_ALU_SBREL_19_12	36	/* Deprecated, prog. base relative.  */
-+#define R_ARM_ALU_SBREL_27_20	37	/* Deprecated, prog. base relative.  */
-+#define R_ARM_TARGET1		38
-+#define R_ARM_SBREL31		39	/* Program base relative.  */
-+#define R_ARM_V4BX		40
-+#define R_ARM_TARGET2		41
-+#define R_ARM_PREL31		42	/* 32 bit PC relative.  */
-+#define R_ARM_MOVW_ABS_NC	43	/* Direct 16-bit (MOVW).  */
-+#define R_ARM_MOVT_ABS		44	/* Direct high 16-bit (MOVT).  */
-+#define R_ARM_MOVW_PREL_NC	45	/* PC relative 16-bit (MOVW).  */
-+#define R_ARM_MOVT_PREL		46	/* PC relative (MOVT).  */
-+#define R_ARM_THM_MOVW_ABS_NC	47	/* Direct 16 bit (Thumb32 MOVW).  */
-+#define R_ARM_THM_MOVT_ABS	48	/* Direct high 16 bit
-+					   (Thumb32 MOVT).  */
-+#define R_ARM_THM_MOVW_PREL_NC	49	/* PC relative 16 bit
-+					   (Thumb32 MOVW).  */
-+#define R_ARM_THM_MOVT_PREL	50	/* PC relative high 16 bit
-+					   (Thumb32 MOVT).  */
-+#define R_ARM_THM_JUMP19	51	/* PC relative 20 bit
-+					   (Thumb32 B<cond>.W).  */
-+#define R_ARM_THM_JUMP6		52	/* PC relative X & 0x7E
-+					   (Thumb16 CBZ, CBNZ).  */
-+#define R_ARM_THM_ALU_PREL_11_0	53	/* PC relative 12 bit
-+					   (Thumb32 ADR.W).  */
-+#define R_ARM_THM_PC12		54	/* PC relative 12 bit
-+					   (Thumb32 LDR{D,SB,H,SH}).  */
-+#define R_ARM_ABS32_NOI		55	/* Direct 32-bit.  */
-+#define R_ARM_REL32_NOI		56	/* PC relative 32-bit.  */
-+#define R_ARM_ALU_PC_G0_NC	57	/* PC relative (ADD, SUB).  */
-+#define R_ARM_ALU_PC_G0		58	/* PC relative (ADD, SUB).  */
-+#define R_ARM_ALU_PC_G1_NC	59	/* PC relative (ADD, SUB).  */
-+#define R_ARM_ALU_PC_G1		60	/* PC relative (ADD, SUB).  */
-+#define R_ARM_ALU_PC_G2		61	/* PC relative (ADD, SUB).  */
-+#define R_ARM_LDR_PC_G1		62	/* PC relative (LDR,STR,LDRB,STRB).  */
-+#define R_ARM_LDR_PC_G2		63	/* PC relative (LDR,STR,LDRB,STRB).  */
-+#define R_ARM_LDRS_PC_G0	64	/* PC relative (STR{D,H},
-+					   LDR{D,SB,H,SH}).  */
-+#define R_ARM_LDRS_PC_G1	65	/* PC relative (STR{D,H},
-+					   LDR{D,SB,H,SH}).  */
-+#define R_ARM_LDRS_PC_G2	66	/* PC relative (STR{D,H},
-+					   LDR{D,SB,H,SH}).  */
-+#define R_ARM_LDC_PC_G0		67	/* PC relative (LDC, STC).  */
-+#define R_ARM_LDC_PC_G1		68	/* PC relative (LDC, STC).  */
-+#define R_ARM_LDC_PC_G2		69	/* PC relative (LDC, STC).  */
-+#define R_ARM_ALU_SB_G0_NC	70	/* Program base relative (ADD,SUB).  */
-+#define R_ARM_ALU_SB_G0		71	/* Program base relative (ADD,SUB).  */
-+#define R_ARM_ALU_SB_G1_NC	72	/* Program base relative (ADD,SUB).  */
-+#define R_ARM_ALU_SB_G1		73	/* Program base relative (ADD,SUB).  */
-+#define R_ARM_ALU_SB_G2		74	/* Program base relative (ADD,SUB).  */
-+#define R_ARM_LDR_SB_G0		75	/* Program base relative (LDR,
-+					   STR, LDRB, STRB).  */
-+#define R_ARM_LDR_SB_G1		76	/* Program base relative
-+					   (LDR, STR, LDRB, STRB).  */
-+#define R_ARM_LDR_SB_G2		77	/* Program base relative
-+					   (LDR, STR, LDRB, STRB).  */
-+#define R_ARM_LDRS_SB_G0	78	/* Program base relative
-+					   (LDR, STR, LDRB, STRB).  */
-+#define R_ARM_LDRS_SB_G1	79	/* Program base relative
-+					   (LDR, STR, LDRB, STRB).  */
-+#define R_ARM_LDRS_SB_G2	80	/* Program base relative
-+					   (LDR, STR, LDRB, STRB).  */
-+#define R_ARM_LDC_SB_G0		81	/* Program base relative (LDC,STC).  */
-+#define R_ARM_LDC_SB_G1		82	/* Program base relative (LDC,STC).  */
-+#define R_ARM_LDC_SB_G2		83	/* Program base relative (LDC,STC).  */
-+#define R_ARM_MOVW_BREL_NC	84	/* Program base relative 16
-+					   bit (MOVW).  */
-+#define R_ARM_MOVT_BREL		85	/* Program base relative high
-+					   16 bit (MOVT).  */
-+#define R_ARM_MOVW_BREL		86	/* Program base relative 16
-+					   bit (MOVW).  */
-+#define R_ARM_THM_MOVW_BREL_NC	87	/* Program base relative 16
-+					   bit (Thumb32 MOVW).  */
-+#define R_ARM_THM_MOVT_BREL	88	/* Program base relative high
-+					   16 bit (Thumb32 MOVT).  */
-+#define R_ARM_THM_MOVW_BREL	89	/* Program base relative 16
-+					   bit (Thumb32 MOVW).  */
-+#define R_ARM_TLS_GOTDESC	90
-+#define R_ARM_TLS_CALL		91
-+#define R_ARM_TLS_DESCSEQ	92	/* TLS relaxation.  */
-+#define R_ARM_THM_TLS_CALL	93
-+#define R_ARM_PLT32_ABS		94
-+#define R_ARM_GOT_ABS		95	/* GOT entry.  */
-+#define R_ARM_GOT_PREL		96	/* PC relative GOT entry.  */
-+#define R_ARM_GOT_BREL12	97	/* GOT entry relative to GOT
-+					   origin (LDR).  */
-+#define R_ARM_GOTOFF12		98	/* 12 bit, GOT entry relative
-+					   to GOT origin (LDR, STR).  */
-+#define R_ARM_GOTRELAX		99
- #define R_ARM_GNU_VTENTRY	100
- #define R_ARM_GNU_VTINHERIT	101
--#define R_ARM_THM_PC11		102	/* thumb unconditional branch */
--#define R_ARM_THM_PC9		103	/* thumb conditional branch */
-+#define R_ARM_THM_PC11		102	/* PC relative & 0xFFE (Thumb16 B).  */
-+#define R_ARM_THM_PC9		103	/* PC relative & 0x1FE
-+					   (Thumb16 B/B<cond>).  */
- #define R_ARM_TLS_GD32		104	/* PC-rel 32 bit for global dynamic
- 					   thread local data */
- #define R_ARM_TLS_LDM32		105	/* PC-rel 32 bit for local dynamic
-@@ -2269,6 +2571,19 @@ typedef Elf32_Addr Elf32_Conflict;
- 					   static TLS block offset */
- #define R_ARM_TLS_LE32		108	/* 32 bit offset relative to static
- 					   TLS block */
-+#define R_ARM_TLS_LDO12		109	/* 12 bit relative to TLS
-+					   block (LDR, STR).  */
-+#define R_ARM_TLS_LE12		110	/* 12 bit relative to static
-+					   TLS block (LDR, STR).  */
-+#define R_ARM_TLS_IE12GP	111	/* 12 bit GOT entry relative
-+					   to GOT origin (LDR).  */
-+#define R_ARM_ME_TOO		128	/* Obsolete.  */
-+#define R_ARM_THM_TLS_DESCSEQ	129
-+#define R_ARM_THM_TLS_DESCSEQ16	129
-+#define R_ARM_THM_TLS_DESCSEQ32	130
-+#define R_ARM_THM_GOT_BREL12	131	/* GOT entry relative to GOT
-+					   origin, 12 bit (Thumb32 LDR).  */
-+#define R_ARM_IRELATIVE		160
- #define R_ARM_RXPC25		249
- #define R_ARM_RSBREL32		250
- #define R_ARM_THM_RPC22		251
-@@ -2393,6 +2708,30 @@ typedef Elf32_Addr Elf32_Conflict;
- 
- /* SH specific declarations */
- 
-+/* Processor specific flags for the ELF header e_flags field.  */
-+#define EF_SH_MACH_MASK		0x1f
-+#define EF_SH_UNKNOWN		0x0
-+#define EF_SH1			0x1
-+#define EF_SH2			0x2
-+#define EF_SH3			0x3
-+#define EF_SH_DSP		0x4
-+#define EF_SH3_DSP		0x5
-+#define EF_SH4AL_DSP		0x6
-+#define EF_SH3E			0x8
-+#define EF_SH4			0x9
-+#define EF_SH2E			0xb
-+#define EF_SH4A			0xc
-+#define EF_SH2A			0xd
-+#define EF_SH4_NOFPU		0x10
-+#define EF_SH4A_NOFPU		0x11
-+#define EF_SH4_NOMMU_NOFPU	0x12
-+#define EF_SH2A_NOFPU		0x13
-+#define EF_SH3_NOMMU		0x14
-+#define EF_SH2A_SH4_NOFPU	0x15
-+#define EF_SH2A_SH3_NOFPU	0x16
-+#define EF_SH2A_SH4		0x17
-+#define EF_SH2A_SH3E		0x18
-+
- /* SH relocs.  */
- #define	R_SH_NONE		0
- #define	R_SH_DIR32		1
-@@ -2434,6 +2773,12 @@ typedef Elf32_Addr Elf32_Conflict;
- /* Keep this the last entry.  */
- #define	R_SH_NUM		256
- 
-+/* S/390 specific definitions.  */
-+
-+/* Valid values for the e_flags field.  */
-+
-+#define EF_S390_HIGH_GPRS    0x00000001  /* High GPRs kernel facility needed.  */
-+
- /* Additional s390 relocs */
- 
- #define R_390_NONE		0	/* No reloc.  */
-@@ -2515,8 +2860,9 @@ typedef Elf32_Addr Elf32_Conflict;
- #define R_390_GOTPLT20		59	/* 20 bit offset to jump slot.  */
- #define R_390_TLS_GOTIE20	60	/* 20 bit GOT offset for static TLS
- 					   block offset.  */
-+#define R_390_IRELATIVE         61      /* STT_GNU_IFUNC relocation.  */
- /* Keep this the last entry.  */
--#define R_390_NUM		61
-+#define R_390_NUM		62
- 
- 
- /* CRIS relocations.  */
-@@ -2577,13 +2923,23 @@ typedef Elf32_Addr Elf32_Conflict;
- #define R_X86_64_GOTOFF64	25	/* 64 bit offset to GOT */
- #define R_X86_64_GOTPC32	26	/* 32 bit signed pc relative
- 					   offset to GOT */
--/* 27 .. 33 */
-+#define R_X86_64_GOT64		27	/* 64-bit GOT entry offset */
-+#define R_X86_64_GOTPCREL64	28	/* 64-bit PC relative offset
-+					   to GOT entry */
-+#define R_X86_64_GOTPC64	29	/* 64-bit PC relative offset to GOT */
-+#define R_X86_64_GOTPLT64	30 	/* like GOT64, says PLT entry needed */
-+#define R_X86_64_PLTOFF64	31	/* 64-bit GOT relative offset
-+					   to PLT entry */
-+#define R_X86_64_SIZE32		32	/* Size of symbol plus 32-bit addend */
-+#define R_X86_64_SIZE64		33	/* Size of symbol plus 64-bit addend */
- #define R_X86_64_GOTPC32_TLSDESC 34	/* GOT offset for TLS descriptor.  */
- #define R_X86_64_TLSDESC_CALL   35	/* Marker for call through TLS
- 					   descriptor.  */
- #define R_X86_64_TLSDESC        36	/* TLS descriptor.  */
-+#define R_X86_64_IRELATIVE	37	/* Adjust indirectly by program base */
-+#define R_X86_64_RELATIVE64	38	/* 64-bit adjust by program base */
- 
--#define R_X86_64_NUM		37
-+#define R_X86_64_NUM		39
- 
- 
- /* AM33 relocations.  */
-@@ -2611,8 +2967,23 @@ typedef Elf32_Addr Elf32_Conflict;
- #define R_MN10300_GLOB_DAT	21	/* Create GOT entry.  */
- #define R_MN10300_JMP_SLOT	22	/* Create PLT entry.  */
- #define R_MN10300_RELATIVE	23	/* Adjust by program base.  */
--
--#define R_MN10300_NUM		24
-+#define R_MN10300_TLS_GD	24	/* 32-bit offset for global dynamic.  */
-+#define R_MN10300_TLS_LD	25	/* 32-bit offset for local dynamic.  */
-+#define R_MN10300_TLS_LDO	26	/* Module-relative offset.  */
-+#define R_MN10300_TLS_GOTIE	27	/* GOT offset for static TLS block
-+					   offset.  */
-+#define R_MN10300_TLS_IE	28	/* GOT address for static TLS block
-+					   offset.  */
-+#define R_MN10300_TLS_LE	29	/* Offset relative to static TLS
-+					   block.  */
-+#define R_MN10300_TLS_DTPMOD	30	/* ID of module containing symbol.  */
-+#define R_MN10300_TLS_DTPOFF	31	/* Offset in module TLS block.  */
-+#define R_MN10300_TLS_TPOFF	32	/* Offset in static TLS block.  */
-+#define R_MN10300_SYM_DIFF	33	/* Adjustment for next reloc as needed
-+					   by linker relaxation.  */
-+#define R_MN10300_ALIGN		34	/* Alignment requirement for linker
-+					   relaxation.  */
-+#define R_MN10300_NUM		35
- 
- 
- /* M32R relocs.  */
-@@ -2670,5 +3041,264 @@ typedef Elf32_Addr Elf32_Conflict;
- #define R_M32R_GOTOFF_LO	64	/* Low 16 bit offset to GOT */
- #define R_M32R_NUM		256	/* Keep this the last entry. */
- 
-+/* MicroBlaze relocations */
-+#define R_MICROBLAZE_NONE		0	/* No reloc. */
-+#define R_MICROBLAZE_32 		1	/* Direct 32 bit. */
-+#define R_MICROBLAZE_32_PCREL		2	/* PC relative 32 bit. */
-+#define R_MICROBLAZE_64_PCREL		3	/* PC relative 64 bit. */
-+#define R_MICROBLAZE_32_PCREL_LO	4	/* Low 16 bits of PCREL32. */
-+#define R_MICROBLAZE_64 		5	/* Direct 64 bit. */
-+#define R_MICROBLAZE_32_LO		6	/* Low 16 bit. */
-+#define R_MICROBLAZE_SRO32		7	/* Read-only small data area. */
-+#define R_MICROBLAZE_SRW32		8	/* Read-write small data area. */
-+#define R_MICROBLAZE_64_NONE		9	/* No reloc. */
-+#define R_MICROBLAZE_32_SYM_OP_SYM	10	/* Symbol Op Symbol relocation. */
-+#define R_MICROBLAZE_GNU_VTINHERIT	11	/* GNU C++ vtable hierarchy. */
-+#define R_MICROBLAZE_GNU_VTENTRY	12	/* GNU C++ vtable member usage. */
-+#define R_MICROBLAZE_GOTPC_64		13	/* PC-relative GOT offset.  */
-+#define R_MICROBLAZE_GOT_64		14	/* GOT entry offset.  */
-+#define R_MICROBLAZE_PLT_64		15	/* PLT offset (PC-relative).  */
-+#define R_MICROBLAZE_REL		16	/* Adjust by program base.  */
-+#define R_MICROBLAZE_JUMP_SLOT		17	/* Create PLT entry.  */
-+#define R_MICROBLAZE_GLOB_DAT		18	/* Create GOT entry.  */
-+#define R_MICROBLAZE_GOTOFF_64		19	/* 64 bit offset to GOT. */
-+#define R_MICROBLAZE_GOTOFF_32		20	/* 32 bit offset to GOT. */
-+#define R_MICROBLAZE_COPY		21	/* Runtime copy.  */
-+#define R_MICROBLAZE_TLS		22	/* TLS Reloc. */
-+#define R_MICROBLAZE_TLSGD		23	/* TLS General Dynamic. */
-+#define R_MICROBLAZE_TLSLD		24	/* TLS Local Dynamic. */
-+#define R_MICROBLAZE_TLSDTPMOD32	25	/* TLS Module ID. */
-+#define R_MICROBLAZE_TLSDTPREL32	26	/* TLS Offset Within TLS Block. */
-+#define R_MICROBLAZE_TLSDTPREL64	27	/* TLS Offset Within TLS Block. */
-+#define R_MICROBLAZE_TLSGOTTPREL32	28	/* TLS Offset From Thread Pointer. */
-+#define R_MICROBLAZE_TLSTPREL32 	29	/* TLS Offset From Thread Pointer. */
-+
-+/* TILEPro relocations.  */
-+#define R_TILEPRO_NONE		0	/* No reloc */
-+#define R_TILEPRO_32		1	/* Direct 32 bit */
-+#define R_TILEPRO_16		2	/* Direct 16 bit */
-+#define R_TILEPRO_8		3	/* Direct 8 bit */
-+#define R_TILEPRO_32_PCREL	4	/* PC relative 32 bit */
-+#define R_TILEPRO_16_PCREL	5	/* PC relative 16 bit */
-+#define R_TILEPRO_8_PCREL	6	/* PC relative 8 bit */
-+#define R_TILEPRO_LO16		7	/* Low 16 bit */
-+#define R_TILEPRO_HI16		8	/* High 16 bit */
-+#define R_TILEPRO_HA16		9	/* High 16 bit, adjusted */
-+#define R_TILEPRO_COPY		10	/* Copy relocation */
-+#define R_TILEPRO_GLOB_DAT	11	/* Create GOT entry */
-+#define R_TILEPRO_JMP_SLOT	12	/* Create PLT entry */
-+#define R_TILEPRO_RELATIVE	13	/* Adjust by program base */
-+#define R_TILEPRO_BROFF_X1	14	/* X1 pipe branch offset */
-+#define R_TILEPRO_JOFFLONG_X1	15	/* X1 pipe jump offset */
-+#define R_TILEPRO_JOFFLONG_X1_PLT 16	/* X1 pipe jump offset to PLT */
-+#define R_TILEPRO_IMM8_X0	17	/* X0 pipe 8-bit */
-+#define R_TILEPRO_IMM8_Y0	18	/* Y0 pipe 8-bit */
-+#define R_TILEPRO_IMM8_X1	19	/* X1 pipe 8-bit */
-+#define R_TILEPRO_IMM8_Y1	20	/* Y1 pipe 8-bit */
-+#define R_TILEPRO_MT_IMM15_X1	21	/* X1 pipe mtspr */
-+#define R_TILEPRO_MF_IMM15_X1	22	/* X1 pipe mfspr */
-+#define R_TILEPRO_IMM16_X0	23	/* X0 pipe 16-bit */
-+#define R_TILEPRO_IMM16_X1	24	/* X1 pipe 16-bit */
-+#define R_TILEPRO_IMM16_X0_LO	25	/* X0 pipe low 16-bit */
-+#define R_TILEPRO_IMM16_X1_LO	26	/* X1 pipe low 16-bit */
-+#define R_TILEPRO_IMM16_X0_HI	27	/* X0 pipe high 16-bit */
-+#define R_TILEPRO_IMM16_X1_HI	28	/* X1 pipe high 16-bit */
-+#define R_TILEPRO_IMM16_X0_HA	29	/* X0 pipe high 16-bit, adjusted */
-+#define R_TILEPRO_IMM16_X1_HA	30	/* X1 pipe high 16-bit, adjusted */
-+#define R_TILEPRO_IMM16_X0_PCREL 31	/* X0 pipe PC relative 16 bit */
-+#define R_TILEPRO_IMM16_X1_PCREL 32	/* X1 pipe PC relative 16 bit */
-+#define R_TILEPRO_IMM16_X0_LO_PCREL 33	/* X0 pipe PC relative low 16 bit */
-+#define R_TILEPRO_IMM16_X1_LO_PCREL 34	/* X1 pipe PC relative low 16 bit */
-+#define R_TILEPRO_IMM16_X0_HI_PCREL 35	/* X0 pipe PC relative high 16 bit */
-+#define R_TILEPRO_IMM16_X1_HI_PCREL 36	/* X1 pipe PC relative high 16 bit */
-+#define R_TILEPRO_IMM16_X0_HA_PCREL 37	/* X0 pipe PC relative ha() 16 bit */
-+#define R_TILEPRO_IMM16_X1_HA_PCREL 38	/* X1 pipe PC relative ha() 16 bit */
-+#define R_TILEPRO_IMM16_X0_GOT	39	/* X0 pipe 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT	40	/* X1 pipe 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_LO 41	/* X0 pipe low 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_LO 42	/* X1 pipe low 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_HI 43	/* X0 pipe high 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_HI 44	/* X1 pipe high 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X0_GOT_HA 45	/* X0 pipe ha() 16-bit GOT offset */
-+#define R_TILEPRO_IMM16_X1_GOT_HA 46	/* X1 pipe ha() 16-bit GOT offset */
-+#define R_TILEPRO_MMSTART_X0	47	/* X0 pipe mm "start" */
-+#define R_TILEPRO_MMEND_X0	48	/* X0 pipe mm "end" */
-+#define R_TILEPRO_MMSTART_X1	49	/* X1 pipe mm "start" */
-+#define R_TILEPRO_MMEND_X1	50	/* X1 pipe mm "end" */
-+#define R_TILEPRO_SHAMT_X0	51	/* X0 pipe shift amount */
-+#define R_TILEPRO_SHAMT_X1	52	/* X1 pipe shift amount */
-+#define R_TILEPRO_SHAMT_Y0	53	/* Y0 pipe shift amount */
-+#define R_TILEPRO_SHAMT_Y1	54	/* Y1 pipe shift amount */
-+#define R_TILEPRO_DEST_IMM8_X1	55	/* X1 pipe destination 8-bit */
-+/* Relocs 56-59 are currently not defined.  */
-+#define R_TILEPRO_TLS_GD_CALL	60	/* "jal" for TLS GD */
-+#define R_TILEPRO_IMM8_X0_TLS_GD_ADD 61	/* X0 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_X1_TLS_GD_ADD 62	/* X1 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_Y0_TLS_GD_ADD 63	/* Y0 pipe "addi" for TLS GD */
-+#define R_TILEPRO_IMM8_Y1_TLS_GD_ADD 64	/* Y1 pipe "addi" for TLS GD */
-+#define R_TILEPRO_TLS_IE_LOAD	65	/* "lw_tls" for TLS IE */
-+#define R_TILEPRO_IMM16_X0_TLS_GD 66	/* X0 pipe 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD 67	/* X1 pipe 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_LO 68	/* X0 pipe low 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_LO 69	/* X1 pipe low 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_HI 70	/* X0 pipe high 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_HI 71	/* X1 pipe high 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_GD_HA 72	/* X0 pipe ha() 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X1_TLS_GD_HA 73	/* X1 pipe ha() 16-bit TLS GD offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE 74	/* X0 pipe 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE 75	/* X1 pipe 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_LO 76	/* X0 pipe low 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_LO 77	/* X1 pipe low 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_HI 78	/* X0 pipe high 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_HI 79	/* X1 pipe high 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_IE_HA 80	/* X0 pipe ha() 16-bit TLS IE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_IE_HA 81	/* X1 pipe ha() 16-bit TLS IE offset */
-+#define R_TILEPRO_TLS_DTPMOD32	82	/* ID of module containing symbol */
-+#define R_TILEPRO_TLS_DTPOFF32	83	/* Offset in TLS block */
-+#define R_TILEPRO_TLS_TPOFF32	84	/* Offset in static TLS block */
-+#define R_TILEPRO_IMM16_X0_TLS_LE 85	/* X0 pipe 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE 86	/* X1 pipe 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_LO 87	/* X0 pipe low 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_LO 88	/* X1 pipe low 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_HI 89	/* X0 pipe high 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_HI 90	/* X1 pipe high 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X0_TLS_LE_HA 91	/* X0 pipe ha() 16-bit TLS LE offset */
-+#define R_TILEPRO_IMM16_X1_TLS_LE_HA 92	/* X1 pipe ha() 16-bit TLS LE offset */
-+
-+#define R_TILEPRO_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
-+#define R_TILEPRO_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
-+
-+#define R_TILEPRO_NUM		130
-+
-+
-+/* TILE-Gx relocations.  */
-+#define R_TILEGX_NONE		0	/* No reloc */
-+#define R_TILEGX_64		1	/* Direct 64 bit */
-+#define R_TILEGX_32		2	/* Direct 32 bit */
-+#define R_TILEGX_16		3	/* Direct 16 bit */
-+#define R_TILEGX_8		4	/* Direct 8 bit */
-+#define R_TILEGX_64_PCREL	5	/* PC relative 64 bit */
-+#define R_TILEGX_32_PCREL	6	/* PC relative 32 bit */
-+#define R_TILEGX_16_PCREL	7	/* PC relative 16 bit */
-+#define R_TILEGX_8_PCREL	8	/* PC relative 8 bit */
-+#define R_TILEGX_HW0		9	/* hword 0 16-bit */
-+#define R_TILEGX_HW1		10	/* hword 1 16-bit */
-+#define R_TILEGX_HW2		11	/* hword 2 16-bit */
-+#define R_TILEGX_HW3		12	/* hword 3 16-bit */
-+#define R_TILEGX_HW0_LAST	13	/* last hword 0 16-bit */
-+#define R_TILEGX_HW1_LAST	14	/* last hword 1 16-bit */
-+#define R_TILEGX_HW2_LAST	15	/* last hword 2 16-bit */
-+#define R_TILEGX_COPY		16	/* Copy relocation */
-+#define R_TILEGX_GLOB_DAT	17	/* Create GOT entry */
-+#define R_TILEGX_JMP_SLOT	18	/* Create PLT entry */
-+#define R_TILEGX_RELATIVE	19	/* Adjust by program base */
-+#define R_TILEGX_BROFF_X1	20	/* X1 pipe branch offset */
-+#define R_TILEGX_JUMPOFF_X1	21	/* X1 pipe jump offset */
-+#define R_TILEGX_JUMPOFF_X1_PLT	22	/* X1 pipe jump offset to PLT */
-+#define R_TILEGX_IMM8_X0	23	/* X0 pipe 8-bit */
-+#define R_TILEGX_IMM8_Y0	24	/* Y0 pipe 8-bit */
-+#define R_TILEGX_IMM8_X1	25	/* X1 pipe 8-bit */
-+#define R_TILEGX_IMM8_Y1	26	/* Y1 pipe 8-bit */
-+#define R_TILEGX_DEST_IMM8_X1	27	/* X1 pipe destination 8-bit */
-+#define R_TILEGX_MT_IMM14_X1	28	/* X1 pipe mtspr */
-+#define R_TILEGX_MF_IMM14_X1	29	/* X1 pipe mfspr */
-+#define R_TILEGX_MMSTART_X0	30	/* X0 pipe mm "start" */
-+#define R_TILEGX_MMEND_X0	31	/* X0 pipe mm "end" */
-+#define R_TILEGX_SHAMT_X0	32	/* X0 pipe shift amount */
-+#define R_TILEGX_SHAMT_X1	33	/* X1 pipe shift amount */
-+#define R_TILEGX_SHAMT_Y0	34	/* Y0 pipe shift amount */
-+#define R_TILEGX_SHAMT_Y1	35	/* Y1 pipe shift amount */
-+#define R_TILEGX_IMM16_X0_HW0	36	/* X0 pipe hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0	37	/* X1 pipe hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1	38	/* X0 pipe hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1	39	/* X1 pipe hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2	40	/* X0 pipe hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2	41	/* X1 pipe hword 2 */
-+#define R_TILEGX_IMM16_X0_HW3	42	/* X0 pipe hword 3 */
-+#define R_TILEGX_IMM16_X1_HW3	43	/* X1 pipe hword 3 */
-+#define R_TILEGX_IMM16_X0_HW0_LAST 44	/* X0 pipe last hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_LAST 45	/* X1 pipe last hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_LAST 46	/* X0 pipe last hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_LAST 47	/* X1 pipe last hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_LAST 48	/* X0 pipe last hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_LAST 49	/* X1 pipe last hword 2 */
-+#define R_TILEGX_IMM16_X0_HW0_PCREL 50	/* X0 pipe PC relative hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_PCREL 51	/* X1 pipe PC relative hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_PCREL 52	/* X0 pipe PC relative hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_PCREL 53	/* X1 pipe PC relative hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_PCREL 54	/* X0 pipe PC relative hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_PCREL 55	/* X1 pipe PC relative hword 2 */
-+#define R_TILEGX_IMM16_X0_HW3_PCREL 56	/* X0 pipe PC relative hword 3 */
-+#define R_TILEGX_IMM16_X1_HW3_PCREL 57	/* X1 pipe PC relative hword 3 */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_PCREL 58 /* X0 pipe PC-rel last hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_PCREL 59 /* X1 pipe PC-rel last hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_PCREL 60 /* X0 pipe PC-rel last hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_PCREL 61 /* X1 pipe PC-rel last hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_LAST_PCREL 62 /* X0 pipe PC-rel last hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_LAST_PCREL 63 /* X1 pipe PC-rel last hword 2 */
-+#define R_TILEGX_IMM16_X0_HW0_GOT 64	/* X0 pipe hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW0_GOT 65	/* X1 pipe hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X0_HW0_PLT_PCREL 66 /* X0 pipe PC-rel PLT hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_PLT_PCREL 67 /* X1 pipe PC-rel PLT hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_PLT_PCREL 68 /* X0 pipe PC-rel PLT hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_PLT_PCREL 69 /* X1 pipe PC-rel PLT hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_PLT_PCREL 70 /* X0 pipe PC-rel PLT hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_PLT_PCREL 71 /* X1 pipe PC-rel PLT hword 2 */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_GOT 72 /* X0 pipe last hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_GOT 73 /* X1 pipe last hword 0 GOT offset */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_GOT 74 /* X0 pipe last hword 1 GOT offset */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_GOT 75 /* X1 pipe last hword 1 GOT offset */
-+#define R_TILEGX_IMM16_X0_HW3_PLT_PCREL 76 /* X0 pipe PC-rel PLT hword 3 */
-+#define R_TILEGX_IMM16_X1_HW3_PLT_PCREL 77 /* X1 pipe PC-rel PLT hword 3 */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_GD 78	/* X0 pipe hword 0 TLS GD offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_GD 79	/* X1 pipe hword 0 TLS GD offset */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_LE 80	/* X0 pipe hword 0 TLS LE offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_LE 81	/* X1 pipe hword 0 TLS LE offset */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE 82 /* X0 pipe last hword 0 LE off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE 83 /* X1 pipe last hword 0 LE off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE 84 /* X0 pipe last hword 1 LE off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE 85 /* X1 pipe last hword 1 LE off */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD 86 /* X0 pipe last hword 0 GD off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD 87 /* X1 pipe last hword 0 GD off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD 88 /* X0 pipe last hword 1 GD off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD 89 /* X1 pipe last hword 1 GD off */
-+/* Relocs 90-91 are currently not defined.  */
-+#define R_TILEGX_IMM16_X0_HW0_TLS_IE 92	/* X0 pipe hword 0 TLS IE offset */
-+#define R_TILEGX_IMM16_X1_HW0_TLS_IE 93	/* X1 pipe hword 0 TLS IE offset */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL 94 /* X0 pipe PC-rel PLT last hword 0 */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL 95 /* X1 pipe PC-rel PLT last hword 0 */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL 96 /* X0 pipe PC-rel PLT last hword 1 */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL 97 /* X1 pipe PC-rel PLT last hword 1 */
-+#define R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL 98 /* X0 pipe PC-rel PLT last hword 2 */
-+#define R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL 99 /* X1 pipe PC-rel PLT last hword 2 */
-+#define R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE 100 /* X0 pipe last hword 0 IE off */
-+#define R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE 101 /* X1 pipe last hword 0 IE off */
-+#define R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE 102 /* X0 pipe last hword 1 IE off */
-+#define R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE 103 /* X1 pipe last hword 1 IE off */
-+/* Relocs 104-105 are currently not defined.  */
-+#define R_TILEGX_TLS_DTPMOD64	106	/* 64-bit ID of symbol's module */
-+#define R_TILEGX_TLS_DTPOFF64	107	/* 64-bit offset in TLS block */
-+#define R_TILEGX_TLS_TPOFF64	108	/* 64-bit offset in static TLS block */
-+#define R_TILEGX_TLS_DTPMOD32	109	/* 32-bit ID of symbol's module */
-+#define R_TILEGX_TLS_DTPOFF32	110	/* 32-bit offset in TLS block */
-+#define R_TILEGX_TLS_TPOFF32	111	/* 32-bit offset in static TLS block */
-+#define R_TILEGX_TLS_GD_CALL	112	/* "jal" for TLS GD */
-+#define R_TILEGX_IMM8_X0_TLS_GD_ADD 113	/* X0 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_X1_TLS_GD_ADD 114	/* X1 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_Y0_TLS_GD_ADD 115	/* Y0 pipe "addi" for TLS GD */
-+#define R_TILEGX_IMM8_Y1_TLS_GD_ADD 116	/* Y1 pipe "addi" for TLS GD */
-+#define R_TILEGX_TLS_IE_LOAD	117	/* "ld_tls" for TLS IE */
-+#define R_TILEGX_IMM8_X0_TLS_ADD 118	/* X0 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_X1_TLS_ADD 119	/* X1 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_Y0_TLS_ADD 120	/* Y0 pipe "addi" for TLS GD/IE */
-+#define R_TILEGX_IMM8_Y1_TLS_ADD 121	/* Y1 pipe "addi" for TLS GD/IE */
-+
-+#define R_TILEGX_GNU_VTINHERIT	128	/* GNU C++ vtable hierarchy */
-+#define R_TILEGX_GNU_VTENTRY	129	/* GNU C++ vtable member usage */
-+
-+#define R_TILEGX_NUM		130
-+
-+
-+/* __END_DECLS */
- 
- #endif	/* elf.h */
-diff --git a/sources/patchelf/patchelf.cc b/sources/patchelf/patchelf.cc
-index c6f495e..3ca38d9 100644
---- a/sources/patchelf/patchelf.cc
-+++ b/sources/patchelf/patchelf.cc
-@@ -1,91 +1,133 @@
-+/*
-+ *  PatchELF is a utility to modify properties of ELF executables and libraries
-+ *  Copyright (C) 2004-2016  Eelco Dolstra <edolstra at gmail.com>
-+ *
-+ *  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
-+ *  the Free Software Foundation, either version 3 of the License, or (at
-+ *  your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful, but
-+ *  WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ *  General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
- #include <string>
- #include <vector>
- #include <set>
- #include <map>
- #include <algorithm>
--
--#include <stdlib.h>
--#include <stdio.h>
--#include <stdarg.h>
--#include <assert.h>
--#include <string.h>
--#include <errno.h>
-+#include <memory>
-+#include <sstream>
-+#include <limits>
-+#include <stdexcept>
-+
-+#include <cstdlib>
-+#include <cstdio>
-+#include <cstdarg>
-+#include <cassert>
-+#include <cstring>
-+#include <cerrno>
- 
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <unistd.h>
- #include <fcntl.h>
--#include <limits.h>
- 
- #include "elf.h"
- 
--using namespace std;
- 
-+static bool debugMode = false;
- 
--#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 forceRPath = false;
- 
-+static std::vector<std::string> fileNames;
-+static int pageSize = PAGESIZE;
- 
--static bool debugMode = false;
-+typedef std::shared_ptr<std::vector<unsigned char>> FileContents;
- 
--static bool forceRPath = false;
- 
--static string fileName;
-+#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
-+#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Verneed
- 
- 
--off_t fileSize, maxSize;
--unsigned char * contents = 0;
-+static std::vector<std::string> splitColonDelimitedString(const char * s)
-+{
-+    std::vector<std::string> parts;
-+    const char * pos = s;
-+    while (*pos) {
-+        const char * end = strchr(pos, ':');
-+        if (!end) end = strchr(pos, 0);
-+
-+        parts.push_back(std::string(pos, end - pos));
-+        if (*end == ':') ++end;
-+        pos = end;
-+    }
- 
-+    return parts;
-+}
- 
--#define ElfFileParams class Elf_Ehdr, class Elf_Phdr, class Elf_Shdr, class Elf_Addr, class Elf_Off, class Elf_Dyn, class Elf_Sym
--#define ElfFileParamNames Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym
-+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;
-+}
-+
-+
-+static unsigned int getPageSize()
-+{
-+    return pageSize;
-+}
- 
- 
- template<ElfFileParams>
- class ElfFile
- {
-+public:
-+
-+    const FileContents fileContents;
-+
-+private:
-+
-+    unsigned char * contents;
-+
-     Elf_Ehdr * hdr;
--    vector<Elf_Phdr> phdrs;
--    vector<Elf_Shdr> shdrs;
-+    std::vector<Elf_Phdr> phdrs;
-+    std::vector<Elf_Shdr> shdrs;
- 
-     bool littleEndian;
- 
--    bool changed;
-+    bool changed = false;
- 
--    bool isExecutable;
-+    bool isExecutable = false;
- 
--    typedef string SectionName;
--    typedef map<SectionName, string> ReplacedSections;
-+    typedef std::string SectionName;
-+    typedef std::map<SectionName, std::string> ReplacedSections;
- 
-     ReplacedSections replacedSections;
- 
--    string sectionNames; /* content of the .shstrtab section */
-+    std::string sectionNames; /* content of the .shstrtab section */
- 
-     /* Align on 4 or 8 bytes boundaries on 32- or 64-bit platforms
-        respectively. */
--    unsigned int sectionAlignment;
-+    size_t sectionAlignment = sizeof(Elf_Off);
- 
--    vector<SectionName> sectionsByOldIndex;
-+    std::vector<SectionName> sectionsByOldIndex;
- 
- public:
- 
--    ElfFile()
--    {
--        changed = false;
--        sectionAlignment = sizeof(Elf_Off);
--    }
-+    ElfFile(FileContents fileContents);
- 
-     bool isChanged()
-     {
-         return changed;
-     }
- 
--    void parse();
--
- private:
- 
-     struct CompPhdr
-@@ -93,8 +135,11 @@ private:
-         ElfFile * elfFile;
-         bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y)
-         {
--            if (x.p_type == PT_PHDR) return true;
-+            // A PHDR comes before everything else.
-             if (y.p_type == PT_PHDR) return false;
-+            if (x.p_type == PT_PHDR) return true;
-+
-+            // Sort non-PHDRs by address.
-             return elfFile->rdi(x.p_paddr) < elfFile->rdi(y.p_paddr);
-         }
-     };
-@@ -118,7 +163,7 @@ private:
- 
-     void shiftFile(unsigned int extraPages, Elf_Addr startPage);
- 
--    string getSectionName(const Elf_Shdr & shdr);
-+    std::string getSectionName(const Elf_Shdr & shdr);
- 
-     Elf_Shdr & findSection(const SectionName & sectionName);
- 
-@@ -126,9 +171,11 @@ private:
- 
-     unsigned int findSection3(const SectionName & sectionName);
- 
--    string & replaceSection(const SectionName & sectionName,
-+    std::string & replaceSection(const SectionName & sectionName,
-         unsigned int size);
- 
-+    bool haveReplacedSection(const SectionName & sectionName);
-+
-     void writeReplacedSections(Elf_Off & curOff,
-         Elf_Addr startAddr, Elf_Off startOffset);
- 
-@@ -142,15 +189,27 @@ public:
- 
-     void rewriteSections();
- 
--    string getInterpreter();
-+    std::string getInterpreter();
- 
--    void setInterpreter(const string & newInterpreter);
-+    typedef enum { printSoname, replaceSoname } sonameMode;
- 
--    typedef enum { rpPrint, rpShrink, rpSet } RPathOp;
-+    void modifySoname(sonameMode op, const std::string & newSoname);
- 
--    void modifyRPath(RPathOp op, string newRPath);
-+    void setInterpreter(const std::string & newInterpreter);
- 
--    void removeNeeded(set<string> libs);
-+    typedef enum { rpPrint, rpShrink, rpSet, rpRemove } RPathOp;
-+
-+    void modifyRPath(RPathOp op, const std::vector<std::string> & allowedRpathPrefixes, std::string newRPath);
-+
-+    void addNeeded(const std::set<std::string> & libs);
-+
-+    void removeNeeded(const std::set<std::string> & libs);
-+
-+    void replaceNeeded(const std::map<std::string, std::string> & libs);
-+
-+    void printNeededLibs();
-+
-+    void noDefaultLib();
- 
- private:
- 
-@@ -205,73 +264,151 @@ static void debug(const char * format, ...)
- }
- 
- 
--static void error(string msg)
-+void fmt2(std::ostringstream & out)
-+{
-+}
-+
-+
-+template<typename T, typename... Args>
-+void fmt2(std::ostringstream & out, T x, Args... args)
-+{
-+    out << x;
-+    fmt2(out, args...);
-+}
-+
-+
-+template<typename... Args>
-+std::string fmt(Args... args)
- {
--    if (errno) perror(msg.c_str()); else fprintf(stderr, "%s\n", msg.c_str());
--    exit(1);
-+    std::ostringstream out;
-+    fmt2(out, args...);
-+    return out.str();
- }
- 
- 
--static void growFile(off_t newSize)
-+struct SysError : std::runtime_error
- {
--    if (newSize > maxSize) error("maximum file size exceeded");
--    if (newSize <= fileSize) return;
--    if (newSize > fileSize)
--        memset(contents + fileSize, 0, newSize - fileSize);
--    fileSize = newSize;
-+    int errNo;
-+    SysError(const std::string & msg)
-+        : std::runtime_error(fmt(msg + ": " + strerror(errno)))
-+        , errNo(errno)
-+    { }
-+};
-+
-+
-+__attribute__((noreturn)) static void error(std::string msg)
-+{
-+    if (errno)
-+        throw SysError(msg);
-+    else
-+        throw std::runtime_error(msg);
- }
- 
- 
--static void readFile(string fileName, mode_t * fileMode)
-+static void growFile(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,
-+    size_t cutOff = std::numeric_limits<size_t>::max())
- {
-     struct stat st;
--    if (stat(fileName.c_str(), &st) != 0) error("stat");
--    fileSize = st.st_size;
--    *fileMode = st.st_mode;
--    maxSize = fileSize + 8 * 1024 * 1024;
-+    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())
-+        throw SysError(fmt("cannot read file of size ", st.st_size, " into memory"));
-+
-+    size_t size = std::min(cutOff, (size_t) st.st_size);
- 
--    contents = (unsigned char *) malloc(fileSize + maxSize);
--    if (!contents) abort();
-+    FileContents contents = std::make_shared<std::vector<unsigned char>>();
-+    contents->reserve(size + 32 * 1024 * 1024);
-+    contents->resize(size, 0);
- 
-     int fd = open(fileName.c_str(), O_RDONLY);
--    if (fd == -1) error("open");
-+    if (fd == -1) throw SysError(fmt("opening '", fileName, "'"));
- 
--    if (read(fd, contents, fileSize) != fileSize) error("read");
-+    size_t bytesRead = 0;
-+    ssize_t portion;
-+    while ((portion = read(fd, contents->data() + bytesRead, size - bytesRead)) > 0)
-+        bytesRead += portion;
-+
-+    if (bytesRead != size)
-+        throw SysError(fmt("reading '", fileName, "'"));
- 
-     close(fd);
-+
-+    return contents;
- }
- 
- 
--static void checkPointer(void * p, unsigned int size)
-+struct ElfType
-+{
-+    bool is32Bit;
-+    int machine; // one of EM_*
-+};
-+
-+
-+ElfType getElfType(const FileContents & fileContents)
-+{
-+    /* Check the ELF header for basic validity. */
-+    if (fileContents->size() < (off_t) sizeof(Elf32_Ehdr)) error("missing ELF header");
-+
-+    auto contents = fileContents->data();
-+
-+    if (memcmp(contents, ELFMAG, SELFMAG) != 0)
-+        error("not an ELF executable");
-+
-+    if (contents[EI_VERSION] != EV_CURRENT)
-+        error("unsupported ELF version");
-+
-+    if (contents[EI_CLASS] != ELFCLASS32 && contents[EI_CLASS] != ELFCLASS64)
-+        error("ELF executable is not 32 or 64 bit");
-+
-+    bool is32Bit = contents[EI_CLASS] == ELFCLASS32;
-+
-+    // FIXME: endianness
-+    return ElfType{is32Bit, is32Bit ? ((Elf32_Ehdr *) contents)->e_machine : ((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 && q + size <= contents + fileSize);
-+    assert(q >= contents->data() && q + size <= contents->data() + contents->size());
- }
- 
- 
- template<ElfFileParams>
--void ElfFile<ElfFileParamNames>::parse()
-+ElfFile<ElfFileParamNames>::ElfFile(FileContents fileContents)
-+    : fileContents(fileContents)
-+    , contents(fileContents->data())
- {
--    isExecutable = false;
--
-     /* Check the ELF header for basic validity. */
--    if (fileSize < (off_t) sizeof(Elf_Ehdr)) error("missing ELF header");
-+    if (fileContents->size() < (off_t) sizeof(Elf_Ehdr)) error("missing ELF header");
- 
--    hdr = (Elf_Ehdr *) contents;
-+    hdr = (Elf_Ehdr *) fileContents->data();
- 
-     if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
-         error("not an ELF executable");
- 
--    littleEndian = contents[EI_DATA] == ELFDATA2LSB;
-+    littleEndian = hdr->e_ident[EI_DATA] == ELFDATA2LSB;
- 
-     if (rdi(hdr->e_type) != ET_EXEC && rdi(hdr->e_type) != ET_DYN)
-         error("wrong ELF type");
- 
--    if ((off_t) (rdi(hdr->e_phoff) + rdi(hdr->e_phnum) * rdi(hdr->e_phentsize)) > fileSize)
--        error("missing program headers");
-+    if ((size_t) (rdi(hdr->e_phoff) + rdi(hdr->e_phnum) * rdi(hdr->e_phentsize)) > fileContents->size())
-+        error("program header table out of bounds");
- 
--    if ((off_t) (rdi(hdr->e_shoff) + rdi(hdr->e_shnum) * rdi(hdr->e_shentsize)) > fileSize)
--        error("missing section headers");
-+    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())
-+        error("section header table out of bounds");
- 
-     if (rdi(hdr->e_phentsize) != sizeof(Elf_Phdr))
-         error("program headers have wrong size");
-@@ -292,12 +429,12 @@ void ElfFile<ElfFileParamNames>::parse()
-     assert(shstrtabIndex < shdrs.size());
-     unsigned int shstrtabSize = rdi(shdrs[shstrtabIndex].sh_size);
-     char * shstrtab = (char * ) contents + rdi(shdrs[shstrtabIndex].sh_offset);
--    checkPointer(shstrtab, shstrtabSize);
-+    checkPointer(fileContents, shstrtab, shstrtabSize);
- 
-     assert(shstrtabSize > 0);
-     assert(shstrtab[shstrtabSize - 1] == 0);
- 
--    sectionNames = string(shstrtab, shstrtabSize);
-+    sectionNames = std::string(shstrtab, shstrtabSize);
- 
-     sectionsByOldIndex.resize(hdr->e_shnum);
-     for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
-@@ -320,13 +457,13 @@ void ElfFile<ElfFileParamNames>::sortShdrs()
- {
-     /* Translate sh_link mappings to section names, since sorting the
-        sections will invalidate the sh_link fields. */
--    map<SectionName, SectionName> linkage;
-+    std::map<SectionName, SectionName> linkage;
-     for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
-         if (rdi(shdrs[i].sh_link) != 0)
-             linkage[getSectionName(shdrs[i])] = getSectionName(shdrs[rdi(shdrs[i].sh_link)]);
- 
-     /* Idem for sh_info on certain sections. */
--    map<SectionName, SectionName> info;
-+    std::map<SectionName, SectionName> info;
-     for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
-         if (rdi(shdrs[i].sh_info) != 0 &&
-             (rdi(shdrs[i].sh_type) == SHT_REL || rdi(shdrs[i].sh_type) == SHT_RELA))
-@@ -358,21 +495,22 @@ void ElfFile<ElfFileParamNames>::sortShdrs()
- }
- 
- 
--static void writeFile(string fileName, mode_t fileMode)
-+static void writeFile(std::string fileName, FileContents contents)
- {
--    string fileName2 = fileName + "_patchelf_tmp";
--
--    int fd = open(fileName2.c_str(),
--        O_CREAT | O_TRUNC | O_WRONLY, 0700);
--    if (fd == -1) error("open");
-+    int fd = open(fileName.c_str(), O_TRUNC | O_WRONLY);
-+    if (fd == -1)
-+        error("open");
- 
--    if (write(fd, contents, fileSize) != fileSize) error("write");
-+    size_t bytesWritten = 0;
-+    ssize_t portion;
-+    while ((portion = write(fd, contents->data() + bytesWritten, contents->size() - bytesWritten)) > 0)
-+        bytesWritten += portion;
- 
--    if (close(fd) != 0) error("close");
-+    if (bytesWritten != contents->size())
-+        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");
- }
- 
- 
-@@ -385,12 +523,12 @@ static unsigned int roundUp(unsigned int n, unsigned int m)
- template<ElfFileParams>
- void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, Elf_Addr startPage)
- {
--    /* Move the entire contents of the file `extraPages' pages
-+    /* 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 oldSize = fileContents->size();
-+    unsigned int shift = extraPages * getPageSize();
-+    growFile(fileContents, fileContents->size() + extraPages * getPageSize());
-+    memmove(contents + extraPages * getPageSize(), contents, oldSize);
-     memset(contents + sizeof(Elf_Ehdr), 0, shift - sizeof(Elf_Ehdr));
- 
-     /* Adjust the ELF header. */
-@@ -407,8 +545,8 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, Elf_Addr sta
-         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,14 +560,14 @@ void ElfFile<ElfFileParamNames>::shiftFile(unsigned int extraPages, Elf_Addr sta
-     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());
- }
- 
- 
- template<ElfFileParams>
--string ElfFile<ElfFileParamNames>::getSectionName(const Elf_Shdr & shdr)
-+std::string ElfFile<ElfFileParamNames>::getSectionName(const Elf_Shdr & shdr)
- {
--    return string(sectionNames.c_str() + rdi(shdr.sh_name));
-+    return std::string(sectionNames.c_str() + rdi(shdr.sh_name));
- }
- 
- 
-@@ -437,8 +575,12 @@ template<ElfFileParams>
- Elf_Shdr & ElfFile<ElfFileParamNames>::findSection(const SectionName & sectionName)
- {
-     Elf_Shdr * shdr = findSection2(sectionName);
--    if (!shdr)
--        error("cannot find section " + sectionName);
-+    if (!shdr) {
-+        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);
-+    }
-     return *shdr;
- }
- 
-@@ -459,19 +601,28 @@ unsigned int ElfFile<ElfFileParamNames>::findSection3(const SectionName & sectio
-     return 0;
- }
- 
-+template<ElfFileParams>
-+bool ElfFile<ElfFileParamNames>::haveReplacedSection(const SectionName & sectionName)
-+{
-+    ReplacedSections::iterator i = replacedSections.find(sectionName);
-+
-+    if (i != replacedSections.end())
-+        return true;
-+    return false;
-+}
- 
- template<ElfFileParams>
--string & ElfFile<ElfFileParamNames>::replaceSection(const SectionName & sectionName,
-+std::string & ElfFile<ElfFileParamNames>::replaceSection(const SectionName & sectionName,
-     unsigned int size)
- {
-     ReplacedSections::iterator i = replacedSections.find(sectionName);
--    string s;
-+    std::string s;
- 
-     if (i != replacedSections.end()) {
--        s = string(i->second);
-+        s = std::string(i->second);
-     } else {
-         Elf_Shdr & shdr = findSection(sectionName);
--        s = string((char *) contents + rdi(shdr.sh_offset), rdi(shdr.sh_size));
-+        s = std::string((char *) contents + rdi(shdr.sh_offset), rdi(shdr.sh_size));
-     }
- 
-     s.resize(size);
-@@ -488,29 +639,25 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
-     /* Overwrite the old section contents with 'X's.  Do this
-        *before* writing the new section contents (below) to prevent
-        clobbering previously written new section contents. */
--    for (ReplacedSections::iterator i = replacedSections.begin();
--         i != replacedSections.end(); ++i)
--    {
--        string sectionName = i->first;
-+    for (auto & i : replacedSections) {
-+        std::string sectionName = i.first;
-         Elf_Shdr & shdr = findSection(sectionName);
-         memset(contents + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size));
-     }
- 
--    for (ReplacedSections::iterator i = replacedSections.begin();
--         i != replacedSections.end(); ++i)
--    {
--        string sectionName = i->first;
-+    for (auto & i : replacedSections) {
-+        std::string sectionName = i.first;
-         Elf_Shdr & shdr = findSection(sectionName);
--        debug("rewriting section `%s' from offset 0x%x (size %d) to offset 0x%x (size %d)\n",
--            sectionName.c_str(), rdi(shdr.sh_offset), rdi(shdr.sh_size), curOff, i->second.size());
-+        debug("rewriting section '%s' from offset 0x%x (size %d) to offset 0x%x (size %d)\n",
-+            sectionName.c_str(), rdi(shdr.sh_offset), rdi(shdr.sh_size), curOff, i.second.size());
- 
--        memcpy(contents + curOff, (unsigned char *) i->second.c_str(),
--            i->second.size());
-+        memcpy(contents + curOff, (unsigned char *) i.second.c_str(),
-+            i.second.size());
- 
-         /* Update the section header for this section. */
-         wri(shdr.sh_offset, curOff);
-         wri(shdr.sh_addr, startAddr + (curOff - startOffset));
--        wri(shdr.sh_size, i->second.size());
-+        wri(shdr.sh_size, i.second.size());
-         wri(shdr.sh_addralign, sectionAlignment);
- 
-         /* If this is the .interp section, then the PT_INTERP segment
-@@ -535,7 +682,7 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
-                 }
-         }
- 
--        curOff += roundUp(i->second.size(), sectionAlignment);
-+        curOff += roundUp(i.second.size(), sectionAlignment);
-     }
- 
-     replacedSections.clear();
-@@ -551,58 +698,57 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
-        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;
-     }
- 
-     debug("last page is 0x%llx\n", (unsigned long long) startPage);
- 
-+    /* 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
-+       to overlap the program header table in memory; we need to shift the first
-+       few segments to someplace else. */
-+    /* Some sections may already be replaced so account for that */
-+    unsigned int i = 1;
-+    Elf_Addr pht_size = sizeof(Elf_Ehdr) + (phdrs.size() + 1)*sizeof(Elf_Phdr);
-+    while( shdrs[i].sh_addr <= pht_size && i < rdi(hdr->e_shnum) ) {
-+        if (not haveReplacedSection(getSectionName(shdrs[i])))
-+            replaceSection(getSectionName(shdrs[i]), shdrs[i].sh_size);
-+        i++;
-+    }
- 
--    /* Compute the total space needed for the replaced sections and
--       the program headers. */
--    off_t neededSpace = (phdrs.size() + 1) * sizeof(Elf_Phdr);
--    for (ReplacedSections::iterator i = replacedSections.begin();
--         i != replacedSections.end(); ++i)
--        neededSpace += roundUp(i->second.size(), sectionAlignment);
-+    /* Compute the total space needed for the replaced sections */
-+    off_t neededSpace = 0;
-+    for (auto & i : replacedSections)
-+        neededSpace += roundUp(i.second.size(), sectionAlignment);
-     debug("needed space is %d\n", neededSpace);
- 
-+    size_t startOffset = roundUp(fileContents->size(), getPageSize());
- 
--    size_t startOffset = roundUp(fileSize, pageSize);
--
--    growFile(startOffset + neededSpace);
--
-+    growFile(fileContents, startOffset + neededSpace);
- 
-     /* Even though this file is of type ET_DYN, it could actually be
-        an executable.  For instance, Gold produces executables marked
--       ET_DYN.  In that case we can still hit the kernel bug that
--       necessitated rewriteSectionsExecutable().  However, such
--       executables also tend to start at virtual address 0, so
-+       ET_DYN as does LD when linking with pie. If we move PT_PHDR, it
-+       has to stay in the first PT_LOAD segment or any subsequent ones
-+       if they're continuous in memory due to linux kernel constraints
-+       (see BUGS). Since the end of the file would be after bss, we can't 
-+       move PHDR there, we therefore choose to leave PT_PHDR where it is but
-+       move enough following sections such that we can add the extra PT_LOAD
-+       section to it. This PT_LOAD segment ensures the sections at the end of
-+       the file are mapped into memory for ld.so to process.
-+       We can't use the approach in rewriteSectionsExecutable()
-+       since DYN executables tend to start at virtual address 0, so
-        rewriteSectionsExecutable() won't work because it doesn't have
--       any virtual address space to grow downwards into.  As a
--       workaround, make sure that the virtual address of our new
--       PT_LOAD segment relative to the first PT_LOAD segment is equal
--       to its offset; otherwise we hit the kernel bug.  This may
--       require creating a hole in the executable.  The bigger the size
--       of the uninitialised data segment, the bigger the hole. */
-+       any virtual address space to grow downwards into. */
-     if (isExecutable) {
-         if (startOffset >= startPage) {
-             debug("shifting new PT_LOAD segment by %d bytes to work around a Linux kernel bug\n", startOffset - startPage);
--        } else {
--            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);
--            /* !!! We could create an actual hole in the file here,
--               but it's probably not worth the effort. */
--            growFile(fileSize + hole);
--            startOffset += hole;
-         }
-         startPage = startOffset;
-     }
- 
--
--    /* Add a segment that maps the replaced sections and program
--       headers into memory. */
-+    /* Add a segment that maps the replaced sections into memory. */
-     phdrs.resize(rdi(hdr->e_phnum) + 1);
-     wri(hdr->e_phnum, rdi(hdr->e_phnum) + 1);
-     Elf_Phdr & phdr = phdrs[rdi(hdr->e_phnum) - 1];
-@@ -611,19 +757,16 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
-     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. */
--    Elf_Off curOff = startOffset + phdrs.size() * sizeof(Elf_Phdr);
-+    Elf_Off curOff = startOffset;
-     writeReplacedSections(curOff, startPage, startOffset);
--    assert((off_t) curOff == startOffset + neededSpace);
--
-+    assert(curOff == startOffset + neededSpace);
- 
--    /* Move the program header to the start of the new area. */
--    wri(hdr->e_phoff, startOffset);
--
--    rewriteHeaders(startPage);
-+    /* Write out the updated program and section headers */
-+    rewriteHeaders(hdr->e_phoff);
- }
- 
- 
-@@ -638,9 +781,9 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
-     /* What is the index of the last replaced section? */
-     unsigned int lastReplaced = 0;
-     for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i) {
--        string sectionName = getSectionName(shdrs[i]);
-+        std::string sectionName = getSectionName(shdrs[i]);
-         if (replacedSections.find(sectionName) != replacedSections.end()) {
--            debug("using replaced section `%s'\n", sectionName.c_str());
-+            debug("using replaced section '%s'\n", sectionName.c_str());
-             lastReplaced = i;
-         }
-     }
-@@ -656,11 +799,11 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
-     assert(lastReplaced + 1 < shdrs.size()); /* !!! I'm lazy. */
-     size_t startOffset = rdi(shdrs[lastReplaced + 1].sh_offset);
-     Elf_Addr startAddr = rdi(shdrs[lastReplaced + 1].sh_addr);
--    string prevSection;
-+    std::string prevSection;
-     for (unsigned int i = 1; i <= lastReplaced; ++i) {
-         Elf_Shdr & shdr(shdrs[i]);
--        string sectionName = getSectionName(shdr);
--        debug("looking at section `%s'\n", sectionName.c_str());
-+        std::string sectionName = getSectionName(shdr);
-+        debug("looking at section '%s'\n", sectionName.c_str());
-         /* !!! Why do we stop after a .dynstr section? I can't
-            remember! */
-         if ((rdi(shdr.sh_type) == SHT_PROGBITS && sectionName != ".interp")
-@@ -672,7 +815,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
-             break;
-         } else {
-             if (replacedSections.find(sectionName) == replacedSections.end()) {
--                debug("replacing section `%s' which is in the way\n", sectionName.c_str());
-+                debug("replacing section '%s' which is in the way\n", sectionName.c_str());
-                 replaceSection(sectionName, rdi(shdr.sh_size));
-             }
-         }
-@@ -682,23 +825,33 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
-     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);
- 
--    /* Right now we assume that the section headers are somewhere near
--       the end, which appears to be the case most of the time.
--       Therefore they're not accidentally overwritten by the replaced
--       sections. !!!  Fix this. */
--    assert((off_t) rdi(hdr->e_shoff) >= startOffset);
-+    if (rdi(hdr->e_shoff) < startOffset) {
-+        /* The section headers occur too early in the file and would be
-+           overwritten by the replaced sections. Move them to the end of the file
-+           before proceeding. */
-+        off_t shoffNew = fileContents->size();
-+        off_t shSize = rdi(hdr->e_shoff) + rdi(hdr->e_shnum) * rdi(hdr->e_shentsize);
-+        growFile(fileContents, fileContents->size() + shSize);
-+        wri(hdr->e_shoff, shoffNew);
-+
-+        /* Rewrite the section header table.  For neatness, keep the
-+           sections sorted. */
-+        assert(rdi(hdr->e_shnum) == shdrs.size());
-+        sortShdrs();
-+        for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
-+            * ((Elf_Shdr *) (contents + rdi(hdr->e_shoff)) + i) = shdrs[i];
-+    }
- 
- 
-     /* Compute the total space needed for the replaced sections, the
-        ELF header, and the program headers. */
-     size_t neededSpace = sizeof(Elf_Ehdr) + phdrs.size() * sizeof(Elf_Phdr);
--    for (ReplacedSections::iterator i = replacedSections.begin();
--         i != replacedSections.end(); ++i)
--        neededSpace += roundUp(i->second.size(), sectionAlignment);
-+    for (auto & i : replacedSections)
-+        neededSpace += roundUp(i.second.size(), sectionAlignment);
- 
-     debug("needed space is %d\n", neededSpace);
- 
-@@ -711,13 +864,13 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
-         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);
-     }
-@@ -731,7 +884,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
- 
-     /* Write out the replaced sections. */
-     writeReplacedSections(curOff, firstPage, 0);
--    assert((off_t) curOff == neededSpace);
-+    assert(curOff == neededSpace);
- 
- 
-     rewriteHeaders(firstPage + rdi(hdr->e_phoff));
-@@ -743,10 +896,9 @@ void ElfFile<ElfFileParamNames>::rewriteSections()
- {
-     if (replacedSections.empty()) return;
- 
--    for (ReplacedSections::iterator i = replacedSections.begin();
--         i != replacedSections.end(); ++i)
--        debug("replacing section `%s' with size %d\n",
--            i->first.c_str(), i->second.size());
-+    for (auto & i : replacedSections)
-+        debug("replacing section '%s' with size %d\n",
-+            i.first.c_str(), i.second.size());
- 
-     if (rdi(hdr->e_type) == ET_DYN) {
-         debug("this is a dynamic library\n");
-@@ -764,11 +916,14 @@ void ElfFile<ElfFileParamNames>::rewriteHeaders(Elf_Addr phdrAddress)
-     /* Rewrite the program header table. */
- 
-     /* If there is a segment for the program header table, update it.
--       (According to the ELF spec, it must be the first entry.) */
--    if (rdi(phdrs[0].p_type) == PT_PHDR) {
--        phdrs[0].p_offset = hdr->e_phoff;
--        wri(phdrs[0].p_vaddr, wri(phdrs[0].p_paddr, phdrAddress));
--        wri(phdrs[0].p_filesz, wri(phdrs[0].p_memsz, phdrs.size() * sizeof(Elf_Phdr)));
-+       (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)));
-+            break;
-+        }
-     }
- 
-     sortPhdrs();
-@@ -815,11 +970,18 @@ void ElfFile<ElfFileParamNames>::rewriteHeaders(Elf_Addr phdrAddress)
-                 /* no idea if this makes sense, but it was needed for some
-                    program */
-                 if (!shdr) shdr = findSection2(".rel.got");
--                if (!shdr) error("cannot find .rel.dyn or .rel.got");
-+                /* some programs have neither section, but this doesn't seem
-+                   to be a problem */
-+                if (!shdr) continue;
-+                dyn->d_un.d_ptr = shdr->sh_addr;
-+            }
-+            else if (d_tag == DT_RELA) {
-+                Elf_Shdr * shdr = findSection2(".rela.dyn");
-+                /* some programs lack this section, but it doesn't seem to
-+                   be a problem */
-+                if (!shdr) continue;
-                 dyn->d_un.d_ptr = shdr->sh_addr;
-             }
--            else if (d_tag == DT_RELA)
--                dyn->d_un.d_ptr = findSection(".rela.dyn").sh_addr; /* PPC Linux */
-             else if (d_tag == DT_VERNEED)
-                 dyn->d_un.d_ptr = findSection(".gnu.version_r").sh_addr;
-             else if (d_tag == DT_VERSYM)
-@@ -835,12 +997,21 @@ void ElfFile<ElfFileParamNames>::rewriteHeaders(Elf_Addr phdrAddress)
-         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));
--            if (sym->st_shndx != SHN_UNDEF && sym->st_shndx < SHN_LORESERVE) {
--                string section = sectionsByOldIndex[rdi(sym->st_shndx)];
-+            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);
-                 assert(!section.empty());
-                 unsigned int newIndex = findSection3(section); // inefficient
--                //debug("rewriting symbol %d: index = %d (%s) -> %d\n", entry, rdi(sym->st_shndx), section.c_str(), newIndex);
-+                //debug("rewriting symbol %d: index = %d (%s) -> %d\n", entry, shndx, section.c_str(), newIndex);
-                 wri(sym->st_shndx, newIndex);
-+                /* Rewrite st_value.  FIXME: we should do this for all
-+                   types, but most don't actually change. */
-+                if (ELF32_ST_TYPE(rdi(sym->st_info)) == STT_SECTION)
-+                    wri(sym->st_value, rdi(shdrs[newIndex].sh_addr));
-             }
-         }
-     }
-@@ -848,7 +1019,7 @@ void ElfFile<ElfFileParamNames>::rewriteHeaders(Elf_Addr phdrAddress)
- 
- 
- 
--static void setSubstr(string & s, unsigned int pos, const string & t)
-+static void setSubstr(std::string & s, unsigned int pos, const std::string & t)
- {
-     assert(pos + t.size() <= s.size());
-     copy(t.begin(), t.end(), s.begin() + pos);
-@@ -856,23 +1027,102 @@ static void setSubstr(string & s, unsigned int pos, const string & t)
- 
- 
- template<ElfFileParams>
--string ElfFile<ElfFileParamNames>::getInterpreter()
-+std::string ElfFile<ElfFileParamNames>::getInterpreter()
- {
-     Elf_Shdr & shdr = findSection(".interp");
--    return string((char *) contents + rdi(shdr.sh_offset), rdi(shdr.sh_size));
-+    return std::string((char *) contents + rdi(shdr.sh_offset), rdi(shdr.sh_size));
- }
- 
-+template<ElfFileParams>
-+void ElfFile<ElfFileParamNames>::modifySoname(sonameMode op, const std::string & newSoname)
-+{
-+    if (rdi(hdr->e_type) != ET_DYN) {
-+        debug("this is not a dynamic library\n");
-+        return;
-+    }
-+
-+    Elf_Shdr & shdrDynamic = findSection(".dynamic");
-+    Elf_Shdr & shdrDynStr = findSection(".dynstr");
-+    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;
-+    for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
-+        if (rdi(dyn->d_tag) == DT_SONAME) {
-+            dynSoname = dyn;
-+            soname = strTab + rdi(dyn->d_un.d_val);
-+        }
-+    }
-+
-+    if (op == printSoname) {
-+        if (soname) {
-+            if (std::string(soname ? soname : "") == "")
-+                debug("DT_SONAME is empty\n");
-+            else
-+                printf("%s\n", soname);
-+        } else {
-+            debug("no DT_SONAME found\n");
-+        }
-+        return;
-+    }
-+
-+    if (std::string(soname ? soname : "") == newSoname) {
-+        debug("current and proposed new SONAMEs are equal keeping DT_SONAME entry\n");
-+        return;
-+    }
-+
-+    /* Zero out the previous SONAME */
-+    unsigned int sonameSize = 0;
-+    if (soname) {
-+        sonameSize = strlen(soname);
-+        memset(soname, 'X', sonameSize);
-+    }
-+
-+    debug("new SONAME is '%s'\n", newSoname.c_str());
-+
-+    /* Grow the .dynstr section to make room for the new SONAME. */
-+    debug("SONAME is too long, resizing...\n");
-+
-+    std::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 (dynSoname) {
-+        dynSoname->d_un.d_val = shdrDynStr.sh_size;
-+    } else {
-+        /* There is no DT_SONAME entry in the .dynamic section, so we
-+           have to grow the .dynamic section. */
-+        std::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), std::string(newDynamic, 0, sizeof(Elf_Dyn) * (idx + 1)));
-+
-+        /* Add the DT_SONAME entry at the top. */
-+        Elf_Dyn newDyn;
-+        wri(newDyn.d_tag, DT_SONAME);
-+        newDyn.d_un.d_val = shdrDynStr.sh_size;
-+        setSubstr(newDynamic, 0, std::string((char *)&newDyn, sizeof(Elf_Dyn)));
-+    }
-+
-+    changed = true;
-+}
- 
- template<ElfFileParams>
--void ElfFile<ElfFileParamNames>::setInterpreter(const string & newInterpreter)
-+void ElfFile<ElfFileParamNames>::setInterpreter(const std::string & newInterpreter)
- {
--    string & section = replaceSection(".interp", newInterpreter.size() + 1);
-+    std::string & section = replaceSection(".interp", newInterpreter.size() + 1);
-     setSubstr(section, 0, newInterpreter + '\0');
-     changed = true;
- }
- 
- 
--static void concatToRPath(string & rpath, const string & path)
-+static void concatToRPath(std::string & rpath, const std::string & path)
- {
-     if (!rpath.empty()) rpath += ":";
-     rpath += path;
-@@ -880,7 +1130,8 @@ static void concatToRPath(string & rpath, const string & path)
- 
- 
- template<ElfFileParams>
--void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-+void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op,
-+    const std::vector<std::string> & allowedRpathPrefixes, std::string newRPath)
- {
-     Elf_Shdr & shdrDynamic = findSection(".dynamic");
- 
-@@ -889,15 +1140,6 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-     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");
--
--    assert(strTabAddr == rdi(shdrDynStr.sh_addr));
--
- 
-     /* Walk through the dynamic section, look for the RPATH/RUNPATH
-        entry.
-@@ -907,12 +1149,12 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-        overriden by LD_LIBRARY_PATH, and it's scoped (the DT_RUNPATH
-        for an executable or library doesn't affect the search path for
-        libraries used by it).  DT_RPATH is ignored if DT_RUNPATH is
--       present.  The binutils `ld' still generates only DT_RPATH,
--       unless you use its `--enable-new-dtag' option, in which case it
-+       present.  The binutils 'ld' still generates only DT_RPATH,
-+       unless you use its '--enable-new-dtag' option, in which case it
-        generates a DT_RPATH and DT_RUNPATH pointing at the same
-        string. */
--    static vector<string> neededLibs;
--    dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
-+    std::vector<std::string> neededLibs;
-+    Elf_Dyn * dyn = (Elf_Dyn *) (contents + rdi(shdrDynamic.sh_offset));
-     Elf_Dyn * dynRPath = 0, * dynRunPath = 0;
-     char * rpath = 0;
-     for ( ; rdi(dyn->d_tag) != DT_NULL; dyn++) {
-@@ -927,7 +1169,7 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-             rpath = strTab + rdi(dyn->d_un.d_val);
-         }
-         else if (rdi(dyn->d_tag) == DT_NEEDED)
--            neededLibs.push_back(string(strTab + rdi(dyn->d_un.d_val)));
-+            neededLibs.push_back(std::string(strTab + rdi(dyn->d_un.d_val)));
-     }
- 
-     if (op == rpPrint) {
-@@ -944,19 +1186,11 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-     /* For each directory in the RPATH, check if it contains any
-        needed library. */
-     if (op == rpShrink) {
--        static vector<bool> neededLibFound(neededLibs.size(), false);
-+        std::vector<bool> neededLibFound(neededLibs.size(), false);
- 
-         newRPath = "";
- 
--        char * pos = rpath;
--        while (*pos) {
--            char * end = strchr(pos, ':');
--            if (!end) end = strchr(pos, 0);
--
--            /* Get the name of the directory. */
--            string dirName(pos, end - pos);
--            if (*end == ':') ++end;
--            pos = end;
-+        for (auto & dirName : splitColonDelimitedString(rpath)) {
- 
-             /* Non-absolute entries are allowed (e.g., the special
-                "$ORIGIN" hack). */
-@@ -965,28 +1199,62 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-                 continue;
-             }
- 
-+            /* If --allowed-rpath-prefixes was given, reject directories
-+               not starting with any of the (colon-delimited) prefixes. */
-+            if (!allowedRpathPrefixes.empty() && !hasAllowedPrefix(dirName, allowedRpathPrefixes)) {
-+                debug("removing directory '%s' from RPATH because of non-allowed prefix\n", dirName.c_str());
-+                continue;
-+            }
-+
-             /* For each library that we haven't found yet, see if it
-                exists in this directory. */
-             bool libFound = false;
-             for (unsigned int j = 0; j < neededLibs.size(); ++j)
-                 if (!neededLibFound[j]) {
--                    string libName = dirName + "/" + neededLibs[j];
--                    struct stat st;
--                    if (stat(libName.c_str(), &st) == 0) {
--                        neededLibFound[j] = true;
--                        libFound = true;
-+                    std::string libName = dirName + "/" + neededLibs[j];
-+                    try {
-+                        if (getElfType(readFile(libName, sizeof(Elf32_Ehdr))).machine == rdi(hdr->e_machine)) {
-+                            neededLibFound[j] = true;
-+                            libFound = true;
-+                        } else
-+                            debug("ignoring library '%s' because its machine type differs\n", libName.c_str());
-+                    } catch (SysError & e) {
-+                        if (e.errNo != ENOENT) throw;
-                     }
-                 }
- 
-             if (!libFound)
--                debug("removing directory `%s' from RPATH\n", dirName.c_str());
-+                debug("removing directory '%s' from RPATH\n", dirName.c_str());
-             else
-                 concatToRPath(newRPath, dirName);
-         }
-     }
- 
-+    if (op == rpRemove) {
-+        if (!rpath) {
-+            debug("no RPATH to delete\n");
-+            return;
-+        }
- 
--    if (string(rpath ? rpath : "") == newRPath) return;
-+        Elf_Dyn * 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) {
-+                debug("removing DT_RPATH entry\n");
-+                changed = true;
-+            } else if (rdi(dyn->d_tag) == DT_RUNPATH) {
-+                debug("removing DT_RUNPATH entry\n");
-+                changed = true;
-+            } else {
-+                *last++ = *dyn;
-+            }
-+        }
-+        memset(last, 0, sizeof(Elf_Dyn) * (dyn - last));
-+        return;
-+    }
-+
-+
-+    if (std::string(rpath ? rpath : "") == newRPath) return;
- 
-     changed = true;
- 
-@@ -998,7 +1266,7 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-         memset(rpath, 'X', rpathSize);
-     }
- 
--    debug("new rpath is `%s'\n", newRPath.c_str());
-+    debug("new rpath is '%s'\n", newRPath.c_str());
- 
-     if (!forceRPath && dynRPath && !dynRunPath) { /* convert DT_RPATH to DT_RUNPATH */
-         dynRPath->d_tag = DT_RUNPATH;
-@@ -1018,7 +1286,7 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-     /* Grow the .dynstr section to make room for the new RPATH. */
-     debug("rpath is too long, resizing...\n");
- 
--    string & newDynStr = replaceSection(".dynstr",
-+    std::string & newDynStr = replaceSection(".dynstr",
-         rdi(shdrDynStr.sh_size) + newRPath.size() + 1);
-     setSubstr(newDynStr, rdi(shdrDynStr.sh_size), newRPath + '\0');
- 
-@@ -1031,7 +1299,7 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
-     else {
-         /* There is no DT_RUNPATH entry in the .dynamic section, so we
-            have to grow the .dynamic section. */
--        string & newDynamic = replaceSection(".dynamic",
-+        std::string & newDynamic = replaceSection(".dynamic",
-             rdi(shdrDynamic.sh_size) + sizeof(Elf_Dyn));
- 
-         unsigned int idx = 0;
-@@ -1040,19 +1308,19 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, string newRPath)
- 
-         /* Shift all entries down by one. */
-         setSubstr(newDynamic, sizeof(Elf_Dyn),
--            string(newDynamic, 0, sizeof(Elf_Dyn) * (idx + 1)));
-+            std::string(newDynamic, 0, sizeof(Elf_Dyn) * (idx + 1)));
- 
-         /* Add the DT_RUNPATH entry at the top. */
-         Elf_Dyn newDyn;
-         wri(newDyn.d_tag, forceRPath ? DT_RPATH : DT_RUNPATH);
-         newDyn.d_un.d_val = shdrDynStr.sh_size;
--        setSubstr(newDynamic, 0, string((char *) &newDyn, sizeof(Elf_Dyn)));
-+        setSubstr(newDynamic, 0, std::string((char *) &newDyn, sizeof(Elf_Dyn)));
-     }
- }
- 
- 
- template<ElfFileParams>
--void ElfFile<ElfFileParamNames>::removeNeeded(set<string> libs)
-+void ElfFile<ElfFileParamNames>::removeNeeded(const std::set<std::string> & libs)
- {
-     if (libs.empty()) return;
- 
-@@ -1066,10 +1334,10 @@ void ElfFile<ElfFileParamNames>::removeNeeded(set<string> libs)
-         if (rdi(dyn->d_tag) == DT_NEEDED) {
-             char * name = strTab + rdi(dyn->d_un.d_val);
-             if (libs.find(name) != libs.end()) {
--                debug("removing DT_NEEDED entry `%s'\n", name);
-+                debug("removing DT_NEEDED entry '%s'\n", name);
-                 changed = true;
-             } else {
--                debug("keeping DT_NEEDED entry `%s'\n", name);
-+                debug("keeping DT_NEEDED entry '%s'\n", name);
-                 *last++ = *dyn;
-             }
-         } else
-@@ -1079,96 +1347,309 @@ void ElfFile<ElfFileParamNames>::removeNeeded(set<string> libs)
-     memset(last, 0, sizeof(Elf_Dyn) * (dyn - last));
- }
- 
-+template<ElfFileParams>
-+void ElfFile<ElfFileParamNames>::replaceNeeded(const std::map<std::string, std::string> & libs)
-+{
-+    if (libs.empty()) return;
- 
--static bool printInterpreter = false;
--static string newInterpreter;
-+    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 verNeedNum = 0;
-+
-+    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);
-+            auto i = libs.find(name);
-+            if (i != libs.end()) {
-+                auto replacement = i->second;
-+
-+                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 ...\n");
-+
-+                std::string & newDynStr = replaceSection(".dynstr",
-+                    rdi(shdrDynStr.sh_size) + replacement.size() + 1 + dynStrAddedBytes);
-+                setSubstr(newDynStr, rdi(shdrDynStr.sh_size) + dynStrAddedBytes, replacement + '\0');
-+
-+                wri(dyn->d_un.d_val, rdi(shdrDynStr.sh_size) + dynStrAddedBytes);
-+
-+                dynStrAddedBytes += replacement.size() + 1;
-+
-+                changed = true;
-+            } else {
-+                debug("keeping DT_NEEDED entry '%s'\n", name);
-+            }
-+        }
-+        if (rdi(dyn->d_tag) == DT_VERNEEDNUM) {
-+            verNeedNum = rdi(dyn->d_un.d_val);
-+        }
-+    }
- 
-+    // If a replaced library uses symbol versions, then there will also be
-+    // references to it in the "version needed" table, and these also need to
-+    // be replaced.
-+
-+    if (verNeedNum) {
-+        Elf_Shdr & shdrVersionR = findSection(".gnu.version_r");
-+        // The filename strings in the .gnu.version_r are different from the
-+        // ones in .dynamic: instead of being in .dynstr, they're in some
-+        // arbitrary section and we have to look in ->sh_link to figure out
-+        // which one.
-+        Elf_Shdr & shdrVersionRStrings = shdrs[rdi(shdrVersionR.sh_link)];
-+        // this is where we find the actual filename strings
-+        char * verStrTab = (char *) contents + rdi(shdrVersionRStrings.sh_offset);
-+        // and we also need the name of the section containing the strings, so
-+        // that we can pass it to replaceSection
-+        std::string versionRStringsSName = getSectionName(shdrVersionRStrings);
-+
-+        debug("found .gnu.version_r with %i entries, strings in %s\n", verNeedNum, versionRStringsSName.c_str());
-+
-+        unsigned int verStrAddedBytes = 0;
-+
-+        Elf_Verneed * 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()) {
-+                auto replacement = i->second;
-+
-+                debug("replacing .gnu.version_r entry '%s' with '%s'\n", file, replacement.c_str());
-+                debug("resizing string section %s ...\n", versionRStringsSName.c_str());
-+
-+                std::string & newVerDynStr = replaceSection(versionRStringsSName,
-+                    rdi(shdrVersionRStrings.sh_size) + replacement.size() + 1 + verStrAddedBytes);
-+                setSubstr(newVerDynStr, rdi(shdrVersionRStrings.sh_size) + verStrAddedBytes, replacement + '\0');
-+
-+                wri(need->vn_file, rdi(shdrVersionRStrings.sh_size) + verStrAddedBytes);
-+
-+                verStrAddedBytes += replacement.size() + 1;
-+
-+                changed = true;
-+            } else {
-+                debug("keeping .gnu.version_r entry '%s'\n", file);
-+            }
-+            // the Elf_Verneed structures form a linked list, so jump to next entry
-+            need = (Elf_Verneed *) (((char *) need) + rdi(need->vn_next));
-+            --verNeedNum;
-+        }
-+    }
-+}
-+
-+template<ElfFileParams>
-+void ElfFile<ElfFileParamNames>::addNeeded(const std::set<std::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 (auto & i : libs) length += i.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) {
-+        setSubstr(newDynStr, rdi(shdrDynStr.sh_size) + pos, i + '\0');
-+        libStrings.insert(rdi(shdrDynStr.sh_size) + pos);
-+        pos += i.size() + 1;
-+    }
-+
-+    /* add all new needed entries to the dynamic section */
-+    std::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(),
-+        std::string(newDynamic, 0, sizeof(Elf_Dyn) * (idx + 1)));
-+
-+    /* Add the DT_NEEDED entries at the top. */
-+    unsigned int i = 0;
-+    for (auto & j : libStrings) {
-+        Elf_Dyn newDyn;
-+        wri(newDyn.d_tag, DT_NEEDED);
-+        wri(newDyn.d_un.d_val, j);
-+        setSubstr(newDynamic, i * sizeof(Elf_Dyn), std::string((char *) &newDyn, sizeof(Elf_Dyn)));
-+        i++;
-+    }
-+
-+    changed = true;
-+}
-+
-+template<ElfFileParams>
-+void ElfFile<ElfFileParamNames>::printNeededLibs()
-+{
-+    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));
-+
-+    for (; rdi(dyn->d_tag) != DT_NULL; dyn++) {
-+        if (rdi(dyn->d_tag) == DT_NEEDED) {
-+            char *name = strTab + rdi(dyn->d_un.d_val);
-+            printf("%s\n", name);
-+        }
-+    }
-+}
-+
-+
-+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 {
-+        std::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),
-+                std::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, std::string((char *) &newDyn, sizeof(Elf_Dyn)));
-+    }
-+
-+    changed = true;
-+}
-+
-+
-+static bool printInterpreter = false;
-+static bool printSoname = false;
-+static bool setSoname = false;
-+static std::string newSoname;
-+static std::string newInterpreter;
- static bool shrinkRPath = false;
-+static std::vector<std::string> allowedRpathPrefixes;
-+static bool removeRPath = false;
- static bool setRPath = false;
- static bool printRPath = false;
--static string newRPath;
--static set<string> neededLibsToRemove;
--
-+static std::string newRPath;
-+static std::set<std::string> neededLibsToRemove;
-+static std::map<std::string, std::string> neededLibsToReplace;
-+static std::set<std::string> neededLibsToAdd;
-+static bool printNeeded = false;
-+static bool noDefaultLib = false;
- 
- template<class ElfFile>
--static void patchElf2(ElfFile & elfFile, mode_t fileMode)
-+static void patchElf2(ElfFile && elfFile, std::string fileName)
- {
--    elfFile.parse();
--
-     if (printInterpreter)
-         printf("%s\n", elfFile.getInterpreter().c_str());
- 
-+    if (printSoname)
-+        elfFile.modifySoname(elfFile.printSoname, "");
-+
-+    if (setSoname)
-+        elfFile.modifySoname(elfFile.replaceSoname, newSoname);
-+
-     if (newInterpreter != "")
-         elfFile.setInterpreter(newInterpreter);
- 
-     if (printRPath)
--        elfFile.modifyRPath(elfFile.rpPrint, "");
-+        elfFile.modifyRPath(elfFile.rpPrint, {}, "");
- 
-     if (shrinkRPath)
--        elfFile.modifyRPath(elfFile.rpShrink, "");
-+        elfFile.modifyRPath(elfFile.rpShrink, allowedRpathPrefixes, "");
-+    else if (removeRPath)
-+        elfFile.modifyRPath(elfFile.rpRemove, {}, "");
-     else if (setRPath)
--        elfFile.modifyRPath(elfFile.rpSet, newRPath);
-+        elfFile.modifyRPath(elfFile.rpSet, {}, newRPath);
-+
-+    if (printNeeded) elfFile.printNeededLibs();
- 
-     elfFile.removeNeeded(neededLibsToRemove);
-+    elfFile.replaceNeeded(neededLibsToReplace);
-+    elfFile.addNeeded(neededLibsToAdd);
-+
-+    if (noDefaultLib)
-+        elfFile.noDefaultLib();
- 
-     if (elfFile.isChanged()){
-         elfFile.rewriteSections();
--        writeFile(fileName, fileMode);
-+        writeFile(fileName, elfFile.fileContents);
-     }
- }
- 
- 
- static void patchElf()
- {
--    if (!printInterpreter && !printRPath)
--        debug("patching ELF file `%s'\n", fileName.c_str());
--
--    mode_t fileMode;
-+    for (auto fileName : fileNames) {
-+        if (!printInterpreter && !printRPath && !printSoname && !printNeeded)
-+            debug("patching ELF file '%s'\n", fileName.c_str());
- 
--    readFile(fileName, &fileMode);
-+        debug("Kernel page size is %u bytes\n", getPageSize());
- 
-+        auto fileContents = readFile(fileName);
- 
--    /* Check the ELF header for basic validity. */
--    if (fileSize < (off_t) sizeof(Elf32_Ehdr)) error("missing ELF header");
--
--    if (memcmp(contents, ELFMAG, SELFMAG) != 0)
--        error("not an ELF executable");
--
--    if (contents[EI_CLASS] == ELFCLASS32 &&
--        contents[EI_VERSION] == EV_CURRENT)
--    {
--        ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, Elf32_Off, Elf32_Dyn, Elf32_Sym> elfFile;
--        patchElf2(elfFile, fileMode);
--    }
--    else if (contents[EI_CLASS] == ELFCLASS64 &&
--        contents[EI_VERSION] == EV_CURRENT)
--    {
--        ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Addr, Elf64_Off, Elf64_Dyn, Elf64_Sym> elfFile;
--        patchElf2(elfFile, fileMode);
--    }
--    else {
--        error("ELF executable is not 32/64-bit, little/big-endian, version 1");
-+        if (getElfType(fileContents).is32Bit)
-+            patchElf2(ElfFile<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Addr, Elf32_Off, Elf32_Dyn, Elf32_Sym, Elf32_Verneed>(fileContents), fileName);
-+        else
-+            patchElf2(ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Addr, Elf64_Off, Elf64_Dyn, Elf64_Sym, Elf64_Verneed>(fileContents), fileName);
-     }
- }
- 
- 
--void showHelp(const string & progName)
-+void showHelp(const std::string & progName)
- {
-         fprintf(stderr, "syntax: %s\n\
-   [--set-interpreter FILENAME]\n\
-+  [--page-size SIZE]\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.\n\
-   [--set-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\
-   [--print-rpath]\n\
-   [--force-rpath]\n\
-+  [--add-needed LIBRARY]\n\
-   [--remove-needed LIBRARY]\n\
-+  [--replace-needed LIBRARY NEW_LIBRARY]\n\
-+  [--print-needed]\n\
-+  [--no-default-lib]\n\
-   [--debug]\n\
-   [--version]\n\
-   FILENAME\n", progName.c_str());
- }
- 
- 
--int main(int argc, char * * argv)
-+int mainWrapped(int argc, char * * argv)
- {
-     if (argc <= 1) {
-         showHelp(argv[0]);
-@@ -1179,17 +1660,37 @@ int main(int argc, char * * argv)
- 
-     int i;
-     for (i = 1; i < argc; ++i) {
--        string arg(argv[i]);
-+        std::string arg(argv[i]);
-         if (arg == "--set-interpreter" || arg == "--interpreter") {
-             if (++i == argc) error("missing argument");
-             newInterpreter = argv[i];
-         }
-+        else if (arg == "--page-size") {
-+            if (++i == argc) error("missing argument");
-+            pageSize = atoi(argv[i]);
-+            if (pageSize <= 0) error("invalid argument to --page-size");
-+        }
-         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 == "--remove-rpath") {
-+            removeRPath = true;
-+        }
-         else if (arg == "--shrink-rpath") {
-             shrinkRPath = true;
-         }
-+        else if (arg == "--allowed-rpath-prefixes") {
-+            if (++i == argc) error("missing argument");
-+            allowedRpathPrefixes = splitColonDelimitedString(argv[i]);
-+        }
-         else if (arg == "--set-rpath") {
-             if (++i == argc) error("missing argument");
-             setRPath = true;
-@@ -1212,28 +1713,54 @@ int main(int argc, char * * argv)
-                added. */
-             forceRPath = true;
-         }
-+        else if (arg == "--print-needed") {
-+            printNeeded = 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;
-         }
-         else if (arg == "--version") {
--            printf("1.0\n");
-+            printf(PACKAGE_STRING "\n");
-             return 0;
-         }
--        else break;
-+        else {
-+            fileNames.push_back(arg);
-+        }
-     }
- 
--    if (i == argc) error("missing filename");
--    fileName = argv[i];
-+    if (fileNames.empty()) error("missing filename");
- 
-     patchElf();
- 
-     return 0;
- }
-+
-+int main(int argc, char * * argv)
-+{
-+    try {
-+        return mainWrapped(argc, argv);
-+    } catch (std::exception & e) {
-+        fprintf(stderr, "patchelf: %s\n", e.what());
-+        return 1;
-+    }
-+}



More information about the Neon-commits mailing list