From f1c8f8a5c96229eee5d06e2eaccecfa7d714fbc9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 19 Aug 2009 16:48:53 -0700 Subject: Use dwarf_type_name in more places * dwarf_wrappers.cxx (dwarf_type_name): Moved here from tapsets.cxx, and added a variant that returns a string for easier ostreaming. * dwflpp.cxx (dwflpp::print_members): Use dwarf_type_name for errors. (dwflpp::find_struct_member): Ditto. (dwflpp::translate_components): Ditto. (dwflpp::translate_final_fetch_or_store): Ditto. (dwflpp::literal_stmt_for_pointer): Ditto. * tapsets.cxx (dwarf_derived_probe::saveargs): Pass die to dwarf_type_name by pointer instead of reference. (uprobe_derived_probe::saveargs): Ditto. (resolve_tracepoint_arg_type): Ditto. --- dwarf_wrappers.cxx | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) (limited to 'dwarf_wrappers.cxx') diff --git a/dwarf_wrappers.cxx b/dwarf_wrappers.cxx index 0cb3cc0f..fe8ead07 100644 --- a/dwarf_wrappers.cxx +++ b/dwarf_wrappers.cxx @@ -10,11 +10,12 @@ #include "staptree.h" #include +#include #include #include #include -using std::string; +using namespace std; void dwfl_assert(const string& desc, int rc) { @@ -89,4 +90,90 @@ dwarf_decl_line_integrate (Dwarf_Die *die, int *linep) #endif // !_ELFUTILS_PREREQ(0, 143) +static bool +dwarf_type_name(Dwarf_Die *type_die, ostringstream& o) +{ + // if we've gotten down to a basic type, then we're done + bool done = true; + switch (dwarf_tag(type_die)) + { + case DW_TAG_enumeration_type: + o << "enum "; + break; + case DW_TAG_structure_type: + o << "struct "; + break; + case DW_TAG_union_type: + o << "union "; + break; + case DW_TAG_typedef: + case DW_TAG_base_type: + break; + default: + done = false; + break; + } + if (done) + { + // this follows gdb precedent that anonymous structs/unions + // are displayed as "struct {...}" and "union {...}". + o << (dwarf_diename(type_die) ?: "{...}"); + return true; + } + + // otherwise, this die is a type modifier. + + // recurse into the referent type + // if it can't be named, just call it "void" + Dwarf_Attribute subtype_attr; + Dwarf_Die subtype_die; + if (!dwarf_attr_integrate(type_die, DW_AT_type, &subtype_attr) + || !dwarf_formref_die(&subtype_attr, &subtype_die) + || !dwarf_type_name(&subtype_die, o)) + o.str("void"), o.seekp(4); + + switch (dwarf_tag(type_die)) + { + case DW_TAG_pointer_type: + o << "*"; + break; + case DW_TAG_array_type: + o << "[]"; + break; + case DW_TAG_const_type: + o << " const"; + break; + case DW_TAG_volatile_type: + o << " volatile"; + break; + default: + return false; + } + + // XXX HACK! The va_list isn't usable as found in the debuginfo... + if (o.str() == "struct __va_list_tag*") + o.str("va_list"), o.seekp(7); + + return true; +} + + +bool +dwarf_type_name(Dwarf_Die *type_die, string& type_name) +{ + ostringstream o; + bool ret = dwarf_type_name(type_die, o); + type_name = o.str(); + return ret; +} + + +string +dwarf_type_name(Dwarf_Die *type_die) +{ + ostringstream o; + return dwarf_type_name(type_die, o) ? o.str() : ""; +} + + /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */ -- cgit