Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create weak_dylibs property inside macho_rewritter #11

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions machotools/macho_rewriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .misc import _install_name_macho, _change_id_dylib_command
from .rpath import _add_rpath_to_header, _list_rpaths_macho
from .utils import convert_to_string, safe_update
from .weak_load import list_weak_dylibs

class _MachoRewriter(object):
"""
Expand Down Expand Up @@ -36,6 +37,7 @@ def __init__(self, filename):

self._rpaths = _list_rpaths_macho(self._m)[0]
self._dependencies = _list_dependencies_macho(self._m)[0]
self._weak_dylibs = list_weak_dylibs(self.filename)[0]

def __enter__(self):
return self
Expand All @@ -60,6 +62,10 @@ def rpaths(self):
"""
return self._rpaths

@property
def weak_dylibs(self):
return self._weak_dylibs

#----------
# rpath API
#----------
Expand Down
57 changes: 57 additions & 0 deletions machotools/weak_load.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from macholib.ptypes import (
Structure
)
import macholib.MachO
import macholib.mach_o

from macholib.mach_o import LC_LOAD_WEAK_DYLIB, dylib
from .utils import convert_to_string


class weak_dylib_command(Structure):
_fields_ = dylib._fields_

def describe(self):
s = {
"timestamp": str(self.timestamp),
"current_version": str(self.current_version),
"compatibility_version": str(self.compatibility_version)
}
return s


def list_weak_dylibs(filename):
"""Get the list of weak dylib defined in the given mach-o binary.

The returned value is a list weak dylibs such as weak_dylibs[i] is the list of weak_dylib
in the i-th header. For this to work, we have to create a new class specifically for
LC_LOAD_WEAK_DYLIB registry

Note
----
The '\0' padding at the end of each weak_dylib is stripped

Parameters
----------
filename: str
The path to the mach-o binary file to look at
"""

macholib.mach_o.LC_REGISTRY[LC_LOAD_WEAK_DYLIB] = weak_dylib_command
m = macholib.MachO.MachO(filename)
return _list_weak_dylibs_macho(m)


def _list_weak_dylibs_macho(m):
weak_dylibs = []
for header in m.headers:
header_weak = []
weak_load_commands = [command for command in header.commands if isinstance(command[1], weak_dylib_command)]
for weak_load_command in weak_load_commands:
weak_dylib = weak_load_command[2]
if not weak_dylib.endswith(b"\x00"):
raise ValueError("Unexpected end character for weak dylib command value: %r".format(weak_dylib))
else:
header_weak.append(convert_to_string(weak_dylib))
weak_dylibs.append(header_weak)
return weak_dylibs