diff options
author | Josh Stone <jistone@redhat.com> | 2009-03-18 19:04:54 -0700 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2009-03-18 19:21:19 -0700 |
commit | 219e62c7eeca850d2898fdbfb6b74719195274a6 (patch) | |
tree | 8cc311618e5a2f58bfd4c5345b8c750ea9ca8030 | |
parent | 8df306c4443bd9dd1397bab6cba7f61cb2d88af9 (diff) | |
download | systemtap-steved-219e62c7eeca850d2898fdbfb6b74719195274a6.tar.gz systemtap-steved-219e62c7eeca850d2898fdbfb6b74719195274a6.tar.xz systemtap-steved-219e62c7eeca850d2898fdbfb6b74719195274a6.zip |
PR9959: improve tracepoint arg type-naming
dwarf_type_name now works with more argument types. There were
three cases that I needed to improve:
- For "const struct foo*", the debuginfo has a const-DIE named "foo"
chained to a struct-DIE named "foo", so we can't assume that seeing a
name means we're down to the base type. The recursion now decends
until it explicitly sees a base_type, typedef, struct, or union.
- For "void*", the debuginfo has a pointer-DIE without any DW_AT_type
after. Now I'm just catching that failed lookup and writing in
"void".
- For "va_list", the debuginfo actually resolves to an internal type
"struct __va_list_tag*", but that struct has no declaration at the
source level. I'm just hacking that exact case to say "va_list"
instead, but it would be nice to find something cleaner...
We'll probably still have problems if any tracepoint uses a function-
pointer argument, but so far I've only seen that as a "void*", which we
now handle ok.
-rw-r--r-- | tapsets.cxx | 40 |
1 files changed, 26 insertions, 14 deletions
diff --git a/tapsets.cxx b/tapsets.cxx index 2548625b..a4da7811 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -9586,32 +9586,39 @@ tracepoint_derived_probe::tracepoint_derived_probe (systemtap_session& s, static bool dwarf_type_name(Dwarf_Die& type_die, string& c_type) { - // if this die has a direct name, then we're done - const char *diename = dwarf_diename_integrate(&type_die); - if (diename != NULL) + // if we've gotten down to a basic type, then we're done + bool done = true; + switch (dwarf_tag(&type_die)) { - 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; - } - c_type.append(diename); + 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) + { + c_type.append(dwarf_diename_integrate(&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)) - return false; + c_type = "void"; const char *suffix = NULL; switch (dwarf_tag(&type_die)) @@ -9632,6 +9639,11 @@ dwarf_type_name(Dwarf_Die& type_die, string& c_type) 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; } |