]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
Implement attribute values in dwarf_edit.
authorRoland McGrath <roland@redhat.com>
Mon, 2 Feb 2009 04:40:36 +0000 (20:40 -0800)
committerRoland McGrath <roland@redhat.com>
Mon, 2 Feb 2009 04:40:36 +0000 (20:40 -0800)
libdw/ChangeLog
libdw/c++/dwarf
libdw/c++/dwarf_edit
libdw/c++/edit-values.cc [new file with mode: 0644]
src/Makefile.am

index 7b1d37e9d060823a642ed4e3bdc90594478cb4a7..cbd457dfca2a711c3ae3f4ad45fa967b3f8244f9 100644 (file)
@@ -1,3 +1,7 @@
+2009-02-01  Roland McGrath  <roland@redhat.com>
+
+       * c++/edit-values.cc: New file.
+
 2009-01-28  Roland McGrath  <roland@redhat.com>
 
        * c++/dwarf: Add line table support.
index 14f2947f0a08b10dcb473a30dd43f23df88ed954..c79a77c09e3af5630ba6ac952bab8b789389001f 100644 (file)
@@ -225,6 +225,7 @@ namespace elfutils
     {
       return !(*this == other);
     }
+
   };
 
   // One DWARF object file.
@@ -1236,9 +1237,11 @@ namespace elfutils
        if (empty ())
          return (other.empty ()
                  || std::find_if (other.begin (), other.end (),
-                                  nonempty<value_type> ()) == other.end ());
+                                  nonempty<typename other_attr::value_type> ()
+                                  ) == other.end ());
        if (!is_list ())
-         return !other.is_list () && location () == other.location ();
+         return (!other.is_list () && !other.empty ()
+                 && location () == other.location ());
 
        return other.is_list () && subr::container_equal (*this, other);
       }
index 3235199bf84bbf5e1e18b730b52a6db2573afe9d..1a8df1e8ae721fe95862acec5c683713720f002e 100644 (file)
@@ -51,6 +51,7 @@
 #define _ELFUTILS_DWARF_EDIT   1
 
 #include "dwarf"
+#include <bitset>
 
 /* Read the comments for elfutils::dwarf first.
 
@@ -80,13 +81,7 @@ namespace elfutils
   {
   public:
     class compile_units;
-
-    // XXX later
-    class attr_value : public dwarf::attr_value
-    {
-    public:
-      attr_value (const dwarf::attr_value &v) : dwarf::attr_value (v) {}
-    };
+    class attr_value;
 
     class debug_info_entry
     {
@@ -220,17 +215,20 @@ namespace elfutils
     {
       friend class dwarf_edit;
     private:
+      typedef std::list<compile_unit> _base;
+
       // Default constructor: an empty container, no CUs.
       inline compile_units () {}
 
       // Constructor copying CUs from input container.
       template<typename input>
       compile_units(const input &units)
-       : std::list<compile_unit> (units.begin (), units.end ())
-      {}
+       : _base (units.begin (), units.end ()) {}
 
     public:
       typedef compile_unit value_type;
+      typedef _base::iterator iterator;
+      typedef _base::const_iterator const_iterator;
 
       inline compile_unit &new_unit ()
       {
@@ -242,7 +240,7 @@ namespace elfutils
       template<typename other_children>
       bool operator== (const other_children &other) const
       {
-       return std::equal (begin (), end (), other.begin ());
+       return subr::container_equal (*this, other);
       }
       template<typename other_children>
       bool operator!= (const other_children &other) const
@@ -251,6 +249,790 @@ namespace elfutils
       }
     };
 
+    // Same as set<pair<Dwarf_Addr, Dwarf_Addr>>.
+    class range_list : public dwarf::arange_list
+    {
+    public:
+      template<typename list>
+      range_list (const list &other)
+       : dwarf::arange_list (other.begin (), other.end ()) {}
+    };
+
+    class source_file
+    {
+    private:
+      std::string _m_name;
+      ::Dwarf_Word _m_mtime;
+      ::Dwarf_Word _m_size;
+
+    public:
+      source_file () : _m_name (), _m_mtime (0), _m_size (0) {}
+      source_file (const std::string &n, ::Dwarf_Word m = 0, ::Dwarf_Word s = 0)
+       : _m_name (n), _m_mtime (m), _m_size (s) {}
+
+      template<typename file>
+      source_file (const file &other)
+       : _m_name (other.name ()),
+         _m_mtime (other.mtime ()), _m_size (other.size ()) {}
+
+      template<typename file>
+      inline source_file &operator= (const file &other)
+      {
+       _m_name = other.name ();
+       _m_mtime = other.mtime ();
+       _m_size = other.size ();
+       return *this;
+      }
+      inline source_file &operator= (const std::string &n)
+      {
+       _m_name = n;
+       _m_mtime = 0;
+       _m_size = 0;
+       return *this;
+      }
+      inline source_file &operator= (const char *n)
+      {
+       _m_name = n;
+       _m_mtime = 0;
+       _m_size = 0;
+       return *this;
+      }
+
+      inline std::string &name ()
+      {
+       return _m_name;
+      }
+      inline const std::string &name () const
+      {
+       return _m_name;
+      }
+      inline ::Dwarf_Word &mtime ()
+      {
+       return _m_mtime;
+      }
+      inline ::Dwarf_Word mtime () const
+      {
+       return _m_mtime;
+      }
+      inline ::Dwarf_Word &size ()
+      {
+       return _m_size;
+      }
+      inline ::Dwarf_Word size () const
+      {
+       return _m_size;
+      }
+
+      template<typename other_file>
+      bool operator== (const other_file &other) const
+      {
+       if (mtime () != 0)
+         {
+           ::Dwarf_Word other_mtime = other.mtime ();
+           if (other_mtime != 0 && other_mtime != mtime ())
+             return false;
+         }
+       if (size () != 0)
+         {
+           ::Dwarf_Word other_size = other.size ();
+           if (other_size != 0 && other_size != size ())
+             return false;
+         }
+       return name () == other.name ();
+      }
+      template<typename other_file>
+      inline bool operator!= (const other_file &other) const
+      {
+       return !(*this == other);
+      }
+    };
+
+    // This describes a CU's directory table, a simple array of strings.
+    class directory_table : public std::vector<std::string>
+    {
+    private:
+      typedef std::vector<std::string> _base;
+
+    public:
+      directory_table () {}
+
+      template<typename table>
+      directory_table (const table &other)
+       : _base (other.begin (), other.end ()) {}
+
+      template<typename table>
+      inline bool operator== (const table &other) const
+      {
+       return size () == other.size () && subr::container_equal (*this, other);
+      }
+      template<typename table>
+      inline bool operator!= (const table &other) const
+      {
+       return !(*this == other);
+      }
+    };
+
+    class line_entry
+    {
+    private:
+      ::Dwarf_Addr _m_addr;    // XXX dwfl, reloc
+      source_file _m_file;
+      unsigned int _m_line;
+      unsigned int _m_column;
+
+      enum flag_bit
+       {
+         flag_statement,
+         flag_basic_block,
+         flag_end_sequence,
+         flag_prologue_end,
+         flag_epilogue_begin,
+         flag_count
+       };
+      std::bitset<flag_count> _m_flags;
+
+    public:
+      line_entry (::Dwarf_Addr addr)
+       : _m_addr (addr), _m_file (), _m_line (0), _m_column (0) {}
+
+      template<typename entry>
+      line_entry (const entry &other)
+       : _m_addr (0), _m_file (), _m_line (0), _m_column (0)
+      {
+       *this = other;
+      }
+
+      template<typename entry>
+      line_entry &operator= (const entry &other)
+      {
+       _m_addr = other.address ();
+       _m_file = other.file ();
+       _m_line = other.line ();
+       _m_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 ();
+       return *this;
+      }
+
+      inline ::Dwarf_Addr &address ()
+      {
+       return _m_addr;
+      }
+      inline ::Dwarf_Addr address () const
+      {
+       return _m_addr;
+      }
+      inline source_file &file ()
+      {
+       return _m_file;
+      }
+      inline const source_file &file () const
+      {
+       return _m_file;
+      }
+      inline unsigned int &line ()
+      {
+       return _m_line;
+      }
+      inline unsigned int line () const
+      {
+       return _m_line;
+      }
+      inline unsigned int &column ()
+      {
+       return _m_column;
+      }
+      inline unsigned int column () const
+      {
+       return _m_column;
+      }
+
+#define _DWARF_EDIT_LE_FLAG(what)                      \
+      bool what () const                               \
+      {                                                        \
+       return _m_flags[flag_##what];                   \
+      }                                                        \
+      std::bitset<flag_count>::reference what ()       \
+      {                                                        \
+       return _m_flags[flag_##what];                   \
+      }
+      _DWARF_EDIT_LE_FLAG (statement)
+      _DWARF_EDIT_LE_FLAG (basic_block)
+      _DWARF_EDIT_LE_FLAG (end_sequence)
+      _DWARF_EDIT_LE_FLAG (prologue_end)
+      _DWARF_EDIT_LE_FLAG (epilogue_begin)
+#undef _DWARF_EDIT_LE_FLAG
+
+      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);
+      }
+    };
+
+    class line_table : public std::vector<line_entry>
+    {
+    private:
+      typedef std::vector<line_entry> _base;
+
+    public:
+      typedef _base::size_type size_type;
+      typedef _base::difference_type difference_type;
+      typedef _base::value_type value_type;
+      typedef _base::iterator iterator;
+      typedef _base::const_iterator const_iterator;
+
+      line_table () {}
+
+      template<typename table>
+      line_table (const table &other) : _base (other.begin (), other.end ()) {}
+
+      template<typename table>
+      inline bool operator== (const table &other) const
+      {
+       return size () == other.size () && subr::container_equal (*this, other);
+      }
+      template<typename table>
+      inline bool operator!= (const table &other) const
+      {
+       return !(*this == other);
+      }
+
+      // Look up by matching address.
+      iterator find (::Dwarf_Addr);
+      const_iterator find (::Dwarf_Addr) const;
+    };
+
+    class line_info_table
+    {
+    private:
+      directory_table _m_dirs;
+      line_table _m_lines;
+
+    public:
+      line_info_table () : _m_dirs (), _m_lines () {}
+
+      template<typename table>
+      line_info_table (const table &other)
+       : _m_dirs (other.include_directories ()), _m_lines (other.lines ()) {}
+
+      template<typename table>
+      inline line_info_table &operator= (const table &other)
+      {
+       _m_dirs = directory_table (other.include_directories ());
+       _m_lines = line_table (other.lines ());
+       return *this;
+      }
+
+      inline directory_table &include_directories ()
+      {
+       return _m_dirs;
+      }
+      inline const directory_table &include_directories () const
+      {
+       return _m_dirs;
+      }
+      inline line_table &lines ()
+      {
+       return _m_lines;
+      }
+      inline const line_table &lines () const
+      {
+       return _m_lines;
+      }
+
+      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);
+      }
+    };
+
+    class location_attr : public std::map<dwarf::location_attr::key_type,
+                                         std::vector<uint8_t> >
+    {
+    private:
+      typedef std::map<dwarf::location_attr::key_type,
+                      std::vector<uint8_t> > _base;
+
+    public:
+      typedef _base::size_type size_type;
+      typedef _base::difference_type difference_type;
+      typedef _base::key_type key_type;
+      typedef _base::mapped_type mapped_type;
+      typedef _base::value_type value_type;
+      typedef _base::iterator iterator;
+      typedef _base::const_iterator const_iterator;
+
+      inline location_attr () : _base () {}
+      inline location_attr (const location_attr &other)
+       : _base (static_cast<const _base &> (other)) {}
+      template<typename loc>
+      inline location_attr (const loc &other) : _base ()
+      {
+       *this = other;
+      }
+
+      template<typename loc>
+      inline location_attr &operator= (const loc &other)
+      {
+       clear ();
+       if (other.empty ())
+         ;
+       else if (other.is_list ())
+         for (typename loc::const_iterator i = other.begin ();
+              i != other.end ();
+              ++i)
+           {
+             const typename loc::mapped_type &x = (*i).second;
+             (*this)[(*i).first] = mapped_type (x.begin (), x.end ());
+           }
+       else
+         (*this)[key_type (0, -1)] = other.location ();
+       return *this;
+      }
+
+      inline bool is_list () const
+      {
+       if (empty ())
+         return false;
+       if (size () > 1)
+         return true;
+
+       const key_type &elt = begin ()->first;
+       return !(elt.first == 0 && elt.second == (Dwarf_Addr) -1);
+      }
+
+      inline mapped_type &location ()
+      {
+       if (empty ())
+         return (*this)[key_type (0, -1)];
+
+       value_type &v = *begin ();
+       if (v.first.first != 0 || v.first.second != (Dwarf_Addr) -1
+           || size () > 1)
+         throw std::runtime_error ("location is list, not single location");
+
+       return v.second;
+      }
+      inline const mapped_type &location () const
+      {
+       if (size () == 1)
+         {
+           const value_type &v = *begin ();
+           if (v.first.first == 0 && v.first.second == (Dwarf_Addr) -1)
+             return v.second;
+         }
+       throw std::runtime_error ("location is list, not single location");
+      }
+    };
+
+  private:
+    class value_dispatch
+    {
+    public:
+      virtual ~value_dispatch () {}
+    };
+
+    struct value_string : public value_dispatch, public std::string
+    {
+      template<typename string>
+      value_string (const string &s) : std::string (s) {}
+
+      std::string to_string () const
+      {
+       std::string result ("\"");
+       result += *this;
+       result += "\"";
+       return result;
+      }
+    };
+
+    struct value_identifier : public value_string
+    {
+      template<typename id>
+      value_identifier (const id &s) : value_string (s) {}
+    };
+
+    struct value_reference : public value_dispatch
+    {
+      debug_info_entry::children::iterator ref;
+      value_reference (const debug_info_entry::children::iterator &i)
+       : ref (i) {}
+
+      template<typename iter>  // XXX dummy
+      value_reference (const iter &i) : ref () {}
+    };
+    struct value_unit_reference : public value_dispatch
+    {
+      compile_units::iterator ref;
+      value_unit_reference (const compile_units::iterator &i) : ref (i) {}
+
+      template<typename iter>  // XXX dummy
+      value_unit_reference (const iter &i) : ref () {}
+    };
+
+    struct value_flag : public value_dispatch
+    {
+      bool flag;
+      value_flag (bool t) : flag (t) {}
+    };
+
+    struct value_address : public value_dispatch
+    {
+      // XXX dwfl, reloc
+      ::Dwarf_Addr addr;
+      value_address (::Dwarf_Addr a) : addr (a) {}
+    };
+
+    struct value_rangelistptr : public value_dispatch, public range_list
+    {
+      template<typename list>
+      value_rangelistptr (const list &other) : range_list (other) {}
+    };
+
+    struct value_lineptr : public value_dispatch, public line_info_table
+    {
+      template<typename table>
+      value_lineptr (const table &other) : line_info_table (other) {}
+    };
+
+    struct value_constant : public value_dispatch
+    {
+      union
+      {
+       ::Dwarf_Word word;
+       ::Dwarf_Sword sword;
+      };
+      value_constant (::Dwarf_Word x) : word (x) {}
+    };
+
+    struct value_constant_block : public value_dispatch,
+                                 public std::vector<uint8_t>
+    {
+      template<typename block>
+      value_constant_block (const block &b)
+       : std::vector<uint8_t> (b.begin (), b.end ()) {}
+    };
+
+    struct value_dwarf_constant : public value_constant
+    {
+      value_dwarf_constant (unsigned int x) : value_constant (x) {}
+    };
+
+    struct value_source_file : public value_dispatch, public source_file
+    {
+      template<typename file>
+      value_source_file (const file &other) : source_file (other) {}
+    };
+
+    struct value_source_line : public value_dispatch
+    {
+      unsigned int n;
+      value_source_line (unsigned int m) : n (m) {}
+    };
+    typedef value_source_line value_source_column;
+
+    struct value_macptr : public value_dispatch {};
+
+    struct value_location : public value_dispatch, public location_attr
+    {
+      template<typename loc>
+      value_location (const loc &other) : location_attr (other) {}
+    };
+
+  public:
+    class attr_value
+    {
+    private:
+      value_dispatch *_m_value;
+
+      template<typename value>
+      inline void init (const value &other)
+      {
+       switch (other.what_space ())
+         {
+         case dwarf::VS_identifier:
+           _m_value = new value_identifier (other.identifier ());
+           break;
+         case dwarf::VS_string:
+           _m_value = new value_string (other.string ());
+           break;
+         case dwarf::VS_flag:
+           _m_value = new value_flag (other.flag ());
+           break;
+         case dwarf::VS_rangelistptr:
+           _m_value = new value_rangelistptr (other.ranges ());
+           break;
+         case dwarf::VS_lineptr:
+           _m_value = new value_lineptr (other.line_info ());
+           break;
+         case dwarf::VS_address:
+           _m_value = new value_address (other.address ());
+           break;
+         case dwarf::VS_constant:
+           _m_value = new value_constant (other.constant ());
+           break;
+         case dwarf::VS_source_line:
+           _m_value = new value_source_line (other.source_line ());
+           break;
+         case dwarf::VS_source_column:
+           _m_value = new value_source_column (other.source_column ());
+           break;
+         case dwarf::VS_source_file:
+           _m_value = new value_source_file (other.source_file ());
+           break;
+         case dwarf::VS_dwarf_constant:
+           _m_value = new value_dwarf_constant (other.constant ()); // XXX
+           break;
+         case dwarf::VS_reference:
+           _m_value = new value_reference (other.reference ());
+           break;
+         case dwarf::VS_unit_reference:
+           _m_value = new value_unit_reference (other.unit_reference ());
+           break;
+         case dwarf::VS_location:
+           _m_value = new value_location (other.location ());
+           break;
+#if 0
+         case dwarf::VS_macptr:
+           _m_value = new value_macptr (other.macptr ());
+           break;
+#endif
+         default:
+         case dwarf::VS_discr_list:
+           throw std::runtime_error ("XXX unimplemented");
+         }
+      }
+
+      template<typename flavor>
+      inline flavor &variant () const
+      {
+       flavor *p = dynamic_cast<flavor *> (_m_value);
+       if (p == NULL)
+         throw std::runtime_error ("wrong value type");
+       return *p;
+      }
+
+    public:
+      attr_value (const attr_value &other) : _m_value (NULL)
+      {
+       init (other);
+      }
+      template<typename value>
+      attr_value (const value &other) : _m_value (NULL)
+      {
+       init (other);
+      }
+
+      attr_value () : _m_value (NULL) {}
+
+      ~attr_value ()
+      {
+       if (_m_value != NULL)
+         delete _m_value;
+      }
+
+      inline attr_value &operator= (const attr_value &other)
+      {
+       if (_m_value != NULL)
+         {
+           delete _m_value;
+           _m_value = NULL;
+         }
+       init (other);
+       return *this;
+      }
+      template<typename value>
+      inline attr_value &operator= (const value &other)
+      {
+       if (_m_value != NULL)
+         {
+           delete _m_value;
+           _m_value = NULL;
+         }
+       init (other);
+       return *this;
+      }
+
+      dwarf::value_space what_space () const;
+      std::string to_string () const;
+
+      inline bool &flag () const
+      {
+       return variant<value_flag> ().flag;
+      }
+
+      // XXX dwfl, reloc
+      inline ::Dwarf_Addr &address () const
+      {
+       return variant<value_address> ().addr;
+      }
+
+      inline debug_info_entry::children::iterator reference () const
+      {
+       return variant<value_reference> ().ref;
+      }
+      inline compile_units::iterator unit_reference () const
+      {
+       return variant<value_unit_reference> ().ref;
+      }
+
+      inline location_attr &location () const
+      {
+       return static_cast<location_attr &> (variant<value_location> ());
+      }
+
+      inline std::string &string () const
+      {
+       return static_cast<std::string &> (variant<value_string> ());
+      }
+      inline std::string &identifier () const
+      {
+       return string ();
+      }
+
+      inline dwarf_edit::source_file &source_file () const
+      {
+       return static_cast<dwarf_edit::source_file &>
+         (variant<value_source_file> ());
+      }
+
+      inline unsigned int &source_line () const
+      {
+       return variant<value_source_line> ().n;
+      }
+
+      inline unsigned int &source_column () const
+      {
+       return variant<value_source_column> ().n;
+      }
+
+      inline ::Dwarf_Word &constant () const
+      {
+       return variant<value_constant> ().word;
+      }
+
+      inline ::Dwarf_Sword &signed_constant () const
+      {
+       return variant<value_constant> ().sword;
+      }
+
+      inline std::vector<uint8_t> &constant_block () const
+      {
+       return static_cast<std::vector<uint8_t> &>
+         (variant<value_constant_block> ());
+      }
+
+      // dwarf_constant<>
+
+      inline range_list &ranges () const
+      {
+       return static_cast<range_list &> (variant<value_rangelistptr> ());
+      }
+
+      inline line_info_table &line_info () const
+      {
+       return static_cast<line_info_table &> (variant<value_lineptr> ());
+      }
+
+      // macptr
+
+      template<typename value>
+      inline bool operator== (const value &other) const
+      {
+       const dwarf::value_space what = what_space ();
+       if (likely (other.what_space () == what))
+         switch (what)
+           {
+           case dwarf::VS_identifier:
+             return identifier () == other.identifier ();
+           case dwarf::VS_string:
+             return string () == other.string ();
+           case dwarf::VS_reference:
+             return reference () == other.reference ();
+           case dwarf::VS_unit_reference:
+             return unit_reference () == other.unit_reference ();
+           case dwarf::VS_flag:
+             return flag () == other.flag ();
+           case dwarf::VS_rangelistptr:
+             return ranges () == other.ranges ();
+           case dwarf::VS_lineptr:
+             return line_info () == other.line_info ();
+           case dwarf::VS_constant:
+             return constant () == other.constant ();
+           case dwarf::VS_source_file:
+             return source_file () == other.source_file ();
+           case dwarf::VS_source_line:
+             return source_line () == other.source_line ();
+           case dwarf::VS_source_column:
+             return source_column () == other.source_column ();
+           case dwarf::VS_address:
+             return address () == other.address ();
+           case dwarf::VS_location:
+             return location () == other.location ();
+           case dwarf::VS_dwarf_constant:
+             return constant () == other.constant (); // XXX
+#if 0
+           case dwarf::VS_macptr:
+             return macptr () == other.macptr ();
+#endif
+           default:
+           case dwarf::VS_discr_list:
+             throw std::runtime_error ("XXX unimplemented");
+           }
+       return false;
+      }
+      template<typename value>
+      inline bool operator!= (const value &other) const
+      {
+       return !(*this == other);
+      }
+    };
+
   private:
     compile_units _m_units;
 
diff --git a/libdw/c++/edit-values.cc b/libdw/c++/edit-values.cc
new file mode 100644 (file)
index 0000000..c579c67
--- /dev/null
@@ -0,0 +1,91 @@
+/* elfutils::dwarf_edit attribute value interfaces.
+   Copyright (C) 2009 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#include <config.h>
+#include "dwarf_edit"
+
+using namespace elfutils;
+
+
+dwarf::value_space
+dwarf_edit::attr_value::what_space () const
+{
+  if (typeid (*_m_value) == typeid (value_flag))
+    return dwarf::VS_flag;
+  if (typeid (*_m_value) == typeid (value_dwarf_constant))
+    return dwarf::VS_dwarf_constant;
+  if (typeid (*_m_value) == typeid (value_reference))
+    return dwarf::VS_reference;
+  if (typeid (*_m_value) == typeid (value_unit_reference))
+    return dwarf::VS_unit_reference;
+  if (typeid (*_m_value) == typeid (value_lineptr))
+    return dwarf::VS_lineptr;
+  if (typeid (*_m_value) == typeid (value_macptr))
+    return dwarf::VS_macptr;
+  if (typeid (*_m_value) == typeid (value_rangelistptr))
+    return dwarf::VS_rangelistptr;
+  if (typeid (*_m_value) == typeid (value_identifier))
+    return dwarf::VS_identifier;
+  if (typeid (*_m_value) == typeid (value_string))
+    return dwarf::VS_string;
+  if (typeid (*_m_value) == typeid (value_source_file))
+    return dwarf::VS_source_file;
+  if (typeid (*_m_value) == typeid (value_source_line))
+    return dwarf::VS_source_line;
+  if (typeid (*_m_value) == typeid (value_source_column))
+    return dwarf::VS_source_column;
+  if (typeid (*_m_value) == typeid (value_address))
+    return dwarf::VS_address;
+  if (typeid (*_m_value) == typeid (value_constant))
+    return dwarf::VS_constant;
+  if (typeid (*_m_value) == typeid (value_location))
+    return dwarf::VS_location;
+
+  throw std::runtime_error ("XXX impossible");
+}
index 7e2e9aad801c44f310bb54123e0f638220115539..032c621c23481293dfed48d8a1a28df997bbb2f1 100644 (file)
@@ -83,7 +83,8 @@ libar_a_SOURCES = arlib.c arlib2.c
 
 # XXX need to figure out C++ dso crapola
 libdwplusplus_SOURCES = ../libdw/c++/values.cc ../libdw/c++/known.cc \
-                       ../libdw/c++/line_info.cc
+                       ../libdw/c++/line_info.cc \
+                       ../libdw/c++/edit-values.cc
 
 dwarfcmp_SOURCES = dwarfcmp.cc
 dwarfcmp_SOURCES += $(libdwplusplus_SOURCES)