llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
#!/usr/bin/env python
|
|
|
|
|
|
|
|
import struct
|
|
|
|
import sys
|
2009-08-22 15:22:36 +08:00
|
|
|
import StringIO
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
|
|
|
|
class Reader:
|
|
|
|
def __init__(self, path):
|
|
|
|
if path == '-':
|
2009-08-22 15:22:36 +08:00
|
|
|
# Snarf all the data so we can seek.
|
|
|
|
self.file = StringIO.StringIO(sys.stdin.read())
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
else:
|
|
|
|
self.file = open(path,'rb')
|
|
|
|
self.isLSB = None
|
2009-08-22 15:22:36 +08:00
|
|
|
|
|
|
|
self.string_table = None
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
|
|
|
|
def setLSB(self, isLSB):
|
|
|
|
self.isLSB = bool(isLSB)
|
|
|
|
|
|
|
|
def tell(self):
|
2009-08-22 15:22:36 +08:00
|
|
|
return self.file.tell()
|
|
|
|
|
|
|
|
def seek(self, pos):
|
|
|
|
self.file.seek(pos)
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
|
|
|
|
def read(self, N):
|
|
|
|
data = self.file.read(N)
|
|
|
|
if len(data) != N:
|
|
|
|
raise ValueError,"Out of data!"
|
|
|
|
return data
|
|
|
|
|
2009-08-22 15:22:36 +08:00
|
|
|
def read8(self):
|
|
|
|
return ord(self.read(1))
|
|
|
|
|
|
|
|
def read16(self):
|
|
|
|
return struct.unpack('><'[self.isLSB] + 'H', self.read(2))[0]
|
|
|
|
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
def read32(self):
|
|
|
|
return struct.unpack('><'[self.isLSB] + 'I', self.read(4))[0]
|
|
|
|
|
2009-08-22 15:22:36 +08:00
|
|
|
def registerStringTable(self, strings):
|
|
|
|
if self.string_table is not None:
|
|
|
|
raise ValueError,"%s: warning: multiple string tables" % sys.argv[0]
|
|
|
|
|
|
|
|
self.string_table = strings
|
|
|
|
|
|
|
|
def getString(self, index):
|
|
|
|
if self.string_table is None:
|
|
|
|
raise ValueError,"%s: warning: no string table registered" % sys.argv[0]
|
|
|
|
|
|
|
|
end = self.string_table.index('\x00', index)
|
|
|
|
return self.string_table[index:end]
|
|
|
|
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
def dumpmacho(path, opts):
|
|
|
|
f = Reader(path)
|
|
|
|
|
|
|
|
magic = f.read(4)
|
|
|
|
if magic == '\xFE\xED\xFA\xCE':
|
|
|
|
f.setLSB(False)
|
|
|
|
elif magic == '\xCE\xFA\xED\xFE':
|
|
|
|
f.setLSB(True)
|
|
|
|
else:
|
|
|
|
raise ValueError,"Not a Mach-O object file: %r (bad magic)" % path
|
|
|
|
|
|
|
|
print "('cputype', %r)" % f.read32()
|
|
|
|
print "('cpusubtype', %r)" % f.read32()
|
|
|
|
filetype = f.read32()
|
|
|
|
print "('filetype', %r)" % filetype
|
|
|
|
|
|
|
|
numLoadCommands = f.read32()
|
|
|
|
print "('num_load_commands', %r)" % filetype
|
|
|
|
|
|
|
|
loadCommandsSize = f.read32()
|
|
|
|
print "('load_commands_size', %r)" % loadCommandsSize
|
|
|
|
|
|
|
|
print "('flag', %r)" % f.read32()
|
|
|
|
|
|
|
|
start = f.tell()
|
|
|
|
|
|
|
|
print "('load_commands', ["
|
|
|
|
for i in range(numLoadCommands):
|
|
|
|
dumpLoadCommand(f, i, opts)
|
|
|
|
print "])"
|
|
|
|
|
|
|
|
if f.tell() - start != loadCommandsSize:
|
2009-08-22 15:22:36 +08:00
|
|
|
raise ValueError,"%s: warning: invalid load commands size: %r" % (sys.argv[0], loadCommandsSize)
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
|
|
|
|
def dumpLoadCommand(f, i, opts):
|
|
|
|
start = f.tell()
|
|
|
|
|
|
|
|
print " # Load Command %r" % i
|
|
|
|
cmd = f.read32()
|
|
|
|
print " (('command', %r)" % cmd
|
|
|
|
cmdSize = f.read32()
|
|
|
|
print " ('size', %r)" % cmdSize
|
|
|
|
|
|
|
|
if cmd == 1:
|
|
|
|
dumpSegmentLoadCommand32(f, opts)
|
|
|
|
elif cmd == 2:
|
|
|
|
dumpSymtabCommand(f, opts)
|
|
|
|
elif cmd == 11:
|
|
|
|
dumpDysymtabCommand(f, opts)
|
|
|
|
else:
|
|
|
|
print >>sys.stderr,"%s: warning: unknown load command: %r" % (sys.argv[0], cmd)
|
|
|
|
f.read(cmdSize - 8)
|
|
|
|
print " ),"
|
|
|
|
|
|
|
|
if f.tell() - start != cmdSize:
|
2009-08-22 15:22:36 +08:00
|
|
|
raise ValueError,"%s: warning: invalid load command size: %r" % (sys.argv[0], cmdSize)
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
|
|
|
|
def dumpSegmentLoadCommand32(f, opts):
|
|
|
|
print " ('segment_name', %r)" % f.read(16)
|
|
|
|
print " ('vm_addr', %r)" % f.read32()
|
|
|
|
print " ('vm_size', %r)" % f.read32()
|
|
|
|
print " ('file_offset', %r)" % f.read32()
|
|
|
|
print " ('file_size', %r)" % f.read32()
|
|
|
|
print " ('maxprot', %r)" % f.read32()
|
|
|
|
print " ('initprot', %r)" % f.read32()
|
|
|
|
numSections = f.read32()
|
|
|
|
print " ('num_sections', %r)" % numSections
|
|
|
|
print " ('flags', %r)" % f.read32()
|
|
|
|
|
|
|
|
print " ('sections', ["
|
|
|
|
for i in range(numSections):
|
|
|
|
dumpSection32(f, i, opts)
|
|
|
|
print " ])"
|
|
|
|
|
|
|
|
def dumpSymtabCommand(f, opts):
|
2009-08-22 15:22:36 +08:00
|
|
|
symoff = f.read32()
|
|
|
|
print " ('symoff', %r)" % symoff
|
|
|
|
nsyms = f.read32()
|
|
|
|
print " ('nsyms', %r)" % nsyms
|
|
|
|
stroff = f.read32()
|
|
|
|
print " ('stroff', %r)" % stroff
|
|
|
|
strsize = f.read32()
|
|
|
|
print " ('strsize', %r)" % strsize
|
|
|
|
|
|
|
|
prev_pos = f.tell()
|
|
|
|
|
|
|
|
f.seek(stroff)
|
|
|
|
string_data = f.read(strsize)
|
|
|
|
print " ('_string_data', %r)" % string_data
|
|
|
|
|
|
|
|
f.registerStringTable(string_data)
|
|
|
|
|
|
|
|
f.seek(symoff)
|
|
|
|
print " ('_symbols', ["
|
|
|
|
for i in range(nsyms):
|
|
|
|
dumpNlist32(f, i, opts)
|
|
|
|
print " ])"
|
|
|
|
|
|
|
|
f.seek(prev_pos)
|
|
|
|
|
|
|
|
def dumpNlist32(f, i, opts):
|
|
|
|
print " # Symbol %r" % i
|
|
|
|
n_strx = f.read32()
|
|
|
|
print " (('n_strx', %r)" % n_strx
|
|
|
|
n_type = f.read8()
|
|
|
|
print " ('n_type', %#x)" % n_type
|
|
|
|
n_sect = f.read8()
|
|
|
|
print " ('n_type', %r)" % n_sect
|
|
|
|
n_desc = f.read16()
|
|
|
|
print " ('n_desc', %r)" % n_desc
|
|
|
|
n_value = f.read32()
|
|
|
|
print " ('n_value', %r)" % n_value
|
|
|
|
print " ('_string', %r)" % f.getString(n_strx)
|
|
|
|
print " ),"
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
|
|
|
|
def dumpDysymtabCommand(f, opts):
|
|
|
|
print " ('ilocalsym', %r)" % f.read32()
|
|
|
|
print " ('nlocalsym', %r)" % f.read32()
|
|
|
|
print " ('iextdefsym', %r)" % f.read32()
|
|
|
|
print " ('nextdefsym', %r)" % f.read32()
|
|
|
|
print " ('iundefsym', %r)" % f.read32()
|
|
|
|
print " ('nundefsym', %r)" % f.read32()
|
|
|
|
print " ('tocoff', %r)" % f.read32()
|
|
|
|
print " ('ntoc', %r)" % f.read32()
|
|
|
|
print " ('modtaboff', %r)" % f.read32()
|
|
|
|
print " ('nmodtab', %r)" % f.read32()
|
|
|
|
print " ('extrefsymoff', %r)" % f.read32()
|
|
|
|
print " ('nextrefsyms', %r)" % f.read32()
|
2009-08-22 15:22:36 +08:00
|
|
|
indirectsymoff = f.read32()
|
|
|
|
print " ('indirectsymoff', %r)" % indirectsymoff
|
|
|
|
nindirectsyms = f.read32()
|
|
|
|
print " ('nindirectsyms', %r)" % nindirectsyms
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
print " ('extreloff', %r)" % f.read32()
|
|
|
|
print " ('nextrel', %r)" % f.read32()
|
|
|
|
print " ('locreloff', %r)" % f.read32()
|
|
|
|
print " ('nlocrel', %r)" % f.read32()
|
|
|
|
|
2009-08-22 15:22:36 +08:00
|
|
|
prev_pos = f.tell()
|
|
|
|
|
|
|
|
f.seek(indirectsymoff)
|
|
|
|
print " ('_indirect_symbols', ["
|
|
|
|
for i in range(nindirectsyms):
|
|
|
|
print " # Indirect Symbol %r" % i
|
|
|
|
print " (('symbol_index', %r),)," % f.read32()
|
|
|
|
print " ])"
|
|
|
|
|
|
|
|
f.seek(prev_pos)
|
|
|
|
|
llvm-mc: Start MCAssembler and MCMachOStreamer.
- Together these form the (Mach-O) back end of the assembler.
- MCAssembler is the actual assembler backend, which is designed to have a
reasonable API. This will eventually grow to support multiple object file
implementations, but for now its Mach-O/i386 only.
- MCMachOStreamer adapts the MCStreamer "actions" API to the MCAssembler API,
e.g. converting the various directives into fragments, managing state like
the current section, and so on.
- llvm-mc will use the new backend via '-filetype=obj', which may eventually
be, but is not yet, since I hear that people like assemblers which actually
assemble.
- The only thing that works at the moment is changing sections. For the time
being I have a Python Mach-O dumping tool in test/scripts so this stuff can
be easily tested, eventually I expect to replace this with a real LLVM tool.
- More doxyments to come.
I assume that since this stuff doesn't touch any of the things which are part of
2.6 that it is ok to put this in not so long before the freeze, but if someone
objects let me know, I can pull it.
llvm-svn: 79612
2009-08-21 17:11:24 +08:00
|
|
|
def dumpSection32(f, i, opts):
|
|
|
|
print " # Section %r" % i
|
|
|
|
print " (('section_name', %r)" % f.read(16)
|
|
|
|
print " ('segment_name', %r)" % f.read(16)
|
|
|
|
print " ('address', %r)" % f.read32()
|
|
|
|
print " ('size', %r)" % f.read32()
|
|
|
|
print " ('offset', %r)" % f.read32()
|
|
|
|
print " ('alignment', %r)" % f.read32()
|
|
|
|
print " ('reloc_offset', %r)" % f.read32()
|
|
|
|
print " ('num_reloc', %r)" % f.read32()
|
|
|
|
print " ('flags', %#x)" % f.read32()
|
|
|
|
print " ('reserved1', %r)" % f.read32()
|
|
|
|
print " ('reserved2', %r)" % f.read32()
|
|
|
|
print " ),"
|
|
|
|
|
|
|
|
def main():
|
|
|
|
from optparse import OptionParser, OptionGroup
|
|
|
|
parser = OptionParser("usage: %prog [options] {files}")
|
|
|
|
|
|
|
|
(opts, args) = parser.parse_args()
|
|
|
|
|
|
|
|
if not args:
|
|
|
|
args.append('-')
|
|
|
|
|
|
|
|
for arg in args:
|
|
|
|
dumpmacho(arg, opts)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|