mirror of
				https://github.com/c64scene-ar/llvm-6502.git
				synced 2025-10-31 08:16:47 +00:00 
			
		
		
		
	git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116038 91177308-0d34-0410-b5e6-96231b3b80d8
		
			
				
	
	
		
			591 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			591 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
| #!/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', '<H', '0x%X', {
 | |
|     0x0:    'IMAGE_FILE_MACHINE_UNKNOWN',
 | |
|     0x1d3:  'IMAGE_FILE_MACHINE_AM33',
 | |
|     0x8664: 'IMAGE_FILE_MACHINE_AMD64',
 | |
|     0x1c0:  'IMAGE_FILE_MACHINE_ARM',
 | |
|     0xebc:  'IMAGE_FILE_MACHINE_EBC',
 | |
|     0x14c:  'IMAGE_FILE_MACHINE_I386',
 | |
|     0x200:  'IMAGE_FILE_MACHINE_IA64',
 | |
|     0x904:  'IMAGE_FILE_MACHINE_M32R',
 | |
|     0x266:  'IMAGE_FILE_MACHINE_MIPS16',
 | |
|     0x366:  'IMAGE_FILE_MACHINE_MIPSFPU',
 | |
|     0x466:  'IMAGE_FILE_MACHINE_MIPSFPU16',
 | |
|     0x1f0:  'IMAGE_FILE_MACHINE_POWERPC',
 | |
|     0x1f1:  'IMAGE_FILE_MACHINE_POWERPCFP',
 | |
|     0x166:  'IMAGE_FILE_MACHINE_R4000',
 | |
|     0x1a2:  'IMAGE_FILE_MACHINE_SH3',
 | |
|     0x1a3:  'IMAGE_FILE_MACHINE_SH3DSP',
 | |
|     0x1a6:  'IMAGE_FILE_MACHINE_SH4',
 | |
|     0x1a8:  'IMAGE_FILE_MACHINE_SH5',
 | |
|     0x1c2:  'IMAGE_FILE_MACHINE_THUMB',
 | |
|     0x169:  'IMAGE_FILE_MACHINE_WCEMIPSV2',
 | |
|   })),
 | |
|   ('NumberOfSections',     ('scalar',  '<H', '%d')),
 | |
|   ('TimeDateStamp',        ('scalar',  '<L', '%d')),
 | |
|   ('PointerToSymbolTable', ('scalar',  '<L', '0x%0X')),
 | |
|   ('NumberOfSymbols',      ('scalar',  '<L', '%d')),
 | |
|   ('SizeOfOptionalHeader', ('scalar',  '<H', '%d')),
 | |
|   ('Characteristics',      ('flags',   '<H', '0x%x', [
 | |
|     (0x0001,      'IMAGE_FILE_RELOCS_STRIPPED',         ),
 | |
|     (0x0002,      'IMAGE_FILE_EXECUTABLE_IMAGE',        ),
 | |
|     (0x0004,      'IMAGE_FILE_LINE_NUMS_STRIPPED',      ),
 | |
|     (0x0008,      'IMAGE_FILE_LOCAL_SYMS_STRIPPED',     ),
 | |
|     (0x0010,      'IMAGE_FILE_AGGRESSIVE_WS_TRIM',      ),
 | |
|     (0x0020,      'IMAGE_FILE_LARGE_ADDRESS_AWARE',     ),
 | |
|     (0x0080,      'IMAGE_FILE_BYTES_REVERSED_LO',       ),
 | |
|     (0x0100,      'IMAGE_FILE_32BIT_MACHINE',           ),
 | |
|     (0x0200,      'IMAGE_FILE_DEBUG_STRIPPED',          ),
 | |
|     (0x0400,      'IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP', ),
 | |
|     (0x0800,      'IMAGE_FILE_NET_RUN_FROM_SWAP',       ),
 | |
|     (0x1000,      'IMAGE_FILE_SYSTEM',                  ),
 | |
|     (0x2000,      'IMAGE_FILE_DLL',                     ),
 | |
|     (0x4000,      'IMAGE_FILE_UP_SYSTEM_ONLY',          ),
 | |
|     (0x8000,      'IMAGE_FILE_BYTES_REVERSED_HI',       ),
 | |
|   ])),
 | |
|   ('Sections', ('array', '1', 'NumberOfSections', ('struct', [
 | |
|     ('Name',                 ('scalar',  '<8s', secname)),
 | |
|     ('VirtualSize',          ('scalar',  '<L',  '%d'   )),
 | |
|     ('VirtualAddress',       ('scalar',  '<L',  '%d'   )),
 | |
|     ('SizeOfRawData',        ('scalar',  '<L',  '%d'   )),
 | |
|     ('PointerToRawData',     ('scalar',  '<L',  '0x%X' )),
 | |
|     ('PointerToRelocations', ('scalar',  '<L',  '0x%X' )),
 | |
|     ('PointerToLineNumbers', ('scalar',  '<L',  '0x%X' )),
 | |
|     ('NumberOfRelocations',  ('scalar',  '<H',  '%d'   )),
 | |
|     ('NumberOfLineNumbers',  ('scalar',  '<H',  '%d'   )),
 | |
|     ('Charateristics',       ('flags',   '<L',  '0x%X', [
 | |
|       (0x00000008, 'IMAGE_SCN_TYPE_NO_PAD'),
 | |
|       (0x00000020, 'IMAGE_SCN_CNT_CODE'),
 | |
|       (0x00000040, 'IMAGE_SCN_CNT_INITIALIZED_DATA'),
 | |
|       (0x00000080, 'IMAGE_SCN_CNT_UNINITIALIZED_DATA'),
 | |
|       (0x00000100, 'IMAGE_SCN_LNK_OTHER'),
 | |
|       (0x00000200, 'IMAGE_SCN_LNK_INFO'),
 | |
|       (0x00000800, 'IMAGE_SCN_LNK_REMOVE'),
 | |
|       (0x00001000, 'IMAGE_SCN_LNK_COMDAT'),
 | |
|       (0x00008000, 'IMAGE_SCN_GPREL'),
 | |
|       (0x00020000, 'IMAGE_SCN_MEM_PURGEABLE'),
 | |
|       (0x00020000, 'IMAGE_SCN_MEM_16BIT'),
 | |
|       (0x00040000, 'IMAGE_SCN_MEM_LOCKED'),
 | |
|       (0x00080000, 'IMAGE_SCN_MEM_PRELOAD'),
 | |
|       (0x00F00000, 'IMAGE_SCN_ALIGN', {
 | |
|         0x00100000: 'IMAGE_SCN_ALIGN_1BYTES',
 | |
|         0x00200000: 'IMAGE_SCN_ALIGN_2BYTES',
 | |
|         0x00300000: 'IMAGE_SCN_ALIGN_4BYTES',
 | |
|         0x00400000: 'IMAGE_SCN_ALIGN_8BYTES',
 | |
|         0x00500000: 'IMAGE_SCN_ALIGN_16BYTES',
 | |
|         0x00600000: 'IMAGE_SCN_ALIGN_32BYTES',
 | |
|         0x00700000: 'IMAGE_SCN_ALIGN_64BYTES',
 | |
|         0x00800000: 'IMAGE_SCN_ALIGN_128BYTES',
 | |
|         0x00900000: 'IMAGE_SCN_ALIGN_256BYTES',
 | |
|         0x00A00000: 'IMAGE_SCN_ALIGN_512BYTES',
 | |
|         0x00B00000: 'IMAGE_SCN_ALIGN_1024BYTES',
 | |
|         0x00C00000: 'IMAGE_SCN_ALIGN_2048BYTES',
 | |
|         0x00D00000: 'IMAGE_SCN_ALIGN_4096BYTES',
 | |
|         0x00E00000: 'IMAGE_SCN_ALIGN_8192BYTES',
 | |
|       }),
 | |
|       (0x01000000, 'IMAGE_SCN_LNK_NRELOC_OVFL'),
 | |
|       (0x02000000, 'IMAGE_SCN_MEM_DISCARDABLE'),
 | |
|       (0x04000000, 'IMAGE_SCN_MEM_NOT_CACHED'),
 | |
|       (0x08000000, 'IMAGE_SCN_MEM_NOT_PAGED'),
 | |
|       (0x10000000, 'IMAGE_SCN_MEM_SHARED'),
 | |
|       (0x20000000, 'IMAGE_SCN_MEM_EXECUTE'),
 | |
|       (0x40000000, 'IMAGE_SCN_MEM_READ'),
 | |
|       (0x80000000, 'IMAGE_SCN_MEM_WRITE'),
 | |
|     ])),
 | |
|     ('SectionData', ('ptr', 'PointerToRawData', ('blob', 'SizeOfRawData'))),
 | |
|     ('Relocations', ('ptr', 'PointerToRelocations', ('array', '0', 'NumberOfRelocations', ('struct', [
 | |
|       ('VirtualAddress',   ('scalar', '<L', '0x%X')),
 | |
|       ('SymbolTableIndex', ('scalar', '<L', '%d'  )),
 | |
|       ('Type',             ('enum', '<H', '%d', ('MachineType', {
 | |
|         0x14c: {
 | |
|           0x0000: 'IMAGE_REL_I386_ABSOLUTE',
 | |
|           0x0001: 'IMAGE_REL_I386_DIR16',
 | |
|           0x0002: 'IMAGE_REL_I386_REL16',
 | |
|           0x0006: 'IMAGE_REL_I386_DIR32',
 | |
|           0x0007: 'IMAGE_REL_I386_DIR32NB',
 | |
|           0x0009: 'IMAGE_REL_I386_SEG12',
 | |
|           0x000A: 'IMAGE_REL_I386_SECTION',
 | |
|           0x000B: 'IMAGE_REL_I386_SECREL',
 | |
|           0x000C: 'IMAGE_REL_I386_TOKEN',
 | |
|           0x000D: 'IMAGE_REL_I386_SECREL7',
 | |
|           0x0014: 'IMAGE_REL_I386_REL32',
 | |
|         },
 | |
|         0x8664: {
 | |
|           0x0000: 'IMAGE_REL_AMD64_ABSOLUTE',
 | |
|           0x0001: 'IMAGE_REL_AMD64_ADDR64',
 | |
|           0x0002: 'IMAGE_REL_AMD64_ADDR32',
 | |
|           0x0003: 'IMAGE_REL_AMD64_ADDR32NB',
 | |
|           0x0004: 'IMAGE_REL_AMD64_REL32',
 | |
|           0x0005: 'IMAGE_REL_AMD64_REL32_1',
 | |
|           0x0006: 'IMAGE_REL_AMD64_REL32_2',
 | |
|           0x0007: 'IMAGE_REL_AMD64_REL32_3',
 | |
|           0x0008: 'IMAGE_REL_AMD64_REL32_4',
 | |
|           0x0009: 'IMAGE_REL_AMD64_REL32_5',
 | |
|           0x000A: 'IMAGE_REL_AMD64_SECTION',
 | |
|           0x000B: 'IMAGE_REL_AMD64_SECREL',
 | |
|           0x000C: 'IMAGE_REL_AMD64_SECREL7',
 | |
|           0x000D: 'IMAGE_REL_AMD64_TOKEN',
 | |
|           0x000E: 'IMAGE_REL_AMD64_SREL32',
 | |
|           0x000F: 'IMAGE_REL_AMD64_PAIR',
 | |
|           0x0010: 'IMAGE_REL_AMD64_SSPAN32',
 | |
|         },
 | |
|       }))),
 | |
|       ('SymbolName',       ('ptr', '+ PointerToSymbolTable * SymbolTableIndex 18', ('scalar',  '<8s', symname)))
 | |
|     ])))),
 | |
|   ]))),
 | |
|   ('Symbols', ('ptr', 'PointerToSymbolTable', ('byte-array', '18', '* NumberOfSymbols 18',  ('struct', [
 | |
|     ('Name',                ('scalar',  '<8s', symname)),
 | |
|     ('Value',               ('scalar',  '<L',  '%d'   )),
 | |
|     ('SectionNumber',       ('scalar',  '<H',  '%d'   )),
 | |
|     ('_Type',               ('scalar',  '<H',  None   )),
 | |
|     ('SimpleType',          ('enum',    '& _Type 15',  '%d', {
 | |
|       0: 'IMAGE_SYM_TYPE_NULL',
 | |
|       1: 'IMAGE_SYM_TYPE_VOID',
 | |
|       2: 'IMAGE_SYM_TYPE_CHAR',
 | |
|       3: 'IMAGE_SYM_TYPE_SHORT',
 | |
|       4: 'IMAGE_SYM_TYPE_INT',
 | |
|       5: 'IMAGE_SYM_TYPE_LONG',
 | |
|       6: 'IMAGE_SYM_TYPE_FLOAT',
 | |
|       7: 'IMAGE_SYM_TYPE_DOUBLE',
 | |
|       8: 'IMAGE_SYM_TYPE_STRUCT',
 | |
|       9: 'IMAGE_SYM_TYPE_UNION',
 | |
|       10: 'IMAGE_SYM_TYPE_ENUM',
 | |
|       11: 'IMAGE_SYM_TYPE_MOE',
 | |
|       12: 'IMAGE_SYM_TYPE_BYTE',
 | |
|       13: 'IMAGE_SYM_TYPE_WORD',
 | |
|       14: 'IMAGE_SYM_TYPE_UINT',
 | |
|       15: 'IMAGE_SYM_TYPE_DWORD',
 | |
|     })),                                # (Type & 0xF0) >> 4
 | |
|     ('ComplexType',         ('enum',    '>> & _Type 240 4',  '%d', {
 | |
|       0: 'IMAGE_SYM_DTYPE_NULL',
 | |
|       1: 'IMAGE_SYM_DTYPE_POINTER',
 | |
|       2: 'IMAGE_SYM_DTYPE_FUNCTION',
 | |
|       3: 'IMAGE_SYM_DTYPE_ARRAY',
 | |
|     })),
 | |
|     ('StorageClass',        ('enum',    '<B',  '%d', {
 | |
|       -1:  'IMAGE_SYM_CLASS_END_OF_FUNCTION',
 | |
|       0: 'IMAGE_SYM_CLASS_NULL',
 | |
|       1: 'IMAGE_SYM_CLASS_AUTOMATIC',
 | |
|       2: 'IMAGE_SYM_CLASS_EXTERNAL',
 | |
|       3: 'IMAGE_SYM_CLASS_STATIC',
 | |
|       4: 'IMAGE_SYM_CLASS_REGISTER',
 | |
|       5: 'IMAGE_SYM_CLASS_EXTERNAL_DEF',
 | |
|       6: 'IMAGE_SYM_CLASS_LABEL',
 | |
|       7: 'IMAGE_SYM_CLASS_UNDEFINED_LABEL',
 | |
|       8: 'IMAGE_SYM_CLASS_MEMBER_OF_STRUCT',
 | |
|       9: 'IMAGE_SYM_CLASS_ARGUMENT',
 | |
|       10: 'IMAGE_SYM_CLASS_STRUCT_TAG',
 | |
|       11: 'IMAGE_SYM_CLASS_MEMBER_OF_UNION',
 | |
|       12: 'IMAGE_SYM_CLASS_UNION_TAG',
 | |
|       13: 'IMAGE_SYM_CLASS_TYPE_DEFINITION',
 | |
|       14: 'IMAGE_SYM_CLASS_UNDEFINED_STATIC',
 | |
|       15: 'IMAGE_SYM_CLASS_ENUM_TAG',
 | |
|       16: 'IMAGE_SYM_CLASS_MEMBER_OF_ENUM',
 | |
|       17: 'IMAGE_SYM_CLASS_REGISTER_PARAM',
 | |
|       18: 'IMAGE_SYM_CLASS_BIT_FIELD',
 | |
|       100: 'IMAGE_SYM_CLASS_BLOCK',
 | |
|       101: 'IMAGE_SYM_CLASS_FUNCTION',
 | |
|       102: 'IMAGE_SYM_CLASS_END_OF_STRUCT',
 | |
|       103: 'IMAGE_SYM_CLASS_FILE',
 | |
|       104: 'IMAGE_SYM_CLASS_SECTION',
 | |
|       105: 'IMAGE_SYM_CLASS_WEAK_EXTERNAL',
 | |
|       107: 'IMAGE_SYM_CLASS_CLR_TOKEN',
 | |
|     })),
 | |
|     ('NumberOfAuxSymbols',  ('scalar',  '<B',  '%d'  )),
 | |
|     ('AuxillaryData', ('blob', '* NumberOfAuxSymbols 18')),
 | |
|   ])))),
 | |
| ])
 | |
| 
 | |
| #
 | |
| # Definition Interpreter
 | |
| #
 | |
| 
 | |
| import sys, types, struct, re
 | |
| 
 | |
| Input = None
 | |
| Stack = []
 | |
| Fields = {}
 | |
| 
 | |
| Indent = 0
 | |
| NewLine = True
 | |
| 
 | |
| def indent():
 | |
|   global Indent
 | |
|   Indent += 1
 | |
| 
 | |
| def dedent():
 | |
|   global Indent
 | |
|   Indent -= 1
 | |
| 
 | |
| def write(input):
 | |
|   global NewLine
 | |
|   output = ""
 | |
| 
 | |
|   for char in input:
 | |
| 
 | |
|     if NewLine:
 | |
|       output += Indent * '  '
 | |
|       NewLine = False
 | |
| 
 | |
|     output += char
 | |
| 
 | |
|     if char == '\n':
 | |
|       NewLine = True
 | |
| 
 | |
|   sys.stdout.write(output)
 | |
| 
 | |
| def read(format):
 | |
|   return struct.unpack(format, Input.read(struct.calcsize(format)))
 | |
| 
 | |
| def read_cstr():
 | |
|   output = ""
 | |
|   while True:
 | |
|     char = Input.read(1)
 | |
|     if len(char) == 0:
 | |
|       raise RuntimeError ("EOF while reading cstr")
 | |
|     if char == '\0':
 | |
|       break
 | |
|     output += char
 | |
|   return output
 | |
| 
 | |
| def push_pos(seek_to = None):
 | |
|   Stack [0:0] = [Input.tell()]
 | |
|   if seek_to:
 | |
|     Input.seek(seek_to)
 | |
| 
 | |
| def pop_pos():
 | |
|   assert(len(Stack) > 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 token == '+':
 | |
|       return eval() + eval()
 | |
|     if token == '-':
 | |
|       return eval() - eval()
 | |
|     if token == '*':
 | |
|       return eval() * eval()
 | |
|     if token == '/':
 | |
|       return eval() / eval()
 | |
|     if token == '&':
 | |
|       return eval() & eval()
 | |
|     if token == '|':
 | |
|       return eval() | eval()
 | |
|     if token == '>>':
 | |
|       return eval() >> eval()
 | |
|     if token == '<<':
 | |
|       return eval() << eval()
 | |
| 
 | |
|     if len(token) > 1 and token[0] in ('=', '@', '<', '!', '>'):
 | |
|       val = read(expr)
 | |
|       assert(len(val) == 1)
 | |
|       return val[0]
 | |
| 
 | |
|     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)
 | |
|   elif format_type is types.NoneType:
 | |
|     pass
 | |
|   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]
 | |
| 
 | |
|     if name[0] != "_":
 | |
|       write("%s = " % name.ljust(24))
 | |
| 
 | |
|     value = handle_element(type)
 | |
| 
 | |
|     if name[0] != "_":
 | |
|       write("\n")
 | |
| 
 | |
|     Fields[name] = value
 | |
|     newFields[name] = value
 | |
| 
 | |
|   dedent()
 | |
|   write("}")
 | |
| 
 | |
|   return newFields
 | |
| 
 | |
| def handle_array(entry):
 | |
|   start_index = entry[1]
 | |
|   length = entry[2]
 | |
|   element = entry[3]
 | |
| 
 | |
|   newItems = []
 | |
| 
 | |
|   write("[\n")
 | |
|   indent()
 | |
| 
 | |
|   start_index = read_value(start_index)
 | |
|   value = read_value(length)
 | |
| 
 | |
|   for index in xrange(value):
 | |
|     write("%d = " % (index + start_index))
 | |
|     value = handle_element(element)
 | |
|     write("\n")
 | |
|     newItems.append(value)
 | |
| 
 | |
|   dedent()
 | |
|   write("]")
 | |
| 
 | |
|   return newItems
 | |
| 
 | |
| def handle_byte_array(entry):
 | |
|   ent_size = entry[1]
 | |
|   length = entry[2]
 | |
|   element = entry[3]
 | |
| 
 | |
|   newItems = []
 | |
| 
 | |
|   write("[\n")
 | |
|   indent()
 | |
| 
 | |
|   item_size = read_value(ent_size)
 | |
|   value = read_value(length)
 | |
|   end_of_array = Input.tell() + value
 | |
| 
 | |
|   prev_loc = Input.tell()
 | |
|   index = 0
 | |
|   while Input.tell() < end_of_array:
 | |
|     write("%d = " % index)
 | |
|     value = handle_element(element)
 | |
|     write("\n")
 | |
|     newItems.append(value)
 | |
|     index += (Input.tell() - prev_loc) / item_size
 | |
|     prev_loc = Input.tell()
 | |
| 
 | |
|   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)
 | |
| 
 | |
| if len(sys.argv) <= 1 or sys.argv[1] == '-':
 | |
|   import StringIO
 | |
|   Input = StringIO.StringIO(sys.stdin.read())
 | |
| else:
 | |
|   Input = open (sys.argv[1], "rb")
 | |
| 
 | |
| try:
 | |
|   handle_element(file)
 | |
| finally:
 | |
|   Input.close()
 | |
|   Input = None
 |