[PATCH 21/43] Add to_location method to DWARF entry classes

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

DWARF standard already contains an implicit conversion between location
description and a DWARF value. In the DWARF 5 version, the only 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 entry classes need to have a support for those.

This patch adds a conversion method from any DWARF entry object into a
location description object.

gdb/ChangeLog:

* dwarf2/expr.c (class dwarf_entry::to_location): New method.
(class dwarf_value::to_location): New method.
(class dwarf_location::to_location): New method.
---
gdb/dwarf2/expr.c | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)

diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c
index 5d47dc83aaa..d0c0efd2d31 100644
--- a/gdb/dwarf2/expr.c
+++ b/gdb/dwarf2/expr.c
@@ -277,6 +277,9 @@ write_to_memory (CORE_ADDR address, const gdb_byte *buffer,
length, buffer);
}

+class dwarf_location;
+class dwarf_memory;
+
/* Base class that describes entries found on a DWARF expression
evaluation stack. */

@@ -287,6 +290,11 @@ class dwarf_entry : public std::enable_shared_from_this<dwarf_entry>
dwarf_entry () = default;

virtual ~dwarf_entry () = 0;
+
+ /* Convert DWARF entry into a DWARF location description. ARCH
+ defines an architecture of the location described. */
+ virtual std::shared_ptr<dwarf_location> to_location
+ (struct gdbarch *arch) = 0;
};

dwarf_entry::~dwarf_entry () = default;
@@ -328,6 +336,15 @@ class dwarf_location : public dwarf_entry
m_initialised = initialised;
};

+ /* Convert DWARF entry into a DWARF location description. If the
+ entry is already a location description, it will be returned as a
+ result and no conversion will be applied to it. ARCH defines an
+ architecture of the location described. */
+ std::shared_ptr<dwarf_location> to_location (struct gdbarch *arch) override
+ {
+ return std::dynamic_pointer_cast<dwarf_location> (shared_from_this ());
+ }
+
protected:
/* Architecture of the location. */
struct gdbarch *m_arch;
@@ -388,6 +405,10 @@ class dwarf_value : public dwarf_entry
return unpack_long (m_type, m_contents.get ());
}

+ /* Convert DWARF value into a DWARF memory location description.
+ ARCH defines an architecture of the location described. */
+ std::shared_ptr<dwarf_location> to_location (struct gdbarch *arch) override;
+
private:
/* Value contents as a stream of bytes in target byte order. */
gdb::unique_xmalloc_ptr<gdb_byte> m_contents;
@@ -396,6 +417,21 @@ class dwarf_value : public dwarf_entry
struct type *m_type;
};

+std::shared_ptr<dwarf_location>
+dwarf_value::to_location (struct gdbarch *arch)
+{
+ LONGEST offset;
+
+ if (gdbarch_integer_to_address_p (arch))
+ offset = gdbarch_integer_to_address (arch, m_type, m_contents.get ());
+ else
+ offset = extract_unsigned_integer (m_contents.get (), TYPE_LENGTH (m_type),
+ type_byte_order (m_type));
+
+ auto memory = std::make_shared<dwarf_memory> (arch, offset);
+ return std::dynamic_pointer_cast<dwarf_location> (memory);
+}
+
/* Undefined location description entry. This is a special location
description type that describes the location description that is
not known. */
--
2.17.1