Move dwarf_call to dwarf_expr_context

Following the idea of merging the evaluators, the dwarf_call and
get_frame_pc method can be moved from dwarf_expr_executor and
dwarf_evaluate_loc_desc classes to their base class dwarf_expr_context.
Once this is done, the get_frame_pc can be replace with lambda
function.

gdb/ChangeLog:

	* dwarf2/expr.c (dwarf_expr_context::dwarf_call): Move from
	dwarf_evaluate_loc_desc.
	(dwarf_expr_context::get_frame_pc): Replace with lambda.
	* dwarf2/expr.h (dwarf_expr_context::get_frame_pc): Remove
	method.
	* dwarf2/frame.c (dwarf_expr_executor::dwarf_call): Remove
	method.
	(dwarf_expr_executor::get_frame_pc): Remove method.
	* dwarf2/loc.c (dwarf_evaluate_loc_desc::get_frame_pc): Remove
	method.
	(dwarf_evaluate_loc_desc::dwarf_call): Move to
	dwarf_expr_context.
	(per_cu_dwarf_call): Inline function.
This commit is contained in:
Zoran Zaric 2020-09-15 10:27:29 +01:00
parent a580d9604b
commit b6d156edd8
4 changed files with 33 additions and 70 deletions

View File

@ -224,6 +224,31 @@ dwarf_expr_context::get_base_type (cu_offset die_cu_off)
return result;
}
/* See expr.h. */
void
dwarf_expr_context::dwarf_call (cu_offset die_cu_off)
{
ensure_have_per_cu (this->per_cu, "DW_OP_call");
frame_info *frame = this->frame;
auto get_pc_from_frame = [frame] ()
{
ensure_have_frame (frame, "DW_OP_call");
return get_frame_address_in_block (frame);
};
dwarf2_locexpr_baton block
= dwarf2_fetch_die_loc_cu_off (die_cu_off, this->per_cu, this->per_objfile,
get_pc_from_frame);
/* DW_OP_call_ref is currently not supported. */
gdb_assert (block.per_cu == this->per_cu);
this->eval (block.data, block.size);
}
/* Require that TYPE be an integral type; throw an exception if not. */
static void
@ -1269,7 +1294,8 @@ dwarf_expr_context::execute_stack_op (const gdb_byte *op_ptr,
returned. */
result = value_as_long (fetch (0));
pop ();
result = this->get_tls_address (result);
result = target_translate_tls_address (this->per_objfile->objfile,
result);
result_val = value_from_ulongest (address_type, result);
break;

View File

@ -191,22 +191,6 @@ struct dwarf_expr_context
/* Read LENGTH bytes at ADDR into BUF. */
virtual void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t length) = 0;
/* Return the PC for the frame. */
virtual CORE_ADDR get_frame_pc ()
{
error (_("%s is invalid in this context"), "DW_OP_implicit_pointer");
}
/* Return the thread-local storage address for
DW_OP_GNU_push_tls_address or DW_OP_form_tls_address. */
virtual CORE_ADDR get_tls_address (CORE_ADDR offset) = 0;
/* Execute DW_AT_location expression for the DWARF expression
subroutine in the DIE at DIE_CU_OFF in the CU. Do not touch
STACK while it being passed to and returned from the called DWARF
subroutine. */
virtual void dwarf_call (cu_offset die_cu_off) = 0;
/* Push on DWARF stack an entry evaluated for DW_TAG_call_site's
parameter matching KIND and KIND_U at the caller of specified BATON.
If DEREF_SIZE is not -1 then use DW_AT_call_data_value instead of
@ -242,6 +226,12 @@ struct dwarf_expr_context
This can throw an exception if the DIE is invalid or does not
represent a base type. */
struct type *get_base_type (cu_offset die_cu_off);
/* Execute DW_AT_location expression for the DWARF expression
subroutine in the DIE at DIE_CU_OFF in the CU. Do not touch
STACK while it being passed to and returned from the called DWARF
subroutine. */
void dwarf_call (cu_offset die_cu_off);
};
/* Return the value of register number REG (a DWARF register number),

View File

@ -249,16 +249,6 @@ class dwarf_expr_executor : public dwarf_expr_context
invalid ("DW_OP_push_object_address");
}
CORE_ADDR get_tls_address (CORE_ADDR offset) override
{
invalid ("DW_OP_form_tls_address");
}
void dwarf_call (cu_offset die_offset) override
{
invalid ("DW_OP_call*");
}
private:
void invalid (const char *op) ATTRIBUTE_NORETURN

View File

@ -618,26 +618,6 @@ func_get_frame_base_dwarf_block (struct symbol *framefunc, CORE_ADDR pc,
framefunc->natural_name ());
}
static void
per_cu_dwarf_call (struct dwarf_expr_context *ctx, cu_offset die_offset,
dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile)
{
struct dwarf2_locexpr_baton block;
auto get_frame_pc_from_ctx = [ctx] ()
{
return ctx->get_frame_pc ();
};
block = dwarf2_fetch_die_loc_cu_off (die_offset, per_cu, per_objfile,
get_frame_pc_from_ctx);
/* DW_OP_call_ref is currently not supported. */
gdb_assert (block.per_cu == per_cu);
ctx->eval (block.data, block.size);
}
/* A helper function to find the definition of NAME and compute its
value. Returns nullptr if the name is not found. */
@ -696,29 +676,6 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
CORE_ADDR obj_address;
/* Helper function for dwarf2_evaluate_loc_desc. Computes the PC for
the frame in BATON. */
CORE_ADDR get_frame_pc () override
{
return get_frame_address_in_block (frame);
}
/* Using the objfile specified in BATON, find the address for the
current thread's thread-local storage with offset OFFSET. */
CORE_ADDR get_tls_address (CORE_ADDR offset) override
{
return target_translate_tls_address (per_objfile->objfile, offset);
}
/* Helper interface of per_cu_dwarf_call for
dwarf2_evaluate_loc_desc. */
void dwarf_call (cu_offset die_offset) override
{
per_cu_dwarf_call (this, die_offset, per_cu, per_objfile);
}
/* Callback function for get_object_address. Return the address of the VLA
object. */