mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-09 04:21:49 +08:00
Move push_dwarf_reg_entry_value to expr.c
Following the idea of merging the evaluators, the push_dwarf_reg_entry_value method can be moved from dwarf_expr_executor and dwarf_evaluate_loc_desc classes to their base class dwarf_expr_context. gdb/ChangeLog: * dwarf2/expr.c (dwarf_expr_context::push_dwarf_reg_entry_value): Move from dwarf_evaluate_loc_desc. * dwarf2/frame.c (dwarf_expr_executor::push_dwarf_reg_entry_value): Remove method. * dwarf2/loc.c (dwarf_expr_reg_to_entry_parameter): Expose function. (dwarf_evaluate_loc_desc::push_dwarf_reg_entry_value): Move to dwarf_expr_context. * dwarf2/loc.h (dwarf_expr_reg_to_entry_parameter): Expose function.
This commit is contained in:
parent
3c7c57cdc0
commit
0a2b69d04b
@ -258,6 +258,56 @@ dwarf_expr_context::read_mem (gdb_byte *buf, CORE_ADDR addr,
|
||||
read_memory (addr, buf, length);
|
||||
}
|
||||
|
||||
/* See expr.h. */
|
||||
|
||||
void
|
||||
dwarf_expr_context::push_dwarf_reg_entry_value (call_site_parameter_kind kind,
|
||||
call_site_parameter_u kind_u,
|
||||
int deref_size)
|
||||
{
|
||||
ensure_have_per_cu (this->per_cu, "DW_OP_entry_value");
|
||||
ensure_have_frame (this->frame, "DW_OP_entry_value");
|
||||
|
||||
dwarf2_per_cu_data *caller_per_cu;
|
||||
dwarf2_per_objfile *caller_per_objfile;
|
||||
frame_info *caller_frame = get_prev_frame (this->frame);
|
||||
call_site_parameter *parameter
|
||||
= dwarf_expr_reg_to_entry_parameter (this->frame, kind, kind_u,
|
||||
&caller_per_cu,
|
||||
&caller_per_objfile);
|
||||
const gdb_byte *data_src
|
||||
= deref_size == -1 ? parameter->value : parameter->data_value;
|
||||
size_t size
|
||||
= deref_size == -1 ? parameter->value_size : parameter->data_value_size;
|
||||
|
||||
/* DEREF_SIZE size is not verified here. */
|
||||
if (data_src == nullptr)
|
||||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||||
_("Cannot resolve DW_AT_call_data_value"));
|
||||
|
||||
/* We are about to evaluate an expression in the context of the caller
|
||||
of the current frame. This evaluation context may be different from
|
||||
the current (callee's) context), so temporarily set the caller's context.
|
||||
|
||||
It is possible for the caller to be from a different objfile from the
|
||||
callee if the call is made through a function pointer. */
|
||||
scoped_restore save_frame = make_scoped_restore (&this->frame,
|
||||
caller_frame);
|
||||
scoped_restore save_per_cu = make_scoped_restore (&this->per_cu,
|
||||
caller_per_cu);
|
||||
scoped_restore save_obj_addr = make_scoped_restore (&this->obj_address,
|
||||
(CORE_ADDR) 0);
|
||||
scoped_restore save_per_objfile = make_scoped_restore (&this->per_objfile,
|
||||
caller_per_objfile);
|
||||
|
||||
scoped_restore save_arch = make_scoped_restore (&this->gdbarch);
|
||||
this->gdbarch = this->per_objfile->objfile->arch ();
|
||||
scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
|
||||
this->addr_size = this->per_cu->addr_size ();
|
||||
|
||||
this->eval (data_src, size);
|
||||
}
|
||||
|
||||
/* Require that TYPE be an integral type; throw an exception if not. */
|
||||
|
||||
static void
|
||||
|
@ -194,14 +194,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);
|
||||
|
||||
/* 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
|
||||
DW_AT_call_value. */
|
||||
virtual void push_dwarf_reg_entry_value (enum call_site_parameter_kind kind,
|
||||
union call_site_parameter_u kind_u,
|
||||
int deref_size) = 0;
|
||||
|
||||
/* Return the `object address' for DW_OP_push_object_address. */
|
||||
virtual CORE_ADDR get_object_address ()
|
||||
{
|
||||
@ -240,6 +232,14 @@ struct dwarf_expr_context
|
||||
STACK while it being passed to and returned from the called DWARF
|
||||
subroutine. */
|
||||
void dwarf_call (cu_offset die_cu_off);
|
||||
|
||||
/* 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
|
||||
DW_AT_call_value. */
|
||||
void push_dwarf_reg_entry_value (call_site_parameter_kind kind,
|
||||
call_site_parameter_u kind_u,
|
||||
int deref_size);
|
||||
};
|
||||
|
||||
/* Return the value of register number REG (a DWARF register number),
|
||||
|
@ -232,13 +232,6 @@ class dwarf_expr_executor : public dwarf_expr_context
|
||||
: dwarf_expr_context (per_objfile)
|
||||
{}
|
||||
|
||||
void push_dwarf_reg_entry_value (enum call_site_parameter_kind kind,
|
||||
union call_site_parameter_u kind_u,
|
||||
int deref_size) override
|
||||
{
|
||||
invalid ("DW_OP_entry_value");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void invalid (const char *op) ATTRIBUTE_NORETURN
|
||||
|
@ -52,13 +52,6 @@ static struct value *dwarf2_evaluate_loc_desc_full
|
||||
size_t size, dwarf2_per_cu_data *per_cu, dwarf2_per_objfile *per_objfile,
|
||||
struct type *subobj_type, LONGEST subobj_byte_offset);
|
||||
|
||||
static struct call_site_parameter *dwarf_expr_reg_to_entry_parameter
|
||||
(struct frame_info *frame,
|
||||
enum call_site_parameter_kind kind,
|
||||
union call_site_parameter_u kind_u,
|
||||
dwarf2_per_cu_data **per_cu_return,
|
||||
dwarf2_per_objfile **per_objfile_return);
|
||||
|
||||
static struct value *indirect_synthetic_pointer
|
||||
(sect_offset die, LONGEST byte_offset,
|
||||
dwarf2_per_cu_data *per_cu,
|
||||
@ -673,61 +666,6 @@ class dwarf_evaluate_loc_desc : public dwarf_expr_context
|
||||
dwarf_evaluate_loc_desc (dwarf2_per_objfile *per_objfile)
|
||||
: dwarf_expr_context (per_objfile)
|
||||
{}
|
||||
|
||||
/* Execute DWARF block of call_site_parameter which matches KIND and
|
||||
KIND_U. Choose DEREF_SIZE value of that parameter. Search
|
||||
caller of this objects's frame.
|
||||
|
||||
The caller can be from a different CU - per_cu_dwarf_call
|
||||
implementation can be more simple as it does not support cross-CU
|
||||
DWARF executions. */
|
||||
|
||||
void push_dwarf_reg_entry_value (enum call_site_parameter_kind kind,
|
||||
union call_site_parameter_u kind_u,
|
||||
int deref_size) override
|
||||
{
|
||||
struct frame_info *caller_frame;
|
||||
dwarf2_per_cu_data *caller_per_cu;
|
||||
dwarf2_per_objfile *caller_per_objfile;
|
||||
struct call_site_parameter *parameter;
|
||||
const gdb_byte *data_src;
|
||||
size_t size;
|
||||
|
||||
caller_frame = get_prev_frame (frame);
|
||||
|
||||
parameter = dwarf_expr_reg_to_entry_parameter (frame, kind, kind_u,
|
||||
&caller_per_cu,
|
||||
&caller_per_objfile);
|
||||
data_src = deref_size == -1 ? parameter->value : parameter->data_value;
|
||||
size = deref_size == -1 ? parameter->value_size : parameter->data_value_size;
|
||||
|
||||
/* DEREF_SIZE size is not verified here. */
|
||||
if (data_src == NULL)
|
||||
throw_error (NO_ENTRY_VALUE_ERROR,
|
||||
_("Cannot resolve DW_AT_call_data_value"));
|
||||
|
||||
/* We are about to evaluate an expression in the context of the caller
|
||||
of the current frame. This evaluation context may be different from
|
||||
the current (callee's) context), so temporarily set the caller's context.
|
||||
|
||||
It is possible for the caller to be from a different objfile from the
|
||||
callee if the call is made through a function pointer. */
|
||||
scoped_restore save_frame = make_scoped_restore (&this->frame,
|
||||
caller_frame);
|
||||
scoped_restore save_per_cu = make_scoped_restore (&this->per_cu,
|
||||
caller_per_cu);
|
||||
scoped_restore save_obj_addr = make_scoped_restore (&this->obj_address,
|
||||
(CORE_ADDR) 0);
|
||||
scoped_restore save_per_objfile = make_scoped_restore (&this->per_objfile,
|
||||
caller_per_objfile);
|
||||
|
||||
scoped_restore save_arch = make_scoped_restore (&this->gdbarch);
|
||||
this->gdbarch = this->per_objfile->objfile->arch ();
|
||||
scoped_restore save_addr_size = make_scoped_restore (&this->addr_size);
|
||||
this->addr_size = this->per_cu->addr_size ();
|
||||
|
||||
this->eval (data_src, size);
|
||||
}
|
||||
};
|
||||
|
||||
/* See dwarf2loc.h. */
|
||||
@ -1208,13 +1146,9 @@ call_site_parameter_matches (struct call_site_parameter *parameter,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Fetch call_site_parameter from caller matching KIND and KIND_U.
|
||||
FRAME is for callee.
|
||||
/* See loc.h. */
|
||||
|
||||
Function always returns non-NULL, it throws NO_ENTRY_VALUE_ERROR
|
||||
otherwise. */
|
||||
|
||||
static struct call_site_parameter *
|
||||
struct call_site_parameter *
|
||||
dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
|
||||
enum call_site_parameter_kind kind,
|
||||
union call_site_parameter_u kind_u,
|
||||
|
@ -61,6 +61,18 @@ struct value *sect_variable_value (sect_offset sect_off,
|
||||
dwarf2_per_cu_data *per_cu,
|
||||
dwarf2_per_objfile *per_objfile);
|
||||
|
||||
/* Fetch call_site_parameter from caller matching KIND and KIND_U.
|
||||
FRAME is for callee.
|
||||
|
||||
Function always returns non-NULL, it throws NO_ENTRY_VALUE_ERROR
|
||||
otherwise. */
|
||||
|
||||
struct call_site_parameter *dwarf_expr_reg_to_entry_parameter
|
||||
(struct frame_info *frame, enum call_site_parameter_kind kind,
|
||||
union call_site_parameter_u kind_u, dwarf2_per_cu_data **per_cu_return,
|
||||
dwarf2_per_objfile **per_objfile_return);
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
Loading…
Reference in New Issue
Block a user