Skip to content

Commit

Permalink
Various _macho_audit fixes
Browse files Browse the repository at this point in the history
- Use correct default RPATH
- Fix copy&paste error in RPATH calculation
  • Loading branch information
ronaldoussoren committed Jul 10, 2024
1 parent 3255fa6 commit f7c9142
Showing 1 changed file with 34 additions and 13 deletions.
47 changes: 34 additions & 13 deletions src/py2app/_macho_audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,6 @@ def audit_macho_issues(
- @rpath/..., @executable_path/... and @loader_path/... that
refer to files that cannot be found.
"""
# XXX: Adjust for py2app's needs:
# - Check if linked to libraries actually exist:
# 1. @rpath/... should be present in Frameworks folder
# 2. system paths should be in FS or in dyld "cache"

# Deployment target per CPU type, this allows us to report more clearly
# about issues.
warnings = []
deployment_targets = {
"arm64": 0xB0000,
Expand All @@ -84,7 +77,7 @@ def audit_macho_issues(
architecture: typing.Optional[str] = "universal2"

# Default @rpath for stub executables:
base_rpath = {bundle_path / "Frameworks"}
base_rpath = {bundle_path / "Contents/Frameworks"}

for macho_path in macho_files(bundle_path):
m = MachO.MachO(str(macho_path))
Expand Down Expand Up @@ -122,13 +115,41 @@ def audit_macho_issues(
rpath = set(base_rpath)
for cmd in hdr.commands:
if isinstance(cmd[1], mach_o.rpath_command):
rpath.add(
pathlib.Path(MachO.lc_str_value(cmd[1].path, cmd).decode())
)
path = MachO.lc_str_value(cmd[1].path, cmd).decode()
if path.startswith("/"):
warnings.append(
f"{str(macho_path)!r} has RPATH entry with absolute path: {path}"
)
continue

elif path.startswith("@loader_path/"):
_, _, relpath = path.partition("/")

rpath.add(macho_path.parent / relpath)

elif path.startswith("@rpath/"):
warnings.append(
f"{str(macho_path)!r} has RPATH entry referring to @rpath: {path}"
)
continue

elif path.startswith("@executable_path/"):
dirpath = bundle_path / "Contents/MacOS"
_, _, relpath = path.partition("/")

rpath.add(macho_path.parent / relpath)

else:
warnings.append(
f"{str(macho_path)!r}: Unhandled special path in link command {mach_o.LC_NAMES[cmd[0].cmd]}: {path}"
)

# Validate commands that load a shared library or framework
for cmd in hdr.commands:
if isinstance(cmd[1], mach_o.dylib_command):
if (
isinstance(cmd[1], mach_o.dylib_command)
and cmd[0].cmd != mach_o.LC_ID_DYLIB
):
name = MachO.lc_str_value(cmd[1].name, cmd).decode()
if (
not name.startswith("/usr/lib")
Expand Down Expand Up @@ -172,7 +193,7 @@ def audit_macho_issues(

elif name.startswith("@"):
warnings.append(
f"{str(macho_path)!r}: Unhandled special path in link command: {name}"
f"{str(macho_path)!r}: Unhandled special path in link command {mach_o.LC_NAMES[cmd[0].cmd]}: {name}"
)

if "x86_64" in cur_archs and "arm64" in cur_archs:
Expand Down

0 comments on commit f7c9142

Please sign in to comment.