summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwarf_wrappers.cxx89
-rw-r--r--dwarf_wrappers.h5
-rw-r--r--dwflpp.cxx75
-rw-r--r--tapsets.cxx79
4 files changed, 124 insertions, 124 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 : */
diff --git a/dwarf_wrappers.h b/dwarf_wrappers.h
index 54ab8fd4..bc1cde2b 100644
--- a/dwarf_wrappers.h
+++ b/dwarf_wrappers.h
@@ -118,6 +118,11 @@ int dwarf_decl_line_integrate (Dwarf_Die *die, int *linep)
#endif // !_ELFUTILS_PREREQ(0, 143)
+// Resolve a full name for dwarf types
+bool dwarf_type_name(Dwarf_Die *type_die, std::string& type_name);
+std::string dwarf_type_name(Dwarf_Die *type_die);
+
+
#endif
/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
diff --git a/dwflpp.cxx b/dwflpp.cxx
index b5663fff..192973f2 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -1555,7 +1555,7 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o)
if (typetag != DW_TAG_structure_type && typetag != DW_TAG_union_type)
{
o << " Error: "
- << (dwarf_diename (vardie) ?: "<anonymous>")
+ << dwarf_type_name(vardie)
<< " isn't a struct/union";
return;
}
@@ -1566,15 +1566,13 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o)
switch (dwarf_child (vardie, die))
{
case 1: // No children.
- o << ((typetag == DW_TAG_union_type) ? " union " : " struct ")
- << (dwarf_diename (die) ?: "<anonymous>")
+ o << dwarf_type_name(vardie)
<< " is empty";
break;
case -1: // Error.
default: // Shouldn't happen.
- o << ((typetag == DW_TAG_union_type) ? " union " : " struct ")
- << (dwarf_diename (die) ?: "<anonymous>")
+ o << dwarf_type_name(vardie)
<< ": " << dwarf_errmsg (-1);
break;
@@ -1591,20 +1589,17 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o)
o << " " << member;
else
{
- Dwarf_Die temp_die = *die;
- Dwarf_Attribute temp_attr ;
+ Dwarf_Die temp_die;
+ Dwarf_Attribute temp_attr;
- if (!dwarf_attr_integrate (&temp_die, DW_AT_type, &temp_attr))
+ if (!dwarf_attr_integrate (die, DW_AT_type, &temp_attr) ||
+ !dwarf_formref_die (&temp_attr, &temp_die))
{
- clog << "\n Error in obtaining type attribute for "
- << (dwarf_diename(&temp_die)?:"<anonymous>");
- return;
- }
-
- if (!dwarf_formref_die (&temp_attr, &temp_die))
- {
- clog << "\n Error in decoding type attribute for "
- << (dwarf_diename(&temp_die)?:"<anonymous>");
+ string source = dwarf_decl_file(die) ?: "<unknown source>";
+ int line = -1;
+ dwarf_decl_line(die, &line);
+ clog << "\n Error in obtaining type attribute for anonymous member at "
+ << source << ":" << line;
return;
}
@@ -1634,8 +1629,7 @@ dwflpp::find_struct_member(const target_symbol::component& c,
return false;
case -1: /* Error. */
default: /* Shouldn't happen */
- throw semantic_error (string (dwarf_tag(parentdie) == DW_TAG_union_type ? "union" : "struct")
- + string (dwarf_diename (parentdie) ?: "<anonymous>")
+ throw semantic_error (dwarf_type_name(parentdie) + ": "
+ string (dwarf_errmsg (-1)),
c.tok);
}
@@ -1760,15 +1754,14 @@ dwflpp::translate_components(struct obstack *pool,
if (c.type != target_symbol::comp_struct_member)
throw semantic_error ("invalid access '"
+ lex_cast<string>(c)
- + "' for struct/union type",
+ + "' for " + dwarf_type_name(die),
c.tok);
if (dwarf_hasattr(die, DW_AT_declaration))
{
Dwarf_Die *tmpdie = dwflpp::declaration_resolve(dwarf_diename(die));
if (tmpdie == NULL)
- throw semantic_error ("unresolved struct "
- + string (dwarf_diename (die) ?: "<anonymous>"),
+ throw semantic_error ("unresolved " + dwarf_type_name(die),
c.tok);
*die_mem = *tmpdie;
}
@@ -1784,8 +1777,8 @@ dwflpp::translate_components(struct obstack *pool,
if (members.str().size() != 0)
alternatives = " (alternatives:" + members.str();
throw semantic_error("unable to find member '" +
- c.member + "' for struct "
- + string(dwarf_diename(&parentdie) ?: "<unknown>")
+ c.member + "' for "
+ + dwarf_type_name(&parentdie)
+ alternatives,
c.tok);
}
@@ -1798,27 +1791,20 @@ dwflpp::translate_components(struct obstack *pool,
break;
case DW_TAG_enumeration_type:
- throw semantic_error ("invalid access '"
- + lex_cast<string>(c)
- + "' vs. enum type "
- + string(dwarf_diename (die) ?: "<anonymous type>"),
- c.tok);
- break;
case DW_TAG_base_type:
throw semantic_error ("invalid access '"
+ lex_cast<string>(c)
- + "' vs. base type "
- + string(dwarf_diename (die) ?: "<anonymous type>"),
+ + "' vs. " + dwarf_type_name(die),
c.tok);
break;
+
case -1:
throw semantic_error ("cannot find type: " + string(dwarf_errmsg (-1)),
c.tok);
break;
default:
- throw semantic_error (string(dwarf_diename (die) ?: "<anonymous type>")
- + ": unexpected type tag "
+ throw semantic_error (dwarf_type_name(die) + ": unexpected type tag "
+ lex_cast<string>(dwarf_tag (die)),
c.tok);
break;
@@ -1881,8 +1867,6 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool,
Dwarf_Die typedie_mem;
Dwarf_Die *typedie;
int typetag;
- char const *dname;
- string diestr;
typedie = resolve_unqualified_inner_typedie (&typedie_mem, attr_mem, e);
typetag = dwarf_tag (typedie);
@@ -1908,19 +1892,15 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool,
switch (typetag)
{
default:
- dname = dwarf_diename(die);
- diestr = (dname != NULL) ? dname : "<unknown>";
throw semantic_error ("unsupported type tag "
+ lex_cast<string>(typetag)
- + " for " + diestr, e->tok);
+ + " for " + dwarf_type_name(die), e->tok);
break;
case DW_TAG_structure_type:
case DW_TAG_union_type:
- dname = dwarf_diename(die);
- diestr = (dname != NULL) ? dname : "<unknown>";
- throw semantic_error ("struct/union '" + diestr
- + "' is being accessed instead of a member of the struct/union", e->tok);
+ throw semantic_error ("'" + dwarf_type_name(die)
+ + "' is being accessed instead of a member", e->tok);
break;
case DW_TAG_enumeration_type:
@@ -1928,9 +1908,6 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool,
// Reject types we can't handle in systemtap
{
- dname = dwarf_diename(die);
- diestr = (dname != NULL) ? dname : "<unknown>";
-
Dwarf_Attribute encoding_attr;
Dwarf_Word encoding = (Dwarf_Word) -1;
dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding, &encoding_attr),
@@ -1939,7 +1916,7 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool,
{
// clog << "bad type1 " << encoding << " diestr" << endl;
throw semantic_error ("unsupported type (mystery encoding " + lex_cast<string>(encoding) + ")" +
- " for " + diestr, e->tok);
+ " for " + dwarf_type_name(die), e->tok);
}
if (encoding == DW_ATE_float
@@ -1948,7 +1925,7 @@ dwflpp::translate_final_fetch_or_store (struct obstack *pool,
{
// clog << "bad type " << encoding << " diestr" << endl;
throw semantic_error ("unsupported type (encoding " + lex_cast<string>(encoding) + ")" +
- " for " + diestr, e->tok);
+ " for " + dwarf_type_name(die), e->tok);
}
}
@@ -2201,7 +2178,7 @@ dwflpp::literal_stmt_for_pointer (Dwarf_Die *type_die,
{
if (sess.verbose>2)
clog << "literal_stmt_for_pointer: finding value for "
- << (dwarf_diename(type_die) ?: "<unknown>")
+ << dwarf_type_name(type_die)
<< "("
<< (dwarf_diename(cu) ?: "<unknown>")
<< ")\n";
diff --git a/tapsets.cxx b/tapsets.cxx
index aee01835..0e46962d 100644
--- a/tapsets.cxx
+++ b/tapsets.cxx
@@ -2770,8 +2770,6 @@ dwarf_derived_probe::dwarf_derived_probe(const string& funcname,
}
-static bool dwarf_type_name(Dwarf_Die& type_die, string& c_type);
-
void
dwarf_derived_probe::saveargs(Dwarf_Die* scope_die)
{
@@ -2788,7 +2786,7 @@ dwarf_derived_probe::saveargs(Dwarf_Die* scope_die)
if (has_return &&
dwarf_attr_integrate (scope_die, DW_AT_type, &type_attr) &&
dwarf_formref_die (&type_attr, &type_die) &&
- dwarf_type_name(type_die, type_name))
+ dwarf_type_name(&type_die, type_name))
argstream << " $return:" << type_name;
Dwarf_Die arg;
@@ -2812,7 +2810,7 @@ dwarf_derived_probe::saveargs(Dwarf_Die* scope_die)
type_name.clear();
if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr) ||
!dwarf_formref_die (&type_attr, &type_die) ||
- !dwarf_type_name(type_die, type_name))
+ !dwarf_type_name(&type_die, type_name))
continue;
argstream << " $" << arg_name << ":" << type_name;
@@ -4294,7 +4292,7 @@ uprobe_derived_probe::saveargs(Dwarf_Die* scope_die)
if (return_p &&
dwarf_attr_integrate (scope_die, DW_AT_type, &type_attr) &&
dwarf_formref_die (&type_attr, &type_die) &&
- dwarf_type_name(type_die, type_name))
+ dwarf_type_name(&type_die, type_name))
argstream << " $return:" << type_name;
Dwarf_Die arg;
@@ -4318,7 +4316,7 @@ uprobe_derived_probe::saveargs(Dwarf_Die* scope_die)
type_name.clear();
if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr) ||
!dwarf_formref_die (&type_attr, &type_die) ||
- !dwarf_type_name(type_die, type_name))
+ !dwarf_type_name(&type_die, type_name))
continue;
argstream << " $" << arg_name << ":" << type_name;
@@ -5583,73 +5581,6 @@ tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s,
static bool
-dwarf_type_name(Dwarf_Die& type_die, string& c_type)
-{
- // if we've gotten down to a basic type, then we're done
- bool done = true;
- switch (dwarf_tag(&type_die))
- {
- case DW_TAG_structure_type:
- c_type.append("struct ");
- break;
- case DW_TAG_union_type:
- c_type.append("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 {...}".
- c_type.append(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, c_type))
- c_type = "void";
-
- const char *suffix = NULL;
- switch (dwarf_tag(&type_die))
- {
- case DW_TAG_pointer_type:
- suffix = "*";
- break;
- case DW_TAG_array_type:
- suffix = "[]";
- break;
- case DW_TAG_const_type:
- suffix = " const";
- break;
- case DW_TAG_volatile_type:
- suffix = " volatile";
- break;
- default:
- return false;
- }
- c_type.append(suffix);
-
- // XXX HACK! The va_list isn't usable as found in the debuginfo...
- if (c_type == "struct __va_list_tag*")
- c_type = "va_list";
-
- return true;
-}
-
-
-static bool
resolve_tracepoint_arg_type(tracepoint_arg& arg)
{
Dwarf_Attribute type_attr;
@@ -5704,7 +5635,7 @@ tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die)
Dwarf_Attribute type_attr;
if (!dwarf_attr_integrate (&arg, DW_AT_type, &type_attr)
|| !dwarf_formref_die (&type_attr, &tparg.type_die)
- || !dwarf_type_name(tparg.type_die, tparg.c_type))
+ || !dwarf_type_name(&tparg.type_die, tparg.c_type))
throw semantic_error ("cannot get type of tracepoint '"
+ tracepoint_name + "' parameter '"
+ tparg.name + "'");