Skip to content

Commit 62e09b3

Browse files
committed
util: elftools: use declaration type info fallback
If we can't find the DIE directly by address, attempt to use the declarations type information. Signed-off-by: Jordan Yates <jordan@embeint.com>
1 parent 20f67e2 commit 62e09b3

1 file changed

Lines changed: 26 additions & 6 deletions

File tree

src/infuse_iot/util/elftools.py

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,21 @@ def symbol_from_address(elf: ELFFile, address: int) -> Symbol | None:
8383
def dwarf_die_from_symbol(elf: ELFFile, symbol: Symbol) -> DIE | None:
8484
"""Get a Debug Information Entry associated with a symbol (Global variables only)"""
8585
dwarfinfo = elf.get_dwarf_info()
86+
candidate_cu = None
87+
candidate_die = None
8688

8789
for CU in dwarfinfo.iter_CUs():
8890
for die in CU.iter_DIEs():
89-
if die.tag == "DW_TAG_variable" and "DW_AT_name" in die.attributes and "DW_AT_location" in die.attributes:
90-
die_name = die.attributes["DW_AT_name"].value.decode("utf-8")
91+
if die.tag != "DW_TAG_variable" or "DW_AT_name" not in die.attributes:
92+
continue
93+
die_name = die.attributes["DW_AT_name"].value.decode("utf-8")
94+
if die_name != symbol.name:
95+
continue
96+
# Store as fallback in case we can't find a matching address
97+
candidate_cu = CU
98+
candidate_die = die
99+
if "DW_AT_location" in die.attributes:
91100
die_location = die.attributes.get("DW_AT_location").value
92-
# Not our symbol
93-
if die_name != symbol.name:
94-
continue
95101
# Constant addresses are in a list of form [0x03, addr_bytes]
96102
if not isinstance(die_location, list):
97103
continue
@@ -100,10 +106,24 @@ def dwarf_die_from_symbol(elf: ELFFile, symbol: Symbol) -> DIE | None:
100106
address = int.from_bytes(die_location[1:], "little")
101107
if address == symbol.entry["st_value"]:
102108
return die
103-
return None
109+
110+
if candidate_cu is None or candidate_die is None:
111+
# No symbols with matching names found
112+
return None
113+
114+
type_attr = candidate_die.attributes["DW_AT_type"]
115+
# The offset may be relative to the CU or absolute
116+
if type_attr.form == "DW_FORM_ref_addr":
117+
type_offset = type_attr.value # absolute offset in .debug_info
118+
else:
119+
type_offset = candidate_cu.cu_offset + type_attr.value # relative to CU
120+
return dwarfinfo.get_DIE_from_refaddr(type_offset)
104121

105122

106123
def dwarf_die_file_info(elf: ELFFile, die: DIE) -> tuple[str | None, int]:
124+
if "DW_AT_decl_file" not in die.attributes or "DW_AT_decl_line" not in die.attributes:
125+
return (None, 0)
126+
107127
file_attr = die.attributes["DW_AT_decl_file"]
108128
line_attr = die.attributes["DW_AT_decl_line"]
109129

0 commit comments

Comments
 (0)