From 0dc32c82c33bae82df269ff26b6f2fa550b9d18f Mon Sep 17 00:00:00 2001 From: Zoran Zaric Date: Mon, 7 Dec 2020 19:00:16 +0000 Subject: [PATCH] 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 --- gdb/dwarf2/expr.c | 12 +++++++++--- gdb/dwarf2/expr.h | 19 ++++++++++++------- gdb/dwarf2/frame.c | 2 +- gdb/dwarf2/loc.c | 27 ++++++++++----------------- gdb/dwarf2/loc.h | 6 ++++-- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/gdb/dwarf2/expr.c b/gdb/dwarf2/expr.c index 5e99a98e1e3..b1283e70df7 100644 --- a/gdb/dwarf2/expr.c +++ b/gdb/dwarf2/expr.c @@ -903,7 +903,8 @@ dwarf_expr_context::push_dwarf_reg_entry_value struct value * dwarf_expr_context::fetch_result (struct type *type, struct type *subobj_type, - LONGEST subobj_offset) + LONGEST subobj_offset, + bool as_lval) { struct value *retval = nullptr; @@ -933,6 +934,11 @@ dwarf_expr_context::fetch_result (struct type *type, } 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) { case DWARF_VALUE_REGISTER: @@ -1057,7 +1063,7 @@ dwarf_expr_context::fetch_result (struct type *type, /* See expr.h. */ 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 frame_info *frame, 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 (); 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. */ diff --git a/gdb/dwarf2/expr.h b/gdb/dwarf2/expr.h index 69a043da50e..1c06308f994 100644 --- a/gdb/dwarf2/expr.h +++ b/gdb/dwarf2/expr.h @@ -130,11 +130,13 @@ struct dwarf_expr_context void push_address (CORE_ADDR value, bool in_stack_memory); /* Evaluate the expression at ADDR (LEN bytes long) in a given PER_CU - FRAME context. Where TYPE, SUBOBJ_TYPE and SUBOBJ_OFFSET describe - expected struct value representation of the evaluation result. - The ADDR_INFO property 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, + FRAME context. AS_LVAL defines if the returned struct value is + expected to be a value or a location description. Where TYPE, + SUBOBJ_TYPE and SUBOBJ_OFFSET describe expected struct value + representation of the evaluation result. The ADDR_INFO property + 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 frame_info *frame, const struct property_addr_info *addr_info = nullptr, @@ -223,10 +225,13 @@ private: /* 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. */ + 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 type *subobj_type, - LONGEST subobj_offset); + LONGEST subobj_offset, + bool as_lval); /* Return the location expression for the frame base attribute, in START and LENGTH. The result must be live until the current diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c index 228c48f3877..40376531067 100644 --- a/gdb/dwarf2/frame.c +++ b/gdb/dwarf2/frame.c @@ -232,7 +232,7 @@ execute_stack_op (const gdb_byte *exp, ULONGEST len, int addr_size, scoped_value_mark free_values; 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) return value_address (result_val); diff --git a/gdb/dwarf2/loc.c b/gdb/dwarf2/loc.c index fdf83859336..1a23e0b2da3 100644 --- a/gdb/dwarf2/loc.c +++ b/gdb/dwarf2/loc.c @@ -50,7 +50,7 @@ static struct value *dwarf2_evaluate_loc_desc_full (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, - 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. 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) { const gdb_byte *data_src; - gdb_byte *data; size_t size; 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, _("Cannot resolve DW_AT_call_data_value")); - /* DW_AT_call_value is a DWARF expression, not a DWARF - location. Postprocessing of DWARF_VALUE_MEMORY would lose the type from - 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); + return dwarf2_evaluate_loc_desc (type, caller_frame, data_src, size, per_cu, + per_objfile, false); } /* 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_objfile *per_objfile, struct type *subobj_type, - LONGEST subobj_byte_offset) + LONGEST subobj_byte_offset, + bool as_lval) { if (subobj_type == NULL) { @@ -1448,8 +1441,8 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame, try { - retval = ctx.eval_exp (data, size, per_cu, frame, nullptr, type, - subobj_type, subobj_byte_offset); + retval = ctx.eval_exp (data, size, as_lval, per_cu, frame, nullptr, + type, subobj_type, subobj_byte_offset); } catch (const gdb_exception_error &ex) { @@ -1490,10 +1483,10 @@ struct value * dwarf2_evaluate_loc_desc (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) + dwarf2_per_objfile *per_objfile, bool as_lval) { 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, @@ -1536,7 +1529,7 @@ dwarf2_locexpr_baton_eval (const struct dwarf2_locexpr_baton *dlbaton, try { 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) { diff --git a/gdb/dwarf2/loc.h b/gdb/dwarf2/loc.h index 1de36041940..c14ba8febd2 100644 --- a/gdb/dwarf2/loc.h +++ b/gdb/dwarf2/loc.h @@ -69,14 +69,16 @@ struct call_site_parameter *dwarf_expr_reg_to_entry_parameter /* Evaluate a location description, starting at DATA and with length 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 frame_info *frame, const gdb_byte *data, size_t size, 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 property. */ -- 2.47.2