2009-01-28 Roland McGrath <roland@redhat.com>
+ * c++/dwarf: Add line table support.
+ * c++/values.cc: New file.
+ * c++/line_info.cc: New file.
+ * c++/subr.hh: New file.
+ * Makefile.am (pkginclude_HEADERS): Add it.
+
* libdwP.h (struct Dwarf_Line_s): Move out of struct Dwarf_Lines_s
defn so C++ doesn't scope the name to not match the Dwarf_Line typedef.
include_HEADERS = dwarf.h
pkginclude_HEADERS = libdw.h \
+ c++/subr.hh \
c++/dwarf c++/dwarf_edit
libdw_a_SOURCES = dwarf_begin.c dwarf_begin_elf.c dwarf_end.c dwarf_getelf.c \
#include "libdw.h"
#include "dwarf.h"
+#include "subr.hh"
#include <stdexcept>
-#include <iterator>
#include <cstring>
#include <iostream>
class location_attr;
class range_list;
class ranges;
+ class line_info_table;
+ class directory_table;
+ class file_table;
+ class line_table;
+ class line_entry;
class debug_info_entry
{
inline compile_unit (const debug_info_entry &die)
: debug_info_entry (die) {}
+ // Fetch the CU's DW_AT_stmt_list.
+ const line_info_table line_info () const;
+
+ // Convenience methods for line_info_table sub-containers.
+ inline const directory_table include_directories () const
+ {
+ return line_info ().include_directories ();
+ }
+ const file_table files () const
+ {
+ return line_info ().files ();
+ }
+ const line_table lines () const
+ {
+ return line_info ().lines ();
+ }
+
/*
containers/iterators:
class source_file
{
friend class attr_value;
+ friend class file_table;
+ friend class line_entry;
private:
::Dwarf_Attribute _m_attr;
inline ::Dwarf_Attribute *thisattr () const
return range_list (*this);
}
- // XXX lineptr
+ const line_info_table line_info () const;
+
// XXX macptr
template<typename value>
case VS_rangelistptr:
return ranges () == other.ranges ();
- case VS_lineptr: // XXX punt for now, treat as constant
+ case VS_lineptr:
+ return line_info () == other.line_info ();
+
case VS_macptr: // XXX punt for now, treat as constant
/*FALLTHRU*/
case VS_constant:
}
};
+ // This describes a CU's directory table, a simple array of strings.
+ class directory_table
+ {
+ private:
+ ::Dwarf_Files *_m_files;
+
+ template<typename string>
+ struct name_equal
+ : public std::binary_function<const char *, string, bool>
+ {
+ bool operator () (const char *me, const string &you)
+ {
+ return you == me;
+ }
+ };
+ template<typename table>
+ inline bool table_equal (const table &other) const
+ {
+ /* We ignore the first element, the compilation directory.
+ This is not encoded in the .debug_line table, but in
+ the DW_AT_comp_dir attribute of the referring CU.
+ The directory table itself matches regardless. */
+ const_iterator i = begin ();
+ typename table::const_iterator j = other.begin ();
+ return std::equal (++i, end (), ++j,
+ name_equal<typename table::value_type> ());
+ }
+
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef const char *value_type;
+
+ inline directory_table (::Dwarf_Files *const files)
+ : _m_files (files) {}
+ inline directory_table (const directory_table &t)
+ : _m_files (t._m_files) {}
+
+ typedef const char *const *const_iterator;
+
+ inline bool empty () const
+ {
+ return size () == 0;
+ }
+
+ size_t size () const;
+ const_iterator begin () const;
+ const_iterator end () const;
+
+ template<typename table>
+ inline bool operator== (const table &other) const
+ {
+ return table_equal (other);
+ }
+ template<typename table>
+ inline bool operator!= (const table &other) const
+ {
+ return !(*this == other);
+ }
+ // Short-circuit for comparing to self.
+ inline bool operator== (const directory_table &other) const
+ {
+ return _m_files == other._m_files || table_equal (other);
+ }
+ };
+
+ /* This describes a CU's file table. It works like a read-only
+ std::vector<source_file>, and also supports lookup by name. */
+ class file_table
+ {
+ private:
+ ::Dwarf_Files *_m_files;
+
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef source_file value_type;
+
+ inline file_table (::Dwarf_Files *const files)
+ : _m_files (files) {}
+ inline file_table (const file_table &t)
+ : _m_files (t._m_files) {}
+
+ inline file_table &operator= (const file_table &t)
+ {
+ _m_files = t._m_files;
+ return *this;
+ }
+
+ typedef subr::indexed_iterator<file_table> const_iterator;
+
+ inline bool empty () const
+ {
+ return size () == 0;
+ }
+
+ size_t size () const;
+
+ inline const_iterator begin () const
+ {
+ return const_iterator (*this, 0);
+ }
+ inline const_iterator end () const
+ {
+ return const_iterator (*this, size ());
+ }
+
+ const source_file at (size_t idx) const;
+ const source_file operator[] (size_t idx) const
+ {
+ return at (idx);
+ }
+
+ // Look up by matching file name.
+ const_iterator find (const source_file &) const;
+ const_iterator find (const char *filename) const
+ {
+ const_iterator i = begin ();
+ while (i != end () && strcmp ((*i).name (), filename) != 0)
+ ++i;
+ return i;
+ }
+ template<typename string>
+ const_iterator find (const string &filename) const
+ {
+ const_iterator i = begin ();
+ while (i != end () && filename != (*i).name ())
+ ++i;
+ return i;
+ }
+ };
+
+ class line_entry
+ {
+ private:
+ ::Dwarf_Line *_m_line;
+
+ public:
+ line_entry (::Dwarf_Line *entry) : _m_line (entry) {}
+ line_entry (const line_entry &entry) : _m_line (entry._m_line) {}
+
+ // XXX reloc, dwfl
+ ::Dwarf_Addr address () const;
+
+ bool statement () const;
+ bool basic_block () const;
+ bool end_sequence () const;
+ bool prologue_end () const;
+ bool epilogue_begin () const;
+
+ const source_file file () const;
+ unsigned int line () const;
+ unsigned int column () const;
+
+ template<typename entry>
+ bool operator< (const entry &other) const
+ {
+ return address () < other.address ();
+ }
+ template<typename entry>
+ bool operator> (const entry &other) const
+ {
+ return address () > other.address ();
+ }
+ template<typename entry>
+ bool operator<= (const entry &other) const
+ {
+ return address () <= other.address ();
+ }
+ template<typename entry>
+ bool operator>= (const entry &other) const
+ {
+ return address () >= other.address ();
+ }
+
+ template<typename entry>
+ inline bool operator== (const entry &other) const
+ {
+ return (address () == other.address ()
+ && line () == other.line ()
+ && column () == other.column ()
+ && statement () == other.statement ()
+ && basic_block () == other.basic_block ()
+ && end_sequence () == other.end_sequence ()
+ && prologue_end () == other.prologue_end ()
+ && epilogue_begin () == other.epilogue_begin ()
+ && file () == other.file ());
+ }
+ template<typename entry>
+ inline bool operator!= (const entry &other) const
+ {
+ return !(*this == other);
+ }
+ // Short-circuit for our own type.
+ bool operator== (const line_entry &other) const;
+ };
+
+ class line_table
+ {
+ private:
+ ::Dwarf_Lines *_m_lines;
+
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef line_entry value_type;
+
+ inline line_table (::Dwarf_Lines *const lines)
+ : _m_lines (lines) {}
+ inline line_table (const line_table &t)
+ : _m_lines (t._m_lines) {}
+
+ inline line_table &operator= (const line_table &t)
+ {
+ _m_lines = t._m_lines;
+ return *this;
+ }
+
+ typedef subr::indexed_iterator<line_table> const_iterator;
+
+ inline bool empty () const
+ {
+ return size () == 0;
+ }
+
+ size_t size () const;
+
+ inline const_iterator begin () const
+ {
+ return const_iterator (*this, 0);
+ }
+ inline const_iterator end () const
+ {
+ return const_iterator (*this, size ());
+ }
+
+ const line_entry at (size_t idx) const;
+ const line_entry operator[] (size_t idx) const
+ {
+ return at (idx);
+ }
+
+ template<typename table>
+ inline bool operator== (const table &other) const
+ {
+ return std::equal (begin (), end (), other.begin ());
+ }
+ template<typename table>
+ inline bool operator!= (const table &other) const
+ {
+ return !(*this == other);
+ }
+ // Short-circuit for comparing to self.
+ inline bool operator== (const line_table &other) const
+ {
+ return (_m_lines == other._m_lines
+ || std::equal (begin (), end (), other.begin ()));
+ }
+
+ // Look up by matching address.
+ const_iterator find (::Dwarf_Addr) const;
+ };
+
+ // The DW_AT_stmt_list attribute yields a line info table.
+ class line_info_table
+ {
+ private:
+ ::Dwarf_Files *_m_files;
+
+ public:
+ inline line_info_table (::Dwarf_Files *const t)
+ : _m_files (t) {}
+ inline line_info_table (const line_info_table &t)
+ : _m_files (t._m_files) {}
+
+ inline line_info_table &operator= (const line_info_table &t)
+ {
+ _m_files = t._m_files;
+ return *this;
+ }
+
+ const directory_table include_directories () const
+ {
+ return directory_table (_m_files);
+ }
+ const file_table files () const
+ {
+ return file_table (_m_files);
+ }
+ const line_table lines () const;
+
+ template<typename table>
+ inline bool operator== (const table &other) const
+ {
+ return (include_directories () == other.include_directories ()
+ && lines () == other.lines ());
+ }
+ template<typename table>
+ inline bool operator!= (const table &other) const
+ {
+ return !(*this == other);
+ }
+ };
+
// This describes one attribute, equivalent to pair<const int, attr_value>.
class attribute
{
}
};
+ // Explicit specialization used inside dwarf::directory_table::operator==.
+ template<>
+ struct dwarf::directory_table::name_equal<const char *>
+ : public std::binary_function<const char *, const char *, bool>
+ {
+ bool operator () (const char *me, const char *you)
+ {
+ return !strcmp (me, you);
+ }
+ };
+
inline class dwarf::debug_info_entry::raw_children
dwarf::debug_info_entry::raw_children () const
{
--- /dev/null
+#include <config.h>
+#include <cassert>
+#include "dwarf"
+
+extern "C"
+{
+#include "libdwP.h"
+}
+
+using namespace elfutils;
+using namespace std;
+
+
+// dwarf::line_info_table
+
+const dwarf::line_info_table
+dwarf::attr_value::line_info () const
+{
+ assert (dwarf_whatattr (thisattr ()) == DW_AT_stmt_list);
+
+ CUDIE (cudie, _m_attr.cu);
+ Dwarf_Lines *lines;
+ size_t n;
+ xif (dwarf_getsrclines (&cudie, &lines, &n) < 0);
+
+ return line_info_table (_m_attr.cu->files);
+}
+
+const dwarf::line_table
+dwarf::line_info_table::lines () const
+{
+ return line_table (_m_files->cu->lines);
+}
+\f
+// dwarf::source_file
+
+const class dwarf::source_file
+dwarf::attr_value::source_file () const
+{
+ switch (what_space ())
+ {
+ case VS_string:
+ case VS_source_file:
+ break;
+ default:
+ throw std::runtime_error ("XXX not a file name");
+ }
+ return source_file::source_file (_m_attr);
+}
+
+static bool
+stringform (Dwarf_Attribute *attr)
+{
+ if (attr->valp != NULL)
+ switch (dwarf_whatform (attr))
+ {
+ case DW_FORM_string:
+ case DW_FORM_strp:
+ return true;
+ }
+ return false;
+}
+
+/* Mock up a dummy attribute with a special kludge that get_files groks.
+ We use these for source_file objects consed directly from an index
+ rather than from a real attribute. */
+static inline const Dwarf_Attribute
+dummy_source_file (Dwarf_CU *cu, unsigned int idx)
+{
+ const Dwarf_Attribute dummy = { idx, DW_FORM_indirect, NULL, cu };
+ return dummy;
+}
+
+static bool
+get_files (const Dwarf_Attribute *attr, Dwarf_Files **files, Dwarf_Word *idx)
+{
+ if (attr->valp == NULL)
+ {
+ // Dummy hack created by dummy_source_file, above.
+ assert (attr->form == DW_FORM_indirect);
+ *files = attr->cu->files;
+ *idx = attr->code;
+ return false;
+ }
+
+ CUDIE (cudie, attr->cu);
+ return (dwarf_formudata (const_cast<Dwarf_Attribute *> (attr), idx) < 0
+ || dwarf_getsrcfiles (&cudie, files, NULL) < 0);
+}
+
+Dwarf_Word
+dwarf::source_file::mtime () const
+{
+ if (stringform (thisattr ()))
+ return 0;
+
+ Dwarf_Files *files;
+ Dwarf_Word idx;
+ xif (get_files (thisattr (), &files, &idx));
+
+ Dwarf_Word result;
+ xif (dwarf_filesrc (files, idx, &result, NULL) == NULL);
+ return result;
+}
+
+Dwarf_Word
+dwarf::source_file::size () const
+{
+ if (stringform (thisattr ()))
+ return 0;
+
+ Dwarf_Files *files;
+ Dwarf_Word idx;
+ xif (get_files (thisattr (), &files, &idx));
+
+ Dwarf_Word result;
+ xif (dwarf_filesrc (files, idx, NULL, &result) == NULL);
+ return result;
+}
+
+const char *
+dwarf::source_file::name () const
+{
+ if (stringform (thisattr ()))
+ return dwarf_formstring (thisattr ());
+
+ Dwarf_Files *files;
+ size_t idx;
+ xif (get_files (thisattr (), &files, &idx));
+
+ const char *result = dwarf_filesrc (files, idx, NULL, NULL);
+ xif (result == NULL);
+ return result;
+}
+
+static inline string
+plain_string (const char *filename)
+{
+ return string ("\"") + filename + "\"";
+}
+
+string
+dwarf::source_file::to_string () const
+{
+ if (stringform (thisattr ()))
+ return plain_string (dwarf_formstring (thisattr ()));
+
+ Dwarf_Files *files;
+ size_t idx;
+ xif (get_files (thisattr (), &files, &idx));
+
+ Dwarf_Word file_mtime;
+ Dwarf_Word file_size;
+ const char *result = dwarf_filesrc (files, idx, &file_mtime, &file_size);
+ xif (result == NULL);
+
+ if (likely (file_mtime == 0) && likely (file_size == 0))
+ return plain_string (result);
+
+ std::ostringstream os;
+ os << "{\"" << result << "," << file_mtime << "," << file_size << "}";
+ return os.str ();
+}
+\f
+// dwarf::directory_table
+
+size_t
+dwarf::directory_table::size () const
+{
+ return _m_files->ndirs;
+}
+
+static inline dwarf::directory_table::const_iterator
+directory_table_array (Dwarf_Files *files)
+{
+ // See dwarf_getsrcdirs.
+ return reinterpret_cast<const char *const *> (&files->info[files->nfiles]);
+}
+
+dwarf::directory_table::const_iterator
+dwarf::directory_table::begin () const
+{
+ return directory_table_array (_m_files);
+}
+
+dwarf::directory_table::const_iterator
+dwarf::directory_table::end () const
+{
+ return directory_table_array (_m_files) + _m_files->ndirs;
+}
+\f
+// dwarf::file_table
+
+size_t
+dwarf::file_table::size () const
+{
+ return _m_files->nfiles;
+}
+
+const dwarf::source_file
+dwarf::file_table::at (size_t idx) const
+{
+ if (unlikely (idx >= _m_files->nfiles))
+ throw std::out_of_range ("XXX fileidx");
+
+ return dwarf::source_file (dummy_source_file (_m_files->cu, idx));
+}
+
+dwarf::file_table::const_iterator
+dwarf::file_table::find (const source_file &src) const
+{
+ if (src._m_attr.cu->files == _m_files)
+ {
+ // Same table, just cons an iterator using its index.
+ Dwarf_Files *files;
+ Dwarf_Word idx;
+ xif (get_files (&src._m_attr, &files, &idx));
+ return const_iterator (*this, idx);
+ }
+
+ // Not from this table, just match on file name.
+ return find (src.name ());
+}
+\f
+// dwarf::line_table
+
+size_t
+dwarf::line_table::size () const
+{
+ return _m_lines->nlines;
+}
+
+const dwarf::line_entry
+dwarf::line_table::at (size_t idx) const
+{
+ if (unlikely (idx >= _m_lines->nlines))
+ throw std::out_of_range ("XXX line table index");
+
+ return line_entry (reinterpret_cast<Dwarf_Line *> (&_m_lines->info[idx]));
+}
+
+dwarf::line_table::const_iterator
+dwarf::line_table::find (Dwarf_Addr address) const
+{
+ size_t idx = _m_lines->nlines; // end ()
+ if (likely (idx > 0))
+ {
+ CUDIE (cudie, _m_lines->info[0].files->cu);
+ Dwarf_Line *line = dwarf_getsrc_die (&cudie, address);
+ if (line != NULL)
+ idx = line - &_m_lines->info[0];
+ }
+ return const_iterator (*this, idx);
+}
+\f
+// dwarf::line_entry
+
+const dwarf::source_file
+dwarf::line_entry::file () const
+{
+ return dwarf::source_file (dummy_source_file (_m_line->files->cu,
+ _m_line->file));
+}
+
+#define LINEFIELD(type, method, field) \
+ type \
+ dwarf::line_entry::method () const \
+ { \
+ return _m_line->field; \
+ }
+
+LINEFIELD (Dwarf_Addr, address, addr) // XXX dwfl?
+LINEFIELD (unsigned int, line, line)
+LINEFIELD (unsigned int, column, column)
+LINEFIELD (bool, statement, is_stmt)
+LINEFIELD (bool, basic_block, basic_block)
+LINEFIELD (bool, end_sequence, end_sequence)
+LINEFIELD (bool, prologue_end, prologue_end)
+LINEFIELD (bool, epilogue_begin, epilogue_begin)
+
+#undef LINEFIELD
+
+bool
+dwarf::line_entry::operator== (const dwarf::line_entry &other) const
+{
+ Dwarf_Line *const a = _m_line;
+ Dwarf_Line *const b = other._m_line;
+
+ if (a == b)
+ return true;
+
+ if (a->addr != b->addr
+ || a->line != b->line
+ || a->column != b->column
+ || a->is_stmt != b->is_stmt
+ || a->basic_block != b->basic_block
+ || a->end_sequence != b->end_sequence
+ || a->prologue_end != b->prologue_end
+ || a->epilogue_begin != b->epilogue_begin)
+ return false;
+
+ // Everything else matches, now have to try the file.
+ if (a->files == b->files)
+ // Same table, just compare indices.
+ return a->file == b->file;
+
+ Dwarf_Word atime;
+ Dwarf_Word asize;
+ const char *aname = dwarf_linesrc (a, &atime, &asize);
+ xif (aname == NULL);
+ Dwarf_Word btime;
+ Dwarf_Word bsize;
+ const char *bname = dwarf_linesrc (b, &btime, &bsize);
+ xif (bname == NULL);
+
+ /* The mtime and size only count when encoded as nonzero.
+ If either side is zero, we don't consider the field. */
+
+ if (atime != btime && atime != 0 && btime != 0)
+ return false;
+
+ if (asize != bsize && asize != 0 && bsize != 0)
+ return false;
+
+ return !strcmp (aname, bname);
+}
+\f
+// dwarf::compile_unit convenience functions.
+
+const dwarf::line_info_table
+dwarf::compile_unit::line_info () const
+{
+ Dwarf_Lines *l;
+ size_t n;
+ xif (dwarf_getsrclines (thisdie (), &l, &n) < 0);
+
+ return line_info_table (thisdie ()->cu->files);
+}
--- /dev/null
+/* Private helper classes for elfutils -*- C++ -*- interfaces.
+
+ */
+
+#ifndef _ELFUTILS_SUBR_HH
+#define _ELFUTILS_SUBR_HH 1
+
+#include <iterator>
+
+namespace elfutils
+{
+ namespace subr
+ {
+
+ template<typename array, typename element = typename array::value_type>
+ class indexed_iterator
+ : public std::iterator<std::random_access_iterator_tag,
+ typename array::value_type,
+ typename array::difference_type>
+ {
+ private:
+ typedef typename array::size_type index_type;
+
+ array _m_contents;
+ index_type _m_idx;
+
+ public:
+ indexed_iterator (array contents, index_type idx)
+ : _m_contents (contents), _m_idx (idx) {}
+ indexed_iterator (const indexed_iterator &i)
+ : _m_contents (i._m_contents), _m_idx (i._m_idx) {}
+
+ inline element operator* () const
+ {
+ return _m_contents[_m_idx];
+ }
+ template<typename elt>
+ inline elt operator* () const
+ {
+ return _m_contents[_m_idx];
+ }
+ template<typename elt>
+ inline elt *operator-> () const
+ {
+ return &_m_contents[_m_idx];
+ }
+ template<typename elt>
+ inline elt operator[] (const index_type &n) const
+ {
+ return _m_contents[_m_idx + n];
+ }
+
+ inline indexed_iterator operator+ (const indexed_iterator &i)
+ {
+ return indexed_iterator (_m_contents, _m_idx + i._m_idx);
+ }
+ inline indexed_iterator operator- (const indexed_iterator &i)
+ {
+ return indexed_iterator (_m_contents, _m_idx - i._m_idx);
+ }
+
+ inline bool operator== (const indexed_iterator &i)
+ {
+ return _m_idx == i._m_idx;
+ }
+ inline bool operator!= (const indexed_iterator &i)
+ {
+ return _m_idx != i._m_idx;
+ }
+ inline bool operator< (const indexed_iterator &i)
+ {
+ return _m_idx < i._m_idx;
+ }
+ inline bool operator> (const indexed_iterator &i)
+ {
+ return _m_idx > i._m_idx;
+ }
+ inline bool operator<= (const indexed_iterator &i)
+ {
+ return _m_idx <= i._m_idx;
+ }
+ inline bool operator>= (const indexed_iterator &i)
+ {
+ return _m_idx >= i._m_idx;
+ }
+
+ inline indexed_iterator &operator= (const indexed_iterator &i)
+ {
+ _m_idx = i._m_idx;
+ return *this;
+ }
+ inline indexed_iterator &operator+= (const index_type &n)
+ {
+ _m_idx += n;
+ return *this;
+ }
+ inline indexed_iterator &operator-= (const index_type &n)
+ {
+ _m_idx -= n;
+ return *this;
+ }
+
+ inline indexed_iterator &operator++ () // prefix
+ {
+ ++_m_idx;
+ return *this;
+ }
+ inline indexed_iterator operator++ (int) // postfix
+ {
+ return indexed_iterator (_m_contents, _m_idx++);
+ }
+ inline indexed_iterator &operator-- () // prefix
+ {
+ --_m_idx;
+ return *this;
+ }
+ inline indexed_iterator operator-- (int) // postfix
+ {
+ return indexed_iterator (_m_contents, _m_idx--);
+ }
+ };
+ };
+};
+
+#endif // <elfutils/subr.hh>
<http://www.openinventionnetwork.com>. */
#include <config.h>
+#include <cassert>
#include "dwarf"
extern "C"
return const_vector<uint8_t> (begin, end);
}
\f
-// dwarf::source_file
-
-const class dwarf::source_file
-dwarf::attr_value::source_file () const
-{
- switch (what_space ())
- {
- case VS_string:
- case VS_source_file:
- break;
- default:
- throw std::runtime_error ("XXX not a file name");
- }
- return source_file::source_file (_m_attr);
-}
-
-static bool
-stringform (Dwarf_Attribute *attr)
-{
- switch (dwarf_whatform (attr))
- {
- case DW_FORM_string:
- case DW_FORM_strp:
- return true;
- }
- return false;
-}
-
-static bool
-get_files (Dwarf_Attribute *attr, Dwarf_Files **files, Dwarf_Word *idx)
-{
- CUDIE (cudie, attr->cu);
- return (dwarf_formudata (attr, idx) < 0
- || dwarf_getsrcfiles (&cudie, files, NULL) < 0);
-}
-
-Dwarf_Word
-dwarf::source_file::mtime () const
-{
- if (stringform (thisattr ()))
- return 0;
-
- Dwarf_Files *files;
- Dwarf_Word idx;
- xif (get_files (thisattr (), &files, &idx));
-
- Dwarf_Word result;
- xif (dwarf_filesrc (files, idx, &result, NULL) == NULL);
- return result;
-}
-
-Dwarf_Word
-dwarf::source_file::size () const
-{
- if (stringform (thisattr ()))
- return 0;
-
- Dwarf_Files *files;
- Dwarf_Word idx;
- xif (get_files (thisattr (), &files, &idx));
-
- Dwarf_Word result;
- xif (dwarf_filesrc (files, idx, NULL, &result) == NULL);
- return result;
-}
-
-const char *
-dwarf::source_file::name () const
-{
- if (stringform (thisattr ()))
- return dwarf_formstring (thisattr ());
-
- Dwarf_Files *files;
- size_t idx;
- xif (get_files (thisattr (), &files, &idx));
-
- const char *result = dwarf_filesrc (files, idx, NULL, NULL);
- xif (result == NULL);
- return result;
-}
-
-string
-dwarf::source_file::to_string () const
-{
- if (stringform (thisattr ()))
- return plain_string (dwarf_formstring (thisattr ()));
-
- Dwarf_Files *files;
- size_t idx;
- xif (get_files (thisattr (), &files, &idx));
-
- Dwarf_Word file_mtime;
- Dwarf_Word file_size;
- const char *result = dwarf_filesrc (files, idx, &file_mtime, &file_size);
- xif (result == NULL);
-
- if (likely (file_mtime == 0) && likely (file_size == 0))
- return plain_string (result);
-
- std::ostringstream os;
- os << "{\"" << result << "," << file_mtime << "," << file_size << "}";
- return os.str ();
-}
-\f
// dwarf::location_attr
const dwarf::location_attr
libar_a_SOURCES = arlib.c arlib2.c
-dwarfcmp_SOURCES = dwarfcmp.cc
# XXX need to figure out C++ dso crapola
-dwarfcmp_SOURCES += ../libdw/c++/values.cc ../libdw/c++/known.cc
+libdwplusplus_SOURCES = ../libdw/c++/values.cc ../libdw/c++/known.cc \
+ ../libdw/c++/line_info.cc
+
+dwarfcmp_SOURCES = dwarfcmp.cc
+dwarfcmp_SOURCES += $(libdwplusplus_SOURCES)
noinst_HEADERS = ld.h symbolhash.h sectionhash.h versionhash.h \
ldscript.h xelf.h unaligned.h