summaryrefslogtreecommitdiffstats
path: root/dwarf_wrappers.cxx
diff options
context:
space:
mode:
authorJosh Stone <jistone@redhat.com>2009-08-19 16:48:53 -0700
committerJosh Stone <jistone@redhat.com>2009-08-19 16:48:53 -0700
commitf1c8f8a5c96229eee5d06e2eaccecfa7d714fbc9 (patch)
tree5ae11a198b05204453f66b515382c5d013a7bbf7 /dwarf_wrappers.cxx
parent966940426dbd5c44d7f25b0f2bd6b28cf829c384 (diff)
downloadsystemtap-steved-f1c8f8a5c96229eee5d06e2eaccecfa7d714fbc9.tar.gz
systemtap-steved-f1c8f8a5c96229eee5d06e2eaccecfa7d714fbc9.tar.xz
systemtap-steved-f1c8f8a5c96229eee5d06e2eaccecfa7d714fbc9.zip
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.
Diffstat (limited to 'dwarf_wrappers.cxx')
-rw-r--r--dwarf_wrappers.cxx89
1 files changed, 88 insertions, 1 deletions
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 <cstring>
+#include <sstream>
#include <string>
#include <elfutils/libdwfl.h>
#include <dwarf.h>
-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() : "<unknown>";
+}
+
+
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */