1 #-------------------------------------------------------------------------------
2 # elftools: dwarf/dwarfinfo.py
4 # DWARFInfo - Main class for accessing DWARF debug information
6 # Eli Bendersky (eliben@gmail.com)
7 # This code is in the public domain
8 #-------------------------------------------------------------------------------
9 from collections
import namedtuple
11 from ..common
.exceptions
import DWARFError
12 from ..common
.utils
import struct_parse
, dwarf_assert
13 from .structs
import DWARFStructs
14 from .compileunit
import CompileUnit
17 # Describes a debug section in a stream: offset and size
19 DebugSectionLocator
= namedtuple('DebugSectionLocator', 'offset size')
22 class DWARFInfo(object):
23 """ Creation: the constructor accepts a stream (file-like object) that
24 contains debug sections, along with locators (DebugSectionLocator)
25 of the required sections. In addition, little_endian is a boolean
26 parameter specifying endianity.
36 self
.debug_info_loc
= debug_info_loc
37 self
.debug_abbrev_loc
= debug_abbrev_loc
38 self
.debug_str_loc
= debug_str_loc
39 self
.debug_line_loc
= debug_line_loc
41 self
.little_endian
= little_endian
42 self
.dwarf_format
= 32
43 self
.structs
= DWARFStructs(
44 little_endian
=self
.little_endian
,
45 dwarf_format
=self
.dwarf_format
)
47 # Populate the list with CUs found in debug_info
48 self
._CU
= self
._parse
_CUs
()
51 """ Parse CU entries from debug_info.
53 offset
= self
.debug_info_loc
.offset
54 section_boundary
= self
.debug_info_loc
.offset
+ self
.debug_info_loc
.size
56 while offset
< section_boundary
:
57 # Section 7.4 (32-bit and 64-bit DWARF Formats) of the DWARF spec v3
58 # states that the first 32-bit word of the CU header determines
59 # whether the CU is represented with 32-bit or 64-bit DWARF format.
61 # So we peek at the first byte in the CU header to determine its
62 # dwarf format. Based on it, we then create a new DWARFStructs
63 # instance suitable for this CU and use it to parse the rest.
65 initial_length
= struct_parse(
66 self
.structs
.Dwarf_uint32(''), self
.stream
, offset
)
67 if initial_length
== 0xFFFFFFFF:
68 self
.dwarf_format
= 64
69 cu_structs
= DWARFStructs(
70 little_endian
=self
.little_endian
,
71 dwarf_format
=self
.dwarf_format
)
73 cu_header
= struct_parse(
74 self
.structs
.Dwarf_CU_header
, self
.stream
, offset
)
76 self
._is
_supported
_version
(cu_header
['version']),
77 "Expected supported DWARF version. Got '%s'" % cu_header
['version'])
78 CUlist
.append(CompileUnit(cu_header
, cu_structs
, None))
79 # Compute the offset of the next CU in the section. The unit_length
80 # field of the CU header contains its size not including the length
83 cu_header
['unit_length'] +
84 cu_structs
.initial_lenght_field_size())
87 def _is_supported_version(self
, version
):
88 """ DWARF version supported by this parser
90 return 2 <= version
<= 3