llvm-mc: Start MCAssembler and MCMachOStreamer.
[oota-llvm.git] / test / Scripts / macho-dump
1 #!/usr/bin/env python
2
3 import struct
4 import sys
5
6 class Reader:
7    def __init__(self, path):
8       if path == '-':
9          self.file = sys.stdin
10       else:
11          self.file = open(path,'rb')
12       self.isLSB = None
13       self.pos = 0
14
15    def setLSB(self, isLSB):
16       self.isLSB = bool(isLSB)
17
18    def tell(self):
19       return self.pos
20
21    def read(self, N):
22       data = self.file.read(N)
23       self.pos += len(data)
24       if len(data) != N:
25          raise ValueError,"Out of data!"
26       return data
27
28    def read32(self):
29       return struct.unpack('><'[self.isLSB] + 'I', self.read(4))[0]
30
31 def dumpmacho(path, opts):
32    f = Reader(path)
33
34    magic = f.read(4)
35    if magic == '\xFE\xED\xFA\xCE':
36       f.setLSB(False)
37    elif magic == '\xCE\xFA\xED\xFE':
38       f.setLSB(True)
39    else:
40       raise ValueError,"Not a Mach-O object file: %r (bad magic)" % path
41
42    print "('cputype', %r)" % f.read32()
43    print "('cpusubtype', %r)" % f.read32()
44    filetype = f.read32()
45    print "('filetype', %r)" % filetype
46    
47    numLoadCommands = f.read32()
48    print "('num_load_commands', %r)" % filetype
49
50    loadCommandsSize = f.read32()
51    print "('load_commands_size', %r)" % loadCommandsSize
52
53    print "('flag', %r)" % f.read32()
54
55    start = f.tell()
56
57    print "('load_commands', ["
58    for i in range(numLoadCommands):
59       dumpLoadCommand(f, i, opts)
60    print "])"
61
62    if f.tell() - start != loadCommandsSize:
63       raise ValueError,"%s: warning: invalid load commands size: %r" % (sys.argv, loadCommandsSize)
64
65 def dumpLoadCommand(f, i, opts):
66    start = f.tell()
67
68    print "  # Load Command %r" % i
69    cmd = f.read32()
70    print " (('command', %r)" % cmd
71    cmdSize = f.read32()
72    print "  ('size', %r)" % cmdSize
73
74    if cmd == 1:
75       dumpSegmentLoadCommand32(f, opts)
76    elif cmd == 2:
77       dumpSymtabCommand(f, opts)
78    elif cmd == 11:
79       dumpDysymtabCommand(f, opts)
80    else:
81       print >>sys.stderr,"%s: warning: unknown load command: %r" % (sys.argv[0], cmd)
82       f.read(cmdSize - 8)
83    print " ),"
84
85    if f.tell() - start != cmdSize:
86       raise ValueError,"%s: warning: invalid load command size: %r" % (sys.argv, cmdSize)
87
88 def dumpSegmentLoadCommand32(f, opts):
89    print "  ('segment_name', %r)" % f.read(16) 
90    print "  ('vm_addr', %r)" % f.read32()
91    print "  ('vm_size', %r)" % f.read32()
92    print "  ('file_offset', %r)" % f.read32()
93    print "  ('file_size', %r)" % f.read32()
94    print "  ('maxprot', %r)" % f.read32()
95    print "  ('initprot', %r)" % f.read32()
96    numSections = f.read32()
97    print "  ('num_sections', %r)" % numSections
98    print "  ('flags', %r)" % f.read32()
99
100    print "  ('sections', ["
101    for i in range(numSections):
102       dumpSection32(f, i, opts)
103    print "  ])"
104
105 def dumpSymtabCommand(f, opts):
106    print "  ('symoff', %r)" % f.read32()
107    print "  ('nsyms', %r)" % f.read32()
108    print "  ('stroff', %r)" % f.read32()
109    print "  ('strsize', %r)" % f.read32()
110
111 def dumpDysymtabCommand(f, opts):   
112    print "  ('ilocalsym', %r)" % f.read32()
113    print "  ('nlocalsym', %r)" % f.read32()
114    print "  ('iextdefsym', %r)" % f.read32()
115    print "  ('nextdefsym', %r)" % f.read32()
116    print "  ('iundefsym', %r)" % f.read32()
117    print "  ('nundefsym', %r)" % f.read32()
118    print "  ('tocoff', %r)" % f.read32()
119    print "  ('ntoc', %r)" % f.read32()
120    print "  ('modtaboff', %r)" % f.read32()
121    print "  ('nmodtab', %r)" % f.read32()
122    print "  ('extrefsymoff', %r)" % f.read32()
123    print "  ('nextrefsyms', %r)" % f.read32()
124    print "  ('indirectsymoff', %r)" % f.read32()
125    print "  ('nindirectsyms', %r)" % f.read32()
126    print "  ('extreloff', %r)" % f.read32()
127    print "  ('nextrel', %r)" % f.read32()
128    print "  ('locreloff', %r)" % f.read32()
129    print "  ('nlocrel', %r)" % f.read32()
130
131 def dumpSection32(f, i, opts):
132    print "    # Section %r" % i
133    print "   (('section_name', %r)" % f.read(16)
134    print "    ('segment_name', %r)" % f.read(16)
135    print "    ('address', %r)" % f.read32()
136    print "    ('size', %r)" % f.read32()
137    print "    ('offset', %r)" % f.read32()
138    print "    ('alignment', %r)" % f.read32()
139    print "    ('reloc_offset', %r)" % f.read32()
140    print "    ('num_reloc', %r)" % f.read32()
141    print "    ('flags', %#x)" % f.read32()
142    print "    ('reserved1', %r)" % f.read32()
143    print "    ('reserved2', %r)" % f.read32()
144    print "   ),"
145    
146 def main():
147     from optparse import OptionParser, OptionGroup
148     parser = OptionParser("usage: %prog [options] {files}")
149
150     (opts, args) = parser.parse_args()
151
152     if not args:
153        args.append('-')
154
155     for arg in args:
156        dumpmacho(arg, opts)
157
158 if __name__ == '__main__':
159    main()