]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
fixes for direct dwarf_edit usage
authorRoland McGrath <roland@redhat.com>
Thu, 2 Jul 2009 00:46:47 +0000 (17:46 -0700)
committerRoland McGrath <roland@redhat.com>
Thu, 2 Jul 2009 00:46:47 +0000 (17:46 -0700)
libdw/c++/dwarf_data
libdw/c++/dwarf_edit
tests/Makefile.am
tests/dwarf-print.cc

index 56e61ed25d559bb285d5fcc544c3956f8b1c7222..1f92fddf81f62f0b620d501ded3eac155a299622 100644 (file)
@@ -52,6 +52,7 @@
 
 #include "dwarf"
 #include <bitset>
+#include <typeinfo>
 
 /* This contains common classes/templates used by dwarf_output and dwarf_edit.
 
@@ -470,7 +471,12 @@ namespace elfutils
     private:
       typedef std::pair< ::Dwarf_Word, unsigned int> _base;
 
+      inline dwarf_enum ()
+       : _base (0, 0)
+      {}
+
     public:
+
       inline dwarf_enum (unsigned int attr, unsigned int value)
        : _base (value, attr)
       {}
@@ -491,10 +497,26 @@ namespace elfutils
        return this->first;
       }
 
+      inline dwarf_enum &operator= (::Dwarf_Word value)
+      {
+       this->first = value;
+       return *this;
+      }
+
       inline dwarf_enum &operator= (const dwarf_enum& other)
       {
+       if (this->second == 0)
+         {
+           throw std::logic_error("dwarf_enum default constructed");
+           this->second = other.second;
+         }
+       else if (this->second != other.second)
+         throw std::runtime_error
+           ("cannot assign dwarf_constant () from "
+            + dwarf::attributes::name (other.second) + "to "
+            + dwarf::attributes::name (this->second));
+
        this->first = other.first;
-       this->second = other.second;
        return *this;
       }
 
@@ -654,9 +676,8 @@ namespace elfutils
     template<typename impl, typename constructor_arg_type>
     struct value
     {
-      class value_dispatch
+      struct value_dispatch
       {
-      public:
        virtual ~value_dispatch () {}
       };
 
@@ -669,6 +690,8 @@ namespace elfutils
 
       struct value_string : public value_dispatch, public std::string
       {
+       inline value_string () {}
+
        template<typename string>
        inline value_string (const string &s, const constructor_arg_type &arg)
          : std::string (s)
@@ -724,6 +747,11 @@ namespace elfutils
       struct value_flag : public value_dispatch
       {
        bool flag;
+
+       inline value_flag ()
+         : flag (true)
+       {}
+
        inline value_flag (bool t, const constructor_arg_type &arg)
          : flag (t)
        {}
@@ -733,6 +761,11 @@ namespace elfutils
       {
        // XXX dwfl, reloc
        ::Dwarf_Addr addr;
+
+       inline value_address ()
+         : addr (0)
+       {}
+
        inline value_address (::Dwarf_Addr a, const constructor_arg_type &arg)
          : addr (a)
        {}
@@ -740,6 +773,9 @@ namespace elfutils
 
       struct value_rangelistptr : public value_dispatch, public range_list
       {
+       inline value_rangelistptr ()
+       {}
+
        template<typename list>
        inline value_rangelistptr (const list &other,
                                   const constructor_arg_type &arg)
@@ -749,6 +785,9 @@ namespace elfutils
 
       struct value_lineptr : public value_dispatch, public impl::line_info_table
       {
+       inline value_lineptr ()
+       {}
+
        template<typename table>
        inline value_lineptr (const table &other,
                              const constructor_arg_type &arg)
@@ -763,6 +802,11 @@ namespace elfutils
          ::Dwarf_Word word;
          ::Dwarf_Sword sword;
        };
+
+       inline value_constant ()
+         : word (0)
+       {}
+
        inline value_constant (::Dwarf_Word x, const constructor_arg_type &arg)
          : word (x)
        {}
@@ -771,6 +815,8 @@ namespace elfutils
       struct value_constant_block : public value_dispatch,
                                    public std::vector<uint8_t>
       {
+       inline value_constant_block () {}
+
        template<typename block>
        inline value_constant_block (const block &b,
                                     const constructor_arg_type &arg)
@@ -780,6 +826,8 @@ namespace elfutils
 
       struct value_dwarf_constant : public value_dispatch, public dwarf_enum
       {
+       inline value_dwarf_constant () {}
+
        template<typename constant>
        inline value_dwarf_constant (const constant &other,
                                     const constructor_arg_type &arg)
@@ -788,6 +836,9 @@ namespace elfutils
 
       struct value_source_file : public value_dispatch, public source_file
       {
+       inline value_source_file ()
+       {}
+
        template<typename file>
        inline value_source_file (const file &other,
                                  const constructor_arg_type &arg)
@@ -797,6 +848,11 @@ namespace elfutils
       struct value_source_line : public value_dispatch
       {
        unsigned int n;
+
+       inline value_source_line ()
+         : n (0)
+       {}
+
        inline value_source_line (unsigned int m,
                                  const constructor_arg_type &arg)
          : n (m)
@@ -808,6 +864,9 @@ namespace elfutils
 
       struct value_location : public value_dispatch, public location_attr
       {
+       inline value_location ()
+       {}
+
        template<typename loc>
        inline value_location (const loc &other,
                               const constructor_arg_type &arg)
@@ -876,7 +935,7 @@ namespace elfutils
       }
 
       template<typename flavor>
-      inline flavor &variant () const
+      inline flavor &const_variant () const
       {
        flavor *p = dynamic_cast<flavor *> (_m_value);
        if (p == NULL)
@@ -884,10 +943,26 @@ namespace elfutils
        return *p;
       }
 
+      template<typename flavor>
+      inline flavor &variant () const
+      {
+       return const_variant<flavor> ();
+      }
+
+      template<typename flavor>
+      inline flavor &variant ()
+      {
+       if (_m_value == NULL)
+         _m_value = new flavor;
+       return const_variant<flavor> ();
+      }
+
     public:
-      attr_value (const attr_value &other) : _m_value (NULL)
+      attr_value (const attr_value &other)
+       : _m_value (NULL)
       {
-       init (other);
+       if (other._m_value != NULL)
+         init (other);
       }
 
       template<typename value>
@@ -960,49 +1035,95 @@ namespace elfutils
          (variant<typename vw::value_location> ());
       }
 
+      inline std::string &string ()
+      {
+       return static_cast<std::string &>
+         (variant<typename vw::value_string> ());
+      }
       inline const std::string &string () const
       {
        return static_cast<const std::string &>
          (variant<typename vw::value_string> ());
       }
+      inline std::string &identifier ()
+      {
+       return string ();
+      }
       inline const std::string &identifier () const
       {
        return string ();
       }
 
-      inline typename impl::source_file &source_file () const
+      inline const typename impl::source_file &source_file () const
+      {
+       return static_cast<typename impl::source_file &>
+         (variant<typename vw::value_source_file> ());
+      }
+
+      inline typename impl::source_file &source_file ()
       {
        return static_cast<typename impl::source_file &>
          (variant<typename vw::value_source_file> ());
       }
 
-      inline unsigned int &source_line () const
+      inline const unsigned int &source_line () const
       {
        return variant<typename vw::value_source_line> ().n;
       }
 
-      inline unsigned int &source_column () const
+      inline unsigned int &source_line ()
+      {
+       return variant<typename vw::value_source_line> ().n;
+      }
+
+      inline const unsigned int &source_column () const
+      {
+       return variant<typename vw::value_source_column> ().n;
+      }
+
+      inline unsigned int &source_column ()
       {
        return variant<typename vw::value_source_column> ().n;
       }
 
-      inline ::Dwarf_Word &constant () const
+      inline const ::Dwarf_Word &constant () const
       {
        return variant<typename vw::value_constant> ().word;
       }
 
-      inline ::Dwarf_Sword &signed_constant () const
+      inline ::Dwarf_Word &constant ()
+      {
+       return variant<typename vw::value_constant> ().word;
+      }
+
+      inline const ::Dwarf_Sword &signed_constant () const
       {
        return variant<typename vw::value_constant> ().sword;
       }
 
-      inline std::vector<uint8_t> &constant_block () const
+      inline ::Dwarf_Sword &signed_constant ()
+      {
+       return variant<typename vw::value_constant> ().sword;
+      }
+
+      inline const std::vector<uint8_t> &constant_block () const
       {
        return static_cast<std::vector<uint8_t> &>
          (variant<typename vw::value_constant_block> ());
       }
 
-      inline typename impl::dwarf_enum &dwarf_constant () const
+      inline std::vector<uint8_t> &constant_block ()
+      {
+       return static_cast<std::vector<uint8_t> &>
+         (variant<typename vw::value_constant_block> ());
+      }
+
+      inline const typename impl::dwarf_enum &dwarf_constant () const
+      {
+       return variant<typename vw::value_dwarf_constant> ();
+      }
+
+      inline typename impl::dwarf_enum &dwarf_constant ()
       {
        return variant<typename vw::value_dwarf_constant> ();
       }
@@ -1012,13 +1133,25 @@ namespace elfutils
        return dynamic_cast<typename vw::value_constant *> (_m_value) != NULL;
       }
 
-      inline typename impl::range_list &ranges () const
+      inline const typename impl::range_list &ranges () const
+      {
+       return static_cast<range_list &>
+         (variant<typename vw::value_rangelistptr> ());
+      }
+
+      inline typename impl::range_list &ranges ()
       {
        return static_cast<range_list &>
          (variant<typename vw::value_rangelistptr> ());
       }
 
-      inline typename impl::line_info_table &line_info () const
+      inline const typename impl::line_info_table &line_info () const
+      {
+       return static_cast<typename impl::line_info_table &>
+         (variant<typename vw::value_lineptr> ());
+      }
+
+      inline typename impl::line_info_table &line_info ()
       {
        return static_cast<typename impl::line_info_table &>
          (variant<typename vw::value_lineptr> ());
index 0d67a3e17e13689d859c5a163e6069c08bd0b04c..a4ff1570e491d865bc5906655d9dbcddf23633f9 100644 (file)
@@ -280,6 +280,12 @@ namespace elfutils
       return _m_units;
     }
 
+    // Convenience entry point.
+    inline compile_unit &new_unit ()
+    {
+      return compile_units ().new_unit ();
+    }
+
   public:
     // Default constructor: an empty container, no CUs.
     inline dwarf_edit () {}
index ba95008852a4001a3c1fa25d9fb101af2b52030e..3531c9d247576771f24afd7ac10f6c144073cfa1 100644 (file)
@@ -60,7 +60,8 @@ noinst_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
                  find-prologues funcretval allregs rdwrmmap \
                  dwfl-bug-addr-overflow arls dwfl-bug-fd-leak \
                  dwfl-addr-sect dwfl-bug-report early-offscn \
-                 dwfl-bug-getmodules dwarf-getmacros dwarf-print
+                 dwfl-bug-getmodules dwarf-getmacros dwarf-print \
+                 dwarf_edit
 # get-ciefde
 asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
            asm-tst6 asm-tst7 asm-tst8 asm-tst9
@@ -193,6 +194,9 @@ libdwpp = ../libdw/libdwpp.a $(libdw)
 dwarf_print_SOURCES = dwarf-print.cc
 dwarf_print_LDADD = $(libdwpp) $(libmudflap) -ldl
 
+dwarf_edit_SOURCES = dwarf_edit.cc
+dwarf_edit_LDADD = $(libdwpp) $(libmudflap) -ldl
+
 arextract_LDADD = $(libelf) $(libmudflap)
 arsymtest_LDADD = $(libelf) $(libmudflap)
 newfile_LDADD = $(libelf) $(libmudflap)
index d37a006a041bc18baa855152764db422c63f52c4..8d09ba1576432247d0c01e9117de427e2faaa528 100644 (file)
@@ -41,6 +41,8 @@
 using namespace elfutils;
 using namespace std;
 
+#include "print-die.hh"
+
 static Dwarf *
 open_file (const char *fname)
 {
@@ -57,75 +59,14 @@ open_file (const char *fname)
   return dw;
 }
 
-static void
-print_die (const dwarf::debug_info_entry &die,
-          unsigned int indent, unsigned int limit)
-{
-  string prefix (indent, ' ');
-  const string tag = dwarf::tags::name (die.tag ());
-
-  cout << prefix << "<" << tag << " offset=[" << die.offset () << "]";
-
-  for (dwarf::debug_info_entry::attributes_type::const_iterator i
-        = die.attributes ().begin (); i != die.attributes ().end (); ++i)
-    cout << " " << (*i).to_string ();
-
-  if (die.has_children ())
-    {
-      if (limit != 0 && indent >= limit)
-       {
-         cout << ">...\n";
-         return;
-       }
-
-      cout << ">\n";
-
-      for (dwarf::debug_info_entry::children_type::const_iterator i
-            = die.children ().begin (); i != die.children ().end (); ++i)
-       print_die (*i, indent + 1, limit);
-
-      cout << prefix << "</" << tag << ">\n";
-    }
-  else
-    cout << "/>\n";
-}
-
-static void
-process_file (const char *file, unsigned int limit)
-{
-  dwarf dw (open_file (file));
-
-  cout << file << ":\n";
-
-  for (dwarf::compile_units::const_iterator i = dw.compile_units ().begin ();
-       i != dw.compile_units ().end ();
-       ++i)
-    print_die (*i, 1, limit);
-}
-
 int
 main (int argc, char *argv[])
 {
-  /* Set locale.  */
-  (void) setlocale (LC_ALL, "");
-
-  /* Make sure the message catalog can be found.  */
-  (void) bindtextdomain (PACKAGE_TARNAME, LOCALEDIR);
-
-  /* Initialize the message catalog.  */
-  (void) textdomain (PACKAGE_TARNAME);
-
-  cout << hex << setiosflags (ios::showbase);
-
-  unsigned int depth = 0;
-  if (argc > 1 && sscanf (argv[1], "--depth=%u", &depth) == 1)
-    {
-      --argc;
-      ++argv;
-    }
+  unsigned int depth;
+  print_die_main (argc, argv, depth);
 
   for (int i = 1; i < argc; ++i)
-    process_file (argv[i], depth);
+    print_file (argv[i], dwarf (open_file (argv[i])), depth);
 
   return 0;
 }