Commits

Ronald Oussoren committed e24c563

Seperate copy no longer needed, the official tree is up-to-date

  • Participants
  • Parent commits 7f9dfb7
  • Branches pyobjc-ancient

Comments (0)

Files changed (26)

File macholib/ReadMe.Leopard

-Based on revision 21 in http://svn.pythonmac.org/macholib/macholib/trunk

File macholib/ez_setup/README.txt

-This directory exists so that Subversion-based projects can share a single
-copy of the ``ez_setup`` bootstrap module for ``setuptools``, and have it
-automatically updated in their projects when ``setuptools`` is updated.
-
-For your convenience, you may use the following svn:externals definition::
-
-    ez_setup svn://svn.eby-sarna.com/svnroot/ez_setup
-
-You can set this by executing this command in your project directory::
-
-    svn propedit svn:externals .
-
-And then adding the line shown above to the file that comes up for editing.
-Then, whenever you update your project, ``ez_setup`` will be updated as well.
-

File macholib/ez_setup/__init__.py

-#!python
-"""Bootstrap setuptools installation
-
-If you want to use setuptools in your package's setup.py, just include this
-file in the same directory with it, and add this to the top of your setup.py::
-
-    from ez_setup import use_setuptools
-    use_setuptools()
-
-If you want to require a specific version of setuptools, set a download
-mirror, or use an alternate download directory, you can do so by supplying
-the appropriate options to ``use_setuptools()``.
-
-This file can also be run as a script to install or upgrade setuptools.
-"""
-import sys
-DEFAULT_VERSION = "0.6c7"
-DEFAULT_URL     = "http://pypi.python.org/packages/%s/s/setuptools/" % sys.version[:3]
-
-md5_data = {
-    'setuptools-0.6b1-py2.3.egg': '8822caf901250d848b996b7f25c6e6ca',
-    'setuptools-0.6b1-py2.4.egg': 'b79a8a403e4502fbb85ee3f1941735cb',
-    'setuptools-0.6b2-py2.3.egg': '5657759d8a6d8fc44070a9d07272d99b',
-    'setuptools-0.6b2-py2.4.egg': '4996a8d169d2be661fa32a6e52e4f82a',
-    'setuptools-0.6b3-py2.3.egg': 'bb31c0fc7399a63579975cad9f5a0618',
-    'setuptools-0.6b3-py2.4.egg': '38a8c6b3d6ecd22247f179f7da669fac',
-    'setuptools-0.6b4-py2.3.egg': '62045a24ed4e1ebc77fe039aa4e6f7e5',
-    'setuptools-0.6b4-py2.4.egg': '4cb2a185d228dacffb2d17f103b3b1c4',
-    'setuptools-0.6c1-py2.3.egg': 'b3f2b5539d65cb7f74ad79127f1a908c',
-    'setuptools-0.6c1-py2.4.egg': 'b45adeda0667d2d2ffe14009364f2a4b',
-    'setuptools-0.6c2-py2.3.egg': 'f0064bf6aa2b7d0f3ba0b43f20817c27',
-    'setuptools-0.6c2-py2.4.egg': '616192eec35f47e8ea16cd6a122b7277',
-    'setuptools-0.6c3-py2.3.egg': 'f181fa125dfe85a259c9cd6f1d7b78fa',
-    'setuptools-0.6c3-py2.4.egg': 'e0ed74682c998bfb73bf803a50e7b71e',
-    'setuptools-0.6c3-py2.5.egg': 'abef16fdd61955514841c7c6bd98965e',
-    'setuptools-0.6c4-py2.3.egg': 'b0b9131acab32022bfac7f44c5d7971f',
-    'setuptools-0.6c4-py2.4.egg': '2a1f9656d4fbf3c97bf946c0a124e6e2',
-    'setuptools-0.6c4-py2.5.egg': '8f5a052e32cdb9c72bcf4b5526f28afc',
-    'setuptools-0.6c5-py2.3.egg': 'ee9fd80965da04f2f3e6b3576e9d8167',
-    'setuptools-0.6c5-py2.4.egg': 'afe2adf1c01701ee841761f5bcd8aa64',
-    'setuptools-0.6c5-py2.5.egg': 'a8d3f61494ccaa8714dfed37bccd3d5d',
-    'setuptools-0.6c6-py2.3.egg': '35686b78116a668847237b69d549ec20',
-    'setuptools-0.6c6-py2.4.egg': '3c56af57be3225019260a644430065ab',
-    'setuptools-0.6c6-py2.5.egg': 'b2f8a7520709a5b34f80946de5f02f53',
-    'setuptools-0.6c7-py2.3.egg': '209fdf9adc3a615e5115b725658e13e2',
-    'setuptools-0.6c7-py2.4.egg': '5a8f954807d46a0fb67cf1f26c55a82e',
-    'setuptools-0.6c7-py2.5.egg': '45d2ad28f9750e7434111fde831e8372',
-}
-
-import sys, os
-
-def _validate_md5(egg_name, data):
-    if egg_name in md5_data:
-        from md5 import md5
-        digest = md5(data).hexdigest()
-        if digest != md5_data[egg_name]:
-            print >>sys.stderr, (
-                "md5 validation of %s failed!  (Possible download problem?)"
-                % egg_name
-            )
-            sys.exit(2)
-    return data
-
-
-def use_setuptools(
-    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
-    download_delay=15
-):
-    """Automatically find/download setuptools and make it available on sys.path
-
-    `version` should be a valid setuptools version number that is available
-    as an egg for download under the `download_base` URL (which should end with
-    a '/').  `to_dir` is the directory where setuptools will be downloaded, if
-    it is not already available.  If `download_delay` is specified, it should
-    be the number of seconds that will be paused before initiating a download,
-    should one be required.  If an older version of setuptools is installed,
-    this routine will print a message to ``sys.stderr`` and raise SystemExit in
-    an attempt to abort the calling script.
-    """
-    try:
-        import setuptools
-        if setuptools.__version__ == '0.0.1':
-            print >>sys.stderr, (
-            "You have an obsolete version of setuptools installed.  Please\n"
-            "remove it from your system entirely before rerunning this script."
-            )
-            sys.exit(2)
-    except ImportError:
-        egg = download_setuptools(version, download_base, to_dir, download_delay)
-        sys.path.insert(0, egg)
-        import setuptools; setuptools.bootstrap_install_from = egg
-
-    import pkg_resources
-    try:
-        pkg_resources.require("setuptools>="+version)
-
-    except pkg_resources.VersionConflict, e:
-        # XXX could we install in a subprocess here?
-        print >>sys.stderr, (
-            "The required version of setuptools (>=%s) is not available, and\n"
-            "can't be installed while this script is running. Please install\n"
-            " a more recent version first.\n\n(Currently using %r)"
-        ) % (version, e.args[0])
-        sys.exit(2)
-
-def download_setuptools(
-    version=DEFAULT_VERSION, download_base=DEFAULT_URL, to_dir=os.curdir,
-    delay = 15
-):
-    """Download setuptools from a specified location and return its filename
-
-    `version` should be a valid setuptools version number that is available
-    as an egg for download under the `download_base` URL (which should end
-    with a '/'). `to_dir` is the directory where the egg will be downloaded.
-    `delay` is the number of seconds to pause before an actual download attempt.
-    """
-    import urllib2, shutil
-    egg_name = "setuptools-%s-py%s.egg" % (version,sys.version[:3])
-    url = download_base + egg_name
-    saveto = os.path.join(to_dir, egg_name)
-    src = dst = None
-    if not os.path.exists(saveto):  # Avoid repeated downloads
-        try:
-            from distutils import log
-            if delay:
-                log.warn("""
----------------------------------------------------------------------------
-This script requires setuptools version %s to run (even to display
-help).  I will attempt to download it for you (from
-%s), but
-you may need to enable firewall access for this script first.
-I will start the download in %d seconds.
-
-(Note: if this machine does not have network access, please obtain the file
-
-   %s
-
-and place it in this directory before rerunning this script.)
----------------------------------------------------------------------------""",
-                    version, download_base, delay, url
-                ); from time import sleep; sleep(delay)
-            log.warn("Downloading %s", url)
-            src = urllib2.urlopen(url)
-            # Read/write all in one block, so we don't create a corrupt file
-            # if the download is interrupted.
-            data = _validate_md5(egg_name, src.read())
-            dst = open(saveto,"wb"); dst.write(data)
-        finally:
-            if src: src.close()
-            if dst: dst.close()
-    return os.path.realpath(saveto)
-
-def main(argv, version=DEFAULT_VERSION):
-    """Install or upgrade setuptools and EasyInstall"""
-
-    try:
-        import setuptools
-    except ImportError:
-        egg = None
-        try:
-            egg = download_setuptools(version, delay=0)
-            sys.path.insert(0,egg)
-            from setuptools.command.easy_install import main
-            return main(list(argv)+[egg])   # we're done here
-        finally:
-            if egg and os.path.exists(egg):
-                os.unlink(egg)
-    else:
-        if setuptools.__version__ == '0.0.1':
-            # tell the user to uninstall obsolete version
-            use_setuptools(version)
-
-    req = "setuptools>="+version
-    import pkg_resources
-    try:
-        pkg_resources.require(req)
-    except pkg_resources.VersionConflict:
-        try:
-            from setuptools.command.easy_install import main
-        except ImportError:
-            from easy_install import main
-        main(list(argv)+[download_setuptools(delay=0)])
-        sys.exit(0) # try to force an exit
-    else:
-        if argv:
-            from setuptools.command.easy_install import main
-            main(argv)
-        else:
-            print "Setuptools version",version,"or greater has been installed."
-            print '(Run "ez_setup.py -U setuptools" to reinstall or upgrade.)'
-
-
-
-def update_md5(filenames):
-    """Update our built-in md5 registry"""
-
-    import re
-    from md5 import md5
-
-    for name in filenames:
-        base = os.path.basename(name)
-        f = open(name,'rb')
-        md5_data[base] = md5(f.read()).hexdigest()
-        f.close()
-
-    data = ["    %r: %r,\n" % it for it in md5_data.items()]
-    data.sort()
-    repl = "".join(data)
-
-    import inspect
-    srcfile = inspect.getsourcefile(sys.modules[__name__])
-    f = open(srcfile, 'rb'); src = f.read(); f.close()
-
-    match = re.search("\nmd5_data = {\n([^}]+)}", src)
-    if not match:
-        print >>sys.stderr, "Internal error!"
-        sys.exit(2)
-
-    src = src[:match.start(1)] + repl + src[match.end(1):]
-    f = open(srcfile,'w')
-    f.write(src)
-    f.close()
-
-
-if __name__=='__main__':
-    if len(sys.argv)>2 and sys.argv[1]=='--md5update':
-        update_md5(sys.argv[2:])
-    else:
-        main(sys.argv[1:])
-
-
-
-
-

File macholib/macholib.egg-info/PKG-INFO

-Metadata-Version: 1.0
-Name: macholib
-Version: 1.2.1.dev-r432
-Summary: Mach-O header analysis and editing
-Home-page: http://undefined.org/python/#macholib
-Author: Bob Ippolito
-Author-email: bob@redivi.com
-License: MIT License
-Description: 
-        macholib can be used to analyze and edit Mach-O headers, the executable
-        format used by Mac OS X.
-        
-        It's typically used as a dependency analysis tool, and also to rewrite dylib
-        references in Mach-O headers to be @executable_path relative.
-        
-        Though this tool targets a platform specific file format, it is pure python
-        code that is platform and endian independent.
-        
-Platform: any
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python
-Classifier: Operating System :: MacOS :: MacOS X
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Software Development :: Build Tools

File macholib/macholib.egg-info/SOURCES.txt

-ReadMe.Leopard
-setup.cfg
-setup.py
-ez_setup/README.txt
-ez_setup/__init__.py
-macholib/MachO.py
-macholib/MachOGraph.py
-macholib/MachOStandalone.py
-macholib/SymbolTable.py
-macholib/__init__.py
-macholib/dyld.py
-macholib/dylib.py
-macholib/framework.py
-macholib/itergraphreport.py
-macholib/mach_o.py
-macholib/macho_find.py
-macholib/macho_standalone.py
-macholib/ptypes.py
-macholib/util.py
-macholib.egg-info/PKG-INFO
-macholib.egg-info/SOURCES.txt
-macholib.egg-info/dependency_links.txt
-macholib.egg-info/entry_points.txt
-macholib.egg-info/requires.txt
-macholib.egg-info/top_level.txt
-macholib.egg-info/zip-safe

File macholib/macholib.egg-info/dependency_links.txt

-

File macholib/macholib.egg-info/entry_points.txt

-[console_scripts]
-macho_standalone = macholib.macho_standalone:main
-macho_find = macholib.macho_find:main
-

File macholib/macholib.egg-info/requires.txt

-altgraph>=0.6.6

File macholib/macholib.egg-info/top_level.txt

-macholib

File macholib/macholib.egg-info/zip-safe

Empty file removed.

File macholib/macholib/MachO.py

-"""
-Utilities for reading and writing Mach-O headers
-"""
-
-from pkg_resources import require
-require("altgraph")
-
-import sys
-import struct
-
-from altgraph.compat import *
-
-from macholib.mach_o import *
-from macholib.dyld import dyld_find, framework_info
-from macholib.util import fileview
-
-__all__ = ['MachO']
-
-RELOCATABLE = set((
-    # relocatable commands that should be used for dependency walking
-    LC_LOAD_DYLIB,
-    LC_LOAD_WEAK_DYLIB,
-    LC_PREBOUND_DYLIB,
-))
-
-RELOCATABLE_NAMES = {
-    LC_LOAD_DYLIB: 'load_dylib',
-    LC_LOAD_WEAK_DYLIB: 'load_weak_dylib',
-    LC_PREBOUND_DYLIB: 'prebound_dylib',
-}
-
-def shouldRelocateCommand(cmd):
-    """
-    Should this command id be investigated for relocation?
-    """
-    return cmd in RELOCATABLE
-
-class MachO(object):
-    """
-    Provides reading/writing the Mach-O header of a specific existing file
-    """
-    #   filename   - the original filename of this mach-o
-    #   sizediff   - the current deviation from the initial mach-o size
-    #   header     - the mach-o header
-    #   commands   - a list of (load_command, somecommand, data)
-    #                data is either a str, or a list of segment structures
-    #   total_size - the current mach-o header size (including header)
-    #   low_offset - essentially, the maximum mach-o header size
-    #   id_cmd     - the index of my id command, or None
-
-
-    def __init__(self, filename):
-
-        # supports the ObjectGraph protocol
-        self.graphident = filename
-        self.filename = filename
-        
-        # initialized by load
-        self.fat = None
-        self.headers = []
-        self.load(file(filename, 'rb'))
-
-    def __repr__(self):
-        return "<MachO filename=%r>" % (self.filename,)
-
-    def load(self, fh):
-        assert fh.tell() == 0
-        header = struct.unpack('>I', fh.read(4))[0]
-        fh.seek(0)
-        if header == FAT_MAGIC:
-            self.load_fat(fh)
-        else:
-            fh.seek(0, 2)
-            size = fh.tell()
-            fh.seek(0)
-            self.load_header(fh, 0, size)
-
-    def load_fat(self, fh):
-        self.fat = fat_header.from_fileobj(fh)
-        archs = [fat_arch.from_fileobj(fh) for i in xrange(self.fat.nfat_arch)]
-        for arch in archs:
-            self.load_header(fh, arch.offset, arch.size)
-
-    def rewriteLoadCommands(self, *args, **kw):
-        changed = False
-        for header in self.headers:
-            if header.rewriteLoadCommands(*args, **kw):
-                changed = True
-        return changed
-
-    def load_header(self, fh, offset, size):
-        fh.seek(offset)
-        header = struct.unpack('>I', fh.read(4))[0]
-        fh.seek(offset)
-        if header == MH_MAGIC:
-            magic, hdr, endian = MH_MAGIC, mach_header, '>'
-        elif header == MH_CIGAM:
-            magic, hdr, endian = MH_MAGIC, mach_header, '<'
-        elif header == MH_MAGIC_64:
-            magic, hdr, endian = MH_MAGIC_64, mach_header_64, '>'
-        elif header == MH_CIGAM_64:
-            magic, hdr, endian = MH_MAGIC_64, mach_header_64, '<'
-        else:
-            raise ValueError("Unknown Mach-O header: 0x%08x in %r" % (
-                header, fh))
-        hdr = MachOHeader(self, fh, offset, size, magic, hdr, endian)
-        self.headers.append(hdr)
-
-    def write(self, f):
-        for header in self.headers:
-            header.write(f)
-    
-class MachOHeader(object):
-    """
-    Provides reading/writing the Mach-O header of a specific existing file
-    """
-    #   filename   - the original filename of this mach-o
-    #   sizediff   - the current deviation from the initial mach-o size
-    #   header     - the mach-o header
-    #   commands   - a list of (load_command, somecommand, data)
-    #                data is either a str, or a list of segment structures
-    #   total_size - the current mach-o header size (including header)
-    #   low_offset - essentially, the maximum mach-o header size
-    #   id_cmd     - the index of my id command, or None
-
-
-    def __init__(self, parent, fh, offset, size, magic, hdr, endian):
-        self.MH_MAGIC = magic
-        self.mach_header = hdr
-
-        # These are all initialized by self.load()
-        self.parent = parent
-        self.offset = offset
-        self.size = size
-
-        self.endian = endian
-        self.header = None
-        self.commands = None
-        self.id_cmd = None
-        self.sizediff = None
-        self.total_size = None
-        self.low_offset = None
-        self.filetype = None
-        self.headers = []
-
-        self.load(fh)
-
-    def __repr__(self):
-        return "<%s filename=%r offset=%d size=%d endian=%r>" % (
-            type(self).__name__, self.parent.filename, self.offset, self.size,
-            self.endian)
-
-    def load(self, fh):
-        fh = fileview(fh, self.offset, self.size)
-        fh.seek(0)
-
-        self.sizediff = 0
-        kw = {'_endian_': self.endian}
-        header = self.mach_header.from_fileobj(fh, **kw)
-        self.header = header
-        if header.magic != self.MH_MAGIC:
-            raise ValueError("header has magic %08x, expecting %08x" % (
-                header.magic, self.MH_MAGIC))
-
-        cmd = self.commands = []
-
-        self.filetype = MH_FILETYPE_SHORTNAMES[header.filetype]
-
-        read_bytes = 0
-        low_offset = sys.maxint
-        for i in xrange(header.ncmds):
-            # read the load command
-            cmd_load = load_command.from_fileobj(fh, **kw)
-
-            # read the specific command
-            klass = LC_REGISTRY.get(cmd_load.cmd, None)
-            if klass is None:
-                raise ValueError("Unknown load command: %d" % (cmd_load.cmd,))
-            cmd_cmd = klass.from_fileobj(fh, **kw)
-
-            if cmd_load.cmd == LC_ID_DYLIB:
-                # remember where this command was
-                if self.id_cmd is not None:
-                    raise ValueError("This dylib already has an id")
-                self.id_cmd = i
-
-            if cmd_load.cmd in (LC_SEGMENT, LC_SEGMENT_64):
-                # for segment commands, read the list of segments
-                segs = []
-                # assert that the size makes sense
-                if cmd_load.cmd == LC_SEGMENT:
-                    section_cls = section
-                else: # LC_SEGMENT_64
-                    section_cls = section_64
-                    
-                expected_size = (
-                    sizeof(klass) + sizeof(load_command) +
-                    (sizeof(section_cls) * cmd_cmd.nsects)
-                )
-                if cmd_load.cmdsize != expected_size:
-                    raise ValueError("Segment size mismatch")
-                # this is a zero block or something
-                # so the beginning is wherever the fileoff of this command is
-                if cmd_cmd.nsects == 0:
-                    if cmd_cmd.filesize != 0:
-                        low_offset = min(low_offset, cmd_cmd.fileoff)
-                else:
-                    # this one has multiple segments
-                    for j in xrange(cmd_cmd.nsects):
-                        # read the segment
-                        seg = section_cls.from_fileobj(fh, **kw)
-                        # if the segment has a size and is not zero filled
-                        # then its beginning is the offset of this segment
-                        not_zerofill = ((seg.flags & S_ZEROFILL) != S_ZEROFILL)
-                        if seg.offset > 0 and seg.size > 0 and not_zerofill:
-                            low_offset = min(low_offset, seg.offset)
-                        segs.append(seg)
-                # data is a list of segments
-                cmd_data = segs
-            else:
-                # data is a raw str
-                data_size = (
-                    cmd_load.cmdsize - sizeof(klass) - sizeof(load_command)
-                )
-                cmd_data = fh.read(data_size)
-            cmd.append((cmd_load, cmd_cmd, cmd_data))
-            read_bytes += cmd_load.cmdsize
-
-        # make sure the header made sense
-        if read_bytes != header.sizeofcmds:
-            raise ValueError("Read %d bytes, header reports %d bytes" % (
-                read_bytes, header.sizeofcmds))
-        self.total_size = sizeof(self.mach_header) + read_bytes
-        self.low_offset = low_offset
-
-        # this header overwrites a segment, what the heck?
-        if self.total_size > low_offset:
-            raise ValueError("total_size > low_offset (%d > %d)" % (
-                self.total_size, low_offset))
-
-    def walkRelocatables(self, shouldRelocateCommand=shouldRelocateCommand):
-        """
-        for all relocatable commands
-        yield (command_index, command_name, filename)
-        """
-        for (idx, (lc, cmd, data)) in enumerate(self.commands):
-            if shouldRelocateCommand(lc.cmd):
-                name = RELOCATABLE_NAMES[lc.cmd]
-                ofs = cmd.name - sizeof(lc.__class__) - sizeof(cmd.__class__)
-                yield idx, name, data[ofs:data.find('\x00', ofs)]
-
-    def rewriteInstallNameCommand(self, loadcmd):
-        """Rewrite the load command of this dylib"""
-        if self.id_cmd is not None:
-            self.rewriteDataForCommand(self.id_cmd, loadcmd)
-            return True
-        return False
-
-    def changedHeaderSizeBy(self, bytes):
-        self.sizediff += bytes
-        if (self.total_size + self.sizediff) > self.low_offset:
-            print "WARNING: Mach-O header may be too large to relocate"
-
-    def rewriteLoadCommands(self, changefunc):
-        """
-        Rewrite the load commands based upon a change dictionary
-        """
-        data = changefunc(self.parent.filename)
-        changed = False
-        if data is not None:
-            if self.rewriteInstallNameCommand(data):
-                changed = True
-        for idx, name, filename in self.walkRelocatables():
-            data = changefunc(filename)
-            if data is not None:
-                if self.rewriteDataForCommand(idx, data):
-                    changed = True
-        return changed
-
-    def rewriteDataForCommand(self, idx, data):
-        lc, cmd, old_data = self.commands[idx]
-        hdrsize = sizeof(lc.__class__) + sizeof(cmd.__class__)
-        data = data + ('\x00' * (4 - (len(data) % 4)))
-        newsize = hdrsize + len(data)
-        self.commands[idx] = (lc, cmd, data)
-        self.changedHeaderSizeBy(newsize - lc.cmdsize)
-        lc.cmdsize, cmd.name = newsize, hdrsize
-        return True
-
-    def synchronize_size(self):
-        if (self.total_size + self.sizediff) > self.low_offset:
-            raise ValueError("New Mach-O header is too large to relocate")
-        self.header.sizeofcmds += self.sizediff
-        self.total_size = sizeof(self.mach_header) + self.header.sizeofcmds
-        self.sizediff = 0
-
-    def write(self, fileobj):
-        fileobj = fileview(fileobj, self.offset, self.size)
-        fileobj.seek(0)
-
-        # serialize all the mach-o commands
-        self.synchronize_size()
-
-        self.header.to_fileobj(fileobj)
-        for lc, cmd, data in self.commands:
-            lc.to_fileobj(fileobj)
-            cmd.to_fileobj(fileobj)
-            if isinstance(data, unicode):
-                data = data.encode('utf-8')
-            
-            if isinstance(data, str):
-                fileobj.write(data)
-            else:
-                # segments..
-                for obj in data:
-                    obj.to_fileobj(fileobj)
-
-        # zero out the unused space, doubt this is strictly necessary
-        # and is generally probably already the case
-        fileobj.write('\x00' * (self.low_offset - fileobj.tell()))
-
-    def getSymbolTableCommand(self):
-        for lc, cmd, data in self.commands:
-            if lc.cmd == LC_SYMTAB:
-                return cmd
-        return None
-
-    def getDynamicSymbolTableCommand(self):
-        for lc, cmd, data in self.commands:
-            if lc.cmd == LC_DYSYMTAB:
-                return cmd
-        return None
-
-def main(fn):
-    m = MachO(fn)
-    seen = set()
-    for header in m.headers:
-        #print '[%s endian=%r]' % (header.__class__.__name__, header.endian)
-        #seen = set()
-        for idx, name, other in header.walkRelocatables():
-            if other not in seen:
-                seen.add(other)
-                print '\t' + other
-
-if __name__ == '__main__':
-    import sys
-    files = sys.argv[1:] or ['/bin/ls']
-    for fn in files:
-        print fn
-        main(fn)

File macholib/macholib/MachOGraph.py

-"""
-Utilities for reading and writing Mach-O headers
-"""
-
-from pkg_resources import require
-require("altgraph")
-
-import os
-import sys
-
-from altgraph.Graph import Graph
-from altgraph.ObjectGraph import ObjectGraph
-from altgraph.compat import *
-
-from macholib.mach_o import *
-from macholib.dyld import dyld_find
-from macholib.MachO import MachO
-from macholib.itergraphreport import itergraphreport
-
-__all__ = ['MachOGraph']
-
-class MissingMachO(object):
-    def __init__(self, filename):
-        self.graphident = filename
-        self.headers = ()
-
-    def __repr__(self):
-        return '<%s graphident=%r>' % (type(self).__name__, self.graphident)
-
-class MachOGraph(ObjectGraph):
-    """
-    Graph data structure of Mach-O dependencies
-    """
-    def __init__(self, debug=0, graph=None, env=None, executable_path=None):
-        super(MachOGraph, self).__init__(debug=debug, graph=graph)
-        self.env = env
-        self.trans_table = {}
-        self.executable_path = executable_path
-
-    def locate(self, filename):
-        fn = self.trans_table.get(filename)
-        if fn is None:
-            try:
-                fn = dyld_find(filename, env=self.env,
-                    executable_path=self.executable_path)
-                self.trans_table[filename] = fn
-            except ValueError:
-                return None
-        return fn
-
-    def findNode(self, name):
-        data = super(MachOGraph, self).findNode(name)
-        if data is not None:
-            return data
-        newname = self.locate(name)
-        if newname is not None and newname != name:
-            return self.findNode(newname)
-        return None
-
-    def run_file(self, pathname, caller=None):
-        self.msgin(2, "run_file", pathname)
-        m = self.findNode(pathname)
-        if m is None:
-            if not os.path.exists(pathname):
-                raise ValueError('%r does not exist' % (pathname,))
-            m = self.createNode(MachO, pathname)
-            self.createReference(caller, m, edge_data='run_file')
-            self.scan_node(m)
-        self.msgout(2, '')
-        return m
-
-    def load_file(self, name, caller=None):
-        self.msgin(2, "load_file", name)
-        m = self.findNode(name)
-        if m is None:
-            newname = self.locate(name)
-            if newname is not None and newname != name:
-                return self.load_file(newname, caller=caller)
-            if os.path.exists(name):
-                m = self.createNode(MachO, name)
-                self.scan_node(m)
-            else:
-                m = self.createNode(MissingMachO, name)
-        self.msgout(2, '')
-        return m
-
-    def scan_node(self, node):
-        self.msgin(2, 'scan_node', node)
-        for header in node.headers:
-            for idx, name, filename in header.walkRelocatables():
-                m = self.load_file(filename, caller=node)
-                self.createReference(node, m, edge_data=name)
-        self.msgout(2, '', node)
-
-    def itergraphreport(self, name='G'):
-        nodes = map(self.graph.describe_node, self.graph.iterdfs(self))
-        describe_edge = self.graph.describe_edge
-        return itergraphreport(nodes, describe_edge, name=name)
-
-    def graphreport(self, fileobj=None):
-        if fileobj is None:
-            fileobj = sys.stdout
-        fileobj.writelines(self.itergraphreport())
-
-def main(args):
-    g = MachOGraph()
-    for arg in args:
-        g.run_file(arg)
-    g.graphreport()
-
-if __name__ == '__main__':
-    main(sys.argv[1:] or ['/bin/ls'])

File macholib/macholib/MachOStandalone.py

-from pkg_resources import require
-require("altgraph")
-
-import os
-
-from altgraph.compat import *
-
-from macholib.MachOGraph import MachOGraph, MissingMachO
-from macholib.util import iter_platform_files, in_system_path, mergecopy, \
-    mergetree, writablefile, has_filename_filter
-from macholib.dyld import framework_info
-
-class ExcludedMachO(MissingMachO):
-    pass
-
-class FilteredMachOGraph(MachOGraph):
-    def __init__(self, delegate, *args, **kwargs):
-        super(FilteredMachOGraph, self).__init__(*args, **kwargs)
-        self.delegate = delegate
-
-    def createNode(self, cls, name):
-        cls = self.delegate.getClass(name, cls)
-        res = super(FilteredMachOGraph, self).createNode(cls, name)
-        return res
-
-    def locate(self, filename):
-        newname = super(FilteredMachOGraph, self).locate(filename)
-        if newname is None:
-            return None
-        return self.delegate.locate(newname)
-
-class MachOStandalone(object):
-    def __init__(self, base, dest=None, graph=None, env=None,
-            executable_path=None):
-        self.base = os.path.join(os.path.abspath(base), '')
-        if dest is None:
-            dest = os.path.join(self.base, 'Contents', 'Frameworks')
-        self.dest = dest
-        self.mm = FilteredMachOGraph(self, graph=graph, env=env,
-            executable_path=executable_path)
-        self.changemap = {}
-        self.excludes = []
-        self.pending = deque()
-
-    def getClass(self, name, cls):
-        if in_system_path(name):
-            return ExcludedMachO
-        for base in self.excludes:
-            if name.startswith(base):
-                return ExcludedMachO
-        return cls
-
-    def locate(self, filename):
-        if in_system_path(filename):
-            return filename
-        if filename.startswith(self.base):
-            return filename
-        for base in self.excludes:
-            if filename.startswith(base):
-                return filename
-        if filename in self.changemap:
-            return self.changemap[filename]
-        info = framework_info(filename)
-        if info is None:
-            res = self.copy_dylib(filename)
-            self.changemap[filename] = res
-            return res
-        else:
-            res = self.copy_framework(info)
-            self.changemap[filename] = res
-            return res
-
-    def copy_dylib(self, filename):
-        dest = os.path.join(self.dest, os.path.basename(filename))
-        if not os.path.exists(dest):
-            self.mergecopy(filename, dest)
-        return dest
-
-    def mergecopy(self, src, dest):
-        return mergecopy(src, dest)
-
-    def mergetree(self, src, dest):
-        return mergetree(src, dest)
-
-    def copy_framework(self, info):
-        dest = os.path.join(self.dest, info['shortname'] + '.framework')
-        destfn = os.path.join(self.dest, info['name'])
-        src = os.path.join(info['location'], info['shortname'] + '.framework')
-        if not os.path.exists(dest):
-            self.mergetree(src, dest)
-            self.pending.append((destfn, iter_platform_files(dest)))
-        return destfn
-
-    def run(self, platfiles=None, contents=None):
-        mm = self.mm
-        if contents is None:
-            contents = '@executable_path/..'
-        if platfiles is None:
-            platfiles = iter_platform_files(self.base)
-
-        for fn in platfiles:
-            mm.run_file(fn)
-
-        while self.pending:
-            fmwk, files = self.pending.popleft()
-            ref = mm.findNode(fmwk)
-            for fn in files:
-                mm.run_file(fn, caller=ref)
-
-        changemap = {}
-        skipcontents = os.path.join(os.path.dirname(self.dest), '')
-        machfiles = []
-
-        for node in mm.flatten(has_filename_filter):
-            machfiles.append(node)
-            dest = os.path.join(contents, node.filename[len(skipcontents):])
-            changemap[node.filename] = dest
-
-        def changefunc(path):
-            res = mm.locate(path)
-            return changemap.get(res)
-
-        for node in machfiles:
-            fn = mm.locate(node.filename)
-            if fn is None:
-                continue
-            rewroteAny = False
-            for header in node.headers:
-                if node.rewriteLoadCommands(changefunc):
-                    rewroteAny = True
-            if rewroteAny:
-                f = writablefile(fn, 'rb+')
-                for header in node.headers:
-                    f.seek(0)
-                    node.write(f)
-                f.seek(0, 2)
-                f.flush()
-                f.close()
-
-        allfiles = [mm.locate(node.filename) for node in machfiles]
-        return set(filter(None, allfiles))

File macholib/macholib/SymbolTable.py

-"""
-Class to read the symbol table from a Mach-O header
-"""
-
-from macholib.mach_o import *
-
-__all__ = ['SymbolTable']
-
-# XXX: Does not support 64-bit, probably broken anyway
-
-class SymbolTable(object):
-    def __init__(self, macho, openfile=None):
-        if openfile is None:
-            openfile = open
-        self.macho = macho.headers[0]
-        self.symtab = macho.getSymbolTableCommand()
-        self.dysymtab = macho.getDynamicSymbolTableCommand()
-        fh = openfile(self.macho.filename, 'rb')
-        if self.symtab is not None:
-            self.readSymbolTable(fh)
-        if self.dysymtab is not None:
-            self.readDynamicSymbolTable(fh)
-
-    def readSymbolTable(self, fh):
-        cmd = self.symtab
-        fh.seek(cmd.stroff)
-        strtab = fh.read(cmd.strsize)
-        fh.seek(cmd.symoff)
-        nlists = []
-        for i in xrange(cmd.nsyms):
-            cmd = nlist.from_fileobj(fh)
-            if cmd.n_un == 0:
-                nlists.append((cmd, ''))
-            else:
-                nlists.append((cmd, strtab[cmd.n_un:strtab.find('\x00', cmd.n_un)]))
-        self.nlists = nlists
-
-    def readDynamicSymbolTable(self, fh):
-        cmd = self.dysymtab
-        nlists = self.nlists
-        self.localsyms = nlists[cmd.ilocalsym:cmd.ilocalsym+cmd.nlocalsym]
-        self.extdefsyms = nlists[cmd.iextdefsym:cmd.iextdefsym+cmd.nextdefsym]
-        self.undefsyms = nlists[cmd.iundefsym:cmd.iundefsym+cmd.nundefsym]
-        #if cmd.tocoff == 0:
-        #    self.toc = None
-        #else:
-        #    self.toc = self.readtoc(fh, cmd.tocoff, cmd.ntoc)
-        #if cmd.modtaboff == 0:
-        #    self.modtab = None
-        #else:
-        #    self.modtab = self.readmodtab(fh, cmd.modtaboff, cmd.nmodtab)
-        if cmd.extrefsymoff == 0:
-            self.extrefsym = None
-        else:
-            self.extrefsym = self.readsym(fh, cmd.extrefsymoff, cmd.nextrefsyms)
-        #if cmd.indirectsymoff == 0:
-        #    self.indirectsym = None
-        #else:
-        #    self.indirectsym = self.readsym(fh, cmd.indirectsymoff, cmd.nindirectsyms)
-        #if cmd.extreloff == 0:
-        #    self.extrel = None
-        #else:
-        #    self.extrel = self.readrel(fh, cmd.extreloff, cmd.nextrel)
-        #if cmd.locreloff == 0:
-        #    self.locrel = None
-        #else:
-        #    self.locrel = self.readrel(fh, cmd.locreloff, cmd.nlocrel)
-
-    def readtoc(self, fh, off, n):
-        #print 'toc', off, n
-        fh.seek(off)
-        return [dylib_table_of_contents.from_fileobj(fh) for i in xrange(n)]
-
-    def readmodtab(self, fh, off, n):
-        #print 'modtab', off, n
-        fh.seek(off)
-        return [dylib_module.from_fileobj(fh) for i in xrange(n)]
-
-    def readsym(self, fh, off, n):
-        #print 'sym', off, n
-        fh.seek(off)
-        refs = []
-        for i in xrange(n):
-            ref = dylib_reference.from_fileobj(fh)
-            isym, flags = divmod(ref.isym_flags, 256)
-            refs.append((self.nlists[isym], flags))
-        return refs
-
-    def readrel(self, fh, off, n):
-        #print 'rel', off, n
-        fh.seek(off)
-        return [relocation_info.from_fileobj(fh) for i in xrange(n)]

File macholib/macholib/__init__.py

-"""
-Enough Mach-O to make your head spin.
-
-See the relevant header files in /usr/include/mach-o
-
-And also Apple's documentation.
-"""
-
-__version__ = '1.2'

File macholib/macholib/dyld.py

-"""
-dyld emulation
-"""
-
-import os
-from itertools import *
-
-from macholib.framework import framework_info
-from macholib.dylib import dylib_info
-
-__all__ = [
-    'dyld_find', 'framework_find',
-    'framework_info', 'dylib_info',
-]
-
-# These are the defaults as per man dyld(1)
-#
-DEFAULT_FRAMEWORK_FALLBACK = [
-    os.path.expanduser("~/Library/Frameworks"),
-    "/Library/Frameworks",
-    "/Network/Library/Frameworks",
-    "/System/Library/Frameworks",
-]
-
-DEFAULT_LIBRARY_FALLBACK = [
-    os.path.expanduser("~/lib"),
-    "/usr/local/lib",
-    "/lib",
-    "/usr/lib",
-]
-
-def ensure_utf8(s):
-    """Not all of PyObjC and Python understand unicode paths very well yet"""
-    if isinstance(s, unicode):
-        return s.encode('utf8')
-    return s
-
-def dyld_env(env, var):
-    if env is None:
-        env = os.environ
-    rval = env.get(var)
-    if rval is None:
-        return []
-    return rval.split(':')
-
-def dyld_image_suffix(env=None):
-    if env is None:
-        env = os.environ
-    return env.get('DYLD_IMAGE_SUFFIX')
-
-def dyld_framework_path(env=None):
-    return dyld_env(env, 'DYLD_FRAMEWORK_PATH')
-
-def dyld_library_path(env=None):
-    return dyld_env(env, 'DYLD_LIBRARY_PATH')
-
-def dyld_fallback_framework_path(env=None):
-    return dyld_env(env, 'DYLD_FALLBACK_FRAMEWORK_PATH')
-
-def dyld_fallback_library_path(env=None):
-    return dyld_env(env, 'DYLD_FALLBACK_LIBRARY_PATH')
-
-def dyld_image_suffix_search(iterator, env=None):
-    """For a potential path iterator, add DYLD_IMAGE_SUFFIX semantics"""
-    suffix = dyld_image_suffix(env)
-    if suffix is None:
-        return iterator
-    def _inject(iterator=iterator, suffix=suffix):
-        for path in iterator:
-            if path.endswith('.dylib'):
-                yield path[:-len('.dylib')] + suffix + '.dylib'
-            else:
-                yield path + suffix
-            yield path
-    return _inject()
-
-def dyld_override_search(name, env=None):
-    # If DYLD_FRAMEWORK_PATH is set and this dylib_name is a
-    # framework name, use the first file that exists in the framework
-    # path if any.  If there is none go on to search the DYLD_LIBRARY_PATH
-    # if any.
-
-    framework = framework_info(name)
-
-    if framework is not None:
-        for path in dyld_framework_path(env):
-            yield os.path.join(path, framework['name'])
-
-    # If DYLD_LIBRARY_PATH is set then use the first file that exists
-    # in the path.  If none use the original name.
-    for path in dyld_library_path(env):
-        yield os.path.join(path, os.path.basename(name))
-
-def dyld_executable_path_search(name, executable_path=None):
-    # If we haven't done any searching and found a library and the
-    # dylib_name starts with "@executable_path/" then construct the
-    # library name.
-    if name.startswith('@executable_path/') and executable_path is not None:
-        yield os.path.join(executable_path, name[len('@executable_path/'):])
-
-def dyld_default_search(name, env=None):
-    yield name
-
-    framework = framework_info(name)
-
-    if framework is not None:
-        fallback_framework_path = dyld_fallback_framework_path(env)
-        for path in fallback_framework_path:
-            yield os.path.join(path, framework['name'])
-
-    fallback_library_path = dyld_fallback_library_path(env)
-    for path in fallback_library_path:
-        yield os.path.join(path, os.path.basename(name))
-
-    if framework is not None and not fallback_framework_path:
-        for path in DEFAULT_FRAMEWORK_FALLBACK:
-            yield os.path.join(path, framework['name'])
-
-    if not fallback_library_path:
-        for path in DEFAULT_LIBRARY_FALLBACK:
-            yield os.path.join(path, os.path.basename(name))
-
-def dyld_find(name, executable_path=None, env=None):
-    """
-    Find a library or framework using dyld semantics
-    """
-    name = ensure_utf8(name)
-    executable_path = ensure_utf8(executable_path)
-    for path in dyld_image_suffix_search(chain(
-                dyld_override_search(name, env),
-                dyld_executable_path_search(name, executable_path),
-                dyld_default_search(name, env),
-            ), env):
-        if os.path.isfile(path):
-            return path
-    raise ValueError, "dylib %s could not be found" % (name,)
-
-def framework_find(fn, executable_path=None, env=None):
-    """
-    Find a framework using dyld semantics in a very loose manner.
-
-    Will take input such as:
-        Python
-        Python.framework
-        Python.framework/Versions/Current
-    """
-    try:
-        return dyld_find(fn, executable_path=executable_path, env=env)
-    except ValueError, e:
-        pass
-    fmwk_index = fn.rfind('.framework')
-    if fmwk_index == -1:
-        fmwk_index = len(fn)
-        fn += '.framework'
-    fn = os.path.join(fn, os.path.basename(fn[:fmwk_index]))
-    try:
-        return dyld_find(fn, executable_path=executable_path, env=env)
-    except ValueError:
-        raise e
-
-def test_dyld_find():
-    env = {}
-    assert dyld_find('libSystem.dylib') == '/usr/lib/libSystem.dylib'
-    assert dyld_find('System.framework/System') == '/System/Library/Frameworks/System.framework/System'
-
-if __name__ == '__main__':
-    test_dyld_find()

File macholib/macholib/dylib.py

-"""
-Generic dylib path manipulation
-"""
-
-import re
-
-__all__ = ['dylib_info']
-
-DYLIB_RE = re.compile(r"""(?x)
-(?P<location>^.*)(?:^|/)
-(?P<name>
-    (?P<shortname>\w+?)
-    (?:\.(?P<version>[^._]+))?
-    (?:_(?P<suffix>[^._]+))?
-    \.dylib$
-)
-""")
-
-def dylib_info(filename):
-    """
-    A dylib name can take one of the following four forms:
-        Location/Name.SomeVersion_Suffix.dylib
-        Location/Name.SomeVersion.dylib
-        Location/Name_Suffix.dylib
-        Location/Name.dylib
-
-    returns None if not found or a mapping equivalent to:
-        dict(
-            location='Location',
-            name='Name.SomeVersion_Suffix.dylib',
-            shortname='Name',
-            version='SomeVersion',
-            suffix='Suffix',
-        )
-
-    Note that SomeVersion and Suffix are optional and may be None
-    if not present.
-    """
-    is_dylib = DYLIB_RE.match(filename)
-    if not is_dylib:
-        return None
-    return is_dylib.groupdict()
-
-
-def test_dylib_info():
-    def d(location=None, name=None, shortname=None, version=None, suffix=None):
-        return dict(
-            location=location,
-            name=name,
-            shortname=shortname,
-            version=version,
-            suffix=suffix
-        )
-    assert dylib_info('completely/invalid') is None
-    assert dylib_info('completely/invalide_debug') is None
-    assert dylib_info('P/Foo.dylib') == d('P', 'Foo.dylib', 'Foo')
-    assert dylib_info('P/Foo_debug.dylib') == d('P', 'Foo_debug.dylib', 'Foo', suffix='debug')
-    assert dylib_info('P/Foo.A.dylib') == d('P', 'Foo.A.dylib', 'Foo', 'A')
-    assert dylib_info('P/Foo_debug.A.dylib') == d('P', 'Foo_debug.A.dylib', 'Foo_debug', 'A')
-    assert dylib_info('P/Foo.A_debug.dylib') == d('P', 'Foo.A_debug.dylib', 'Foo', 'A', 'debug')
-
-if __name__ == '__main__':
-    test_dylib_info()

File macholib/macholib/framework.py

-"""
-Generic framework path manipulation
-"""
-
-import re
-
-__all__ = ['framework_info']
-
-STRICT_FRAMEWORK_RE = re.compile(r"""(?x)
-(?P<location>^.*)(?:^|/)
-(?P<name>
-    (?P<shortname>\w+).framework/
-    (?:Versions/(?P<version>[^/]+)/)?
-    (?P=shortname)
-    (?:_(?P<suffix>[^_]+))?
-)$
-""")
-
-def framework_info(filename):
-    """
-    A framework name can take one of the following four forms:
-        Location/Name.framework/Versions/SomeVersion/Name_Suffix
-        Location/Name.framework/Versions/SomeVersion/Name
-        Location/Name.framework/Name_Suffix
-        Location/Name.framework/Name
-
-    returns None if not found, or a mapping equivalent to:
-        dict(
-            location='Location',
-            name='Name.framework/Versions/SomeVersion/Name_Suffix',
-            shortname='Name',
-            version='SomeVersion',
-            suffix='Suffix',
-        )
-
-    Note that SomeVersion and Suffix are optional and may be None
-    if not present
-    """
-    is_framework = STRICT_FRAMEWORK_RE.match(filename)
-    if not is_framework:
-        return None
-    return is_framework.groupdict()
-
-def test_framework_info():
-    def d(location=None, name=None, shortname=None, version=None, suffix=None):
-        return dict(
-            location=location,
-            name=name,
-            shortname=shortname,
-            version=version,
-            suffix=suffix
-        )
-    assert framework_info('completely/invalid') is None
-    assert framework_info('completely/invalid/_debug') is None
-    assert framework_info('P/F.framework') is None
-    assert framework_info('P/F.framework/_debug') is None
-    assert framework_info('P/F.framework/F') == d('P', 'F.framework/F', 'F')
-    assert framework_info('P/F.framework/F_debug') == d('P', 'F.framework/F_debug', 'F', suffix='debug')
-    assert framework_info('P/F.framework/Versions') is None
-    assert framework_info('P/F.framework/Versions/A') is None
-    assert framework_info('P/F.framework/Versions/A/F') == d('P', 'F.framework/Versions/A/F', 'F', 'A')
-    assert framework_info('P/F.framework/Versions/A/F_debug') == d('P', 'F.framework/Versions/A/F_debug', 'F', 'A', 'debug')
-
-if __name__ == '__main__':
-    test_framework_info()

File macholib/macholib/itergraphreport.py

-"""
-Utilities for creating dot output from a MachOGraph
-"""
-
-from pkg_resources import require
-require("altgraph")
-
-from altgraph.compat import *
-
-__all__ = ['itergraphreport']
-
-def itergraphreport(nodes, describe_edge, name='G'):
-    edges = deque()
-    nodetoident = {}
-    mainedges = set()
-
-    def nodevisitor(node, data, outgoing, incoming):
-        return {'label': str(node)}
-
-    def edgevisitor(edge, data, head, tail):
-        return {}
-
-    yield 'digraph %s {\n' % (name,)
-    attr = dict(rankdir='LR', concentrate='true')
-    cpatt  = '%s="%s"'
-    for item in attr.iteritems():
-        yield '\t%s;\n' % (cpatt % item,)
-
-    # find all packages (subgraphs)
-    for (node, data, outgoing, incoming) in nodes:
-        nodetoident[node] = getattr(data, 'identifier', node)
-
-    # create sets for subgraph, write out descriptions
-    for (node, data, outgoing, incoming) in nodes:
-        # update edges
-        for edge in imap(describe_edge, outgoing):
-            edges.append(edge)
-
-        # describe node
-        yield '\t"%s" [%s];\n' % (
-            node,
-            ','.join([
-                (cpatt % item) for item in
-                nodevisitor(node, data, outgoing, incoming).iteritems()
-            ]),
-        )
-
-    graph = []
-
-    while edges:
-        edge, data, head, tail = edges.popleft()
-        if data in ('run_file', 'load_dylib'):
-            graph.append((edge, data, head, tail))
-
-    def do_graph(edges, tabs):
-        edgestr = tabs + '"%s" -> "%s" [%s];\n'
-        # describe edge
-        for (edge, data, head, tail) in edges:
-            attribs = edgevisitor(edge, data, head, tail)
-            yield edgestr % (
-                head,
-                tail,
-                ','.join([(cpatt % item) for item in attribs.iteritems()]),
-            )
-
-    for s in do_graph(graph, '\t'):
-        yield s
-
-    yield '}\n'

File macholib/macholib/mach_o.py

-"""
-Other than changing the load commands in such a way that they do not
-contain the load command itself, this is largely a by-hand conversion
-of the C headers.  Hopefully everything in here should be at least as
-obvious as the C headers, and you should be using the C headers as a real
-reference because the documentation didn't come along for the ride.
-
-Doing much of anything with the symbol tables or segments is really
-not covered at this point.
-
-See /usr/include/mach-o and friends.
-"""
-import time
-
-from macholib.ptypes import *
-
-CPU_TYPE_NAMES = {
-    -1:     'ANY',
-    1:      'VAX',
-    6:      'MC680x0',
-    7:      'i386',
-    8:      'MIPS',
-    10:     'MC98000',
-    11:     'HPPA',
-    12:     'ARM',
-    13:     'MC88000',
-    14:     'SPARC',
-    15:     'i860',
-    16:     'Alpha',
-    18:     'PowerPC',
-}
-
-_MH_EXECUTE_SYM = "__mh_execute_header"
-MH_EXECUTE_SYM = "_mh_execute_header"
-_MH_BUNDLE_SYM = "__mh_bundle_header"
-MH_BUNDLE_SYM = "_mh_bundle_header"
-_MH_DYLIB_SYM = "__mh_dylib_header"
-MH_DYLIB_SYM = "_mh_dylib_header"
-_MH_DYLINKER_SYM = "__mh_dylinker_header"
-MH_DYLINKER_SYM = "_mh_dylinker_header"
-
-(
-    MH_OBJECT, MH_EXECUTE, MH_FVMLIB, MH_CORE, MH_PRELOAD, MH_DYLIB,
-    MH_DYLINKER, MH_BUNDLE, MH_DYLIB_STUB,
-) = range(0x1, 0xa)
-
-(
-    MH_NOUNDEFS, MH_INCRLINK, MH_DYLDLINK, MH_BINDATLOAD, MH_PREBOUND,
-    MH_SPLIT_SEGS, MH_LAZY_INIT, MH_TWOLEVEL, MH_FORCE_FLAT, MH_NOMULTIDEFS,
-    MH_NOFIXPREBINDING
-) = map((1).__lshift__, range(11))
-
-MH_MAGIC = 0xfeedfaceL
-MH_CIGAM = 0xcefaedfeL
-MH_MAGIC_64 = 0xfeedfacfL
-MH_CIGAM_64 = 0xcffaedfeL
-
-integer_t = p_int
-cpu_type_t = integer_t
-cpu_subtype_t = integer_t
-
-MH_FILETYPE_NAMES = {
-    MH_OBJECT:      'relocatable object',
-    MH_EXECUTE:     'demand paged executable',
-    MH_FVMLIB:      'fixed vm shared library',
-    MH_CORE:        'core',
-    MH_PRELOAD:     'preloaded executable',
-    MH_DYLIB:       'dynamically bound shared library',
-    MH_DYLINKER:    'dynamic link editor',
-    MH_BUNDLE:      'dynamically bound bundle',
-    MH_DYLIB_STUB:  'shared library stub for static linking',
-}
-
-MH_FILETYPE_SHORTNAMES = {
-    MH_OBJECT:      'object',
-    MH_EXECUTE:     'execute',
-    MH_FVMLIB:      'fvmlib',
-    MH_CORE:        'core',
-    MH_PRELOAD:     'preload',
-    MH_DYLIB:       'dylib',
-    MH_DYLINKER:    'dylinker',
-    MH_BUNDLE:      'bundle',
-    MH_DYLIB_STUB:  'dylib_stub',
-}
-
-MH_FLAGS_NAMES = {
-    MH_NOUNDEFS:    'no undefined references',
-    MH_INCRLINK:    'output of an incremental link',
-    MH_DYLDLINK:    'input for the dynamic linker',
-    MH_BINDATLOAD:  'undefined references bound dynamically when loaded',
-    MH_PREBOUND:    'dynamic undefined references prebound',
-    MH_SPLIT_SEGS:  'split read-only and read-write segments',
-    MH_LAZY_INIT:   '(obsolete)',
-    MH_TWOLEVEL:    'using two-level name space bindings',
-    MH_FORCE_FLAT:  'forcing all imagges to use flat name space bindings',
-    MH_NOMULTIDEFS: 'umbrella guarantees no multiple definitions',
-    MH_NOFIXPREBINDING: 'do not notify prebinding agent about this executable',
-}
-
-class mach_version_helper(Structure):
-    _fields_ = (
-        ('major', p_ushort),
-        ('minor', p_ubyte),
-        ('rev', p_ubyte),
-    )
-    def __str__(self):
-        return '%s.%s.%s' % (self.major, self.minor, self.rev)
-
-class mach_timestamp_helper(p_ulong):
-    def __str__(self):
-        return time.ctime(self)
-
-def read_struct(f, s, **kw):
-    return s.from_fileobj(f, **kw)
-
-class mach_header(Structure):
-    _fields_ = (
-        ('magic', p_ulong),
-        ('cputype', cpu_type_t),
-        ('cpusubtype', cpu_subtype_t),
-        ('filetype', p_ulong),
-        ('ncmds', p_ulong),
-        ('sizeofcmds', p_ulong),
-        ('flags', p_ulong),
-    )
-    def _describe(self):
-        bit = 1L
-        flags = self.flags
-        dflags = []
-        while flags and bit < (1<<32L):
-            if flags & bit:
-                dflags.append(MH_FLAGS_NAMES.get(bit, str(bit)))
-                flags = flags ^ bit
-            bit <<= 1L
-        return (
-            ('magic', '0x%08X' % self.magic),
-            ('cputype', CPU_TYPE_NAMES.get(self.cputype, self.cputype)),
-            ('cpusubtype', self.cpusubtype),
-            ('filetype', MH_FILETYPE_NAMES.get(self.filetype, self.filetype)),
-            ('ncmds', self.ncmds),
-            ('sizeofcmds', self.sizeofcmds),
-            ('flags', dflags),
-        )
-
-class mach_header_64(mach_header):
-    _fields_ = mach_header._fields_ + (('reserved', p_ulong),)
-
-class load_command(Structure):
-    _fields_ = (
-        ('cmd', p_ulong),
-        ('cmdsize', p_ulong),
-    )
-
-LC_REQ_DYLD = 0x80000000L
-
-(
-    LC_SEGMENT, LC_SYMTAB, LC_SYMSEG, LC_THREAD, LC_UNIXTHREAD, LC_LOADFVMLIB,
-    LC_IDFVMLIB, LC_IDENT, LC_FVMFILE, LC_PREPAGE, LC_DYSYMTAB, LC_LOAD_DYLIB,
-    LC_ID_DYLIB, LC_LOAD_DYLINKER, LC_ID_DYLINKER, LC_PREBOUND_DYLIB,
-    LC_ROUTINES, LC_SUB_FRAMEWORK, LC_SUB_UMBRELLA, LC_SUB_CLIENT,
-    LC_SUB_LIBRARY, LC_TWOLEVEL_HINTS, LC_PREBIND_CKSUM
-) = range(0x1, 0x18)
-
-LC_LOAD_WEAK_DYLIB = LC_REQ_DYLD | 0x18
-
-LC_SEGMENT_64 = 0x19
-LC_ROUTINES_64 = 0x1a
-LC_UUID = 0x1b
-LC_RPATH = (0x1c | LC_REQ_DYLD)
-LC_CODE_SIGNATURE = 0x1d
-LC_CODE_SEGMENT_SPLIT_INFO = 0x1e
-LC_REEXPORT_DYLIB = 0x1f | LC_REQ_DYLD
-
-# this is really a union.. but whatever
-class lc_str(p_ulong):
-    pass
-
-p_str16 = pypackable('p_str16', str, '16s')
-
-vm_prot_t = p_int
-class segment_command(Structure):
-    _fields_ = (
-        ('segname', p_str16),
-        ('vmaddr', p_ulong),
-        ('vmsize', p_ulong),
-        ('fileoff', p_ulong),
-        ('filesize', p_ulong),
-        ('maxprot', vm_prot_t),
-        ('initprot', vm_prot_t),
-        ('nsects', p_ulong), # read the section structures ?
-        ('flags', p_ulong),
-    )
-
-class segment_command_64(Structure):
-    _fields_ = (
-        ('segname', p_str16),
-        ('vmaddr', p_ulonglong),
-        ('vmsize', p_ulonglong),
-        ('fileoff', p_ulonglong),
-        ('filesize', p_ulonglong),
-        ('maxprot', vm_prot_t),
-        ('initprot', vm_prot_t),
-        ('nsects', p_ulong), # read the section structures ?
-        ('flags', p_ulong),
-    )
-
-SG_HIGHVM = 0x1
-SG_FVMLIB = 0x2
-SG_NORELOC = 0x4
-
-class section(Structure):
-    _fields_ = (
-        ('sectname', p_str16),
-        ('segname', p_str16),
-        ('addr', p_ulong),
-        ('size', p_ulong),
-        ('offset', p_ulong),
-        ('align', p_ulong),
-        ('reloff', p_ulong),
-        ('nreloc', p_ulong),
-        ('flags', p_ulong),
-        ('reserved1', p_ulong),
-        ('reserved2', p_ulong),
-    )
-
-class section_64(Structure):
-    _fields_ = (
-        ('sectname', p_str16),
-        ('segname', p_str16),
-        ('addr', p_ulonglong),
-        ('size', p_ulonglong),
-        ('offset', p_ulong),
-        ('align', p_ulong),
-        ('reloff', p_ulong),
-        ('nreloc', p_ulong),
-        ('flags', p_ulong),
-        ('reserved1', p_ulong),
-        ('reserved2', p_ulong),
-        ('reserved3', p_ulong),
-    )
-
-SECTION_TYPE = 0xffL
-SECTION_ATTRIBUTES = 0xffffff00L
-S_REGULAR = 0x0
-S_ZEROFILL = 0x1
-S_CSTRING_LITERALS = 0x2
-S_4BYTE_LITERALS = 0x3
-S_8BYTE_LITERALS = 0x4
-S_LITERAL_POINTERS = 0x5
-S_NON_LAZY_SYMBOL_POINTERS = 0x6
-S_LAZY_SYMBOL_POINTERS = 0x7
-S_SYMBOL_STUBS = 0x8
-S_MOD_INIT_FUNC_POINTERS = 0x9
-S_MOD_TERM_FUNC_POINTERS = 0xa
-S_COALESCED = 0xb
-
-SECTION_ATTRIBUTES_USR = 0xff000000L
-S_ATTR_PURE_INSTRUCTIONS = 0x80000000L
-S_ATTR_NO_TOC = 0x40000000L
-S_ATTR_STRIP_STATIC_SYMS = 0x20000000L
-SECTION_ATTRIBUTES_SYS = 0x00ffff00L
-S_ATTR_SOME_INSTRUCTIONS = 0x00000400L
-S_ATTR_EXT_RELOC = 0x00000200L
-S_ATTR_LOC_RELOC = 0x00000100L
-
-
-SEG_PAGEZERO =    "__PAGEZERO"
-SEG_TEXT =    "__TEXT"
-SECT_TEXT =   "__text"
-SECT_FVMLIB_INIT0 = "__fvmlib_init0"
-SECT_FVMLIB_INIT1 = "__fvmlib_init1"
-SEG_DATA =    "__DATA"
-SECT_DATA =   "__data"
-SECT_BSS =    "__bss"
-SECT_COMMON = "__common"
-SEG_OBJC =    "__OBJC"
-SECT_OBJC_SYMBOLS = "__symbol_table"
-SECT_OBJC_MODULES = "__module_info"
-SECT_OBJC_STRINGS = "__selector_strs"
-SECT_OBJC_REFS = "__selector_refs"
-SEG_ICON =     "__ICON"
-SECT_ICON_HEADER = "__header"
-SECT_ICON_TIFF =   "__tiff"
-SEG_LINKEDIT =    "__LINKEDIT"
-SEG_UNIXSTACK =   "__UNIXSTACK"
-
-#
-#  I really should remove all these _command classes because they
-#  are no different.  I decided to keep the load commands separate,
-#  so classes like fvmlib and fvmlib_command are equivalent.
-#
-
-class fvmlib(Structure):
-    _fields_ = (
-        ('name', lc_str),
-        ('minor_version', mach_version_helper),
-        ('header_addr', p_ulong),
-    )
-
-class fvmlib_command(Structure):
-    _fields_ = fvmlib._fields_
-
-class dylib(Structure):
-    _fields_ = (
-        ('name', lc_str),
-        ('timestamp', mach_timestamp_helper),
-        ('current_version', mach_version_helper),
-        ('compatibility_version', mach_version_helper),
-    )
-
-# merged dylib structure
-class dylib_command(Structure):
-    _fields_ = dylib._fields_
-
-class sub_framework_command(Structure):
-    _fields_ = (
-        ('umbrella', lc_str),
-    )
-
-class sub_client_command(Structure):
-    _fields_ = (
-        ('client', lc_str),
-    )
-
-class sub_umbrella_command(Structure):
-    _fields_ = (
-        ('sub_umbrella', lc_str),
-    )
-
-class sub_library_command(Structure):
-    _fields_ = (
-        ('sub_library', lc_str),
-    )
-
-class prebound_dylib_command(Structure):
-    _fields_ = (
-        ('name', lc_str),
-        ('nmodules', p_ulong),
-        ('linked_modules', p_ulong),
-    )
-
-class dylinker_command(Structure):
-    _fields_ = (
-        ('name', lc_str),
-    )
-
-class thread_command(Structure):
-    _fields_ = (
-    )
-
-class routines_command(Structure):
-    _fields_ = (
-        ('init_address', p_ulong),
-        ('init_module', p_ulong),
-        ('reserved1', p_ulong),
-        ('reserved2', p_ulong),
-        ('reserved3', p_ulong),
-        ('reserved4', p_ulong),
-        ('reserved5', p_ulong),
-        ('reserved6', p_ulong),
-    )
-
-class routines_command_64(Structure):
-    _fields_ = (
-        ('init_address', p_ulonglong),
-        ('init_module', p_ulonglong),
-        ('reserved1', p_ulonglong),
-        ('reserved2', p_ulonglong),
-        ('reserved3', p_ulonglong),
-        ('reserved4', p_ulonglong),
-        ('reserved5', p_ulonglong),
-        ('reserved6', p_ulonglong),
-    )
-
-class symtab_command(Structure):
-    _fields_ = (
-        ('symoff', p_ulong),
-        ('nsyms', p_ulong),
-        ('stroff', p_ulong),
-        ('strsize', p_ulong),
-    )
-
-class dysymtab_command(Structure):
-    _fields_ = (
-        ('ilocalsym', p_ulong),
-        ('nlocalsym', p_ulong),
-        ('iextdefsym', p_ulong),
-        ('nextdefsym', p_ulong),
-        ('iundefsym', p_ulong),
-        ('nundefsym', p_ulong),
-        ('tocoff', p_ulong),
-        ('ntoc', p_ulong),
-        ('modtaboff', p_ulong),
-        ('nmodtab', p_ulong),
-        ('extrefsymoff', p_ulong),
-        ('nextrefsyms', p_ulong),
-        ('indirectsymoff', p_ulong),
-        ('nindirectsyms', p_ulong),
-        ('extreloff', p_ulong),
-        ('nextrel', p_ulong),
-        ('locreloff', p_ulong),
-        ('nlocrel', p_ulong),
-    )
-
-INDIRECT_SYMBOL_LOCAL = 0x80000000L
-INDIRECT_SYMBOL_ABS = 0x40000000L
-
-class dylib_table_of_contents(Structure):
-    _fields_ = (
-        ('symbol_index', p_ulong),
-        ('module_index', p_ulong),
-    )
-
-class dylib_module(Structure):
-    _fields_ = (
-        ('module_name', p_ulong),
-        ('iextdefsym', p_ulong),
-        ('nextdefsym', p_ulong),
-        ('irefsym', p_ulong),
-        ('nrefsym', p_ulong),
-        ('ilocalsym', p_ulong),
-        ('nlocalsym', p_ulong),
-        ('iextrel', p_ulong),
-        ('nextrel', p_ulong),
-        ('iinit_iterm', p_ulong),
-        ('ninit_nterm', p_ulong),
-        ('objc_module_info_addr', p_ulong),
-        ('objc_module_info_size', p_ulong),
-    )
-
-class dylib_module_64(Structure):
-    _fields_ = (
-        ('module_name', p_ulong),
-        ('iextdefsym', p_ulong),
-        ('nextdefsym', p_ulong),
-        ('irefsym', p_ulong),
-        ('nrefsym', p_ulong),
-        ('ilocalsym', p_ulong),
-        ('nlocalsym', p_ulong),
-        ('iextrel', p_ulong),
-        ('nextrel', p_ulong),
-        ('iinit_iterm', p_ulong),
-        ('ninit_nterm', p_ulong),
-        ('objc_module_info_size', p_ulong),
-        ('objc_module_info_addr', p_ulonglong),
-    )
-
-class dylib_reference(Structure):
-    _fields_ = (
-        # XXX - ick, fix
-        ('isym_flags', p_ulong),
-        #('isym', p_ubyte * 3),
-        #('flags', p_ubyte),
-    )
-
-class twolevel_hints_command(Structure):
-    _fields_ = (
-        ('offset', p_ulong),
-        ('nhints', p_ulong),
-    )
-
-class twolevel_hint(Structure):
-    _fields_ = (
-      # XXX - ick, fix
-      ('isub_image_itoc', p_ulong),
-      #('isub_image', p_ubyte),
-      #('itoc', p_ubyte * 3),
-  )
-
-class prebind_cksum_command(Structure):
-    _fields_ = (
-        ('cksum', p_ulong),
-    )
-
-class symseg_command(Structure):
-    _fields_ = (
-        ('offset', p_ulong),
-        ('size', p_ulong),
-    )
-
-class ident_command(Structure):
-    _fields_ = (
-    )
-
-class fvmfile_command(Structure):
-    _fields_ = (
-        ('name', lc_str),
-        ('header_addr', p_ulong),
-    )
-
-class uuid_command (Structure):
-    _fields_ = (
-#        'uuid', pypackable('uuid', str, '16B'),
-    )
-
-class rpath_command (Structure):
-    _fields_ = (
-        ('path', lc_str),
-    )
-
-class linkedit_data_command (Structure):
-    _fields_ = (
-        ('dataoff',   p_ulong),
-        ('datassize', p_ulong),
-    )
-
-
-LC_REGISTRY = {
-    LC_SEGMENT:         segment_command,
-    LC_IDFVMLIB:        fvmlib_command,
-    LC_LOADFVMLIB:      fvmlib_command,
-    LC_ID_DYLIB:        dylib_command,
-    LC_LOAD_DYLIB:      dylib_command,
-    LC_LOAD_WEAK_DYLIB: dylib_command,
-    LC_SUB_FRAMEWORK:   sub_framework_command,
-    LC_SUB_CLIENT:      sub_client_command,
-    LC_SUB_UMBRELLA:    sub_umbrella_command,
-    LC_SUB_LIBRARY:     sub_library_command,
-    LC_PREBOUND_DYLIB:  prebound_dylib_command,
-    LC_ID_DYLINKER:     dylinker_command,
-    LC_LOAD_DYLINKER:   dylinker_command,
-    LC_THREAD:          thread_command,
-    LC_UNIXTHREAD:      thread_command,
-    LC_ROUTINES:        routines_command,
-    LC_SYMTAB:          symtab_command,
-    LC_DYSYMTAB:        dysymtab_command,
-    LC_TWOLEVEL_HINTS:  twolevel_hints_command,
-    LC_PREBIND_CKSUM:   prebind_cksum_command,
-    LC_SYMSEG:          symseg_command,
-    LC_IDENT:           ident_command,
-    LC_FVMFILE:         fvmfile_command,
-    LC_SEGMENT_64:      segment_command_64,
-    LC_ROUTINES_64:     routines_command_64,
-    LC_UUID:            uuid_command,
-    LC_RPATH:           rpath_command,
-    LC_CODE_SIGNATURE:  linkedit_data_command,
-    LC_CODE_SEGMENT_SPLIT_INFO:  linkedit_data_command,
-    LC_REEXPORT_DYLIB:  dylib_command,
-}
-
-class nlist(Structure):
-    _fields_ = (
-        ('n_un', p_long),
-        ('n_type', p_ubyte),
-        ('n_sect', p_ubyte),
-        ('n_desc', p_short),
-        ('n_value', p_ulong),
-    )
-
-N_STAB = 0xe0
-N_PEXT = 0x10
-N_TYPE = 0x0e
-N_EXT = 0x01
-
-N_UNDF = 0x0
-N_ABS = 0x2
-N_SECT = 0xe
-N_PBUD = 0xc
-N_INDR = 0xa
-
-NO_SECT = 0
-MAX_SECT = 255
-
-REFERENCE_TYPE = 0xf
-REFERENCE_FLAG_UNDEFINED_NON_LAZY = 0
-REFERENCE_FLAG_UNDEFINED_LAZY = 1
-REFERENCE_FLAG_DEFINED = 2
-REFERENCE_FLAG_PRIVATE_DEFINED = 3
-REFERENCE_FLAG_PRIVATE_UNDEFINED_NON_LAZY = 4
-REFERENCE_FLAG_PRIVATE_UNDEFINED_LAZY = 5
-
-REFERENCED_DYNAMICALLY = 0x0010
-
-def GET_LIBRARY_ORDINAL(n_desc):
-    return (((n_desc) >> 8) & 0xff)
-
-def SET_LIBRARY_ORDINAL(n_desc, ordinal):
-    return (((n_desc) & 0x00ff) | (((ordinal & 0xff) << 8)))
-
-SELF_LIBRARY_ORDINAL = 0x0
-MAX_LIBRARY_ORDINAL = 0xfd
-DYNAMIC_LOOKUP_ORDINAL = 0xfe
-EXECUTABLE_ORDINAL = 0xff
-
-N_DESC_DISCARDED = 0x0020
-N_WEAK_REF = 0x0040
-N_WEAK_DEF = 0x0080
-
-# /usr/include/mach-o/fat.h
-FAT_MAGIC = 0xcafebabeL
-class fat_header(Structure):
-    _fields_ = (
-        ('magic', p_ulong),
-        ('nfat_arch', p_ulong),
-    )
-
-class fat_arch(Structure):
-    _fields_ = (
-        ('cputype', cpu_type_t),
-        ('cpusubtype', cpu_subtype_t),
-        ('offset', p_ulong),
-        ('size', p_ulong),
-        ('align', p_ulong),
-    )

File macholib/macholib/macho_find.py

-#!/usr/bin/env python
-
-import os
-import sys
-
-from macholib.util import is_platform_file
-
-def check_file(path):
-    if not os.path.exists(path):
-        print >>sys.stderr, '%s: %s: No such file or directory' % (sys.argv[0], path)
-        return 1
-    try:
-        is_plat = is_platform_file(path)
-    except IOError:
-        print >>sys.stderr, '%s: %s: Permission denied' % (sys.argv[0], path)
-        return 1
-    else: