Fix for mixed version loclists, tests (#521)
[pyelftools.git] / examples / elf_low_high_api.py
1 #-------------------------------------------------------------------------------
2 # elftools example: elf_low_high_api.py
3 #
4 # A simple example that shows some usage of the low-level API pyelftools
5 # provides versus the high-level API while inspecting an ELF file's symbol
6 # table.
7 #
8 # Eli Bendersky (eliben@gmail.com)
9 # This code is in the public domain
10 #-------------------------------------------------------------------------------
11 from __future__ import print_function
12 import sys
13
14 # If pyelftools is not installed, the example can also run from the root or
15 # examples/ dir of the source distribution.
16 sys.path[0:0] = ['.', '..']
17
18 from elftools.elf.elffile import ELFFile
19 from elftools.elf.sections import SymbolTableSection
20
21
22 def process_file(filename):
23 print('Processing file:', filename)
24 with open(filename, 'rb') as f:
25 section_info_lowlevel(f)
26 f.seek(0)
27 section_info_highlevel(f)
28
29
30 def section_info_lowlevel(stream):
31 print('Low level API...')
32 # We'll still be using the ELFFile context object. It's just too
33 # convenient to give up, even in the low-level API demonstation :-)
34 elffile = ELFFile(stream)
35
36 # The e_shnum ELF header field says how many sections there are in a file
37 print(' %s sections' % elffile['e_shnum'])
38
39 # Try to find the symbol table
40 for i in range(elffile['e_shnum']):
41 section_offset = elffile['e_shoff'] + i * elffile['e_shentsize']
42 # Parse the section header using structs.Elf_Shdr
43 stream.seek(section_offset)
44 section_header = elffile.structs.Elf_Shdr.parse_stream(stream)
45 if section_header['sh_type'] == 'SHT_SYMTAB':
46 # Some details about the section. Note that the section name is a
47 # pointer to the object's string table, so it's only a number
48 # here. To get to the actual name one would need to parse the string
49 # table section and extract the name from there (or use the
50 # high-level API!)
51 print(' Section name: %s, type: %s' % (
52 section_header['sh_name'], section_header['sh_type']))
53 break
54 else:
55 print(' No symbol table found. Perhaps this ELF has been stripped?')
56
57
58 def section_info_highlevel(stream):
59 print('High level API...')
60 elffile = ELFFile(stream)
61
62 # Just use the public methods of ELFFile to get what we need
63 # Note that section names are strings.
64 print(' %s sections' % elffile.num_sections())
65 section = elffile.get_section_by_name('.symtab')
66
67 if not section:
68 print(' No symbol table found. Perhaps this ELF has been stripped?')
69 return
70
71 # A section type is in its header, but the name was decoded and placed in
72 # a public attribute.
73 print(' Section name: %s, type: %s' %(
74 section.name, section['sh_type']))
75
76 # But there's more... If this section is a symbol table section (which is
77 # the case in the sample ELF file that comes with the examples), we can
78 # get some more information about it.
79 if isinstance(section, SymbolTableSection):
80 num_symbols = section.num_symbols()
81 print(" It's a symbol section with %s symbols" % num_symbols)
82 print(" The name of the last symbol in the section is: %s" % (
83 section.get_symbol(num_symbols - 1).name))
84
85
86 if __name__ == '__main__':
87 if sys.argv[1] == '--test':
88 for filename in sys.argv[2:]:
89 process_file(filename)