summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Gartung <gartung@fnal.gov>2020-03-04 19:21:15 -0600
committerTodd Gamblin <tgamblin@llnl.gov>2020-03-20 11:43:54 -0700
commit62683eb4bf2bcf155c460113be09915f452e9ce6 (patch)
treef125c64aaf362114f6b4cd15fa31ed44eab1e070
parent901bed48ec2d3e03d45014fdbfc936305897d2e2 (diff)
downloadspack-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.py37
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'