Extend instcombine's shufflevector simplification to handle more cases where the...
[oota-llvm.git] / test / Scripts / coff-dump.py
1 #!/usr/bin/env python
2 #===-- 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
15 def string_table_entry (offset):
16   return ('ptr', '+ + PointerToSymbolTable * NumberOfSymbols 18 %s' % offset, ('scalar', 'cstr', '%s'))
17
18 def secname(value):
19   if value[0] == '/':
20     return string_table_entry(value[1:].rstrip('\0'))
21   else:
22     return '%s'
23
24 def symname(value):
25   parts = struct.unpack("<2L", value)
26   if parts[0] == 0:
27     return string_table_entry(parts[1])
28   else:
29     return '%s'
30
31 file = ('struct', [
32   ('MachineType', ('enum', '<H', '0x%X', {
33     0x0:    'IMAGE_FILE_MACHINE_UNKNOWN',
34     0x1d3:  'IMAGE_FILE_MACHINE_AM33',
35     0x8664: 'IMAGE_FILE_MACHINE_AMD64',
36     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', '1', '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', '0', '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         },
143         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         },
162       }))),
163       ('SymbolName',       ('ptr', '+ PointerToSymbolTable * SymbolTableIndex 18', ('scalar',  '<8s', symname)))
164     ])))),
165   ]))),
166   ('Symbols', ('ptr', 'PointerToSymbolTable', ('byte-array', '18', '* NumberOfSymbols 18',  ('struct', [
167     ('Name',                ('scalar',  '<8s', symname)),
168     ('Value',               ('scalar',  '<L',  '%d'   )),
169     ('SectionNumber',       ('scalar',  '<H',  '%d'   )),
170     ('_Type',               ('scalar',  '<H',  None   )),
171     ('SimpleType',          ('enum',    '& _Type 15',  '%d', {
172       0: 'IMAGE_SYM_TYPE_NULL',
173       1: 'IMAGE_SYM_TYPE_VOID',
174       2: 'IMAGE_SYM_TYPE_CHAR',
175       3: 'IMAGE_SYM_TYPE_SHORT',
176       4: 'IMAGE_SYM_TYPE_INT',
177       5: 'IMAGE_SYM_TYPE_LONG',
178       6: 'IMAGE_SYM_TYPE_FLOAT',
179       7: 'IMAGE_SYM_TYPE_DOUBLE',
180       8: 'IMAGE_SYM_TYPE_STRUCT',
181       9: 'IMAGE_SYM_TYPE_UNION',
182       10: 'IMAGE_SYM_TYPE_ENUM',
183       11: 'IMAGE_SYM_TYPE_MOE',
184       12: 'IMAGE_SYM_TYPE_BYTE',
185       13: 'IMAGE_SYM_TYPE_WORD',
186       14: 'IMAGE_SYM_TYPE_UINT',
187       15: 'IMAGE_SYM_TYPE_DWORD',
188     })),                                # (Type & 0xF0) >> 4
189     ('ComplexType',         ('enum',    '>> & _Type 240 4',  '%d', {
190       0: 'IMAGE_SYM_DTYPE_NULL',
191       1: 'IMAGE_SYM_DTYPE_POINTER',
192       2: 'IMAGE_SYM_DTYPE_FUNCTION',
193       3: 'IMAGE_SYM_DTYPE_ARRAY',
194     })),
195     ('StorageClass',        ('enum',    '<B',  '%d', {
196       -1:  'IMAGE_SYM_CLASS_END_OF_FUNCTION',
197       0: 'IMAGE_SYM_CLASS_NULL',
198       1: 'IMAGE_SYM_CLASS_AUTOMATIC',
199       2: 'IMAGE_SYM_CLASS_EXTERNAL',
200       3: 'IMAGE_SYM_CLASS_STATIC',
201       4: 'IMAGE_SYM_CLASS_REGISTER',
202       5: 'IMAGE_SYM_CLASS_EXTERNAL_DEF',
203       6: 'IMAGE_SYM_CLASS_LABEL',
204       7: 'IMAGE_SYM_CLASS_UNDEFINED_LABEL',
205       8: 'IMAGE_SYM_CLASS_MEMBER_OF_STRUCT',
206       9: 'IMAGE_SYM_CLASS_ARGUMENT',
207       10: 'IMAGE_SYM_CLASS_STRUCT_TAG',
208       11: 'IMAGE_SYM_CLASS_MEMBER_OF_UNION',
209       12: 'IMAGE_SYM_CLASS_UNION_TAG',
210       13: 'IMAGE_SYM_CLASS_TYPE_DEFINITION',
211       14: 'IMAGE_SYM_CLASS_UNDEFINED_STATIC',
212       15: 'IMAGE_SYM_CLASS_ENUM_TAG',
213       16: 'IMAGE_SYM_CLASS_MEMBER_OF_ENUM',
214       17: 'IMAGE_SYM_CLASS_REGISTER_PARAM',
215       18: 'IMAGE_SYM_CLASS_BIT_FIELD',
216       100: 'IMAGE_SYM_CLASS_BLOCK',
217       101: 'IMAGE_SYM_CLASS_FUNCTION',
218       102: 'IMAGE_SYM_CLASS_END_OF_STRUCT',
219       103: 'IMAGE_SYM_CLASS_FILE',
220       104: 'IMAGE_SYM_CLASS_SECTION',
221       105: 'IMAGE_SYM_CLASS_WEAK_EXTERNAL',
222       107: 'IMAGE_SYM_CLASS_CLR_TOKEN',
223     })),
224     ('NumberOfAuxSymbols',  ('scalar',  '<B',  '%d'  )),
225     ('AuxillaryData', ('blob', '* NumberOfAuxSymbols 18')),
226   ])))),
227 ])
228
229 #
230 # Definition Interpreter
231 #
232
233 import sys, types, struct, re
234
235 Input = None
236 Stack = []
237 Fields = {}
238
239 Indent = 0
240 NewLine = True
241
242 def indent():
243   global Indent
244   Indent += 1
245
246 def dedent():
247   global Indent
248   Indent -= 1
249
250 def write(input):
251   global NewLine
252   output = ""
253
254   for char in input:
255
256     if NewLine:
257       output += Indent * '  '
258       NewLine = False
259
260     output += char
261
262     if char == '\n':
263       NewLine = True
264
265   sys.stdout.write(output)
266
267 def read(format):
268   return struct.unpack(format, Input.read(struct.calcsize(format)))
269
270 def read_cstr():
271   output = ""
272   while True:
273     char = Input.read(1)
274     if len(char) == 0:
275       raise RuntimeError ("EOF while reading cstr")
276     if char == '\0':
277       break
278     output += char
279   return output
280
281 def push_pos(seek_to = None):
282   Stack [0:0] = [Input.tell()]
283   if seek_to:
284     Input.seek(seek_to)
285
286 def pop_pos():
287   assert(len(Stack) > 0)
288   Input.seek(Stack[0])
289   del Stack[0]
290
291 def print_binary_data(size):
292   value = ""
293   while size > 0:
294     if size >= 16:
295       data = Input.read(16)
296       size -= 16
297     else:
298       data = Input.read(size)
299       size = 0
300     value += data
301     bytes = ""
302     text = ""
303     for index in xrange(16):
304       if index < len(data):
305         if index == 8:
306           bytes += "- "
307         ch = ord(data[index])
308         bytes += "%02X " % ch
309         if ch >= 0x20 and ch <= 0x7F:
310           text += data[index]
311         else:
312           text += "."
313       else:
314         if index == 8:
315           bytes += "  "
316         bytes += "   "
317
318     write("%s|%s|\n" % (bytes, text))
319   return value
320
321 idlit = re.compile("[a-zA-Z_][a-zA-Z0-9_-]*")
322 numlit = re.compile("[0-9]+")
323
324 def read_value(expr):
325
326   input = iter(expr.split())
327
328   def eval():
329
330     token = input.next()
331
332     if expr == 'cstr':
333       return read_cstr()
334     if expr == 'true':
335       return True
336     if expr == 'false':
337       return False
338
339     if token == '+':
340       return eval() + eval()
341     if token == '-':
342       return eval() - eval()
343     if token == '*':
344       return eval() * eval()
345     if token == '/':
346       return eval() / eval()
347     if token == '&':
348       return eval() & eval()
349     if token == '|':
350       return eval() | eval()
351     if token == '>>':
352       return eval() >> eval()
353     if token == '<<':
354       return eval() << eval()
355
356     if len(token) > 1 and token[0] in ('=', '@', '<', '!', '>'):
357       val = read(expr)
358       assert(len(val) == 1)
359       return val[0]
360
361     if idlit.match(token):
362       return Fields[token]
363     if numlit.match(token):
364       return int(token)
365
366     raise RuntimeError("unexpected token %s" % repr(token))
367
368   value = eval()
369
370   try:
371     input.next()
372   except StopIteration:
373     return value
374   raise RuntimeError("unexpected input at end of expression")
375
376 def write_value(format,value):
377   format_type = type(format)
378   if format_type is types.StringType:
379     write(format % value)
380   elif format_type is types.FunctionType:
381     write_value(format(value), value)
382   elif format_type is types.TupleType:
383     Fields['this'] = value
384     handle_element(format)
385   elif format_type is types.NoneType:
386     pass
387   else:
388     raise RuntimeError("unexpected type: %s" % repr(format_type))
389
390 def handle_scalar(entry):
391   iformat = entry[1]
392   oformat = entry[2]
393
394   value = read_value(iformat)
395
396   write_value(oformat, value)
397
398   return value
399
400 def handle_enum(entry):
401   iformat = entry[1]
402   oformat = entry[2]
403   definitions = entry[3]
404
405   value = read_value(iformat)
406
407   if type(definitions) is types.TupleType:
408     selector = read_value(definitions[0])
409     definitions = definitions[1][selector]
410
411   if value in definitions:
412     description = definitions[value]
413   else:
414     description = "unknown"
415
416   write("%s (" % description)
417   write_value(oformat, value)
418   write(")")
419
420   return value
421
422 def handle_flags(entry):
423   iformat = entry[1]
424   oformat = entry[2]
425   definitions = entry[3]
426
427   value = read_value(iformat)
428
429   write_value(oformat, value)
430
431   indent()
432   for entry in definitions:
433     mask = entry[0]
434     name = entry[1]
435     if len (entry) == 3:
436       map = entry[2]
437       selection = value & mask
438       if selection in map:
439         write("\n%s" % map[selection])
440       else:
441         write("\n%s <%d>" % (name, selection))
442     elif len(entry) == 2:
443       if value & mask != 0:
444         write("\n%s" % name)
445   dedent()
446
447   return value
448
449 def handle_struct(entry):
450   global Fields
451   members = entry[1]
452
453   newFields = {}
454
455   write("{\n");
456   indent()
457
458   for member in members:
459     name = member[0]
460     type = member[1]
461
462     if name[0] != "_":
463       write("%s = " % name.ljust(24))
464
465     value = handle_element(type)
466
467     if name[0] != "_":
468       write("\n")
469
470     Fields[name] = value
471     newFields[name] = value
472
473   dedent()
474   write("}")
475
476   return newFields
477
478 def handle_array(entry):
479   start_index = entry[1]
480   length = entry[2]
481   element = entry[3]
482
483   newItems = []
484
485   write("[\n")
486   indent()
487
488   start_index = read_value(start_index)
489   value = read_value(length)
490
491   for index in xrange(value):
492     write("%d = " % (index + start_index))
493     value = handle_element(element)
494     write("\n")
495     newItems.append(value)
496
497   dedent()
498   write("]")
499
500   return newItems
501
502 def handle_byte_array(entry):
503   ent_size = entry[1]
504   length = entry[2]
505   element = entry[3]
506
507   newItems = []
508
509   write("[\n")
510   indent()
511
512   item_size = read_value(ent_size)
513   value = read_value(length)
514   end_of_array = Input.tell() + value
515
516   prev_loc = Input.tell()
517   index = 0
518   while Input.tell() < end_of_array:
519     write("%d = " % index)
520     value = handle_element(element)
521     write("\n")
522     newItems.append(value)
523     index += (Input.tell() - prev_loc) / item_size
524     prev_loc = Input.tell()
525
526   dedent()
527   write("]")
528
529   return newItems
530
531 def handle_ptr(entry):
532   offset = entry[1]
533   element = entry[2]
534
535   value = None
536   offset = read_value(offset)
537
538   if offset != 0:
539
540     push_pos(offset)
541
542     value = handle_element(element)
543
544     pop_pos()
545
546   else:
547     write("None")
548
549   return value
550
551 def handle_blob(entry):
552   length = entry[1]
553
554   write("\n")
555   indent()
556
557   value = print_binary_data(read_value(length))
558
559   dedent()
560
561   return value
562
563 def handle_element(entry):
564   handlers = {
565     'struct':      handle_struct,
566     'scalar':      handle_scalar,
567     'enum':        handle_enum,
568     'flags':       handle_flags,
569     'ptr':         handle_ptr,
570     'blob':        handle_blob,
571     'array':       handle_array,
572     'byte-array':  handle_byte_array,
573   }
574
575   if not entry[0] in handlers:
576     raise RuntimeError ("unexpected type '%s'" % str (entry[0]))
577
578   return handlers[entry[0]](entry)
579
580 if len(sys.argv) <= 1 or sys.argv[1] == '-':
581   import StringIO
582   Input = StringIO.StringIO(sys.stdin.read())
583 else:
584   Input = open (sys.argv[1], "rb")
585
586 try:
587   handle_element(file)
588 finally:
589   Input.close()
590   Input = None