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.
This commit is contained in:
Patrick Gartung 2020-03-04 19:21:15 -06:00 committed by Todd Gamblin
parent 901bed48ec
commit 62683eb4bf

View File

@ -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):
@ -429,6 +429,38 @@ def replace(match):
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)
@ -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'