]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
Add to_location method to dwarf_value class
authorZoran Zaric <Zoran.Zaric@amd.com>
Wed, 24 Feb 2021 11:43:52 +0000 (11:43 +0000)
committerZoran Zaric <zoran.zaric@amd.com>
Fri, 5 Nov 2021 11:46:38 +0000 (11:46 +0000)
DWARF standard already contains an implicit conversion between location
description and a DWARF value. In the DWARF 5 version, one place
where this can happen is at the very end of the evaluation where a
client decides if the result is expected to be in a form of a value or
a location description (as_lval argument of the new evaluation method).

By allowing any location description to be on the DWARF stack, these
implicit conversions are expected on per operation basis which means
that the new dwarf_value class need to have a support for it.

This patch adds a conversion method from a dwarf_value object into a
location description object.

To support the conversion method we also need an implementation of the
C++14 standard library function make_unique which was copied from the
standard library implementation.

gdb/ChangeLog:

        * dwarf2/expr.c (class dwarf_value::to_location): New method.

gdbsupport/ChangeLog:

        * common-utils.h (make_unique): New function.

gdb/dwarf2/expr.c
gdbsupport/common-utils.h

index 6363bcc4707369a3b82324d199f74bdcd30287e7..2cb93706ac42abe4cead6b96f26a2dacf3a3bdd5 100644 (file)
@@ -271,6 +271,8 @@ write_to_memory (CORE_ADDR address, const gdb_byte *buffer,
                                         length, buffer);
 }
 
+class dwarf_location;
+
 /* Base class that describes entries found on a DWARF expression
    evaluation stack.  */
 
@@ -284,6 +286,8 @@ public:
   virtual ~dwarf_entry () = default;
 };
 
+using dwarf_entry_up = std::unique_ptr<dwarf_entry>;
+
 /* Location description entry found on a DWARF expression evaluation
    stack.
 
@@ -332,6 +336,8 @@ protected:
   bool m_initialised = true;
 };
 
+using dwarf_location_up = std::unique_ptr<dwarf_location>;
+
 /* Value entry found on a DWARF expression evaluation stack.  */
 
 class dwarf_value final : public dwarf_entry
@@ -373,6 +379,10 @@ public:
     return unpack_long (m_type, m_contents.data ());
   }
 
+  /* Convert DWARF value into a DWARF memory location description.
+     ARCH defines an architecture of the location described.  */
+  dwarf_location_up to_location (struct gdbarch *arch) const;
+
 private:
   /* Value contents as a stream of bytes in target byte order.  */
   gdb::byte_vector m_contents;
@@ -410,6 +420,21 @@ private:
   bool m_stack;
 };
 
+dwarf_location_up
+dwarf_value::to_location (struct gdbarch *arch) const
+{
+  LONGEST offset;
+
+  if (gdbarch_integer_to_address_p (arch))
+    offset = gdbarch_integer_to_address (arch, m_type, m_contents.data ());
+  else
+    offset = extract_unsigned_integer (m_contents.data (),
+                                      TYPE_LENGTH (m_type),
+                                      type_byte_order (m_type));
+
+  return make_unique<dwarf_memory> (arch, offset);
+}
+
 /* Register location description entry.  */
 
 class dwarf_register final : public dwarf_location
index 224e1f3122268b49e598f76158a5c5e84cc6ed5b..be1b805f7c896ad6c23f0fbbe8788a9e742d19b7 100644 (file)
@@ -206,4 +206,22 @@ extern int hex2bin (const char *hex, gdb_byte *bin, int count);
 /* Like the above, but return a gdb::byte_vector.  */
 gdb::byte_vector hex2bin (const char *hex);
 
+#if __cplusplus >= 201402L
+#include <memory>
+
+using std::make_unique;
+#else
+namespace gdb {
+
+/* Stolen from libstdc++ and adjusted, so probably fine license-wise.  */
+template<typename _Tp, typename ... _Args>
+std::unique_ptr<_Tp>
+make_unique (_Args &&... __args)
+{
+  return std::unique_ptr<_Tp> (new _Tp (std::forward<_Args>(__args)...));
+}
+
+}
+#endif /* __cplusplus >= 201402L */
+
 #endif /* COMMON_COMMON_UTILS_H */