@@ -83,15 +83,21 @@ def symbol_from_address(elf: ELFFile, address: int) -> Symbol | None:
8383def 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
106123def 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