1 #-------------------------------------------------------------------------------
2 # elftools: dwarf/locationlists.py
4 # DWARF location lists section decoding (.debug_loc)
6 # Eli Bendersky (eliben@gmail.com)
7 # This code is in the public domain
8 #-------------------------------------------------------------------------------
10 from collections
import namedtuple
12 from ..common
.utils
import struct_parse
15 LocationEntry
= namedtuple('LocationEntry', 'begin_offset end_offset loc_expr')
16 BaseAddressEntry
= namedtuple('BaseAddressEntry', 'base_address')
19 class LocationLists(object):
20 """ A single location list is a Python list consisting of LocationEntry or
21 BaseAddressEntry objects.
23 def __init__(self
, stream
, structs
):
25 self
.structs
= structs
26 self
._max
_addr
= 2 ** (self
.structs
.address_size
* 8) - 1
28 def get_location_list_at_offset(self
, offset
):
29 """ Get a location list at the given offset in the section.
31 self
.stream
.seek(offset
, os
.SEEK_SET
)
32 return self
._parse
_location
_list
_from
_stream
()
34 def iter_location_lists(self
):
35 """ Yield all location lists found in the section.
37 # Just call _parse_location_list_from_stream until the stream ends
38 self
.stream
.seek(0, os
.SEEK_END
)
39 endpos
= self
.stream
.tell()
41 self
.stream
.seek(0, os
.SEEK_SET
)
42 while self
.stream
.tell() < endpos
:
43 yield self
._parse
_location
_list
_from
_stream
()
45 #------ PRIVATE ------#
47 def _parse_location_list_from_stream(self
):
50 begin_offset
= struct_parse(
51 self
.structs
.Dwarf_target_addr(''), self
.stream
)
52 end_offset
= struct_parse(
53 self
.structs
.Dwarf_target_addr(''), self
.stream
)
54 if begin_offset
== 0 and end_offset
== 0:
55 # End of list - we're done.
57 elif begin_offset
== self
._max
_addr
:
58 # Base address selection entry
59 lst
.append(BaseAddressEntry(base_address
=end_offset
))
62 expr_len
= struct_parse(
63 self
.structs
.Dwarf_uint16(''), self
.stream
)
64 loc_expr
= [struct_parse(self
.structs
.Dwarf_uint8(''),
66 for i
in range(expr_len
)]
67 lst
.append(LocationEntry(
68 begin_offset
=begin_offset
,
69 end_offset
=end_offset
,