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