summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dwarf_wrappers.cxx42
-rw-r--r--dwarf_wrappers.h15
-rw-r--r--dwflpp.cxx12
3 files changed, 63 insertions, 6 deletions
diff --git a/dwarf_wrappers.cxx b/dwarf_wrappers.cxx
index 03979ca2..0cb3cc0f 100644
--- a/dwarf_wrappers.cxx
+++ b/dwarf_wrappers.cxx
@@ -47,4 +47,46 @@ void dwfl_assert(const std::string& desc, bool condition)
}
+#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)
+{
+ Dwarf_Attribute 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 9233fc1d..54ab8fd4 100644
--- a/dwarf_wrappers.h
+++ b/dwarf_wrappers.h
@@ -103,6 +103,21 @@ public:
};
+#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
/* 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 e436a9ca..c31fbe4e 100644
--- a/dwflpp.cxx
+++ b/dwflpp.cxx
@@ -978,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)
{
@@ -993,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++)
{
@@ -1009,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);
}
}