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
5 changed files with 72 additions and 83 deletions
|
@ -258,6 +258,56 @@ dwarf_expr_context::read_mem (gdb_byte *buf, CORE_ADDR addr,
|
||||||
read_memory (addr, buf, length);
|
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. */
|
/* Require that TYPE be an integral type; throw an exception if not. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -194,14 +194,6 @@ struct dwarf_expr_context
|
||||||
/* Read LENGTH bytes at ADDR into BUF. */
|
/* Read LENGTH bytes at ADDR into BUF. */
|
||||||
virtual void read_mem (gdb_byte *buf, CORE_ADDR addr, size_t length);
|
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. */
|
/* Return the `object address' for DW_OP_push_object_address. */
|
||||||
virtual CORE_ADDR get_object_address ()
|
virtual CORE_ADDR get_object_address ()
|
||||||
{
|
{
|
||||||
|
@ -240,6 +232,14 @@ private:
|
||||||
STACK while it being passed to and returned from the called DWARF
|
STACK while it being passed to and returned from the called DWARF
|
||||||
subroutine. */
|
subroutine. */
|
||||||
void dwarf_call (cu_offset die_cu_off);
|
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),
|
/* Return the value of register number REG (a DWARF register number),
|
||||||
|
|
|
@ -232,13 +232,6 @@ public:
|
||||||
: dwarf_expr_context (per_objfile)
|
: 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:
|
private:
|
||||||
|
|
||||||
void invalid (const char *op) ATTRIBUTE_NORETURN
|
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,
|
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);
|
||||||
|
|
||||||
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
|
static struct value *indirect_synthetic_pointer
|
||||||
(sect_offset die, LONGEST byte_offset,
|
(sect_offset die, LONGEST byte_offset,
|
||||||
dwarf2_per_cu_data *per_cu,
|
dwarf2_per_cu_data *per_cu,
|
||||||
|
@ -673,61 +666,6 @@ public:
|
||||||
dwarf_evaluate_loc_desc (dwarf2_per_objfile *per_objfile)
|
dwarf_evaluate_loc_desc (dwarf2_per_objfile *per_objfile)
|
||||||
: dwarf_expr_context (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. */
|
/* See dwarf2loc.h. */
|
||||||
|
@ -1208,13 +1146,9 @@ call_site_parameter_matches (struct call_site_parameter *parameter,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fetch call_site_parameter from caller matching KIND and KIND_U.
|
/* See loc.h. */
|
||||||
FRAME is for callee.
|
|
||||||
|
|
||||||
Function always returns non-NULL, it throws NO_ENTRY_VALUE_ERROR
|
struct call_site_parameter *
|
||||||
otherwise. */
|
|
||||||
|
|
||||||
static struct call_site_parameter *
|
|
||||||
dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
|
dwarf_expr_reg_to_entry_parameter (struct frame_info *frame,
|
||||||
enum call_site_parameter_kind kind,
|
enum call_site_parameter_kind kind,
|
||||||
union call_site_parameter_u kind_u,
|
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_cu_data *per_cu,
|
||||||
dwarf2_per_objfile *per_objfile);
|
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
|
/* 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. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue