diff options
author | Harmen Stoppels <me@harmenstoppels.nl> | 2024-11-27 22:32:37 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-27 22:32:37 +0100 |
commit | 3194be2e92b5d7e12ecfbbd2d6b02f2b053d40df (patch) | |
tree | 2ecaf8242d1420bcb8d619a5a7fdd7b7472aa325 /lib | |
parent | 41be2f5899896755bb73bd70ce17e4c4001a0ed2 (diff) | |
download | spack-3194be2e92b5d7e12ecfbbd2d6b02f2b053d40df.tar.gz spack-3194be2e92b5d7e12ecfbbd2d6b02f2b053d40df.tar.bz2 spack-3194be2e92b5d7e12ecfbbd2d6b02f2b053d40df.tar.xz spack-3194be2e92b5d7e12ecfbbd2d6b02f2b053d40df.zip |
gcc-runtime: remove libz.so from libgfortran.so if present (#47812)
Diffstat (limited to 'lib')
-rw-r--r-- | lib/spack/spack/util/elf.py | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/lib/spack/spack/util/elf.py b/lib/spack/spack/util/elf.py index f0fda07787..86a4e141c0 100644 --- a/lib/spack/spack/util/elf.py +++ b/lib/spack/spack/util/elf.py @@ -7,7 +7,7 @@ import bisect import re import struct from struct import calcsize, unpack, unpack_from -from typing import BinaryIO, Dict, List, NamedTuple, Optional, Pattern, Tuple +from typing import BinaryIO, Callable, Dict, List, NamedTuple, Optional, Pattern, Tuple class ElfHeader(NamedTuple): @@ -476,6 +476,31 @@ def get_interpreter(path: str) -> Optional[str]: return None +def _delete_dynamic_array_entry( + f: BinaryIO, elf: ElfFile, should_delete: Callable[[int, int], bool] +) -> None: + 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, val = unpack(dynamic_array_fmt, data) + + if tag == ELF_CONSTANTS.DT_NULL or not should_delete(tag, val): + if new_offset != old_offset: + f.seek(new_offset) + f.write(data) + f.seek(old_offset + dynamic_array_size) + new_offset += dynamic_array_size + + if tag == ELF_CONSTANTS.DT_NULL: + break + + old_offset += dynamic_array_size + + def delete_rpath(path: str) -> None: """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 @@ -492,29 +517,22 @@ def delete_rpath(path: str) -> None: 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 + # Delete DT_RPATH / DT_RUNPATH entries from the dynamic section + _delete_dynamic_array_entry( + f, elf, lambda tag, _: tag == ELF_CONSTANTS.DT_RPATH or tag == ELF_CONSTANTS.DT_RUNPATH + ) + + +def delete_needed_from_elf(f: BinaryIO, elf: ElfFile, needed: bytes) -> None: + """Delete a needed library from the dynamic section of an ELF file""" + if not elf.has_needed or needed not in elf.dt_needed_strs: + return + + offset = elf.dt_needed_strtab_offsets[elf.dt_needed_strs.index(needed)] + + _delete_dynamic_array_entry( + f, elf, lambda tag, val: tag == ELF_CONSTANTS.DT_NEEDED and val == offset + ) class CStringType: |