diff options
author | Patrick Gartung <gartung@fnal.gov> | 2020-03-04 19:21:15 -0600 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2020-03-20 11:43:54 -0700 |
commit | 62683eb4bf2bcf155c460113be09915f452e9ce6 (patch) | |
tree | f125c64aaf362114f6b4cd15fa31ed44eab1e070 | |
parent | 901bed48ec2d3e03d45014fdbfc936305897d2e2 (diff) | |
download | spack-62683eb4bf2bcf155c460113be09915f452e9ce6.tar.gz spack-62683eb4bf2bcf155c460113be09915f452e9ce6.tar.bz2 spack-62683eb4bf2bcf155c460113be09915f452e9ce6.tar.xz spack-62683eb4bf2bcf155c460113be09915f452e9ce6.zip |
Add function replace_prefix_nullterm for use on mach-o rpaths. (#15347)
This recovers the old behavior of replace_prefix_bin that was
modified to work with elf binaries by prefixing os.sep to new prefix
until length is the same as old prefix.
-rw-r--r-- | lib/spack/spack/relocate.py | 37 |
1 files changed, 34 insertions, 3 deletions
diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py index fb4ff18fae..56fc993b5f 100644 --- a/lib/spack/spack/relocate.py +++ b/lib/spack/spack/relocate.py @@ -400,8 +400,41 @@ def replace_prefix_text(path_name, old_dir, new_dir): def replace_prefix_bin(path_name, old_dir, new_dir): """ Attempt to replace old install prefix with new install prefix + in binary files by prefixing new install prefix with os.sep + until the lengths of the prefixes are the same. + """ + + def replace(match): + occurances = match.group().count(old_dir.encode('utf-8')) + olen = len(old_dir.encode('utf-8')) + nlen = len(new_dir.encode('utf-8')) + padding = (olen - nlen) * occurances + if padding < 0: + return data + return match.group().replace(old_dir.encode('utf-8'), + new_dir.encode('utf-8')) + b'\0' * padding + + with open(path_name, 'rb+') as f: + data = f.read() + f.seek(0) + original_data_len = len(data) + pat = re.compile(old_dir.encode('utf-8') + b'([^\0]*?)\0') + if not pat.search(data): + return + ndata = pat.sub(replace, data) + if not len(ndata) == original_data_len: + raise BinaryStringReplacementException( + path_name, original_data_len, len(ndata)) + f.write(ndata) + f.truncate() + + +def replace_prefix_nullterm(path_name, old_dir, new_dir): + """ + Attempt to replace old install prefix with new install prefix in binary files by replacing with null terminated string that is the same length unless the old path is shorter + Used on linux to replace mach-o rpaths """ def replace(match): @@ -413,7 +446,6 @@ def replace_prefix_bin(path_name, old_dir, new_dir): return data return match.group().replace(old_dir.encode('utf-8'), new_dir.encode('utf-8')) + b'\0' * padding - with open(path_name, 'rb+') as f: data = f.read() f.seek(0) @@ -466,8 +498,7 @@ def relocate_macho_binaries(path_names, old_dir, new_dir, allow_root): modify_object_macholib(path_name, placeholder, new_dir) modify_object_macholib(path_name, old_dir, new_dir) if len(new_dir) <= len(old_dir): - replace_prefix_bin(path_name, old_dir, - new_dir) + replace_prefix_nullterm(path_name, old_dir, new_dir) else: tty.warn('Cannot do a binary string replacement' ' with padding for %s' |