1fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar#!/usr/bin/env python 2fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 3fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarimport struct 4fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarimport sys 58906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbarimport StringIO 6fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 7228290c0d181b663f33680aea03e10843da5f907Rafael Espindolaimport common_dump 8228290c0d181b663f33680aea03e10843da5f907Rafael Espindola 9fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarclass Reader: 10fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar def __init__(self, path): 11fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if path == '-': 128906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar # Snarf all the data so we can seek. 138906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar self.file = StringIO.StringIO(sys.stdin.read()) 14fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar else: 15fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar self.file = open(path,'rb') 16fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar self.isLSB = None 17f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar self.is64Bit = None 188906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 198906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar self.string_table = None 20fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 21fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar def tell(self): 228906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar return self.file.tell() 238906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 248906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar def seek(self, pos): 258906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar self.file.seek(pos) 26fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 27fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar def read(self, N): 28fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar data = self.file.read(N) 29fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if len(data) != N: 30fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar raise ValueError,"Out of data!" 31fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar return data 32fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 338906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar def read8(self): 348906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar return ord(self.read(1)) 358906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 368906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar def read16(self): 378906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar return struct.unpack('><'[self.isLSB] + 'H', self.read(2))[0] 388906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 39fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar def read32(self): 408333a8aea3a42490eba818cf31791c96f3c999ceDaniel Dunbar # Force to 32-bit, if possible; otherwise these might be long ints on a 418333a8aea3a42490eba818cf31791c96f3c999ceDaniel Dunbar # big-endian platform. FIXME: Why??? 428333a8aea3a42490eba818cf31791c96f3c999ceDaniel Dunbar Value = struct.unpack('><'[self.isLSB] + 'I', self.read(4))[0] 438333a8aea3a42490eba818cf31791c96f3c999ceDaniel Dunbar return int(Value) 44fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 45f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar def read64(self): 46b087c8490f6ad46c44825ccb08481c96a45b15adNAKAMURA Takumi Value = struct.unpack('><'[self.isLSB] + 'Q', self.read(8))[0] 47b087c8490f6ad46c44825ccb08481c96a45b15adNAKAMURA Takumi if Value == int(Value): 48b087c8490f6ad46c44825ccb08481c96a45b15adNAKAMURA Takumi Value = int(Value) 49b087c8490f6ad46c44825ccb08481c96a45b15adNAKAMURA Takumi return Value 50f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar 518906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar def registerStringTable(self, strings): 528906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar if self.string_table is not None: 538906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar raise ValueError,"%s: warning: multiple string tables" % sys.argv[0] 548906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 558906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar self.string_table = strings 568906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 578906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar def getString(self, index): 588906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar if self.string_table is None: 598906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar raise ValueError,"%s: warning: no string table registered" % sys.argv[0] 608906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 618906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar end = self.string_table.index('\x00', index) 628906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar return self.string_table[index:end] 638906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 64fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbardef dumpmacho(path, opts): 65fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar f = Reader(path) 66fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 67fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar magic = f.read(4) 68fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if magic == '\xFE\xED\xFA\xCE': 69f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar f.isLSB, f.is64Bit = False, False 70fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar elif magic == '\xCE\xFA\xED\xFE': 71f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar f.isLSB, f.is64Bit = True, False 72f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar elif magic == '\xFE\xED\xFA\xCF': 73f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar f.isLSB, f.is64Bit = False, True 74f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar elif magic == '\xCF\xFA\xED\xFE': 75f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar f.isLSB, f.is64Bit = True, True 76fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar else: 77fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar raise ValueError,"Not a Mach-O object file: %r (bad magic)" % path 78fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 79fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print "('cputype', %r)" % f.read32() 80fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print "('cpusubtype', %r)" % f.read32() 81fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar filetype = f.read32() 82fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print "('filetype', %r)" % filetype 83fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 84fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar numLoadCommands = f.read32() 8544fa0473ae9144a8cfb4a500ae9de17239e69d2eDaniel Dunbar print "('num_load_commands', %r)" % numLoadCommands 86fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 87fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar loadCommandsSize = f.read32() 88fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print "('load_commands_size', %r)" % loadCommandsSize 89fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 90fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print "('flag', %r)" % f.read32() 91fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 92f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar if f.is64Bit: 93f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print "('reserved', %r)" % f.read32() 94f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar 95fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar start = f.tell() 96fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 97fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print "('load_commands', [" 98fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar for i in range(numLoadCommands): 99fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar dumpLoadCommand(f, i, opts) 100fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print "])" 101fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 102fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if f.tell() - start != loadCommandsSize: 103f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar raise ValueError,"%s: warning: invalid load commands size: %r" % ( 104f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar sys.argv[0], loadCommandsSize) 105fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 106fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbardef dumpLoadCommand(f, i, opts): 107fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar start = f.tell() 108fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 109fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " # Load Command %r" % i 110fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar cmd = f.read32() 111fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " (('command', %r)" % cmd 112fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar cmdSize = f.read32() 113fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('size', %r)" % cmdSize 114fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 115fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if cmd == 1: 116f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar dumpSegmentLoadCommand(f, opts, False) 117fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar elif cmd == 2: 118fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar dumpSymtabCommand(f, opts) 119fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar elif cmd == 11: 120fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar dumpDysymtabCommand(f, opts) 121f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar elif cmd == 25: 122f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar dumpSegmentLoadCommand(f, opts, True) 1233bc1b1993063acae36e06fe36cff39dc0295a2d8Daniel Dunbar elif cmd == 27: 1243bc1b1993063acae36e06fe36cff39dc0295a2d8Daniel Dunbar import uuid 1253bc1b1993063acae36e06fe36cff39dc0295a2d8Daniel Dunbar print " ('uuid', %s)" % uuid.UUID(bytes=f.read(16)) 126fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar else: 127f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print >>sys.stderr,"%s: warning: unknown load command: %r" % ( 128f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar sys.argv[0], cmd) 129fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar f.read(cmdSize - 8) 130fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " )," 131fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 132fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if f.tell() - start != cmdSize: 133f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar raise ValueError,"%s: warning: invalid load command size: %r" % ( 134f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar sys.argv[0], cmdSize) 135fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 136f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbardef dumpSegmentLoadCommand(f, opts, is64Bit): 137fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('segment_name', %r)" % f.read(16) 138f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar if is64Bit: 139f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('vm_addr', %r)" % f.read64() 140f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('vm_size', %r)" % f.read64() 141f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('file_offset', %r)" % f.read64() 142f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('file_size', %r)" % f.read64() 143f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar else: 144f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('vm_addr', %r)" % f.read32() 145f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('vm_size', %r)" % f.read32() 146f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('file_offset', %r)" % f.read32() 147f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('file_size', %r)" % f.read32() 148fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('maxprot', %r)" % f.read32() 149fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('initprot', %r)" % f.read32() 150fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar numSections = f.read32() 151fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('num_sections', %r)" % numSections 152fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('flags', %r)" % f.read32() 153fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 154fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('sections', [" 155fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar for i in range(numSections): 156f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar dumpSection(f, i, opts, is64Bit) 157fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ])" 158fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 159fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbardef dumpSymtabCommand(f, opts): 1608906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar symoff = f.read32() 1618906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('symoff', %r)" % symoff 1628906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar nsyms = f.read32() 1638906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('nsyms', %r)" % nsyms 1648906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar stroff = f.read32() 1658906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('stroff', %r)" % stroff 1668906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar strsize = f.read32() 1678906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('strsize', %r)" % strsize 1688906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 1698906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar prev_pos = f.tell() 1708906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 1718906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar f.seek(stroff) 1728906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar string_data = f.read(strsize) 1738906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('_string_data', %r)" % string_data 1748906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 1758906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar f.registerStringTable(string_data) 1768906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 1778906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar f.seek(symoff) 1788906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('_symbols', [" 1798906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar for i in range(nsyms): 1808906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar dumpNlist32(f, i, opts) 1818906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ])" 1828906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 1838906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar f.seek(prev_pos) 1848906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 1858906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbardef dumpNlist32(f, i, opts): 1868906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " # Symbol %r" % i 1878906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar n_strx = f.read32() 1888906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " (('n_strx', %r)" % n_strx 1898906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar n_type = f.read8() 1908906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('n_type', %#x)" % n_type 1918906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar n_sect = f.read8() 192d889ac3b56211b43af9dc94d831969952b22f3f8Daniel Dunbar print " ('n_sect', %r)" % n_sect 1938906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar n_desc = f.read16() 1948906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('n_desc', %r)" % n_desc 1955691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar if f.is64Bit: 1965691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar n_value = f.read64() 1975691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar print " ('n_value', %r)" % n_value 1985691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar else: 1995691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar n_value = f.read32() 2005691e74f97fc8cad671d50450ad986347875e1d1Daniel Dunbar print " ('n_value', %r)" % n_value 2018906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('_string', %r)" % f.getString(n_strx) 2028906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " )," 203fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 204fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbardef dumpDysymtabCommand(f, opts): 205fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('ilocalsym', %r)" % f.read32() 206fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('nlocalsym', %r)" % f.read32() 207fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('iextdefsym', %r)" % f.read32() 208fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('nextdefsym', %r)" % f.read32() 209fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('iundefsym', %r)" % f.read32() 210fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('nundefsym', %r)" % f.read32() 211fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('tocoff', %r)" % f.read32() 212fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('ntoc', %r)" % f.read32() 213fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('modtaboff', %r)" % f.read32() 214fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('nmodtab', %r)" % f.read32() 215fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('extrefsymoff', %r)" % f.read32() 216fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('nextrefsyms', %r)" % f.read32() 2178906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar indirectsymoff = f.read32() 2188906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('indirectsymoff', %r)" % indirectsymoff 2198906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar nindirectsyms = f.read32() 2208906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('nindirectsyms', %r)" % nindirectsyms 221fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('extreloff', %r)" % f.read32() 222fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('nextrel', %r)" % f.read32() 223fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('locreloff', %r)" % f.read32() 224fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('nlocrel', %r)" % f.read32() 225fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 2268906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar prev_pos = f.tell() 2278906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 2288906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar f.seek(indirectsymoff) 2298906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ('_indirect_symbols', [" 2308906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar for i in range(nindirectsyms): 2318906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " # Indirect Symbol %r" % i 232573e53627e3e44cce60e8c0443a34cd43c41e316Daniel Dunbar print " (('symbol_index', %#x),)," % f.read32() 2338906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar print " ])" 2348906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 2358906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar f.seek(prev_pos) 2368906ff1b9dfde28f1ff00706643ca10843b26e01Daniel Dunbar 237f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbardef dumpSection(f, i, opts, is64Bit): 238fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " # Section %r" % i 239fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " (('section_name', %r)" % f.read(16) 240fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('segment_name', %r)" % f.read(16) 241f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar if is64Bit: 242f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('address', %r)" % f.read64() 243f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar size = f.read64() 244f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('size', %r)" % size 245f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar else: 246f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('address', %r)" % f.read32() 247f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar size = f.read32() 248f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('size', %r)" % size 2496c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar offset = f.read32() 2506c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " ('offset', %r)" % offset 2516c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " ('alignment', %r)" % f.read32() 2526c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar reloc_offset = f.read32() 2536c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " ('reloc_offset', %r)" % reloc_offset 2546c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar num_reloc = f.read32() 2556c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " ('num_reloc', %r)" % num_reloc 256fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('flags', %#x)" % f.read32() 257fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('reserved1', %r)" % f.read32() 258fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " ('reserved2', %r)" % f.read32() 259f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar if is64Bit: 260f0a0be47ed02c93e9679e8cf76a52a2ab18d3276Daniel Dunbar print " ('reserved3', %r)" % f.read32() 261fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar print " )," 2626c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar 2636c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar prev_pos = f.tell() 2646c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar 2656c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar f.seek(reloc_offset) 2666c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " ('_relocations', [" 2676c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar for i in range(num_reloc): 2686c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " # Relocation %r" % i 2696c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " (('word-0', %#x)," % f.read32() 2706c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " ('word-1', %#x))," % f.read32() 2716c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar print " ])" 2726c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar 2736c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar if opts.dumpSectionData: 2746c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar f.seek(offset) 275228290c0d181b663f33680aea03e10843da5f907Rafael Espindola print " ('_section_data', '%s')" % common_dump.dataToHex(f.read(size)) 2766c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar 2776c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar f.seek(prev_pos) 278fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 279fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbardef main(): 280fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar from optparse import OptionParser, OptionGroup 281fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar parser = OptionParser("usage: %prog [options] {files}") 2826c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar parser.add_option("", "--dump-section-data", dest="dumpSectionData", 2836c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar help="Dump the contents of sections", 2846c2e2d1c6b29534e99630fedbaa5e39652258449Daniel Dunbar action="store_true", default=False) 285fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar (opts, args) = parser.parse_args() 286fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 287fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar if not args: 288fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar args.append('-') 289fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 290fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar for arg in args: 291fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar dumpmacho(arg, opts) 292fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar 293fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbarif __name__ == '__main__': 294fb4a6b397665df011348ade24a8e38d2219f095aDaniel Dunbar main() 295