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.
This commit is contained in:
Zoran Zaric
2021-02-24 11:43:52 +00:00
committed by Zoran Zaric
parent 0dd1a71b4d
commit 851fa76da8
2 changed files with 43 additions and 0 deletions

View 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

View 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 */