blob: d6f7e93f2e2ee88ae6e53c5f674ea7074d075d96 [file] [log] [blame]
Tobias Grosser56029272010-07-27 09:01:26 +00001#!/usr/bin/env python
Michael J. Spencerdfd30182010-07-27 06:46:15 +00002#===-- coff-dump.py - COFF object file dump utility-------------------------===#
3#
4# The LLVM Compiler Infrastructure
5#
6# This file is distributed under the University of Illinois Open Source
7# License. See LICENSE.TXT for details.
8#
9#===------------------------------------------------------------------------===#
10
11#
12# COFF File Definition
13#
14
15def string_table_entry (offset):
16 return ('ptr', '+ + PointerToSymbolTable * NumberOfSymbols 18 %s' % offset, ('scalar', 'cstr', '%s'))
17
18def secname(value):
19 if value[0] == '/':
Michael J. Spenceraeb83c42010-09-15 03:58:24 +000020 return string_table_entry(value[1:].rstrip('\0'))
Michael J. Spencerdfd30182010-07-27 06:46:15 +000021 else:
22 return '%s'
23
24def symname(value):
25 parts = struct.unpack("<2L", value)
Michael J. Spenceraeb83c42010-09-15 03:58:24 +000026 if parts[0] == 0:
27 return string_table_entry(parts[1])
Michael J. Spencerdfd30182010-07-27 06:46:15 +000028 else:
29 return '%s'
30
31file = ('struct', [
32 ('MachineType', ('enum', '<H', '0x%X', {
33 0x0: 'IMAGE_FILE_MACHINE_UNKNOWN',
34 0x1d3: 'IMAGE_FILE_MACHINE_AM33',
Anton Korobeynikovd7343dd2010-08-17 21:05:54 +000035 0x8664: 'IMAGE_FILE_MACHINE_AMD64',
Michael J. Spencerdfd30182010-07-27 06:46:15 +000036 0x1c0: 'IMAGE_FILE_MACHINE_ARM',
37 0xebc: 'IMAGE_FILE_MACHINE_EBC',
38 0x14c: 'IMAGE_FILE_MACHINE_I386',
39 0x200: 'IMAGE_FILE_MACHINE_IA64',
40 0x904: 'IMAGE_FILE_MACHINE_M32R',
41 0x266: 'IMAGE_FILE_MACHINE_MIPS16',
42 0x366: 'IMAGE_FILE_MACHINE_MIPSFPU',
43 0x466: 'IMAGE_FILE_MACHINE_MIPSFPU16',
44 0x1f0: 'IMAGE_FILE_MACHINE_POWERPC',
45 0x1f1: 'IMAGE_FILE_MACHINE_POWERPCFP',
46 0x166: 'IMAGE_FILE_MACHINE_R4000',
47 0x1a2: 'IMAGE_FILE_MACHINE_SH3',
48 0x1a3: 'IMAGE_FILE_MACHINE_SH3DSP',
49 0x1a6: 'IMAGE_FILE_MACHINE_SH4',
50 0x1a8: 'IMAGE_FILE_MACHINE_SH5',
51 0x1c2: 'IMAGE_FILE_MACHINE_THUMB',
52 0x169: 'IMAGE_FILE_MACHINE_WCEMIPSV2',
53 })),
54 ('NumberOfSections', ('scalar', '<H', '%d')),
55 ('TimeDateStamp', ('scalar', '<L', '%d')),
56 ('PointerToSymbolTable', ('scalar', '<L', '0x%0X')),
57 ('NumberOfSymbols', ('scalar', '<L', '%d')),
58 ('SizeOfOptionalHeader', ('scalar', '<H', '%d')),
59 ('Characteristics', ('flags', '<H', '0x%x', [
60 (0x0001, 'IMAGE_FILE_RELOCS_STRIPPED', ),
61 (0x0002, 'IMAGE_FILE_EXECUTABLE_IMAGE', ),
62 (0x0004, 'IMAGE_FILE_LINE_NUMS_STRIPPED', ),
63 (0x0008, 'IMAGE_FILE_LOCAL_SYMS_STRIPPED', ),
64 (0x0010, 'IMAGE_FILE_AGGRESSIVE_WS_TRIM', ),
65 (0x0020, 'IMAGE_FILE_LARGE_ADDRESS_AWARE', ),
66 (0x0080, 'IMAGE_FILE_BYTES_REVERSED_LO', ),
67 (0x0100, 'IMAGE_FILE_32BIT_MACHINE', ),
68 (0x0200, 'IMAGE_FILE_DEBUG_STRIPPED', ),
69 (0x0400, 'IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP', ),
70 (0x0800, 'IMAGE_FILE_NET_RUN_FROM_SWAP', ),
71 (0x1000, 'IMAGE_FILE_SYSTEM', ),
72 (0x2000, 'IMAGE_FILE_DLL', ),
73 (0x4000, 'IMAGE_FILE_UP_SYSTEM_ONLY', ),
74 (0x8000, 'IMAGE_FILE_BYTES_REVERSED_HI', ),
75 ])),
76 ('Sections', ('array', 'NumberOfSections', ('struct', [
77 ('Name', ('scalar', '<8s', secname)),
78 ('VirtualSize', ('scalar', '<L', '%d' )),
79 ('VirtualAddress', ('scalar', '<L', '%d' )),
80 ('SizeOfRawData', ('scalar', '<L', '%d' )),
81 ('PointerToRawData', ('scalar', '<L', '0x%X' )),
82 ('PointerToRelocations', ('scalar', '<L', '0x%X' )),
83 ('PointerToLineNumbers', ('scalar', '<L', '0x%X' )),
84 ('NumberOfRelocations', ('scalar', '<H', '%d' )),
85 ('NumberOfLineNumbers', ('scalar', '<H', '%d' )),
86 ('Charateristics', ('flags', '<L', '0x%X', [
87 (0x00000008, 'IMAGE_SCN_TYPE_NO_PAD'),
88 (0x00000020, 'IMAGE_SCN_CNT_CODE'),
89 (0x00000040, 'IMAGE_SCN_CNT_INITIALIZED_DATA'),
90 (0x00000080, 'IMAGE_SCN_CNT_UNINITIALIZED_DATA'),
91 (0x00000100, 'IMAGE_SCN_LNK_OTHER'),
92 (0x00000200, 'IMAGE_SCN_LNK_INFO'),
93 (0x00000800, 'IMAGE_SCN_LNK_REMOVE'),
94 (0x00001000, 'IMAGE_SCN_LNK_COMDAT'),
95 (0x00008000, 'IMAGE_SCN_GPREL'),
96 (0x00020000, 'IMAGE_SCN_MEM_PURGEABLE'),
97 (0x00020000, 'IMAGE_SCN_MEM_16BIT'),
98 (0x00040000, 'IMAGE_SCN_MEM_LOCKED'),
99 (0x00080000, 'IMAGE_SCN_MEM_PRELOAD'),
100 (0x00F00000, 'IMAGE_SCN_ALIGN', {
101 0x00100000: 'IMAGE_SCN_ALIGN_1BYTES',
102 0x00200000: 'IMAGE_SCN_ALIGN_2BYTES',
103 0x00300000: 'IMAGE_SCN_ALIGN_4BYTES',
104 0x00400000: 'IMAGE_SCN_ALIGN_8BYTES',
105 0x00500000: 'IMAGE_SCN_ALIGN_16BYTES',
106 0x00600000: 'IMAGE_SCN_ALIGN_32BYTES',
107 0x00700000: 'IMAGE_SCN_ALIGN_64BYTES',
108 0x00800000: 'IMAGE_SCN_ALIGN_128BYTES',
109 0x00900000: 'IMAGE_SCN_ALIGN_256BYTES',
110 0x00A00000: 'IMAGE_SCN_ALIGN_512BYTES',
111 0x00B00000: 'IMAGE_SCN_ALIGN_1024BYTES',
112 0x00C00000: 'IMAGE_SCN_ALIGN_2048BYTES',
113 0x00D00000: 'IMAGE_SCN_ALIGN_4096BYTES',
114 0x00E00000: 'IMAGE_SCN_ALIGN_8192BYTES',
115 }),
116 (0x01000000, 'IMAGE_SCN_LNK_NRELOC_OVFL'),
117 (0x02000000, 'IMAGE_SCN_MEM_DISCARDABLE'),
118 (0x04000000, 'IMAGE_SCN_MEM_NOT_CACHED'),
119 (0x08000000, 'IMAGE_SCN_MEM_NOT_PAGED'),
120 (0x10000000, 'IMAGE_SCN_MEM_SHARED'),
121 (0x20000000, 'IMAGE_SCN_MEM_EXECUTE'),
122 (0x40000000, 'IMAGE_SCN_MEM_READ'),
123 (0x80000000, 'IMAGE_SCN_MEM_WRITE'),
124 ])),
125 ('SectionData', ('ptr', 'PointerToRawData', ('blob', 'SizeOfRawData'))),
126 ('Relocations', ('ptr', 'PointerToRelocations', ('array', 'NumberOfRelocations', ('struct', [
127 ('VirtualAddress', ('scalar', '<L', '0x%X')),
128 ('SymbolTableIndex', ('scalar', '<L', '%d' )),
129 ('Type', ('enum', '<H', '%d', ('MachineType', {
130 0x14c: {
131 0x0000: 'IMAGE_REL_I386_ABSOLUTE',
132 0x0001: 'IMAGE_REL_I386_DIR16',
133 0x0002: 'IMAGE_REL_I386_REL16',
134 0x0006: 'IMAGE_REL_I386_DIR32',
135 0x0007: 'IMAGE_REL_I386_DIR32NB',
136 0x0009: 'IMAGE_REL_I386_SEG12',
137 0x000A: 'IMAGE_REL_I386_SECTION',
138 0x000B: 'IMAGE_REL_I386_SECREL',
139 0x000C: 'IMAGE_REL_I386_TOKEN',
140 0x000D: 'IMAGE_REL_I386_SECREL7',
141 0x0014: 'IMAGE_REL_I386_REL32',
142 },
Anton Korobeynikovd7343dd2010-08-17 21:05:54 +0000143 0x8664: {
144 0x0000: 'IMAGE_REL_AMD64_ABSOLUTE',
145 0x0001: 'IMAGE_REL_AMD64_ADDR64',
146 0x0002: 'IMAGE_REL_AMD64_ADDR32',
147 0x0003: 'IMAGE_REL_AMD64_ADDR32NB',
148 0x0004: 'IMAGE_REL_AMD64_REL32',
149 0x0005: 'IMAGE_REL_AMD64_REL32_1',
150 0x0006: 'IMAGE_REL_AMD64_REL32_2',
151 0x0007: 'IMAGE_REL_AMD64_REL32_3',
152 0x0008: 'IMAGE_REL_AMD64_REL32_4',
153 0x0009: 'IMAGE_REL_AMD64_REL32_5',
154 0x000A: 'IMAGE_REL_AMD64_SECTION',
155 0x000B: 'IMAGE_REL_AMD64_SECREL',
156 0x000C: 'IMAGE_REL_AMD64_SECREL7',
157 0x000D: 'IMAGE_REL_AMD64_TOKEN',
158 0x000E: 'IMAGE_REL_AMD64_SREL32',
159 0x000F: 'IMAGE_REL_AMD64_PAIR',
160 0x0010: 'IMAGE_REL_AMD64_SSPAN32',
161 },
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000162 }))),
163 ('SymbolName', ('ptr', '+ PointerToSymbolTable * - SymbolTableIndex 1 18', ('scalar', '<8s', symname)))
164 ])))),
165 ]))),
166 ('Symbols', ('ptr', 'PointerToSymbolTable', ('byte-array', '* NumberOfSymbols 18', ('struct', [
167 ('Name', ('scalar', '<8s', symname)),
168 ('Value', ('scalar', '<L', '%d' )),
169 ('SectionNumber', ('scalar', '<H', '%d' )),
170 ('SimpleType', ('enum', '<B', '%d', {
171 0: 'IMAGE_SYM_TYPE_NULL',
172 1: 'IMAGE_SYM_TYPE_VOID',
173 2: 'IMAGE_SYM_TYPE_CHAR',
174 3: 'IMAGE_SYM_TYPE_SHORT',
175 4: 'IMAGE_SYM_TYPE_INT',
176 5: 'IMAGE_SYM_TYPE_LONG',
177 6: 'IMAGE_SYM_TYPE_FLOAT',
178 7: 'IMAGE_SYM_TYPE_DOUBLE',
179 8: 'IMAGE_SYM_TYPE_STRUCT',
180 9: 'IMAGE_SYM_TYPE_UNION',
181 10: 'IMAGE_SYM_TYPE_ENUM',
182 11: 'IMAGE_SYM_TYPE_MOE',
183 12: 'IMAGE_SYM_TYPE_BYTE',
184 13: 'IMAGE_SYM_TYPE_WORD',
185 14: 'IMAGE_SYM_TYPE_UINT',
186 15: 'IMAGE_SYM_TYPE_DWORD',
187 })),
188 ('ComplexType', ('enum', '<B', '%d', {
189 0: 'IMAGE_SYM_DTYPE_NULL',
190 1: 'IMAGE_SYM_DTYPE_POINTER',
191 2: 'IMAGE_SYM_DTYPE_FUNCTION',
192 3: 'IMAGE_SYM_DTYPE_ARRAY',
193 })),
194 ('StorageClass', ('enum', '<B', '%d', {
195 -1: 'IMAGE_SYM_CLASS_END_OF_FUNCTION',
196 0: 'IMAGE_SYM_CLASS_NULL',
197 1: 'IMAGE_SYM_CLASS_AUTOMATIC',
198 2: 'IMAGE_SYM_CLASS_EXTERNAL',
199 3: 'IMAGE_SYM_CLASS_STATIC',
200 4: 'IMAGE_SYM_CLASS_REGISTER',
201 5: 'IMAGE_SYM_CLASS_EXTERNAL_DEF',
202 6: 'IMAGE_SYM_CLASS_LABEL',
203 7: 'IMAGE_SYM_CLASS_UNDEFINED_LABEL',
204 8: 'IMAGE_SYM_CLASS_MEMBER_OF_STRUCT',
205 9: 'IMAGE_SYM_CLASS_ARGUMENT',
206 10: 'IMAGE_SYM_CLASS_STRUCT_TAG',
207 11: 'IMAGE_SYM_CLASS_MEMBER_OF_UNION',
208 12: 'IMAGE_SYM_CLASS_UNION_TAG',
209 13: 'IMAGE_SYM_CLASS_TYPE_DEFINITION',
210 14: 'IMAGE_SYM_CLASS_UNDEFINED_STATIC',
211 15: 'IMAGE_SYM_CLASS_ENUM_TAG',
212 16: 'IMAGE_SYM_CLASS_MEMBER_OF_ENUM',
213 17: 'IMAGE_SYM_CLASS_REGISTER_PARAM',
214 18: 'IMAGE_SYM_CLASS_BIT_FIELD',
215 100: 'IMAGE_SYM_CLASS_BLOCK',
216 101: 'IMAGE_SYM_CLASS_FUNCTION',
217 102: 'IMAGE_SYM_CLASS_END_OF_STRUCT',
218 103: 'IMAGE_SYM_CLASS_FILE',
219 104: 'IMAGE_SYM_CLASS_SECTION',
220 105: 'IMAGE_SYM_CLASS_WEAK_EXTERNAL',
221 107: 'IMAGE_SYM_CLASS_CLR_TOKEN',
222 })),
223 ('NumberOfAuxSymbols', ('scalar', '<B', '%d' )),
224 ('AuxillaryData', ('blob', '* NumberOfAuxSymbols 18')),
225 ])))),
226])
227
228#
229# Definition Interpreter
230#
231
232import sys, types, struct, re
233
234Input = None
235Stack = []
236Fields = {}
237
238Indent = 0
239NewLine = True
240
241def indent():
242 global Indent
243 Indent += 1
244
245def dedent():
246 global Indent
247 Indent -= 1
248
249def write(input):
250 global NewLine
251 output = ""
252
253 for char in input:
254
255 if NewLine:
256 output += Indent * ' '
257 NewLine = False
258
259 output += char
260
261 if char == '\n':
262 NewLine = True
263
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000264 sys.stdout.write(output)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000265
266def read(format):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000267 return struct.unpack(format, Input.read(struct.calcsize(format)))
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000268
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000269def read_cstr():
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000270 output = ""
271 while True:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000272 char = Input.read(1)
273 if len(char) == 0:
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000274 raise RuntimeError ("EOF while reading cstr")
275 if char == '\0':
276 break
277 output += char
278 return output
279
280def push_pos(seek_to = None):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000281 Stack [0:0] = [Input.tell()]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000282 if seek_to:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000283 Input.seek(seek_to)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000284
285def pop_pos():
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000286 assert(len(Stack) > 0)
287 Input.seek(Stack[0])
288 del Stack[0]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000289
290def print_binary_data(size):
291 value = ""
292 while size > 0:
293 if size >= 16:
294 data = Input.read(16)
295 size -= 16
296 else:
297 data = Input.read(size)
298 size = 0
299 value += data
300 bytes = ""
301 text = ""
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000302 for index in xrange(16):
303 if index < len(data):
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000304 if index == 8:
305 bytes += "- "
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000306 ch = ord(data[index])
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000307 bytes += "%02X " % ch
308 if ch >= 0x20 and ch <= 0x7F:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000309 text += data[index]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000310 else:
311 text += "."
312 else:
313 if index == 8:
314 bytes += " "
315 bytes += " "
316
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000317 write("%s|%s|\n" % (bytes, text))
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000318 return value
319
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000320idlit = re.compile("[a-zA-Z][a-zA-Z0-9_-]*")
321numlit = re.compile("[0-9]+")
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000322
323def read_value(expr):
324
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000325 input = iter(expr.split())
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000326
327 def eval():
328
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000329 token = input.next()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000330
331 if expr == 'cstr':
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000332 return read_cstr()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000333 if expr == 'true':
334 return True
335 if expr == 'false':
336 return False
337
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000338 if len(token) > 1 and token[0] in ('=', '@', '<', '!', '>'):
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000339 val = read(expr)
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000340 assert(len(val) == 1)
341 return val[0]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000342
343 if token == '+':
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000344 return eval() + eval()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000345 if token == '-':
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000346 return eval() - eval()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000347 if token == '*':
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000348 return eval() * eval()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000349 if token == '/':
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000350 return eval() / eval()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000351
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000352 if idlit.match(token):
353 return Fields[token]
354 if numlit.match(token):
355 return int(token)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000356
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000357 raise RuntimeError("unexpected token %s" % repr(token))
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000358
359 value = eval ()
360
361 try:
362 input.next ()
363 except StopIteration:
364 return value
365 raise RuntimeError("unexpected input at end of expression")
366
367def write_value(format,value):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000368 format_type = type(format)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000369 if format_type is types.StringType:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000370 write(format % value)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000371 elif format_type is types.FunctionType:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000372 write_value(format(value), value)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000373 elif format_type is types.TupleType:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000374 Fields['this'] = value
375 handle_element(format)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000376 else:
377 raise RuntimeError("unexpected type: %s" % repr(format_type))
378
379def handle_scalar(entry):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000380 iformat = entry[1]
381 oformat = entry[2]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000382
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000383 value = read_value(iformat)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000384
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000385 write_value(oformat, value)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000386
387 return value
388
389def handle_enum(entry):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000390 iformat = entry[1]
391 oformat = entry[2]
392 definitions = entry[3]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000393
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000394 value = read_value(iformat)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000395
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000396 if type(definitions) is types.TupleType:
397 selector = read_value(definitions[0])
398 definitions = definitions[1][selector]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000399
NAKAMURA Takumi8794dd72010-08-30 15:19:56 +0000400 if value in definitions:
401 description = definitions[value]
402 else:
403 description = "unknown"
404
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000405 write("%s (" % description)
406 write_value(oformat, value)
407 write(")")
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000408
409 return value
410
411def handle_flags(entry):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000412 iformat = entry[1]
413 oformat = entry[2]
414 definitions = entry[3]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000415
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000416 value = read_value(iformat)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000417
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000418 write_value(oformat, value)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000419
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000420 indent()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000421 for entry in definitions:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000422 mask = entry[0]
423 name = entry[1]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000424 if len (entry) == 3:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000425 map = entry[2]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000426 selection = value & mask
427 if selection in map:
428 write("\n%s" % map[selection])
429 else:
430 write("\n%s <%d>" % (name, selection))
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000431 elif len(entry) == 2:
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000432 if value & mask != 0:
433 write("\n%s" % name)
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000434 dedent()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000435
436 return value
437
438def handle_struct(entry):
439 global Fields
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000440 members = entry[1]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000441
442 newFields = {}
443
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000444 write("{\n");
445 indent()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000446
447 for member in members:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000448 name = member[0]
449 type = member[1]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000450
451 write("%s = "%name.ljust(24))
452
453 value = handle_element(type)
454
455 write("\n")
456
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000457 Fields[name] = value
458 newFields[name] = value
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000459
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000460 dedent()
461 write("}")
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000462
463 return newFields
464
465def handle_array(entry):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000466 length = entry[1]
467 element = entry[2]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000468
469 newItems = []
470
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000471 write("[\n")
472 indent()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000473
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000474 value = read_value(length)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000475
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000476 for index in xrange(value):
477 write("%d = "%index)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000478 value = handle_element(element)
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000479 write("\n")
480 newItems.append(value)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000481
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000482 dedent()
483 write("]")
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000484
485 return newItems
486
487def handle_byte_array(entry):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000488 length = entry[1]
489 element = entry[2]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000490
491 newItems = []
492
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000493 write("[\n")
494 indent()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000495
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000496 value = read_value(length)
497 end_of_array = Input.tell() + value
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000498
499 index = 0
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000500 while Input.tell() < end_of_array:
501 write("%d = "%index)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000502 value = handle_element(element)
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000503 write("\n")
504 newItems.append(value)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000505 index += 1
506
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000507 dedent()
508 write("]")
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000509
510 return newItems
511
512def handle_ptr(entry):
513 offset = entry[1]
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000514 element = entry[2]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000515
516 value = None
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000517 offset = read_value(offset)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000518
519 if offset != 0:
520
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000521 push_pos(offset)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000522
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000523 value = handle_element(element)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000524
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000525 pop_pos()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000526
527 else:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000528 write("None")
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000529
530 return value
531
532def handle_blob(entry):
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000533 length = entry[1]
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000534
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000535 write("\n")
536 indent()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000537
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000538 value = print_binary_data(read_value(length))
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000539
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000540 dedent()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000541
542 return value
543
544def handle_element(entry):
545 handlers = {
546 'struct': handle_struct,
547 'scalar': handle_scalar,
548 'enum': handle_enum,
549 'flags': handle_flags,
550 'ptr': handle_ptr,
551 'blob': handle_blob,
552 'array': handle_array,
553 'byte-array': handle_byte_array,
554 }
555
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000556 if not entry[0] in handlers:
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000557 raise RuntimeError ("unexpected type '%s'" % str (entry[0]))
558
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000559 return handlers[entry[0]](entry)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000560
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000561Input = open (sys.argv[1], "rb")
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000562try:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000563 handle_element(file)
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000564finally:
Michael J. Spenceraeb83c42010-09-15 03:58:24 +0000565 Input.close()
Michael J. Spencerdfd30182010-07-27 06:46:15 +0000566 Input = None