[PATCH 22/43] Add to_value method to DWARF entry classes

Zoran Zaric via Gdb-patches
2021-03-01T14:47:20Z

Following the idea from the last patch this patch is adding another
conversion method from any DWARF entry object into a DWARF value
object.

Currently, we only know how to convert from a memory location
description into a value, but it is resonable to expect a set of target
hooks that would let the target decide on how to do other conversions
in the future.

gdb/ChangeLog:

* dwarf2/expr.c (dwarf_entry::to_value): New method.
(dwarf_location::to_value): New method.
(dwarf_memory::to_value): New method.
(ill_formed_expression): New function.
---
gdb/dwarf2/expr.c | 40 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 40 insertions(+)

diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index d0c0efd2d31..69be36fcf2d 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -97,6 +97,14 @@ bits_to_bytes (ULONGEST start, ULONGEST n_bits)
return (start % HOST_CHAR_BIT + n_bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
}

+/* Throw an exception about the invalid DWARF expression. */
+
+static void
+ill_formed_expression ()
+{
+ error (_("Ill-formed DWARF expression"));
+}
+
/* See expr.h. */

CORE_ADDR
@@ -279,6 +287,7 @@ write_to_memory (CORE_ADDR address, const gdb_byte *buffer,

class dwarf_location;
class dwarf_memory;
+class dwarf_value;

/* Base class that describes entries found on a DWARF expression
evaluation stack. */
@@ -295,6 +304,11 @@ class dwarf_entry : public std::enable_shared_from_this<dwarf_entry>
defines an architecture of the location described. */
virtual std::shared_ptr<dwarf_location> to_location
(struct gdbarch *arch) = 0;
+
+ /* Convert DWARF entry into a DWARF value. TYPE defines a
+ desired type of the returned DWARF value if it already
+ doesnt have one. */
+ virtual std::shared_ptr<dwarf_value> to_value (struct type *type) = 0;
};

dwarf_entry::~dwarf_entry () = default;
@@ -345,6 +359,16 @@ class dwarf_location : public dwarf_entry
return std::dynamic_pointer_cast<dwarf_location> (shared_from_this ());
}

+ /* Convert DWARF entry into a DWARF value. If the conversion
+ from that location description kind to a value is not supported
+ the result is an empty pointer. TYPE defines a desired type of
+ the returned DWARF value if it already doesnt have one. */
+ virtual std::shared_ptr<dwarf_value> to_value (struct type *type) override
+ {
+ ill_formed_expression ();
+ return std::shared_ptr<dwarf_value> (nullptr);
+ }
+
protected:
/* Architecture of the location. */
struct gdbarch *m_arch;
@@ -409,6 +433,14 @@ class dwarf_value : public dwarf_entry
ARCH defines an architecture of the location described. */
std::shared_ptr<dwarf_location> to_location (struct gdbarch *arch) override;

+ /* Convert DWARF entry into a DWARF value. If the entry
+ is already a value, it is just returned and the TYPE type
+ information is ignored. */
+ std::shared_ptr<dwarf_value> to_value (struct type *type) override
+ {
+ return std::dynamic_pointer_cast<dwarf_value> (shared_from_this ());
+ }
+
private:
/* Value contents as a stream of bytes in target byte order. */
gdb::unique_xmalloc_ptr<gdb_byte> m_contents;
@@ -459,11 +491,19 @@ class dwarf_memory : public dwarf_location
m_stack = stack;
};

+ std::shared_ptr<dwarf_value> to_value (struct type *type) override;
+
private:
/* True if the location belongs to a stack memory region. */
bool m_stack;
};

+std::shared_ptr<dwarf_value>
+dwarf_memory::to_value (struct type *type)
+{
+ return std::make_shared<dwarf_value> (m_offset, type);
+}
+
/* Register location description entry. */

class dwarf_register : public dwarf_location
--
2.17.1