Add as_lval argument to expression evaluator

There are cases where the result of the expression evaluation is
expected to be in a form of a value and not location description.

One place that has this requirement is dwarf_entry_parameter_to_value
function, but more are expected in the future. Until now, this
requirement was fulfilled by extending the evaluated expression with
a DW_OP_stack_value operation at the end.

New implementation, introduces a new evaluation argument instead.

	* dwarf2/expr.c (dwarf_expr_context::fetch_result): Add as_lval
	argument.
	(dwarf_expr_context::eval_exp): Add as_lval argument.
	* dwarf2/expr.h (struct dwarf_expr_context): Add as_lval
	argument to fetch_result and eval_exp methods.
	* dwarf2/frame.c (execute_stack_op): Add as_lval argument.
	* dwarf2/loc.c (dwarf_entry_parameter_to_value): Remove
	DWARF expression extension.
	(dwarf2_evaluate_loc_desc_full): Add as_lval argument support.
	(dwarf2_evaluate_loc_desc): Add as_lval argument support.
	(dwarf2_locexpr_baton_eval): Add as_lval argument support.

Change-Id: I04000d8a506030c747a82cd14d1729a90339ebaf
This commit is contained in:
Zoran Zaric
2020-12-07 19:00:16 +00:00
committed by Simon Marchi
parent e6bada58eb
commit 0dc32c82c3
5 changed files with 36 additions and 30 deletions

View File

@@ -903,7 +903,8 @@ dwarf_expr_context::push_dwarf_reg_entry_value
struct value * struct value *
dwarf_expr_context::fetch_result (struct type *type, dwarf_expr_context::fetch_result (struct type *type,
struct type *subobj_type, struct type *subobj_type,
LONGEST subobj_offset) LONGEST subobj_offset,
bool as_lval)
{ {
struct value *retval = nullptr; struct value *retval = nullptr;
@@ -933,6 +934,11 @@ dwarf_expr_context::fetch_result (struct type *type,
} }
else else
{ {
/* If AS_LVAL is false, means that the implicit conversion
from a location description to value is expected. */
if (as_lval == false)
this->location = DWARF_VALUE_STACK;
switch (this->location) switch (this->location)
{ {
case DWARF_VALUE_REGISTER: case DWARF_VALUE_REGISTER:
@@ -1057,7 +1063,7 @@ dwarf_expr_context::fetch_result (struct type *type,
/* See expr.h. */ /* See expr.h. */
struct value * struct value *
dwarf_expr_context::eval_exp (const gdb_byte *addr, size_t len, dwarf_expr_context::eval_exp (const gdb_byte *addr, size_t len, bool as_lval,
struct dwarf2_per_cu_data *per_cu, struct dwarf2_per_cu_data *per_cu,
struct frame_info *frame, struct frame_info *frame,
const struct property_addr_info *addr_info, const struct property_addr_info *addr_info,
@@ -1073,7 +1079,7 @@ dwarf_expr_context::eval_exp (const gdb_byte *addr, size_t len,
this->ref_addr_size = per_cu->ref_addr_size (); this->ref_addr_size = per_cu->ref_addr_size ();
eval (addr, len); eval (addr, len);
return fetch_result (type, subobj_type, subobj_offset); return fetch_result (type, subobj_type, subobj_offset, as_lval);
} }
/* Require that TYPE be an integral type; throw an exception if not. */ /* Require that TYPE be an integral type; throw an exception if not. */

View File

@@ -130,11 +130,13 @@ struct dwarf_expr_context
void push_address (CORE_ADDR value, bool in_stack_memory); void push_address (CORE_ADDR value, bool in_stack_memory);
/* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU /* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU
FRAME context. Where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET describe FRAME context. AS_LVAL defines if the returned struct value is
expected struct value representation of the evaluation result. expected to be a value or a location description. Where TYPE,
The ADDR_INFO property can be specified to override the range of SUBOBJ_TYPE and SUBOBJ_OFFSET describe expected struct value
memory addresses with the passed in buffer. */ representation of the evaluation result. The ADDR_INFO property
struct value *eval_exp (const gdb_byte *addr, size_t len, can be specified to override the range of memory addresses with
the passed in buffer. */
struct value *eval_exp (const gdb_byte *addr, size_t len, bool as_lval,
struct dwarf2_per_cu_data *per_cu, struct dwarf2_per_cu_data *per_cu,
struct frame_info *frame, struct frame_info *frame,
const struct property_addr_info *addr_info = nullptr, const struct property_addr_info *addr_info = nullptr,
@@ -223,10 +225,13 @@ private:
/* Fetch the result of the expression evaluation in a form of /* Fetch the result of the expression evaluation in a form of
a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET a struct value, where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET
describe the source level representation of that result. */ describe the source level representation of that result.
AS_LVAL defines if the fetched struct value is expected to
be a value or a location description. */
struct value *fetch_result (struct type *type, struct value *fetch_result (struct type *type,
struct type *subobj_type, struct type *subobj_type,
LONGEST subobj_offset); LONGEST subobj_offset,
bool as_lval);
/* 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

View File

@@ -232,7 +232,7 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size,
scoped_value_mark free_values; scoped_value_mark free_values;
ctx.push_address (initial, initial_in_stack_memory); ctx.push_address (initial, initial_in_stack_memory);
struct value *result_val = ctx.eval_exp (exp, len, nullptr, this_frame); struct value *result_val = ctx.eval_exp (exp, len, true, nullptr, this_frame);
if (VALUE_LVAL (result_val) == lval_memory) if (VALUE_LVAL (result_val) == lval_memory)
return value_address (result_val); return value_address (result_val);

View File

@@ -50,7 +50,7 @@
static struct value *dwarf2_evaluate_loc_desc_full static struct value *dwarf2_evaluate_loc_desc_full
(struct type *type, struct frame_info *frame, const gdb_byte *data, (struct type *type, struct frame_info *frame, const gdb_byte *data,
size_t size, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile, size_t size, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
struct type *subobj_type, LONGEST subobj_byte_offset); struct type *subobj_type, LONGEST subobj_byte_offset, bool as_lval = true);
/* Until these have formal names, we define these here. /* Until these have formal names, we define these here.
ref: http://gcc.gnu.org/wiki/DebugFission ref: http://gcc.gnu.org/wiki/DebugFission
@@ -1183,7 +1183,6 @@ dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
dwarf2_per_objfile *per_objfile) dwarf2_per_objfile *per_objfile)
{ {
const gdb_byte *data_src; const gdb_byte *data_src;
gdb_byte *data;
size_t size; size_t size;
data_src = deref_size == -1 ? parameter->value : parameter->data_value; data_src = deref_size == -1 ? parameter->value : parameter->data_value;
@@ -1194,15 +1193,8 @@ dwarf_entry_parameter_to_value (struct call_site_parameter *parameter,
throw_error (NO_ENTRY_VALUE_ERROR, throw_error (NO_ENTRY_VALUE_ERROR,
_("Cannot resolve DW_AT_call_data_value")); _("Cannot resolve DW_AT_call_data_value"));
/* DW_AT_call_value is a DWARF expression, not a DWARF return dwarf2_evaluate_loc_desc (type, caller_frame, data_src, size, per_cu,
location. Postprocessing of DWARF_VALUE_MEMORY would lose the type from per_objfile, false);
DWARF block. */
data = (gdb_byte *) alloca (size + 1);
memcpy (data, data_src, size);
data[size] = DW_OP_stack_value;
return dwarf2_evaluate_loc_desc (type, caller_frame, data, size + 1, per_cu,
per_objfile);
} }
/* VALUE must be of type lval_computed with entry_data_value_funcs. Perform /* VALUE must be of type lval_computed with entry_data_value_funcs. Perform
@@ -1428,7 +1420,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
dwarf2_per_cu_data *per_cu, dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile, dwarf2_per_objfile *per_objfile,
struct type *subobj_type, struct type *subobj_type,
LONGEST subobj_byte_offset) LONGEST subobj_byte_offset,
bool as_lval)
{ {
if (subobj_type == NULL) if (subobj_type == NULL)
{ {
@@ -1448,8 +1441,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
try try
{ {
retval = ctx.eval_exp (data, size, per_cu, frame, nullptr, type, retval = ctx.eval_exp (data, size, as_lval, per_cu, frame, nullptr,
subobj_type, subobj_byte_offset); type, subobj_type, subobj_byte_offset);
} }
catch (const gdb_exception_error &ex) catch (const gdb_exception_error &ex)
{ {
@@ -1490,10 +1483,10 @@ struct value *
dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame, dwarf2_evaluate_loc_desc (struct type *type, struct frame_info *frame,
const gdb_byte *data, size_t size, const gdb_byte *data, size_t size,
dwarf2_per_cu_data *per_cu, dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile) dwarf2_per_objfile *per_objfile, bool as_lval)
{ {
return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu, return dwarf2_evaluate_loc_desc_full (type, frame, data, size, per_cu,
per_objfile, NULL, 0); per_objfile, NULL, 0, as_lval);
} }
/* Evaluates a dwarf expression and stores the result in VAL, /* Evaluates a dwarf expression and stores the result in VAL,
@@ -1536,7 +1529,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton,
try try
{ {
result = ctx.eval_exp (dlbaton->data, dlbaton->size, result = ctx.eval_exp (dlbaton->data, dlbaton->size,
per_cu, frame, addr_stack); true, per_cu, frame, addr_stack);
} }
catch (const gdb_exception_error &ex) catch (const gdb_exception_error &ex)
{ {

View File

@@ -69,14 +69,16 @@ struct call_site_parameter *dwarf_expr_reg_to_entry_parameter
/* Evaluate a location description, starting at DATA and with length /* Evaluate a location description, starting at DATA and with length
SIZE, to find the current location of variable of TYPE in the context SIZE, to find the current location of variable of TYPE in the context
of FRAME. */ of FRAME. AS_LVAL defines if the resulting struct value is expected to
be a value or a location description. */
struct value *dwarf2_evaluate_loc_desc (struct type *type, struct value *dwarf2_evaluate_loc_desc (struct type *type,
struct frame_info *frame, struct frame_info *frame,
const gdb_byte *data, const gdb_byte *data,
size_t size, size_t size,
dwarf2_per_cu_data *per_cu, dwarf2_per_cu_data *per_cu,
dwarf2_per_objfile *per_objfile); dwarf2_per_objfile *per_objfile,
bool as_lval = true);
/* A chain of addresses that might be needed to resolve a dynamic /* A chain of addresses that might be needed to resolve a dynamic
property. */ property. */