Simplify dwarf_expr_context class interface

Idea of this patch is to get a clean and simple public interface for
the dwarf_expr_context class, looking like:

- constructor,
- destructor,
- push_address method and
- evaluate method.

Where constructor should only ever require a target architecture
information. This information is held in per object file
(dwarf2_per_objfile) structure, so it makes sense to keep that
structure as a constructor argument. It also makes sense to get the
address size from that structure, but unfortunately that interface
doesn't exist at the moment, so the dwarf_expr_context class user
needs to provide that information.

The push_address method is used to push a CORE_ADDR as a value on
top of the DWARF stack before the evaluation. This method can be
later changed to push any struct value object on the stack.

The evaluate method is the method that evaluates a DWARF expression
and provides the evaluation result, in a form of a single struct
value object that describes a location. To do this, the method requires
a context of the evaluation, as well as expected result type
information. If the type information is not provided, the DWARF generic
type will be used instead.

To avoid storing the gdbarch information in the evaluator object, that
information is now always acquired from the per_objfile object.

All data members are now private and only visible to the evaluator
class, so a m_ prefix was added to all of their names to reflect that.
To make this distinction clear, they are also accessed through objects
this pointer, wherever that was not the case before.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::dwarf_expr_context): Add
	address size argument.
	(dwarf_expr_context::read_mem): Change to use property_addr_info
	structure.
	(dwarf_expr_context::evaluate): New function.
	(dwarf_expr_context::execute_stack_op): Change to use
	property_addr_info structure.
	* dwarf2/expr.h (struct dwarf_expr_context): New evaluate
	declaration. Change eval and fetch_result method to private.
        (dwarf_expr_context::gdbarch): Remove member.
        (dwarf_expr_context::stack): Make private and add m_ prefix.
        (dwarf_expr_context::addr_size): Make private and add
        m_ prefix.
        (dwarf_expr_context::recursion_depth): Make private and add
        m_ prefix.
        (dwarf_expr_context::max_recursion_depth): Make private and
        add m_ prefix.
        (dwarf_expr_context::len): Make private and add m_ prefix.
        (dwarf_expr_context::data): Make private and add m_ prefix.
        (dwarf_expr_context::initialized): Make private and add
        m_ prefix.
        (dwarf_expr_context::pieces): Make private and add m_ prefix.
        (dwarf_expr_context::per_objfile): Make private and add
        m_ prefix.
        (dwarf_expr_context::frame): Make private and add m_ prefix.
        (dwarf_expr_context::per_cu): Make private and add m_ prefix.
        (dwarf_expr_context::addr_info): Make private and add
        m_ prefix.
	* dwarf2/frame.c (execute_stack_op): Change to call evaluate
	method.
	* dwarf2/loc.c (dwarf2_evaluate_loc_desc_full): Change to call
	evaluate method.
	(dwarf2_locexpr_baton_eval): Change to call evaluate method.
This commit is contained in:
Zoran Zaric 2020-09-17 10:28:20 +01:00
parent ba5bc3e5a9
commit 0579205aec
4 changed files with 237 additions and 232 deletions

View file

@ -668,25 +668,24 @@ sect_variable_value (sect_offset sect_off,
struct type * struct type *
dwarf_expr_context::address_type () const dwarf_expr_context::address_type () const
{ {
struct dwarf_gdbarch_types *types gdbarch *arch = this->m_per_objfile->objfile->arch ();
= (struct dwarf_gdbarch_types *) gdbarch_data (this->gdbarch, dwarf_gdbarch_types *types
dwarf_arch_cookie); = (dwarf_gdbarch_types *) gdbarch_data (arch, dwarf_arch_cookie);
int ndx; int ndx;
if (this->addr_size == 2) if (this->m_addr_size == 2)
ndx = 0; ndx = 0;
else if (this->addr_size == 4) else if (this->m_addr_size == 4)
ndx = 1; ndx = 1;
else if (this->addr_size == 8) else if (this->m_addr_size == 8)
ndx = 2; ndx = 2;
else else
error (_("Unsupported address size in DWARF expressions: %d bits"), error (_("Unsupported address size in DWARF expressions: %d bits"),
8 * this->addr_size); 8 * this->m_addr_size);
if (types->dw_types[ndx] == NULL) if (types->dw_types[ndx] == NULL)
types->dw_types[ndx] types->dw_types[ndx]
= arch_integer_type (this->gdbarch, = arch_integer_type (arch, 8 * this->m_addr_size,
8 * this->addr_size,
0, "<signed DWARF address type>"); 0, "<signed DWARF address type>");
return types->dw_types[ndx]; return types->dw_types[ndx];
@ -694,8 +693,10 @@ dwarf_expr_context::address_type () const
/* Create a new context for the expression evaluator. */ /* Create a new context for the expression evaluator. */
dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile) dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile,
: per_objfile (per_objfile) int addr_size)
: m_addr_size (addr_size),
m_per_objfile (per_objfile)
{ {
} }
@ -704,7 +705,7 @@ dwarf_expr_context::dwarf_expr_context (dwarf2_per_objfile *per_objfile)
void void
dwarf_expr_context::push (struct value *value, bool in_stack_memory) dwarf_expr_context::push (struct value *value, bool in_stack_memory)
{ {
stack.emplace_back (value, in_stack_memory); this->m_stack.emplace_back (value, in_stack_memory);
} }
/* Push VALUE onto the stack. */ /* Push VALUE onto the stack. */
@ -720,10 +721,10 @@ dwarf_expr_context::push_address (CORE_ADDR value, bool in_stack_memory)
void void
dwarf_expr_context::pop () dwarf_expr_context::pop ()
{ {
if (stack.empty ()) if (this->m_stack.empty ())
error (_("dwarf expression stack underflow")); error (_("dwarf expression stack underflow"));
stack.pop_back (); this->m_stack.pop_back ();
} }
/* Retrieve the N'th item on the stack. */ /* Retrieve the N'th item on the stack. */
@ -731,11 +732,11 @@ dwarf_expr_context::pop ()
struct value * struct value *
dwarf_expr_context::fetch (int n) dwarf_expr_context::fetch (int n)
{ {
if (stack.size () <= n) if (this->m_stack.size () <= n)
error (_("Asked for position %d of stack, " error (_("Asked for position %d of stack, "
"stack only has %zu elements on it."), "stack only has %zu elements on it."),
n, stack.size ()); n, this->m_stack.size ());
return stack[stack.size () - (1 + n)].value; return this->m_stack[this->m_stack.size () - (1 + n)].value;
} }
/* See expr.h. */ /* See expr.h. */
@ -744,9 +745,9 @@ void
dwarf_expr_context::get_frame_base (const gdb_byte **start, dwarf_expr_context::get_frame_base (const gdb_byte **start,
size_t * length) size_t * length)
{ {
ensure_have_frame (this->frame, "DW_OP_fbreg"); ensure_have_frame (this->m_frame, "DW_OP_fbreg");
const block *bl = get_frame_block (this->frame, NULL); const block *bl = get_frame_block (this->m_frame, NULL);
if (bl == NULL) if (bl == NULL)
error (_("frame address is not available.")); error (_("frame address is not available."));
@ -762,7 +763,7 @@ dwarf_expr_context::get_frame_base (const gdb_byte **start,
gdb_assert (framefunc != NULL); gdb_assert (framefunc != NULL);
func_get_frame_base_dwarf_block (framefunc, func_get_frame_base_dwarf_block (framefunc,
get_frame_address_in_block (this->frame), get_frame_address_in_block (this->m_frame),
start, length); start, length);
} }
@ -771,11 +772,11 @@ dwarf_expr_context::get_frame_base (const gdb_byte **start,
struct type * struct type *
dwarf_expr_context::get_base_type (cu_offset die_cu_off) dwarf_expr_context::get_base_type (cu_offset die_cu_off)
{ {
if (per_cu == nullptr) if (this->m_per_cu == nullptr)
return builtin_type (this->gdbarch)->builtin_int; return builtin_type (this->m_per_objfile->objfile->arch ())->builtin_int;
struct type *result = dwarf2_get_die_type (die_cu_off, this->per_cu, struct type *result = dwarf2_get_die_type (die_cu_off, this->m_per_cu,
this->per_objfile); this->m_per_objfile);
if (result == nullptr) if (result == nullptr)
error (_("Could not find type for operation")); error (_("Could not find type for operation"));
@ -788,9 +789,9 @@ dwarf_expr_context::get_base_type (cu_offset die_cu_off)
void void
dwarf_expr_context::dwarf_call (cu_offset die_cu_off) dwarf_expr_context::dwarf_call (cu_offset die_cu_off)
{ {
ensure_have_per_cu (this->per_cu, "DW_OP_call"); ensure_have_per_cu (this->m_per_cu, "DW_OP_call");
frame_info *frame = this->frame; frame_info *frame = this->m_frame;
auto get_pc_from_frame = [frame] () auto get_pc_from_frame = [frame] ()
{ {
@ -799,11 +800,11 @@ dwarf_expr_context::dwarf_call (cu_offset die_cu_off)
}; };
dwarf2_locexpr_baton block dwarf2_locexpr_baton block
= dwarf2_fetch_die_loc_cu_off (die_cu_off, this->per_cu, this->per_objfile, = dwarf2_fetch_die_loc_cu_off (die_cu_off, this->m_per_cu,
get_pc_from_frame); this->m_per_objfile, get_pc_from_frame);
/* DW_OP_call_ref is currently not supported. */ /* DW_OP_call_ref is currently not supported. */
gdb_assert (block.per_cu == this->per_cu); gdb_assert (block.per_cu == this->m_per_cu);
this->eval (block.data, block.size); this->eval (block.data, block.size);
} }
@ -818,13 +819,16 @@ dwarf_expr_context::read_mem (gdb_byte *buf, CORE_ADDR addr,
return; return;
/* Prefer the passed-in memory, if it exists. */ /* Prefer the passed-in memory, if it exists. */
CORE_ADDR offset = addr - this->obj_address; if (this->m_addr_info != nullptr)
if (offset < this->data_view.size ()
&& offset + length <= this->data_view.size ())
{ {
memcpy (buf, this->data_view.data (), length); CORE_ADDR offset = addr - this->m_addr_info->addr;
return;
if (offset < this->m_addr_info->valaddr.size ()
&& offset + length <= this->m_addr_info->valaddr.size ())
{
memcpy (buf, this->m_addr_info->valaddr.data (), length);
return;
}
} }
read_memory (addr, buf, length); read_memory (addr, buf, length);
@ -837,14 +841,14 @@ dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind,
call_site_parameter_u kind_u, call_site_parameter_u kind_u,
int deref_size) int deref_size)
{ {
ensure_have_per_cu (this->per_cu, "DW_OP_entry_value"); ensure_have_per_cu (this->m_per_cu, "DW_OP_entry_value");
ensure_have_frame (this->frame, "DW_OP_entry_value"); ensure_have_frame (this->m_frame, "DW_OP_entry_value");
dwarf2_per_cu_data *caller_per_cu; dwarf2_per_cu_data *caller_per_cu;
dwarf2_per_objfile *caller_per_objfile; dwarf2_per_objfile *caller_per_objfile;
frame_info *caller_frame = get_prev_frame (this->frame); frame_info *caller_frame = get_prev_frame (this->m_frame);
call_site_parameter *parameter call_site_parameter *parameter
= dwarf_expr_reg_to_entry_parameter (this->frame, kind, kind_u, = dwarf_expr_reg_to_entry_parameter (this->m_frame, kind, kind_u,
&caller_per_cu, &caller_per_cu,
&caller_per_objfile); &caller_per_objfile);
const gdb_byte *data_src const gdb_byte *data_src
@ -863,19 +867,17 @@ dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind,
It is possible for the caller to be from a different objfile from the It is possible for the caller to be from a different objfile from the
callee if the call is made through a function pointer. */ callee if the call is made through a function pointer. */
scoped_restore save_frame = make_scoped_restore (&this->frame, scoped_restore save_frame = make_scoped_restore (&this->m_frame,
caller_frame); caller_frame);
scoped_restore save_per_cu = make_scoped_restore (&this->per_cu, scoped_restore save_per_cu = make_scoped_restore (&this->m_per_cu,
caller_per_cu); caller_per_cu);
scoped_restore save_obj_addr = make_scoped_restore (&this->obj_address, scoped_restore save_addr_info = make_scoped_restore (&this->m_addr_info,
(CORE_ADDR) 0); nullptr);
scoped_restore save_per_objfile = make_scoped_restore (&this->per_objfile, scoped_restore save_per_objfile = make_scoped_restore (&this->m_per_objfile,
caller_per_objfile); caller_per_objfile);
scoped_restore save_arch = make_scoped_restore (&this->gdbarch); scoped_restore save_addr_size = make_scoped_restore (&this->m_addr_size);
this->gdbarch = this->per_objfile->objfile->arch (); this->m_addr_size = this->m_per_cu->addr_size ();
scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
this->addr_size = this->per_cu->addr_size ();
this->eval (data_src, size); this->eval (data_src, size);
} }
@ -887,6 +889,7 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
LONGEST subobj_offset) LONGEST subobj_offset)
{ {
value *retval = nullptr; value *retval = nullptr;
gdbarch *arch = this->m_per_objfile->objfile->arch ();
if (type == nullptr) if (type == nullptr)
type = address_type (); type = address_type ();
@ -894,11 +897,11 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
if (subobj_type == nullptr) if (subobj_type == nullptr)
subobj_type = type; subobj_type = type;
if (this->pieces.size () > 0) if (this->m_pieces.size () > 0)
{ {
ULONGEST bit_size = 0; ULONGEST bit_size = 0;
for (dwarf_expr_piece &piece : this->pieces) for (dwarf_expr_piece &piece : this->m_pieces)
bit_size += piece.size; bit_size += piece.size;
/* Complain if the expression is larger than the size of the /* Complain if the expression is larger than the size of the
outer type. */ outer type. */
@ -906,30 +909,29 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
invalid_synthetic_pointer (); invalid_synthetic_pointer ();
piece_closure *c piece_closure *c
= allocate_piece_closure (this->per_cu, this->per_objfile, = allocate_piece_closure (this->m_per_cu, this->m_per_objfile,
std::move (this->pieces), this->frame); std::move (this->m_pieces), this->m_frame);
retval = allocate_computed_value (subobj_type, retval = allocate_computed_value (subobj_type,
&pieced_value_funcs, c); &pieced_value_funcs, c);
set_value_offset (retval, subobj_offset); set_value_offset (retval, subobj_offset);
} }
else else
{ {
switch (this->location) switch (this->m_location)
{ {
case DWARF_VALUE_REGISTER: case DWARF_VALUE_REGISTER:
{ {
int dwarf_regnum int dwarf_regnum
= longest_to_int (value_as_long (this->fetch (0))); = longest_to_int (value_as_long (this->fetch (0)));
int gdb_regnum = dwarf_reg_to_regnum_or_error (this->gdbarch, int gdb_regnum = dwarf_reg_to_regnum_or_error (arch, dwarf_regnum);
dwarf_regnum);
if (subobj_offset != 0) if (subobj_offset != 0)
error (_("cannot use offset on synthetic pointer to register")); error (_("cannot use offset on synthetic pointer to register"));
gdb_assert (this->frame != NULL); gdb_assert (this->m_frame != NULL);
retval = value_from_register (subobj_type, gdb_regnum, retval = value_from_register (subobj_type, gdb_regnum,
this->frame); this->m_frame);
if (value_optimized_out (retval)) if (value_optimized_out (retval))
{ {
/* This means the register has undefined value / was /* This means the register has undefined value / was
@ -964,10 +966,10 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
{ {
case TYPE_CODE_FUNC: case TYPE_CODE_FUNC:
case TYPE_CODE_METHOD: case TYPE_CODE_METHOD:
ptr_type = builtin_type (this->gdbarch)->builtin_func_ptr; ptr_type = builtin_type (arch)->builtin_func_ptr;
break; break;
default: default:
ptr_type = builtin_type (this->gdbarch)->builtin_data_ptr; ptr_type = builtin_type (arch)->builtin_data_ptr;
break; break;
} }
address = value_as_address (value_from_pointer (ptr_type, address)); address = value_as_address (value_from_pointer (ptr_type, address));
@ -992,7 +994,7 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
retval = allocate_value (subobj_type); retval = allocate_value (subobj_type);
/* The given offset is relative to the actual object. */ /* The given offset is relative to the actual object. */
if (gdbarch_byte_order (this->gdbarch) == BFD_ENDIAN_BIG) if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG)
subobj_offset += n - max; subobj_offset += n - max;
memcpy (value_contents_raw (retval), memcpy (value_contents_raw (retval),
@ -1004,12 +1006,12 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
{ {
size_t n = TYPE_LENGTH (subobj_type); size_t n = TYPE_LENGTH (subobj_type);
if (subobj_offset + n > this->len) if (subobj_offset + n > this->m_len)
invalid_synthetic_pointer (); invalid_synthetic_pointer ();
retval = allocate_value (subobj_type); retval = allocate_value (subobj_type);
bfd_byte *contents = value_contents_raw (retval); bfd_byte *contents = value_contents_raw (retval);
memcpy (contents, this->data + subobj_offset, n); memcpy (contents, this->m_data + subobj_offset, n);
} }
break; break;
@ -1027,11 +1029,28 @@ dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type,
} }
} }
set_value_initialized (retval, this->initialized); set_value_initialized (retval, this->m_initialized);
return retval; return retval;
} }
/* See expr.h. */
value *
dwarf_expr_context::evaluate (const gdb_byte *addr, size_t len,
dwarf2_per_cu_data *per_cu, frame_info *frame,
const struct property_addr_info *addr_info,
struct type *type, struct type *subobj_type,
LONGEST subobj_offset)
{
this->m_per_cu = per_cu;
this->m_frame = frame;
this->m_addr_info = addr_info;
eval (addr, len);
return fetch_result (type, subobj_type, subobj_offset);
}
/* Require that TYPE be an integral type; throw an exception if not. */ /* Require that TYPE be an integral type; throw an exception if not. */
static void static void
@ -1092,8 +1111,9 @@ get_signed_type (struct gdbarch *gdbarch, struct type *type)
CORE_ADDR CORE_ADDR
dwarf_expr_context::fetch_address (int n) dwarf_expr_context::fetch_address (int n)
{ {
struct value *result_val = fetch (n); gdbarch *arch = this->m_per_objfile->objfile->arch ();
enum bfd_endian byte_order = gdbarch_byte_order (this->gdbarch); value *result_val = fetch (n);
bfd_endian byte_order = gdbarch_byte_order (arch);
ULONGEST result; ULONGEST result;
dwarf_require_integral (value_type (result_val)); dwarf_require_integral (value_type (result_val));
@ -1107,14 +1127,14 @@ dwarf_expr_context::fetch_address (int n)
extract_unsigned_integer() will not produce a correct extract_unsigned_integer() will not produce a correct
result. Make sure we invoke gdbarch_integer_to_address() result. Make sure we invoke gdbarch_integer_to_address()
for those architectures which require it. */ for those architectures which require it. */
if (gdbarch_integer_to_address_p (this->gdbarch)) if (gdbarch_integer_to_address_p (arch))
{ {
gdb_byte *buf = (gdb_byte *) alloca (this->addr_size); gdb_byte *buf = (gdb_byte *) alloca (this->m_addr_size);
struct type *int_type = get_unsigned_type (this->gdbarch, type *int_type = get_unsigned_type (arch,
value_type (result_val)); value_type (result_val));
store_unsigned_integer (buf, this->addr_size, byte_order, result); store_unsigned_integer (buf, this->m_addr_size, byte_order, result);
return gdbarch_integer_to_address (this->gdbarch, int_type, buf); return gdbarch_integer_to_address (arch, int_type, buf);
} }
return (CORE_ADDR) result; return (CORE_ADDR) result;
@ -1125,11 +1145,11 @@ dwarf_expr_context::fetch_address (int n)
bool bool
dwarf_expr_context::fetch_in_stack_memory (int n) dwarf_expr_context::fetch_in_stack_memory (int n)
{ {
if (stack.size () <= n) if (this->m_stack.size () <= n)
error (_("Asked for position %d of stack, " error (_("Asked for position %d of stack, "
"stack only has %zu elements on it."), "stack only has %zu elements on it."),
n, stack.size ()); n, this->m_stack.size ());
return stack[stack.size () - (1 + n)].in_stack_memory; return this->m_stack[this->m_stack.size () - (1 + n)].in_stack_memory;
} }
/* Return true if the expression stack is empty. */ /* Return true if the expression stack is empty. */
@ -1137,24 +1157,24 @@ dwarf_expr_context::fetch_in_stack_memory (int n)
bool bool
dwarf_expr_context::stack_empty_p () const dwarf_expr_context::stack_empty_p () const
{ {
return stack.empty (); return m_stack.empty ();
} }
/* Add a new piece to the dwarf_expr_context's piece list. */ /* Add a new piece to the dwarf_expr_context's piece list. */
void void
dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset) dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
{ {
this->pieces.emplace_back (); this->m_pieces.emplace_back ();
dwarf_expr_piece &p = this->pieces.back (); dwarf_expr_piece &p = this->m_pieces.back ();
p.location = this->location; p.location = this->m_location;
p.size = size; p.size = size;
p.offset = offset; p.offset = offset;
if (p.location == DWARF_VALUE_LITERAL) if (p.location == DWARF_VALUE_LITERAL)
{ {
p.v.literal.data = this->data; p.v.literal.data = this->m_data;
p.v.literal.length = this->len; p.v.literal.length = this->m_len;
} }
else if (stack_empty_p ()) else if (stack_empty_p ())
{ {
@ -1163,7 +1183,7 @@ dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
a somewhat strange approach, but this lets us avoid setting a somewhat strange approach, but this lets us avoid setting
the location to DWARF_VALUE_MEMORY in all the individual the location to DWARF_VALUE_MEMORY in all the individual
cases in the evaluator. */ cases in the evaluator. */
this->location = DWARF_VALUE_OPTIMIZED_OUT; this->m_location = DWARF_VALUE_OPTIMIZED_OUT;
} }
else if (p.location == DWARF_VALUE_MEMORY) else if (p.location == DWARF_VALUE_MEMORY)
{ {
@ -1172,7 +1192,7 @@ dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
} }
else if (p.location == DWARF_VALUE_IMPLICIT_POINTER) else if (p.location == DWARF_VALUE_IMPLICIT_POINTER)
{ {
p.v.ptr.die_sect_off = (sect_offset) this->len; p.v.ptr.die_sect_off = (sect_offset) this->m_len;
p.v.ptr.offset = value_as_long (fetch (0)); p.v.ptr.offset = value_as_long (fetch (0));
} }
else if (p.location == DWARF_VALUE_REGISTER) else if (p.location == DWARF_VALUE_REGISTER)
@ -1188,13 +1208,13 @@ dwarf_expr_context::add_piece (ULONGEST size, ULONGEST offset)
void void
dwarf_expr_context::eval (const gdb_byte *addr, size_t len) dwarf_expr_context::eval (const gdb_byte *addr, size_t len)
{ {
int old_recursion_depth = this->recursion_depth; int old_recursion_depth = this->m_recursion_depth;
execute_stack_op (addr, addr + len); execute_stack_op (addr, addr + len);
/* RECURSION_DEPTH becomes invalid if an exception was thrown here. */ /* RECURSION_DEPTH becomes invalid if an exception was thrown here. */
gdb_assert (this->recursion_depth == old_recursion_depth); gdb_assert (this->m_recursion_depth == old_recursion_depth);
} }
/* Helper to read a uleb128 value or throw an error. */ /* Helper to read a uleb128 value or throw an error. */
@ -1438,7 +1458,8 @@ void
dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr, dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
const gdb_byte *op_end) const gdb_byte *op_end)
{ {
enum bfd_endian byte_order = gdbarch_byte_order (this->gdbarch); gdbarch *arch = this->m_per_objfile->objfile->arch ();
bfd_endian byte_order = gdbarch_byte_order (arch);
/* Old-style "untyped" DWARF values need special treatment in a /* Old-style "untyped" DWARF values need special treatment in a
couple of places, specifically DW_OP_mod and DW_OP_shr. We need couple of places, specifically DW_OP_mod and DW_OP_shr. We need
a special type for these values so we can distinguish them from a special type for these values so we can distinguish them from
@ -1446,19 +1467,19 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
values do not need special treatment. This special type must be values do not need special treatment. This special type must be
different (in the `==' sense) from any base type coming from the different (in the `==' sense) from any base type coming from the
CU. */ CU. */
struct type *address_type = this->address_type (); type *address_type = this->address_type ();
this->location = DWARF_VALUE_MEMORY; this->m_location = DWARF_VALUE_MEMORY;
this->initialized = 1; /* Default is initialized. */ this->m_initialized = 1; /* Default is initialized. */
if (this->recursion_depth > this->max_recursion_depth) if (this->m_recursion_depth > this->m_max_recursion_depth)
error (_("DWARF-2 expression error: Loop detected (%d)."), error (_("DWARF-2 expression error: Loop detected (%d)."),
this->recursion_depth); this->m_recursion_depth);
this->recursion_depth++; this->m_recursion_depth++;
while (op_ptr < op_end) while (op_ptr < op_end)
{ {
enum dwarf_location_atom op = (enum dwarf_location_atom) *op_ptr++; dwarf_location_atom op = (dwarf_location_atom) *op_ptr++;
ULONGEST result; ULONGEST result;
/* Assume the value is not in stack memory. /* Assume the value is not in stack memory.
Code that knows otherwise sets this to true. Code that knows otherwise sets this to true.
@ -1469,7 +1490,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
bool in_stack_memory = false; bool in_stack_memory = false;
uint64_t uoffset, reg; uint64_t uoffset, reg;
int64_t offset; int64_t offset;
struct value *result_val = NULL; value *result_val = NULL;
/* The DWARF expression might have a bug causing an infinite /* The DWARF expression might have a bug causing an infinite
loop. In that case, quitting is the only way out. */ loop. In that case, quitting is the only way out. */
@ -1515,32 +1536,32 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_addr: case DW_OP_addr:
result = extract_unsigned_integer (op_ptr, result = extract_unsigned_integer (op_ptr,
this->addr_size, byte_order); this->m_addr_size, byte_order);
op_ptr += this->addr_size; op_ptr += this->m_addr_size;
/* Some versions of GCC emit DW_OP_addr before /* Some versions of GCC emit DW_OP_addr before
DW_OP_GNU_push_tls_address. In this case the value is an DW_OP_GNU_push_tls_address. In this case the value is an
index, not an address. We don't support things like index, not an address. We don't support things like
branching between the address and the TLS op. */ branching between the address and the TLS op. */
if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address) if (op_ptr >= op_end || *op_ptr != DW_OP_GNU_push_tls_address)
result += this->per_objfile->objfile->text_section_offset (); result += this->m_per_objfile->objfile->text_section_offset ();
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
break; break;
case DW_OP_addrx: case DW_OP_addrx:
case DW_OP_GNU_addr_index: case DW_OP_GNU_addr_index:
ensure_have_per_cu (this->per_cu, "DW_OP_addrx"); ensure_have_per_cu (this->m_per_cu, "DW_OP_addrx");
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
result = dwarf2_read_addr_index (this->per_cu, this->per_objfile, result = dwarf2_read_addr_index (this->m_per_cu, this->m_per_objfile,
uoffset); uoffset);
result += this->per_objfile->objfile->text_section_offset (); result += this->m_per_objfile->objfile->text_section_offset ();
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
break; break;
case DW_OP_GNU_const_index: case DW_OP_GNU_const_index:
ensure_have_per_cu (this->per_cu, "DW_OP_GNU_const_index"); ensure_have_per_cu (this->m_per_cu, "DW_OP_GNU_const_index");
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
result = dwarf2_read_addr_index (this->per_cu, this->per_objfile, result = dwarf2_read_addr_index (this->m_per_cu, this->m_per_objfile,
uoffset); uoffset);
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
break; break;
@ -1634,7 +1655,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
result = op - DW_OP_reg0; result = op - DW_OP_reg0;
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
this->location = DWARF_VALUE_REGISTER; this->m_location = DWARF_VALUE_REGISTER;
break; break;
case DW_OP_regx: case DW_OP_regx:
@ -1643,7 +1664,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
result = reg; result = reg;
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
this->location = DWARF_VALUE_REGISTER; this->m_location = DWARF_VALUE_REGISTER;
break; break;
case DW_OP_implicit_value: case DW_OP_implicit_value:
@ -1653,9 +1674,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
op_ptr = safe_read_uleb128 (op_ptr, op_end, &len); op_ptr = safe_read_uleb128 (op_ptr, op_end, &len);
if (op_ptr + len > op_end) if (op_ptr + len > op_end)
error (_("DW_OP_implicit_value: too few bytes available.")); error (_("DW_OP_implicit_value: too few bytes available."));
this->len = len; this->m_len = len;
this->data = op_ptr; this->m_data = op_ptr;
this->location = DWARF_VALUE_LITERAL; this->m_location = DWARF_VALUE_LITERAL;
op_ptr += len; op_ptr += len;
dwarf_expr_require_composition (op_ptr, op_end, dwarf_expr_require_composition (op_ptr, op_end,
"DW_OP_implicit_value"); "DW_OP_implicit_value");
@ -1663,7 +1684,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
goto no_push; goto no_push;
case DW_OP_stack_value: case DW_OP_stack_value:
this->location = DWARF_VALUE_STACK; this->m_location = DWARF_VALUE_STACK;
dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_stack_value"); dwarf_expr_require_composition (op_ptr, op_end, "DW_OP_stack_value");
goto no_push; goto no_push;
@ -1671,12 +1692,12 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_GNU_implicit_pointer: case DW_OP_GNU_implicit_pointer:
{ {
int64_t len; int64_t len;
ensure_have_per_cu (this->per_cu, "DW_OP_implicit_pointer"); ensure_have_per_cu (this->m_per_cu, "DW_OP_implicit_pointer");
int ref_addr_size = this->per_cu->ref_addr_size (); int ref_addr_size = this->m_per_cu->ref_addr_size ();
/* The referred-to DIE of sect_offset kind. */ /* The referred-to DIE of sect_offset kind. */
this->len = extract_unsigned_integer (op_ptr, ref_addr_size, this->m_len = extract_unsigned_integer (op_ptr, ref_addr_size,
byte_order); byte_order);
op_ptr += ref_addr_size; op_ptr += ref_addr_size;
@ -1685,7 +1706,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
result = (ULONGEST) len; result = (ULONGEST) len;
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
this->location = DWARF_VALUE_IMPLICIT_POINTER; this->m_location = DWARF_VALUE_IMPLICIT_POINTER;
dwarf_expr_require_composition (op_ptr, op_end, dwarf_expr_require_composition (op_ptr, op_end,
"DW_OP_implicit_pointer"); "DW_OP_implicit_pointer");
} }
@ -1725,9 +1746,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_breg31: case DW_OP_breg31:
{ {
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
ensure_have_frame (this->frame, "DW_OP_breg"); ensure_have_frame (this->m_frame, "DW_OP_breg");
result = read_addr_from_reg (this->frame, op - DW_OP_breg0); result = read_addr_from_reg (this->m_frame, op - DW_OP_breg0);
result += offset; result += offset;
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
} }
@ -1736,9 +1757,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
{ {
op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg); op_ptr = safe_read_uleb128 (op_ptr, op_end, &reg);
op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset); op_ptr = safe_read_sleb128 (op_ptr, op_end, &offset);
ensure_have_frame (this->frame, "DW_OP_bregx"); ensure_have_frame (this->m_frame, "DW_OP_bregx");
result = read_addr_from_reg (this->frame, reg); result = read_addr_from_reg (this->m_frame, reg);
result += offset; result += offset;
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
} }
@ -1754,19 +1775,19 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
backup the current stack locally and install a new empty stack, backup the current stack locally and install a new empty stack,
then reset it afterwards, effectively erasing whatever the then reset it afterwards, effectively erasing whatever the
recursive call put there. */ recursive call put there. */
std::vector<dwarf_stack_value> saved_stack = std::move (stack); std::vector<dwarf_stack_value> saved_stack = std::move (this->m_stack);
stack.clear (); this->m_stack.clear ();
/* FIXME: cagney/2003-03-26: This code should be using /* FIXME: cagney/2003-03-26: This code should be using
get_frame_base_address(), and then implement a dwarf2 get_frame_base_address(), and then implement a dwarf2
specific this_base method. */ specific this_base method. */
this->get_frame_base (&datastart, &datalen); this->get_frame_base (&datastart, &datalen);
eval (datastart, datalen); eval (datastart, datalen);
if (this->location == DWARF_VALUE_MEMORY) if (this->m_location == DWARF_VALUE_MEMORY)
result = fetch_address (0); result = fetch_address (0);
else if (this->location == DWARF_VALUE_REGISTER) else if (this->m_location == DWARF_VALUE_REGISTER)
result result
= read_addr_from_reg (this->frame, value_as_long (fetch (0))); = read_addr_from_reg (this->m_frame, value_as_long (fetch (0)));
else else
error (_("Not implemented: computing frame " error (_("Not implemented: computing frame "
"base using explicit value operator")); "base using explicit value operator"));
@ -1775,9 +1796,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
in_stack_memory = true; in_stack_memory = true;
/* Restore the content of the original stack. */ /* Restore the content of the original stack. */
stack = std::move (saved_stack); this->m_stack = std::move (saved_stack);
this->location = DWARF_VALUE_MEMORY; this->m_location = DWARF_VALUE_MEMORY;
} }
break; break;
@ -1798,13 +1819,13 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_swap: case DW_OP_swap:
{ {
if (stack.size () < 2) if (this->m_stack.size () < 2)
error (_("Not enough elements for " error (_("Not enough elements for "
"DW_OP_swap. Need 2, have %zu."), "DW_OP_swap. Need 2, have %zu."),
stack.size ()); this->m_stack.size ());
dwarf_stack_value &t1 = stack[stack.size () - 1]; dwarf_stack_value &t1 = this->m_stack[this->m_stack.size () - 1];
dwarf_stack_value &t2 = stack[stack.size () - 2]; dwarf_stack_value &t2 = this->m_stack[this->m_stack.size () - 2];
std::swap (t1, t2); std::swap (t1, t2);
goto no_push; goto no_push;
} }
@ -1816,15 +1837,17 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_rot: case DW_OP_rot:
{ {
if (stack.size () < 3) if (this->m_stack.size () < 3)
error (_("Not enough elements for " error (_("Not enough elements for "
"DW_OP_rot. Need 3, have %zu."), "DW_OP_rot. Need 3, have %zu."),
stack.size ()); this->m_stack.size ());
dwarf_stack_value temp = stack[stack.size () - 1]; dwarf_stack_value temp = this->m_stack[this->m_stack.size () - 1];
stack[stack.size () - 1] = stack[stack.size () - 2]; this->m_stack[this->m_stack.size () - 1]
stack[stack.size () - 2] = stack[stack.size () - 3]; = this->m_stack[this->m_stack.size () - 2];
stack[stack.size () - 3] = temp; this->m_stack[this->m_stack.size () - 2]
= this->m_stack[this->m_stack.size () - 3];
this->m_stack[this->m_stack.size () - 3] = temp;
goto no_push; goto no_push;
} }
@ -1833,7 +1856,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_deref_type: case DW_OP_deref_type:
case DW_OP_GNU_deref_type: case DW_OP_GNU_deref_type:
{ {
int addr_size = (op == DW_OP_deref ? this->addr_size : *op_ptr++); int addr_size = (op == DW_OP_deref ? this->m_addr_size : *op_ptr++);
gdb_byte *buf = (gdb_byte *) alloca (addr_size); gdb_byte *buf = (gdb_byte *) alloca (addr_size);
CORE_ADDR addr = fetch_address (0); CORE_ADDR addr = fetch_address (0);
struct type *type; struct type *type;
@ -1954,8 +1977,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
math. */ math. */
if (orig_type == address_type) if (orig_type == address_type)
{ {
struct type *utype struct type *utype = get_unsigned_type (arch, orig_type);
= get_unsigned_type (this->gdbarch, orig_type);
cast_back = 1; cast_back = 1;
first = value_cast (utype, first); first = value_cast (utype, first);
@ -1990,7 +2012,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
if (!value_type (first)->is_unsigned ()) if (!value_type (first)->is_unsigned ())
{ {
struct type *utype struct type *utype
= get_unsigned_type (this->gdbarch, value_type (first)); = get_unsigned_type (arch, value_type (first));
first = value_cast (utype, first); first = value_cast (utype, first);
} }
@ -2007,7 +2029,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
if (value_type (first)->is_unsigned ()) if (value_type (first)->is_unsigned ())
{ {
struct type *stype struct type *stype
= get_signed_type (this->gdbarch, value_type (first)); = get_signed_type (arch, value_type (first));
first = value_cast (stype, first); first = value_cast (stype, first);
} }
@ -2058,9 +2080,9 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
break; break;
case DW_OP_call_frame_cfa: case DW_OP_call_frame_cfa:
ensure_have_frame (this->frame, "DW_OP_call_frame_cfa"); ensure_have_frame (this->m_frame, "DW_OP_call_frame_cfa");
result = dwarf2_frame_cfa (this->frame); result = dwarf2_frame_cfa (this->m_frame);
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
in_stack_memory = true; in_stack_memory = true;
break; break;
@ -2077,7 +2099,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
returned. */ returned. */
result = value_as_long (fetch (0)); result = value_as_long (fetch (0));
pop (); pop ();
result = target_translate_tls_address (this->per_objfile->objfile, result = target_translate_tls_address (this->m_per_objfile->objfile,
result); result);
result_val = value_from_ulongest (address_type, result); result_val = value_from_ulongest (address_type, result);
break; break;
@ -2115,10 +2137,10 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
/* Pop off the address/regnum, and reset the location /* Pop off the address/regnum, and reset the location
type. */ type. */
if (this->location != DWARF_VALUE_LITERAL if (this->m_location != DWARF_VALUE_LITERAL
&& this->location != DWARF_VALUE_OPTIMIZED_OUT) && this->m_location != DWARF_VALUE_OPTIMIZED_OUT)
pop (); pop ();
this->location = DWARF_VALUE_MEMORY; this->m_location = DWARF_VALUE_MEMORY;
} }
goto no_push; goto no_push;
@ -2133,10 +2155,10 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
/* Pop off the address/regnum, and reset the location /* Pop off the address/regnum, and reset the location
type. */ type. */
if (this->location != DWARF_VALUE_LITERAL if (this->m_location != DWARF_VALUE_LITERAL
&& this->location != DWARF_VALUE_OPTIMIZED_OUT) && this->m_location != DWARF_VALUE_OPTIMIZED_OUT)
pop (); pop ();
this->location = DWARF_VALUE_MEMORY; this->m_location = DWARF_VALUE_MEMORY;
} }
goto no_push; goto no_push;
@ -2145,7 +2167,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always " error (_("DWARF-2 expression error: DW_OP_GNU_uninit must always "
"be the very last op.")); "be the very last op."));
this->initialized = 0; this->m_initialized = 0;
goto no_push; goto no_push;
case DW_OP_call2: case DW_OP_call2:
@ -2168,16 +2190,16 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_GNU_variable_value: case DW_OP_GNU_variable_value:
{ {
ensure_have_per_cu (this->per_cu, "DW_OP_GNU_variable_value"); ensure_have_per_cu (this->m_per_cu, "DW_OP_GNU_variable_value");
int ref_addr_size = this->per_cu->ref_addr_size (); int ref_addr_size = this->m_per_cu->ref_addr_size ();
sect_offset sect_off sect_offset sect_off
= (sect_offset) extract_unsigned_integer (op_ptr, = (sect_offset) extract_unsigned_integer (op_ptr,
ref_addr_size, ref_addr_size,
byte_order); byte_order);
op_ptr += ref_addr_size; op_ptr += ref_addr_size;
result_val = sect_variable_value (sect_off, this->per_cu, result_val = sect_variable_value (sect_off, this->m_per_cu,
this->per_objfile); this->m_per_objfile);
result_val = value_cast (address_type, result_val); result_val = value_cast (address_type, result_val);
} }
break; break;
@ -2209,7 +2231,7 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
if (kind_u.dwarf_reg != -1) if (kind_u.dwarf_reg != -1)
{ {
if (deref_size == -1) if (deref_size == -1)
deref_size = this->addr_size; deref_size = this->m_addr_size;
op_ptr += len; op_ptr += len;
this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_DWARF_REG, this->push_dwarf_reg_entry_value (CALL_SITE_PARAMETER_DWARF_REG,
kind_u, deref_size); kind_u, deref_size);
@ -2264,13 +2286,13 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset); op_ptr = safe_read_uleb128 (op_ptr, op_end, &uoffset);
cu_offset type_die_cu_off = (cu_offset) uoffset; cu_offset type_die_cu_off = (cu_offset) uoffset;
ensure_have_frame (this->frame, "DW_OP_regval_type"); ensure_have_frame (this->m_frame, "DW_OP_regval_type");
struct type *type = get_base_type (type_die_cu_off); struct type *type = get_base_type (type_die_cu_off);
int regnum int regnum
= dwarf_reg_to_regnum_or_error (get_frame_arch (this->frame), = dwarf_reg_to_regnum_or_error (get_frame_arch (this->m_frame),
reg); reg);
result_val = value_from_register (type, regnum, this->frame); result_val = value_from_register (type, regnum, this->m_frame);
} }
break; break;
@ -2310,11 +2332,11 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
case DW_OP_push_object_address: case DW_OP_push_object_address:
/* Return the address of the object we are currently observing. */ /* Return the address of the object we are currently observing. */
if (this->data_view.data () == nullptr if (this->m_addr_info == nullptr)
&& this->obj_address == 0)
error (_("Location address is not set.")); error (_("Location address is not set."));
result_val = value_from_ulongest (address_type, this->obj_address); result_val
= value_from_ulongest (address_type, this->m_addr_info->addr);
break; break;
default: default:
@ -2331,11 +2353,11 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
/* To simplify our main caller, if the result is an implicit /* To simplify our main caller, if the result is an implicit
pointer, then make a pieced value. This is ok because we can't pointer, then make a pieced value. This is ok because we can't
have implicit pointers in contexts where pieces are invalid. */ have implicit pointers in contexts where pieces are invalid. */
if (this->location == DWARF_VALUE_IMPLICIT_POINTER) if (this->m_location == DWARF_VALUE_IMPLICIT_POINTER)
add_piece (8 * this->addr_size, 0); add_piece (8 * this->m_addr_size, 0);
this->recursion_depth--; this->m_recursion_depth--;
gdb_assert (this->recursion_depth >= 0); gdb_assert (this->m_recursion_depth >= 0);
} }
void _initialize_dwarf2expr (); void _initialize_dwarf2expr ();

View file

@ -119,45 +119,48 @@ struct dwarf_stack_value
its current state and its callbacks. */ its current state and its callbacks. */
struct dwarf_expr_context struct dwarf_expr_context
{ {
dwarf_expr_context (dwarf2_per_objfile *per_objfile); dwarf_expr_context (dwarf2_per_objfile *per_objfile,
int addr_size);
virtual ~dwarf_expr_context () = default; virtual ~dwarf_expr_context () = default;
void push_address (CORE_ADDR value, bool in_stack_memory); void push_address (CORE_ADDR value, bool in_stack_memory);
void eval (const gdb_byte *addr, size_t len);
/* Fetch the result of the expression evaluation in a form of /* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU
a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET and FRAME context. TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET describe
describe the source level representation of that result. */ the expected struct value representation of the evaluation
value *fetch_result (struct type *type = nullptr, result. The ADDR_INFO property can be specified to override the
struct type *subobj_type = nullptr, range of memory addresses with the passed in buffer. */
LONGEST subobj_offset = 0); value *evaluate (const gdb_byte *addr, size_t len,
dwarf2_per_cu_data *per_cu, frame_info *frame,
const struct property_addr_info *addr_info = nullptr,
struct type *type = nullptr,
struct type *subobj_type = nullptr,
LONGEST subobj_offset = 0);
private:
/* The stack of values. */ /* The stack of values. */
std::vector<dwarf_stack_value> stack; std::vector<dwarf_stack_value> m_stack;
/* Target architecture to use for address operations. */
struct gdbarch *gdbarch = nullptr;
/* Target address size in bytes. */ /* Target address size in bytes. */
int addr_size = 0; int m_addr_size = 0;
/* The current depth of dwarf expression recursion, via DW_OP_call*, /* The current depth of dwarf expression recursion, via DW_OP_call*,
DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum DW_OP_fbreg, DW_OP_push_object_address, etc., and the maximum
depth we'll tolerate before raising an error. */ depth we'll tolerate before raising an error. */
int recursion_depth = 0, max_recursion_depth = 0x100; int m_recursion_depth = 0, m_max_recursion_depth = 0x100;
/* Location of the value. */ /* Location of the value. */
dwarf_value_location location = DWARF_VALUE_MEMORY; dwarf_value_location m_location = DWARF_VALUE_MEMORY;
/* For DWARF_VALUE_LITERAL, the current literal value's length and /* For DWARF_VALUE_LITERAL, the current literal value's length and
data. For DWARF_VALUE_IMPLICIT_POINTER, LEN is the offset of the data. For DWARF_VALUE_IMPLICIT_POINTER, LEN is the offset of the
target DIE of sect_offset kind. */ target DIE of sect_offset kind. */
ULONGEST len = 0; ULONGEST m_len = 0;
const gdb_byte *data = nullptr; const gdb_byte *m_data = nullptr;
/* Initialization status of variable: Non-zero if variable has been /* Initialization status of variable: Non-zero if variable has been
initialized; zero otherwise. */ initialized; zero otherwise. */
int initialized = 0; int m_initialized = 0;
/* A vector of pieces. /* A vector of pieces.
@ -181,25 +184,21 @@ struct dwarf_expr_context
no DW_OP_piece operations have no value to place in a piece's no DW_OP_piece operations have no value to place in a piece's
'size' field; the size comes from the surrounding data. So the 'size' field; the size comes from the surrounding data. So the
two cases need to be handled separately.) */ two cases need to be handled separately.) */
std::vector<dwarf_expr_piece> pieces; std::vector<dwarf_expr_piece> m_pieces;
/* We evaluate the expression in the context of this objfile. */ /* We evaluate the expression in the context of this objfile. */
dwarf2_per_objfile *per_objfile; dwarf2_per_objfile *m_per_objfile;
/* Frame information used for the evaluation. */ /* Frame information used for the evaluation. */
frame_info *frame = nullptr; frame_info *m_frame = nullptr;
/* Compilation unit used for the evaluation. */ /* Compilation unit used for the evaluation. */
dwarf2_per_cu_data *per_cu = nullptr; dwarf2_per_cu_data *m_per_cu = nullptr;
/* Object address used for the evaluation. */ /* Property address info used for the evaluation. */
CORE_ADDR obj_address = 0; const struct property_addr_info *m_addr_info = nullptr;
/* The data that was passed in. */
gdb::array_view<const gdb_byte> data_view;
private:
void eval (const gdb_byte *addr, size_t len);
struct type *address_type () const; struct type *address_type () const;
void push (struct value *value, bool in_stack_memory); void push (struct value *value, bool in_stack_memory);
bool stack_empty_p () const; bool stack_empty_p () const;
@ -210,6 +209,12 @@ private:
CORE_ADDR fetch_address (int n); CORE_ADDR fetch_address (int n);
bool fetch_in_stack_memory (int n); bool fetch_in_stack_memory (int n);
/* Fetch the result of the expression evaluation in a form of
a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET
describe the source level representation of that result. */
value *fetch_result (struct type *type, struct type *subobj_type,
LONGEST subobj_offset);
/* Return the location expression for the frame base attribute, in /* Return the location expression for the frame base attribute, in
START and LENGTH. The result must be live until the current START and LENGTH. The result must be live until the current
expression evaluation is complete. */ expression evaluation is complete. */

View file

@ -229,25 +229,16 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
struct frame_info *this_frame, CORE_ADDR initial, struct frame_info *this_frame, CORE_ADDR initial,
int initial_in_stack_memory, dwarf2_per_objfile *per_objfile) int initial_in_stack_memory, dwarf2_per_objfile *per_objfile)
{ {
dwarf_expr_context ctx (per_objfile); dwarf_expr_context ctx (per_objfile, addr_size);
scoped_value_mark free_values; scoped_value_mark free_values;
ctx.frame = this_frame;
ctx.gdbarch = get_frame_arch (this_frame);
ctx.addr_size = addr_size;
ctx.push_address (initial, initial_in_stack_memory); ctx.push_address (initial, initial_in_stack_memory);
ctx.eval (exp, len); value *result_val = ctx.evaluate (exp, len, nullptr, this_frame);
CORE_ADDR result;
struct value *result_val = ctx.fetch_result ();
if (VALUE_LVAL (result_val) == lval_memory) if (VALUE_LVAL (result_val) == lval_memory)
result = value_address (result_val); return value_address (result_val);
else else
result = value_as_address (result_val); return value_as_address (result_val);
return result;
} }

View file

@ -1461,8 +1461,6 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
struct type *subobj_type, struct type *subobj_type,
LONGEST subobj_byte_offset) LONGEST subobj_byte_offset)
{ {
struct value *retval;
if (subobj_type == NULL) if (subobj_type == NULL)
{ {
subobj_type = type; subobj_type = type;
@ -1474,21 +1472,15 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
if (size == 0) if (size == 0)
return allocate_optimized_out_value (subobj_type); return allocate_optimized_out_value (subobj_type);
dwarf_expr_context ctx (per_objfile); dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());
ctx.frame = frame;
ctx.per_cu = per_cu;
ctx.obj_address = 0;
value *retval;
scoped_value_mark free_values; scoped_value_mark free_values;
ctx.gdbarch = per_objfile->objfile->arch ();
ctx.addr_size = per_cu->addr_size ();
try try
{ {
ctx.eval (data, size); retval = ctx.evaluate (data, size, per_cu, frame, nullptr, type,
retval = ctx.fetch_result (type, subobj_type, subobj_type, subobj_byte_offset);
subobj_byte_offset);
} }
catch (const gdb_exception_error &ex) catch (const gdb_exception_error &ex)
{ {
@ -1558,29 +1550,24 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
return 0; return 0;
dwarf2_per_objfile *per_objfile = dlbaton->per_objfile; dwarf2_per_objfile *per_objfile = dlbaton->per_objfile;
dwarf_expr_context ctx (per_objfile); dwarf2_per_cu_data *per_cu = dlbaton->per_cu;
dwarf_expr_context ctx (per_objfile, per_cu->addr_size ());
struct value *result; value *result;
scoped_value_mark free_values; scoped_value_mark free_values;
ctx.frame = frame;
ctx.per_cu = dlbaton->per_cu;
if (addr_stack != nullptr)
{
ctx.obj_address = addr_stack->addr;
ctx.data_view = addr_stack->valaddr;
}
ctx.gdbarch = per_objfile->objfile->arch ();
ctx.addr_size = dlbaton->per_cu->addr_size ();
if (push_initial_value) if (push_initial_value)
ctx.push_address (ctx.obj_address, false); {
if (addr_stack != nullptr)
ctx.push_address (addr_stack->addr, false);
else
ctx.push_address (0, false);
}
try try
{ {
ctx.eval (dlbaton->data, dlbaton->size); result = ctx.evaluate (dlbaton->data, dlbaton->size,
result = ctx.fetch_result (); per_cu, frame, addr_stack);
} }
catch (const gdb_exception_error &ex) catch (const gdb_exception_error &ex)
{ {