#!/usr/bin/env python #===-- coff-dump.py - COFF object file dump utility-------------------------===# # # The LLVM Compiler Infrastructure # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # #===------------------------------------------------------------------------===# # # COFF File Definition # def string_table_entry (offset): return ('ptr', '+ + PointerToSymbolTable * NumberOfSymbols 18 %s' % offset, ('scalar', 'cstr', '%s')) def secname(value): if value[0] == '/': return string_table_entry (value [1:].rstrip('\0')) else: return '%s' def symname(value): parts = struct.unpack("<2L", value) if parts [0] == 0: return string_table_entry (parts [1]) else: return '%s' file = ('struct', [ ('MachineType', ('enum', ' 0) Input.seek (Stack [0]) del Stack [0] def print_binary_data(size): value = "" while size > 0: if size >= 16: data = Input.read(16) size -= 16 else: data = Input.read(size) size = 0 value += data bytes = "" text = "" for index in xrange (16): if index < len (data): if index == 8: bytes += "- " ch = ord (data [index]) bytes += "%02X " % ch if ch >= 0x20 and ch <= 0x7F: text += data [index] else: text += "." else: if index == 8: bytes += " " bytes += " " write ("%s|%s|\n" % (bytes, text)) return value idlit = re.compile ("[a-zA-Z][a-zA-Z0-9_-]*") numlit = re.compile ("[0-9]+") def read_value(expr): input = iter (expr.split ()) def eval(): token = input.next () if expr == 'cstr': return read_cstr () if expr == 'true': return True if expr == 'false': return False if len (token) > 1 and token [0] in ('=', '@', '<', '!', '>'): val = read(expr) assert (len (val) == 1) return val [0] if token == '+': return eval () + eval () if token == '-': return eval () - eval () if token == '*': return eval () * eval () if token == '/': return eval () / eval () if idlit.match (token): return Fields [token] if numlit.match (token): return int (token) raise RuntimeError ("unexpected token %s" % repr(token)) value = eval () try: input.next () except StopIteration: return value raise RuntimeError("unexpected input at end of expression") def write_value(format,value): format_type = type (format) if format_type is types.StringType: write (format%value) elif format_type is types.FunctionType: write_value (format (value), value) elif format_type is types.TupleType: Fields ['this'] = value handle_element (format) else: raise RuntimeError("unexpected type: %s" % repr(format_type)) def handle_scalar(entry): iformat = entry [1] oformat = entry [2] value = read_value (iformat) write_value (oformat, value) return value def handle_enum(entry): iformat = entry [1] oformat = entry [2] definitions = entry [3] value = read_value (iformat) if type (definitions) is types.TupleType: selector = read_value (definitions [0]) definitions = definitions [1] [selector] if value in definitions: description = definitions[value] else: description = "unknown" write ("%s (" % description) write_value (oformat, value) write (")") return value def handle_flags(entry): iformat = entry [1] oformat = entry [2] definitions = entry [3] value = read_value (iformat) write_value (oformat, value) indent () for entry in definitions: mask = entry [0] name = entry [1] if len (entry) == 3: map = entry [2] selection = value & mask if selection in map: write("\n%s" % map[selection]) else: write("\n%s <%d>" % (name, selection)) elif len (entry) == 2: if value & mask != 0: write("\n%s" % name) dedent () return value def handle_struct(entry): global Fields members = entry [1] newFields = {} write ("{\n"); indent () for member in members: name = member [0] type = member [1] write("%s = "%name.ljust(24)) value = handle_element(type) write("\n") Fields [name] = value newFields [name] = value dedent () write ("}") return newFields def handle_array(entry): length = entry [1] element = entry [2] newItems = [] write ("[\n") indent () value = read_value (length) for index in xrange (value): write ("%d = "%index) value = handle_element(element) write ("\n") newItems.append (value) dedent () write ("]") return newItems def handle_byte_array(entry): length = entry [1] element = entry [2] newItems = [] write ("[\n") indent () value = read_value (length) end_of_array = Input.tell () + value index = 0 while Input.tell () < end_of_array: write ("%d = "%index) value = handle_element(element) write ("\n") newItems.append (value) index += 1 dedent () write ("]") return newItems def handle_ptr(entry): offset = entry[1] element = entry [2] value = None offset = read_value (offset) if offset != 0: push_pos (offset) value = handle_element (element) pop_pos () else: write ("None") return value def handle_blob(entry): length = entry [1] write ("\n") indent () value = print_binary_data (read_value (length)) dedent () return value def handle_element(entry): handlers = { 'struct': handle_struct, 'scalar': handle_scalar, 'enum': handle_enum, 'flags': handle_flags, 'ptr': handle_ptr, 'blob': handle_blob, 'array': handle_array, 'byte-array': handle_byte_array, } if not entry [0] in handlers: raise RuntimeError ("unexpected type '%s'" % str (entry[0])) return handlers [entry [0]] (entry) Input = open (sys.argv [1], "rb") try: handle_element (file) finally: Input.close () Input = None