d9daaff493e934ed2e1a54a3bd5c7de79182f344
[pyelftools.git] / examples / dwarf_pubnames_types.py
1 #-------------------------------------------------------------------------------
2 # elftools example: dwarf_pubnames_types.py
3 #
4 # Dump the contents of .debug_pubnames and .debug_pubtypes sections from the
5 # ELF file.
6 #
7 # Note: sample_exe64.elf doesn't have a .debug_pubtypes section.
8 #
9 # Vijay Ramasami (rvijayc@gmail.com)
10 # This code is in the public domain
11 #-------------------------------------------------------------------------------
12 from __future__ import print_function
13 import sys
14
15 # If pyelftools is not installed, the example can also run from the root or
16 # examples/ dir of the source distribution.
17 sys.path[0:0] = ['.', '..']
18
19 from elftools.elf.elffile import ELFFile
20 from elftools.common.py3compat import bytes2str
21
22 def process_file(filename):
23 print('Processing file:', filename)
24 with open(filename, 'rb') as f:
25 elffile = ELFFile(f)
26
27 if not elffile.has_dwarf_info():
28 print(' file has no DWARF info')
29 return
30
31 # get_dwarf_info returns a DWARFInfo context object, which is the
32 # starting point for all DWARF-based processing in pyelftools.
33 dwarfinfo = elffile.get_dwarf_info()
34
35 # get .debug_pubtypes section.
36 pubnames = dwarfinfo.get_pubnames()
37 if pubnames is None:
38 print('ERROR: No .debug_pubnames section found in ELF.')
39 else:
40 print('%d entries found in .debug_pubnames' % len(pubnames))
41
42 print('Trying pubnames example ...')
43 for name, entry in pubnames.items():
44 print('%s: cu_ofs = %d, die_ofs = %d' %
45 (name, entry.cu_ofs, entry.die_ofs))
46
47 # get the actual CU/DIE that has this information.
48 print('Fetching the actual die for %s ...' % name)
49 for cu in dwarfinfo.iter_CUs():
50 if cu.cu_offset == entry.cu_ofs:
51 for die in cu.iter_DIEs():
52 if die.offset == entry.die_ofs:
53 print('Die Name: %s' %
54 bytes2str(die.attributes['DW_AT_name'].value))
55
56 # dump all entries in .debug_pubnames section.
57 print('Dumping .debug_pubnames table ...')
58 print('-' * 66)
59 print('%50s%8s%8s' % ('Symbol', 'CU_OFS', 'DIE_OFS'))
60 print('-' * 66)
61 for (name, entry) in pubnames.items():
62 print('%50s%8d%8d' % (name, entry.cu_ofs, entry.die_ofs))
63 print('-' * 66)
64
65 # get .debug_pubtypes section.
66 pubtypes = dwarfinfo.get_pubtypes()
67 if pubtypes is None:
68 print('ERROR: No .debug_pubtypes section found in ELF')
69 else:
70 print('%d entries found in .debug_pubtypes' % len(pubtypes))
71
72 for name, entry in pubtypes.items():
73 print('%s: cu_ofs = %d, die_ofs = %d' %
74 (name, entry.cu_ofs, entry.die_ofs))
75
76 # get the actual CU/DIE that has this information.
77 print('Fetching the actual die for %s ...' % name)
78 for cu in dwarfinfo.iter_CUs():
79 if cu.cu_offset == entry.cu_ofs:
80 for die in cu.iter_DIEs():
81 if die.offset == entry.die_ofs:
82 print('Die Name: %s' %
83 bytes2str(die.attributes['DW_AT_name'].value))
84 die_info_rec(die)
85
86 # dump all entries in .debug_pubtypes section.
87 print('Dumping .debug_pubtypes table ...')
88 print('-' * 66)
89 print('%50s%8s%8s' % ('Symbol', 'CU_OFS', 'DIE_OFS'))
90 print('-' * 66)
91 for (name, entry) in pubtypes.items():
92 print('%50s%8d%8d' % (name, entry.cu_ofs, entry.die_ofs))
93 print('-' * 66)
94
95
96 def die_info_rec(die, indent_level=' '):
97 """ A recursive function for showing information about a DIE and its
98 children.
99 """
100 print(indent_level + 'DIE tag=%s, attrs=' % die.tag)
101 for name, val in die.attributes.items():
102 print(indent_level + ' %s = %s' % (name, val))
103 child_indent = indent_level + ' '
104 for child in die.iter_children():
105 die_info_rec(child, child_indent)
106
107
108 if __name__ == '__main__':
109 if sys.argv[1] == '--test':
110 process_file(sys.argv[2])
111 sys.exit(0)
112
113 if len(sys.argv) < 2:
114 print('Expected usage: {0} <executable>'.format(sys.argv[0]))
115 sys.exit(1)
116 process_file(sys.argv[1])