diff options
author | Harmen Stoppels <harmenstoppels@gmail.com> | 2023-09-04 07:55:57 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-04 07:55:57 +0200 |
commit | 29aa7117f42f758bc537e03e4bedf66ced0accfa (patch) | |
tree | ca5f0fe36d003067e6090f5d309ce7c6c29b5ca2 /lib | |
parent | d367b4285a07d08fc9f9d7136289d9cbbfed000e (diff) | |
download | spack-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.py | 41 |
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())) |