diff options
-rw-r--r-- | dwarf_wrappers.cxx | 39 | ||||
-rw-r--r-- | dwarf_wrappers.h | 28 | ||||
-rw-r--r-- | dwflpp.cxx | 41 | ||||
-rw-r--r-- | dwflpp.h | 15 | ||||
-rw-r--r-- | loc2c-test.c | 29 | ||||
-rw-r--r-- | tapsets.cxx | 4 | ||||
-rw-r--r-- | translate.cxx | 14 |
7 files changed, 101 insertions, 69 deletions
diff --git a/dwarf_wrappers.cxx b/dwarf_wrappers.cxx index d7183dc3..0cb3cc0f 100644 --- a/dwarf_wrappers.cxx +++ b/dwarf_wrappers.cxx @@ -47,15 +47,46 @@ void dwfl_assert(const std::string& desc, bool condition) } -// Helper for dealing with selected portions of libdwfl in a more readable -// fashion, and with specific cleanup / checking / logging options. +#if !_ELFUTILS_PREREQ(0, 143) +// Elfutils prior to 0.143 didn't use attr_integrate when looking up the +// decl_file or decl_line, so the attributes would sometimes be missed. For +// those old versions, we define custom implementations to do the integration. const char * -dwarf_diename_integrate (Dwarf_Die *die) +dwarf_decl_file_integrate (Dwarf_Die *die) { Dwarf_Attribute attr_mem; - return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem)); + Dwarf_Sword idx = 0; + if (dwarf_formsdata (dwarf_attr_integrate (die, DW_AT_decl_file, &attr_mem), + &idx) != 0 + || idx == 0) + return NULL; + + Dwarf_Die cudie; + Dwarf_Files *files = NULL; + if (dwarf_getsrcfiles (dwarf_diecu (die, &cudie, NULL, NULL), + &files, NULL) != 0) + return NULL; + + return dwarf_filesrc(files, idx, NULL, NULL); } +int +dwarf_decl_line_integrate (Dwarf_Die *die, int *linep) +{ + Dwarf_Attribute attr_mem; + Dwarf_Sword line; + + int res = dwarf_formsdata (dwarf_attr_integrate + (die, DW_AT_decl_line, &attr_mem), + &line); + if (res == 0) + *linep = line; + + return res; +} + +#endif // !_ELFUTILS_PREREQ(0, 143) + /* 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 1442a17c..54ab8fd4 100644 --- a/dwarf_wrappers.h +++ b/dwarf_wrappers.h @@ -8,10 +8,23 @@ #ifndef DWARF_WRAPPERS_H #define DWARF_WRAPPERS_H 1 + +#include "config.h" + +extern "C" { #include <elfutils/libdw.h> +#ifdef HAVE_ELFUTILS_VERSION_H +#include <elfutils/version.h> +#endif +} #include <string> +#if !defined(_ELFUTILS_PREREQ) +// make a dummy PREREQ check for elfutils < 0.138 +#define _ELFUTILS_PREREQ(major, minor) (0 >= 1) +#endif + // NB: "rc == 0" means OK in this case void dwfl_assert(const std::string& desc, int rc); @@ -89,7 +102,20 @@ public: } }; -const char *dwarf_diename_integrate (Dwarf_Die *die); + +#if !_ELFUTILS_PREREQ(0, 143) +// Elfutils prior to 0.143 didn't use attr_integrate when looking up the +// decl_file or decl_line, so the attributes would sometimes be missed. For +// those old versions, we define custom implementations to do the integration. + +const char *dwarf_decl_file_integrate (Dwarf_Die *die); +#define dwarf_decl_file dwarf_decl_file_integrate + +int dwarf_decl_line_integrate (Dwarf_Die *die, int *linep) + __nonnull_attribute__ (2); +#define dwarf_decl_line dwarf_decl_line_integrate + +#endif // !_ELFUTILS_PREREQ(0, 143) #endif @@ -41,9 +41,6 @@ extern "C" { #include <fcntl.h> #include <elfutils/libdwfl.h> #include <elfutils/libdw.h> -#ifdef HAVE_ELFUTILS_VERSION_H -#include <elfutils/version.h> -#endif #include <dwarf.h> #include <elf.h> #include <obstack.h> @@ -981,11 +978,11 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die, && function_name_matches_pattern (name, sym))) { const char *file = dwarf_decl_file (&die); + // Get the line number for this label - Dwarf_Attribute attr; - dwarf_attr (&die,DW_AT_decl_line, &attr); - Dwarf_Sword dline; - dwarf_formsdata (&attr, &dline); + int dline; + dwarf_decl_line (&die, &dline); + Dwarf_Addr stmt_addr; if (dwarf_lowpc (&die, &stmt_addr) != 0) { @@ -996,7 +993,7 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die, size_t nlines = 0; // Get the line for this label Dwarf_Line **aline; - dwarf_getsrc_file (module_dwarf, file, (int)dline, 0, &aline, &nlines); + dwarf_getsrc_file (module_dwarf, file, dline, 0, &aline, &nlines); // Get the address for (size_t i = 0; i < nlines; i++) { @@ -1012,7 +1009,7 @@ dwflpp::iterate_over_labels (Dwarf_Die *begin_die, if (nscopes > 1) { callback(function_name.c_str(), file, - (int)dline, &scopes[1], stmt_addr, q); + dline, &scopes[1], stmt_addr, q); add_label_name(q, name); } } @@ -1561,7 +1558,7 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o) if (typetag != DW_TAG_structure_type && typetag != DW_TAG_union_type) { o << " Error: " - << (dwarf_diename_integrate (vardie) ?: "<anonymous>") + << (dwarf_diename (vardie) ?: "<anonymous>") << " isn't a struct/union"; return; } @@ -1573,14 +1570,14 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o) { case 1: // No children. o << ((typetag == DW_TAG_union_type) ? " union " : " struct ") - << (dwarf_diename_integrate (die) ?: "<anonymous>") + << (dwarf_diename (die) ?: "<anonymous>") << " is empty"; break; case -1: // Error. default: // Shouldn't happen. o << ((typetag == DW_TAG_union_type) ? " union " : " struct ") - << (dwarf_diename_integrate (die) ?: "<anonymous>") + << (dwarf_diename (die) ?: "<anonymous>") << ": " << dwarf_errmsg (-1); break; @@ -1591,7 +1588,7 @@ dwflpp::print_members(Dwarf_Die *vardie, ostream &o) // Output each sibling's name to 'o'. while (dwarf_tag (die) == DW_TAG_member) { - const char *member = dwarf_diename_integrate (die) ; + const char *member = dwarf_diename (die) ; if ( member != NULL ) o << " " << member; @@ -1641,7 +1638,7 @@ dwflpp::find_struct_member(const target_symbol::component& c, case -1: /* Error. */ default: /* Shouldn't happen */ throw semantic_error (string (dwarf_tag(&die) == DW_TAG_union_type ? "union" : "struct") - + string (dwarf_diename_integrate (&die) ?: "<anonymous>") + + string (dwarf_diename (&die) ?: "<anonymous>") + string (dwarf_errmsg (-1)), c.tok); } @@ -1651,7 +1648,7 @@ dwflpp::find_struct_member(const target_symbol::component& c, if (dwarf_tag(&die) != DW_TAG_member) continue; - const char *name = dwarf_diename_integrate(&die); + const char *name = dwarf_diename(&die); if (name == NULL) { // need to recurse for anonymous structs/unions @@ -1774,7 +1771,7 @@ dwflpp::translate_components(struct obstack *pool, Dwarf_Die *tmpdie = dwflpp::declaration_resolve(dwarf_diename(die)); if (tmpdie == NULL) throw semantic_error ("unresolved struct " - + string (dwarf_diename_integrate (die) ?: "<anonymous>"), + + string (dwarf_diename (die) ?: "<anonymous>"), c.tok); *die_mem = *tmpdie; } @@ -1790,7 +1787,7 @@ dwflpp::translate_components(struct obstack *pool, alternatives = " (alternatives:" + members.str(); throw semantic_error("unable to find member '" + c.member + "' for struct " - + string(dwarf_diename_integrate(die) ?: "<unknown>") + + string(dwarf_diename(die) ?: "<unknown>") + alternatives, c.tok); } @@ -1806,14 +1803,14 @@ dwflpp::translate_components(struct obstack *pool, throw semantic_error ("invalid access '" + lex_cast<string>(c) + "' vs. enum type " - + string(dwarf_diename_integrate (die) ?: "<anonymous 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_integrate (die) ?: "<anonymous type>"), + + string(dwarf_diename (die) ?: "<anonymous type>"), c.tok); break; case -1: @@ -1822,7 +1819,7 @@ dwflpp::translate_components(struct obstack *pool, break; default: - throw semantic_error (string(dwarf_diename_integrate (die) ?: "<anonymous type>") + throw semantic_error (string(dwarf_diename (die) ?: "<anonymous type>") + ": unexpected type tag " + lex_cast<string>(dwarf_tag (die)), c.tok); @@ -2593,9 +2590,8 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) clog << "get_cfa_ops @0x" << hex << pc << dec << ", module_start @0x" << hex << module_start << dec << endl; -#ifdef _ELFUTILS_PREREQ #if _ELFUTILS_PREREQ(0,142) - // Try debug_frame first, then fall back on eh_frame. + // Try debug_frame first, then fall back on eh_frame. size_t cfa_nops; Dwarf_Addr bias; Dwarf_CFI *cfi = dwfl_module_dwarf_cfi (module, &bias); @@ -2630,7 +2626,6 @@ dwflpp::get_cfa_ops (Dwarf_Addr pc) } #endif -#endif if (sess.verbose > 2) clog << (cfa_ops == NULL ? "not " : " ") << "found cfa" << endl; @@ -25,19 +25,14 @@ extern "C" { #include <elfutils/libdwfl.h> -#ifdef HAVE_ELFUTILS_VERSION_H - #include <elfutils/version.h> - #if !_ELFUTILS_PREREQ(0,142) - // Always use newer name, old name is deprecated in 0.142. - #define elf_getshdrstrndx elf_getshstrndx - #endif -#else - // Really old elfutils version, definitely redefine to use old name. - #define elf_getshdrstrndx elf_getshstrndx -#endif #include <regex.h> } +#if !_ELFUTILS_PREREQ(0,142) +// Always use newer name, old name is deprecated in 0.142. +#define elf_getshdrstrndx elf_getshstrndx +#endif + struct func_info; struct inline_instance_info; diff --git a/loc2c-test.c b/loc2c-test.c index ccd9510c..3c260385 100644 --- a/loc2c-test.c +++ b/loc2c-test.c @@ -21,15 +21,12 @@ #include <stdarg.h> #include "loc2c.h" -#define _(msg) msg - -static const char * -dwarf_diename_integrate (Dwarf_Die *die) -{ - Dwarf_Attribute attr_mem; - return dwarf_formstring (dwarf_attr_integrate (die, DW_AT_name, &attr_mem)); -} +#if !defined(_ELFUTILS_PREREQ) +// make a dummy PREREQ check for elfutils < 0.138 +#define _ELFUTILS_PREREQ(major, minor) (0 >= 1) +#endif +#define _(msg) msg static void __attribute__ ((noreturn)) fail (void *arg __attribute__ ((unused)), const char *fmt, ...) @@ -187,13 +184,13 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, { case 1: /* No children. */ error (2, 0, _("empty struct %s"), - dwarf_diename_integrate (die) ?: "<anonymous>"); + dwarf_diename (die) ?: "<anonymous>"); break; case -1: /* Error. */ default: /* Shouldn't happen */ error (2, 0, _("%s %s: %s"), typetag == DW_TAG_union_type ? "union" : "struct", - dwarf_diename_integrate (die) ?: "<anonymous>", + dwarf_diename (die) ?: "<anonymous>", dwarf_errmsg (-1)); break; @@ -201,7 +198,7 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, break; } while (dwarf_tag (die) != DW_TAG_member - || ({ const char *member = dwarf_diename_integrate (die); + || ({ const char *member = dwarf_diename (die); member == NULL || strcmp (member, *fields); })) if (dwarf_siblingof (die, &die_mem) != 0) error (2, 0, _("field name %s not found"), *fields); @@ -230,11 +227,11 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, if (dwarf_formsdata (&attr_mem, &off) != 0) error (2, 0, _("Bad offset for %s %s: %s"), typetag == DW_TAG_union_type ? "union" : "struct", - dwarf_diename_integrate (die) ?: "<anonymous>", + dwarf_diename (die) ?: "<anonymous>", dwarf_errmsg (-1)); if (off != 0) c_translate_add_offset (&pool, 1, - dwarf_diename_integrate (die) + dwarf_diename (die) ?: "", off, &tail); break; @@ -252,7 +249,7 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, case DW_TAG_base_type: error (2, 0, _("field %s vs base type %s"), - *fields, dwarf_diename_integrate (die) ?: "<anonymous type>"); + *fields, dwarf_diename (die) ?: "<anonymous type>"); break; case -1: @@ -261,7 +258,7 @@ handle_variable (Dwarf_Die *scopes, int nscopes, int out, default: error (2, 0, _("%s: unexpected type tag %#x"), - dwarf_diename_integrate (die) ?: "<anonymous type>", + dwarf_diename (die) ?: "<anonymous type>", dwarf_tag (die)); break; } @@ -527,7 +524,6 @@ main (int argc, char **argv) { Dwarf_Op *cfa_ops = NULL; -#ifdef _ELFUTILS_PREREQ #if _ELFUTILS_PREREQ(0,142) size_t cfa_nops; Dwarf_Addr bias; @@ -554,7 +550,6 @@ main (int argc, char **argv) } } #endif -#endif handle_variable (scopes, n, out, cubias, &vardie, pc, cfa_ops, &argv[argi]); diff --git a/tapsets.cxx b/tapsets.cxx index f91d15d3..8d0e0ab2 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -5607,7 +5607,7 @@ dwarf_type_name(Dwarf_Die& type_die, string& c_type) } if (done) { - c_type.append(dwarf_diename_integrate(&type_die)); + c_type.append(dwarf_diename(&type_die)); return true; } @@ -5699,7 +5699,7 @@ tracepoint_derived_probe::build_args(dwflpp& dw, Dwarf_Die& func_die) { // build a tracepoint_arg for this parameter tracepoint_arg tparg; - tparg.name = dwarf_diename_integrate(&arg); + tparg.name = dwarf_diename(&arg); // read the type of this parameter Dwarf_Attribute type_attr; diff --git a/translate.cxx b/translate.cxx index 1ddc1778..b8e22e49 100644 --- a/translate.cxx +++ b/translate.cxx @@ -26,9 +26,6 @@ extern "C" { #include <elfutils/libdwfl.h> -#ifdef HAVE_ELFUTILS_VERSION_H -#include <elfutils/version.h> -#endif } using namespace std; @@ -4545,22 +4542,15 @@ dump_unwindsyms (Dwfl_Module *m, // Enable workaround for elfutils dwfl bug. // see https://bugzilla.redhat.com/show_bug.cgi?id=465872 // and http://sourceware.org/ml/systemtap/2008-q4/msg00579.html -#ifdef _ELFUTILS_PREREQ - #if _ELFUTILS_PREREQ(0,138) +#if _ELFUTILS_PREREQ(0,138) // Let's standardize to the buggy "end of build-id bits" behavior. build_id_vaddr += build_id_len; - #endif - #if !_ELFUTILS_PREREQ(0,141) - #define NEED_ELFUTILS_BUILDID_WORKAROUND - #endif -#else - #define NEED_ELFUTILS_BUILDID_WORKAROUND #endif // And check for another workaround needed. // see https://bugzilla.redhat.com/show_bug.cgi?id=489439 // and http://sourceware.org/ml/systemtap/2009-q1/msg00513.html -#ifdef NEED_ELFUTILS_BUILDID_WORKAROUND +#if !_ELFUTILS_PREREQ(0,141) if (build_id_vaddr < base && dwfl_module_relocations (m) == 1) { GElf_Addr main_bias; |