From 481a5c6cb2347317e19e9787ed01e6596bcaf6a5 Mon Sep 17 00:00:00 2001 From: Gabriel Ionita Date: Sat, 25 Oct 2025 13:25:00 +0100 Subject: [PATCH] implement get_var_size to retrieve variable byte size from DWARF --- src/symbol.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) diff --git a/src/symbol.cpp b/src/symbol.cpp index d797925..d5af909 100644 --- a/src/symbol.cpp +++ b/src/symbol.cpp @@ -149,6 +149,81 @@ Dwarf_Addr Symbol::get_global_var_addr(Dwarf_Debug dbg, Dwarf_Die die) { return addr; } +size_t Symbol::get_var_size(Dwarf_Debug dbg, Dwarf_Die die) { + Dwarf_Error err; + Dwarf_Attribute type_attr; + Dwarf_Off type_offset; + Dwarf_Die type_die; + Dwarf_Half tag; + + // Get the type attribute + if (dwarf_attr(die, DW_AT_type, &type_attr, &err) != DW_DLV_OK) + return 0; + + // Get the type offset + if (dwarf_global_formref(type_attr, &type_offset, &err) != DW_DLV_OK) { + dwarf_dealloc(dbg, type_attr, DW_DLA_ATTR); + return 0; + } + + dwarf_dealloc(dbg, type_attr, DW_DLA_ATTR); + + // Get the type DIE + if (dwarf_offdie_b(dbg, type_offset, true, &type_die, &err) != DW_DLV_OK) + return 0; + + // Get the tag of the type DIE + if (dwarf_tag(type_die, &tag, &err) != DW_DLV_OK) { + dwarf_dealloc(dbg, type_die, DW_DLA_DIE); + return 0; + } + + // Skip through const/volatile qualifiers + while (tag == DW_TAG_const_type || tag == DW_TAG_volatile_type) { + Dwarf_Attribute inner_type_attr; + Dwarf_Off inner_type_offset; + Dwarf_Die inner_type_die; + + if (dwarf_attr(type_die, DW_AT_type, &inner_type_attr, &err) != DW_DLV_OK) { + dwarf_dealloc(dbg, type_die, DW_DLA_DIE); + return 0; + } + + if (dwarf_global_formref(inner_type_attr, &inner_type_offset, &err) != DW_DLV_OK) { + dwarf_dealloc(dbg, inner_type_attr, DW_DLA_ATTR); + dwarf_dealloc(dbg, type_die, DW_DLA_DIE); + return 0; + } + + dwarf_dealloc(dbg, inner_type_attr, DW_DLA_ATTR); + + if (dwarf_offdie_b(dbg, inner_type_offset, true, &inner_type_die, &err) != DW_DLV_OK) { + dwarf_dealloc(dbg, type_die, DW_DLA_DIE); + return 0; + } + + dwarf_dealloc(dbg, type_die, DW_DLA_DIE); + type_die = inner_type_die; + + if (dwarf_tag(type_die, &tag, &err) != DW_DLV_OK) { + dwarf_dealloc(dbg, type_die, DW_DLA_DIE); + return 0; + } + } + + // Get the byte size + Dwarf_Attribute size_attr; + Dwarf_Unsigned byte_size = 0; + + if (dwarf_attr(type_die, DW_AT_byte_size, &size_attr, &err) == DW_DLV_OK) { + dwarf_formudata(size_attr, &byte_size, &err); + dwarf_dealloc(dbg, size_attr, DW_DLA_ATTR); + } + + dwarf_dealloc(dbg, type_die, DW_DLA_DIE); + return byte_size; +} + void Symbol::list_global_integer_vars(Dwarf_Debug dbg) { Dwarf_Error err; Dwarf_Unsigned cu_hdr_len, abbr_offset, next_cu_hdr;