summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwarf_wrappers.cxx39
-rw-r--r--dwarf_wrappers.h28
-rw-r--r--dwflpp.cxx41
-rw-r--r--dwflpp.h15
-rw-r--r--loc2c-test.c29
-rw-r--r--tapsets.cxx4
-rw-r--r--translate.cxx14
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
diff --git a/dwflpp.cxx b/dwflpp.cxx
index ff62265f..c31fbe4e 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -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;
diff --git a/dwflpp.h b/dwflpp.h
index f6305bcf..b376d004 100644
--- a/dwflpp.h
+++ b/dwflpp.h
@@ -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;