summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPatrick Gartung <gartung@fnal.gov>2020-03-04 19:21:15 -0600
committerGitHub <noreply@github.com>2020-03-04 19:21:15 -0600
commite2b3d529999d3fc25ab668b75ae4ec04f2d37174 (patch)
tree99f877ccef98f2b2f91a18e9ff2c9920f5c558d1 /lib
parentd7f84c738e104e0dd079b6e80b5443c8bdf3b653 (diff)
downloadspack-e2b3d529999d3fc25ab668b75ae4ec04f2d37174.tar.gz
spack-e2b3d529999d3fc25ab668b75ae4ec04f2d37174.tar.bz2
spack-e2b3d529999d3fc25ab668b75ae4ec04f2d37174.tar.xz
spack-e2b3d529999d3fc25ab668b75ae4ec04f2d37174.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.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/relocate.py39
1 files changed, 35 insertions, 4 deletions
diff --git a/lib/spack/spack/relocate.py b/lib/spack/spack/relocate.py
index a6aea329e1..c8c7947f9c 100644
--- a/lib/spack/spack/relocate.py
+++ b/lib/spack/spack/relocate.py
@@ -400,8 +400,8 @@ 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 replacing with null terminated string
- that is the same length unless the old path is shorter
+ in binary files by prefixing new install prefix with os.sep
+ until the lengths of the prefixes are the same.
"""
def replace(match):
@@ -430,6 +430,38 @@ def replace_prefix_bin(path_name, old_dir, new_dir):
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):
+ 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 relocate_macho_binaries(path_names, old_dir, new_dir, allow_root):
"""
Change old_dir to new_dir in LC_RPATH of mach-o files (on macOS)
@@ -467,8 +499,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'