From: Zoran Zaric Date: Wed, 24 Feb 2021 11:43:52 +0000 (+0000) Subject: Add to_location method to dwarf_value class X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=851fa76da81ae006da9797755dab9ecd3d338e92;p=thirdparty%2Fbinutils-gdb.git Add to_location method to dwarf_value class 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. --- diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index 6363bcc4707..2cb93706ac4 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -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; + /* 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; + /* 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 (arch, offset); +} + /* Register location description entry. */ class dwarf_register final : public dwarf_location diff --git a/gdbsupport/common-utils.h b/gdbsupport/common-utils.h index 224e1f31222..be1b805f7c8 100644 --- a/gdbsupport/common-utils.h +++ b/gdbsupport/common-utils.h @@ -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 + +using std::make_unique; +#else +namespace gdb { + +/* Stolen from libstdc++ and adjusted, so probably fine license-wise. */ +template +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 */