summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorHarmen Stoppels <harmenstoppels@gmail.com>2023-09-04 07:55:57 +0200
committerGitHub <noreply@github.com>2023-09-04 07:55:57 +0200
commit29aa7117f42f758bc537e03e4bedf66ced0accfa (patch)
treeca5f0fe36d003067e6090f5d309ce7c6c29b5ca2 /lib
parentd367b4285a07d08fc9f9d7136289d9cbbfed000e (diff)
downloadspack-29aa7117f42f758bc537e03e4bedf66ced0accfa.tar.gz
spack-29aa7117f42f758bc537e03e4bedf66ced0accfa.tar.bz2
spack-29aa7117f42f758bc537e03e4bedf66ced0accfa.tar.xz
spack-29aa7117f42f758bc537e03e4bedf66ced0accfa.zip
glibc: add package (#39695)
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/util/elf.py41
1 files changed, 41 insertions, 0 deletions
diff --git a/lib/spack/spack/util/elf.py b/lib/spack/spack/util/elf.py
index 39d653aa24..cab1db0b03 100644
--- a/lib/spack/spack/util/elf.py
+++ b/lib/spack/spack/util/elf.py
@@ -432,6 +432,47 @@ def get_rpaths(path):
return rpath.split(":")
+def delete_rpath(path):
+ """Modifies a binary to remove the rpath. It zeros out the rpath string
+ and also drops the DT_R(UN)PATH entry from the dynamic section, so it doesn't
+ show up in 'readelf -d file', nor in 'strings file'."""
+ with open(path, "rb+") as f:
+ elf = parse_elf(f, interpreter=False, dynamic_section=True)
+
+ if not elf.has_rpath:
+ return
+
+ # Zero out the rpath *string* in the binary
+ new_rpath_string = b"\x00" * len(elf.dt_rpath_str)
+ rpath_offset = elf.pt_dynamic_strtab_offset + elf.rpath_strtab_offset
+ f.seek(rpath_offset)
+ f.write(new_rpath_string)
+
+ # Next update the dynamic array
+ f.seek(elf.pt_dynamic_p_offset)
+ dynamic_array_fmt = elf.byte_order + ("qQ" if elf.is_64_bit else "lL")
+ dynamic_array_size = calcsize(dynamic_array_fmt)
+ new_offset = elf.pt_dynamic_p_offset # points to the new dynamic array
+ old_offset = elf.pt_dynamic_p_offset # points to the current dynamic array
+ for _ in range(elf.pt_dynamic_p_filesz // dynamic_array_size):
+ data = read_exactly(f, dynamic_array_size, "Malformed dynamic array entry")
+ tag, _ = unpack(dynamic_array_fmt, data)
+
+ # Overwrite any entry that is not DT_RPATH or DT_RUNPATH, including DT_NULL
+ if tag != ELF_CONSTANTS.DT_RPATH and tag != ELF_CONSTANTS.DT_RUNPATH:
+ if new_offset != old_offset:
+ f.seek(new_offset)
+ f.write(data)
+ f.seek(old_offset + dynamic_array_size)
+ new_offset += dynamic_array_size
+
+ # End of the dynamic array
+ if tag == ELF_CONSTANTS.DT_NULL:
+ break
+
+ old_offset += dynamic_array_size
+
+
def replace_rpath_in_place_or_raise(path, substitutions):
regex = re.compile(b"|".join(re.escape(p) for p in substitutions.keys()))