From e47cb7147d759d0b960379102b21e32fb7110a09 Mon Sep 17 00:00:00 2001 From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com> Date: Sun, 17 Sep 2023 00:52:31 -0400 Subject: [PATCH] Move some commented out type dwarf tree walking code to the end of the file --- src/symbols/symbols_with_libdwarf.cpp | 482 +++++++++++++------------- 1 file changed, 242 insertions(+), 240 deletions(-) diff --git a/src/symbols/symbols_with_libdwarf.cpp b/src/symbols/symbols_with_libdwarf.cpp index d433619..381f810 100644 --- a/src/symbols/symbols_with_libdwarf.cpp +++ b/src/symbols/symbols_with_libdwarf.cpp @@ -507,246 +507,6 @@ namespace libdwarf { return continue_traversal; } - /*die_object get_type_die(Dwarf_Debug dbg, const die_object& die) { - Dwarf_Off type_offset; - Dwarf_Bool is_info; - int ret = dwarf_dietype_offset(die.get(), &type_offset, &is_info, nullptr); - if(ret == DW_DLV_OK) { - Dwarf_Die type_die; - ret = dwarf_offdie_b( - dbg, - type_offset, - is_info, - &type_die, - nullptr - ); - if(ret == DW_DLV_OK) { - return die_object(dbg, type_die); - } else { - fprintf(stderr, "Error\n"); - exit(1); - } - } else { - fprintf(stderr, "no type offset??\n"); - } - return die_object(dbg, nullptr); - } - - bool has_type(Dwarf_Debug dbg, const die_object& die) { - Dwarf_Attribute attr; - int ret = dwarf_attr(die.get(), DW_AT_type, &attr, nullptr); - if(ret == DW_DLV_NO_ENTRY) { - return false; - } else if(ret == DW_DLV_OK) { - dwarf_dealloc_attribute(attr); - return true; - } else { - fprintf(stderr, "Error\n"); - exit(1); - } - } - - struct type_result { - std::string base; - std::string extent; - - std::string get_type() { - return base + extent; - } - }; - - // TODO: ::*, namespace lookup, arrays - // DW_TAG_namespace - const char* tag_to_keyword(Dwarf_Half tag) { - switch(tag) { - case DW_TAG_atomic_type: - return "_Atomic"; - case DW_TAG_const_type: - return "const"; - case DW_TAG_volatile_type: - return "volatile"; - case DW_TAG_restrict_type: - return "restrict"; - default: - { - const char* tag_name = nullptr; - dwarf_get_TAG_name(tag, &tag_name); - fprintf(stderr, "tag_to_keyword unknown tag %s\n", tag_name); - exit(1); - } - } - } - const char* tag_to_ptr_ref(Dwarf_Half tag) { - switch(tag) { - case DW_TAG_pointer_type: - return "*"; - case DW_TAG_ptr_to_member_type: - return "::*"; // TODO - case DW_TAG_reference_type: - return "&"; - case DW_TAG_rvalue_reference_type: - return "&&"; - default: - { - const char* tag_name = nullptr; - dwarf_get_TAG_name(tag, &tag_name); - fprintf(stderr, "tag_to_ptr_ref unknown tag %s\n", tag_name); - exit(1); - } - } - } - - std::string resolve_type(Dwarf_Debug dbg, const die_object& die, std::string build = ""); - - std::string get_array_extents(Dwarf_Debug dbg, const die_object& die) { - CPPTRACE_VERIFY(die.get_tag() == DW_TAG_array_type); - std::string extents = ""; - walk_die_list(dbg, die.get_child(), [&extents](Dwarf_Debug dbg, const die_object& subrange) { - if(subrange.get_tag() == DW_TAG_subrange_type) { - Dwarf_Attribute attr = 0; - int res = 0; - res = dwarf_attr(subrange.get(), DW_AT_upper_bound, &attr, nullptr); - if(res != DW_DLV_OK) { - fprintf(stderr, "Error\n"); - return; - } - Dwarf_Half form; - res = dwarf_whatform(attr, &form, nullptr); - if(res != DW_DLV_OK) { - fprintf(stderr, "Error\n"); - return; - } - //fprintf(stderr, "form: %d\n", form); - Dwarf_Unsigned val; - res = dwarf_formudata(attr, &val, nullptr); - if(res != DW_DLV_OK) { - fprintf(stderr, "Error\n"); - return; - } - extents += "[" + std::to_string(val + 1) + "]"; - dwarf_dealloc_attribute(attr); - } else { - fprintf(stderr, "unknown tag %s\n", subrange.get_tag_name()); - } - }); - return extents; - } - - std::string get_parameters(Dwarf_Debug dbg, const die_object& die) { - CPPTRACE_VERIFY(die.get_tag() == DW_TAG_subroutine_type); - std::vector params; - walk_die_list(dbg, die.get_child(), [¶ms](Dwarf_Debug dbg, const die_object& die) { - if(die.get_tag() == DW_TAG_formal_parameter) { - // TODO: Ignore DW_AT_artificial - params.push_back(resolve_type(dbg, get_type_die(dbg, die))); - } - }); - return "(" + join(params, ", ") + ")"; - } - - std::string resolve_type(Dwarf_Debug dbg, const die_object& die, std::string build) { - switch(auto tag = die.get_tag()) { - case DW_TAG_base_type: - case DW_TAG_class_type: - case DW_TAG_structure_type: - case DW_TAG_union_type: - case DW_TAG_enumeration_type: - return die.get_name() + build; - case DW_TAG_typedef: - return resolve_type(dbg, get_type_die(dbg, die)); - //case DW_TAG_subroutine_type: - // { - // // If there's no DW_AT_type then it's a void - // std::vector params; - // // TODO: Code duplication with retrieve_symbol_for_subprogram? - // walk_die_list(dbg, die.get_child(), [¶ms] (Dwarf_Debug dbg, const die_object& die) { - // if(die.get_tag() == DW_TAG_formal_parameter) { - // // TODO: Ignore DW_AT_artificial - // params.push_back(resolve_type(dbg, get_type_die(dbg, die))); - // } - // }); - // if(!has_type(dbg, die)) { - // return "void" + (build.empty() ? "" : "(" + build + ")") + "(" + join(params, ", ") + ")"; - // } else { - // // resolving return type, building on build - // return resolve_type( - // dbg, get_type_die(dbg, die), - // (build.empty() ? "" : "(" + build + ")") - // + "(" - // + join(params, ", ") - // + ")" - // ); - // } - // } - //case DW_TAG_array_type: - // return resolve_type(dbg, get_type_die(dbg, die), (build.empty() ? "" : "(" + build + ")") + "[" + "x" + "]"); - case DW_TAG_pointer_type: - case DW_TAG_reference_type: - case DW_TAG_rvalue_reference_type: - case DW_TAG_ptr_to_member_type: - { - const auto child = get_type_die(dbg, die); // AST child, rather than dwarf child - const auto child_tag = child.get_tag(); - switch(child_tag) { - case DW_TAG_subroutine_type: - if(!has_type(dbg, child)) { - return "void(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_parameters(dbg, child); - } else { - return resolve_type( - dbg, - get_type_die(dbg, child), - "(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_parameters(dbg, child) - ); - } - case DW_TAG_array_type: - return resolve_type( - dbg, - get_type_die(dbg, child), - "(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_array_extents(dbg, child) - ); - default: - if(build.empty()) { - return resolve_type(dbg, get_type_die(dbg, die), tag_to_ptr_ref(tag)); - } else { - return resolve_type( - dbg, - get_type_die(dbg, die), - std::string(tag_to_ptr_ref(tag)) + " " + build - ); - } - } - } - case DW_TAG_const_type: - case DW_TAG_atomic_type: - case DW_TAG_volatile_type: - case DW_TAG_restrict_type: - { - const auto child = get_type_die(dbg, die); // AST child, rather than dwarf child - const auto child_tag = child.get_tag(); - switch(child_tag) { - case DW_TAG_base_type: - case DW_TAG_class_type: - case DW_TAG_typedef: - return std::string(tag_to_keyword(tag)) - + " " - + resolve_type(dbg, get_type_die(dbg, die), build); - default: - return resolve_type( - dbg, - get_type_die(dbg, die), - std::string(tag_to_keyword(tag)) + " " + build - ); - } - } - default: - { - fprintf(stderr, "unknown tag %s\n", die.get_tag_name()); - exit(1); - } - } - return {"", ""}; - }*/ - bool is_mangled_name(const std::string& name) { return name.find("_Z") || name.find("?h@@"); } @@ -1083,6 +843,248 @@ namespace libdwarf { } return trace; } + + // Currently commented out. Need to decide if this is worth it. The mangled name is easier and maybe more + // trustworthy. This is a lot of effort for something that would only be relevant for extern "C" methods. + /*die_object get_type_die(Dwarf_Debug dbg, const die_object& die) { + Dwarf_Off type_offset; + Dwarf_Bool is_info; + int ret = dwarf_dietype_offset(die.get(), &type_offset, &is_info, nullptr); + if(ret == DW_DLV_OK) { + Dwarf_Die type_die; + ret = dwarf_offdie_b( + dbg, + type_offset, + is_info, + &type_die, + nullptr + ); + if(ret == DW_DLV_OK) { + return die_object(dbg, type_die); + } else { + fprintf(stderr, "Error\n"); + exit(1); + } + } else { + fprintf(stderr, "no type offset??\n"); + } + return die_object(dbg, nullptr); + } + + bool has_type(Dwarf_Debug dbg, const die_object& die) { + Dwarf_Attribute attr; + int ret = dwarf_attr(die.get(), DW_AT_type, &attr, nullptr); + if(ret == DW_DLV_NO_ENTRY) { + return false; + } else if(ret == DW_DLV_OK) { + dwarf_dealloc_attribute(attr); + return true; + } else { + fprintf(stderr, "Error\n"); + exit(1); + } + } + + struct type_result { + std::string base; + std::string extent; + + std::string get_type() { + return base + extent; + } + }; + + // TODO: ::*, namespace lookup, arrays + // DW_TAG_namespace + const char* tag_to_keyword(Dwarf_Half tag) { + switch(tag) { + case DW_TAG_atomic_type: + return "_Atomic"; + case DW_TAG_const_type: + return "const"; + case DW_TAG_volatile_type: + return "volatile"; + case DW_TAG_restrict_type: + return "restrict"; + default: + { + const char* tag_name = nullptr; + dwarf_get_TAG_name(tag, &tag_name); + fprintf(stderr, "tag_to_keyword unknown tag %s\n", tag_name); + exit(1); + } + } + } + const char* tag_to_ptr_ref(Dwarf_Half tag) { + switch(tag) { + case DW_TAG_pointer_type: + return "*"; + case DW_TAG_ptr_to_member_type: + return "::*"; // TODO + case DW_TAG_reference_type: + return "&"; + case DW_TAG_rvalue_reference_type: + return "&&"; + default: + { + const char* tag_name = nullptr; + dwarf_get_TAG_name(tag, &tag_name); + fprintf(stderr, "tag_to_ptr_ref unknown tag %s\n", tag_name); + exit(1); + } + } + } + + std::string resolve_type(Dwarf_Debug dbg, const die_object& die, std::string build = ""); + + std::string get_array_extents(Dwarf_Debug dbg, const die_object& die) { + CPPTRACE_VERIFY(die.get_tag() == DW_TAG_array_type); + std::string extents = ""; + walk_die_list(dbg, die.get_child(), [&extents](Dwarf_Debug dbg, const die_object& subrange) { + if(subrange.get_tag() == DW_TAG_subrange_type) { + Dwarf_Attribute attr = 0; + int res = 0; + res = dwarf_attr(subrange.get(), DW_AT_upper_bound, &attr, nullptr); + if(res != DW_DLV_OK) { + fprintf(stderr, "Error\n"); + return; + } + Dwarf_Half form; + res = dwarf_whatform(attr, &form, nullptr); + if(res != DW_DLV_OK) { + fprintf(stderr, "Error\n"); + return; + } + //fprintf(stderr, "form: %d\n", form); + Dwarf_Unsigned val; + res = dwarf_formudata(attr, &val, nullptr); + if(res != DW_DLV_OK) { + fprintf(stderr, "Error\n"); + return; + } + extents += "[" + std::to_string(val + 1) + "]"; + dwarf_dealloc_attribute(attr); + } else { + fprintf(stderr, "unknown tag %s\n", subrange.get_tag_name()); + } + }); + return extents; + } + + std::string get_parameters(Dwarf_Debug dbg, const die_object& die) { + CPPTRACE_VERIFY(die.get_tag() == DW_TAG_subroutine_type); + std::vector params; + walk_die_list(dbg, die.get_child(), [¶ms](Dwarf_Debug dbg, const die_object& die) { + if(die.get_tag() == DW_TAG_formal_parameter) { + // TODO: Ignore DW_AT_artificial + params.push_back(resolve_type(dbg, get_type_die(dbg, die))); + } + }); + return "(" + join(params, ", ") + ")"; + } + + std::string resolve_type(Dwarf_Debug dbg, const die_object& die, std::string build) { + switch(auto tag = die.get_tag()) { + case DW_TAG_base_type: + case DW_TAG_class_type: + case DW_TAG_structure_type: + case DW_TAG_union_type: + case DW_TAG_enumeration_type: + return die.get_name() + build; + case DW_TAG_typedef: + return resolve_type(dbg, get_type_die(dbg, die)); + //case DW_TAG_subroutine_type: + // { + // // If there's no DW_AT_type then it's a void + // std::vector params; + // // TODO: Code duplication with retrieve_symbol_for_subprogram? + // walk_die_list(dbg, die.get_child(), [¶ms] (Dwarf_Debug dbg, const die_object& die) { + // if(die.get_tag() == DW_TAG_formal_parameter) { + // // TODO: Ignore DW_AT_artificial + // params.push_back(resolve_type(dbg, get_type_die(dbg, die))); + // } + // }); + // if(!has_type(dbg, die)) { + // return "void" + (build.empty() ? "" : "(" + build + ")") + "(" + join(params, ", ") + ")"; + // } else { + // // resolving return type, building on build + // return resolve_type( + // dbg, get_type_die(dbg, die), + // (build.empty() ? "" : "(" + build + ")") + // + "(" + // + join(params, ", ") + // + ")" + // ); + // } + // } + //case DW_TAG_array_type: + // return resolve_type(dbg, get_type_die(dbg, die), (build.empty() ? "" : "(" + build + ")") + "[" + "x" + "]"); + case DW_TAG_pointer_type: + case DW_TAG_reference_type: + case DW_TAG_rvalue_reference_type: + case DW_TAG_ptr_to_member_type: + { + const auto child = get_type_die(dbg, die); // AST child, rather than dwarf child + const auto child_tag = child.get_tag(); + switch(child_tag) { + case DW_TAG_subroutine_type: + if(!has_type(dbg, child)) { + return "void(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_parameters(dbg, child); + } else { + return resolve_type( + dbg, + get_type_die(dbg, child), + "(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_parameters(dbg, child) + ); + } + case DW_TAG_array_type: + return resolve_type( + dbg, + get_type_die(dbg, child), + "(" + std::string(tag_to_ptr_ref(tag)) + build + ")" + get_array_extents(dbg, child) + ); + default: + if(build.empty()) { + return resolve_type(dbg, get_type_die(dbg, die), tag_to_ptr_ref(tag)); + } else { + return resolve_type( + dbg, + get_type_die(dbg, die), + std::string(tag_to_ptr_ref(tag)) + " " + build + ); + } + } + } + case DW_TAG_const_type: + case DW_TAG_atomic_type: + case DW_TAG_volatile_type: + case DW_TAG_restrict_type: + { + const auto child = get_type_die(dbg, die); // AST child, rather than dwarf child + const auto child_tag = child.get_tag(); + switch(child_tag) { + case DW_TAG_base_type: + case DW_TAG_class_type: + case DW_TAG_typedef: + return std::string(tag_to_keyword(tag)) + + " " + + resolve_type(dbg, get_type_die(dbg, die), build); + default: + return resolve_type( + dbg, + get_type_die(dbg, die), + std::string(tag_to_keyword(tag)) + " " + build + ); + } + } + default: + { + fprintf(stderr, "unknown tag %s\n", die.get_tag_name()); + exit(1); + } + } + return {"", ""}; + }*/ } } }