split dwarf2_fetch_cfa_info from dwarf2_compile_expr_to_ax
This removes dwarf2_compile_expr_to_ax, replacing it with a utility function that fetches the CFA data and adding the code to actually compile to an agent expression directly into dwarf2_compile_expr_to_ax. This refactoring lets a later patch reuse the new dwarf2_fetch_cfa_info. gdb/ChangeLog 2014-12-12 Tom Tromey <tromey@redhat.com> * dwarf2loc.c (dwarf2_compile_expr_to_ax) <DW_OP_call_frame_cfa>: Update. * dwarf2-frame.c (dwarf2_fetch_cfa_info): New function, based on dwarf2_compile_cfa_to_ax. (dwarf2_compile_cfa_to_ax): Remove. * dwarf2-frame.h (dwarf2_fetch_cfa_info): Declare. (dwarf2_compile_cfa_to_ax): Remove.
This commit is contained in:
parent
ed12ef62cc
commit
a8fd558970
@ -1,3 +1,13 @@
|
||||
2014-12-12 Tom Tromey <tromey@redhat.com>
|
||||
|
||||
* dwarf2loc.c (dwarf2_compile_expr_to_ax) <DW_OP_call_frame_cfa>:
|
||||
Update.
|
||||
* dwarf2-frame.c (dwarf2_fetch_cfa_info): New function, based on
|
||||
dwarf2_compile_cfa_to_ax.
|
||||
(dwarf2_compile_cfa_to_ax): Remove.
|
||||
* dwarf2-frame.h (dwarf2_fetch_cfa_info): Declare.
|
||||
(dwarf2_compile_cfa_to_ax): Remove.
|
||||
|
||||
2014-12-12 Jan Kratochvil <jan.kratochvil@redhat.com>
|
||||
|
||||
* infcall.h (call_function_by_hand_dummy): Declare.
|
||||
|
@ -882,11 +882,15 @@ dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dwarf2_compile_cfa_to_ax (struct agent_expr *expr, struct axs_value *loc,
|
||||
struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc,
|
||||
struct dwarf2_per_cu_data *data)
|
||||
/* See dwarf2-frame.h. */
|
||||
|
||||
int
|
||||
dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
|
||||
struct dwarf2_per_cu_data *data,
|
||||
int *regnum_out, LONGEST *offset_out,
|
||||
CORE_ADDR *text_offset_out,
|
||||
const gdb_byte **cfa_start_out,
|
||||
const gdb_byte **cfa_end_out)
|
||||
{
|
||||
struct dwarf2_fde *fde;
|
||||
CORE_ADDR text_offset;
|
||||
@ -932,26 +936,20 @@ dwarf2_compile_cfa_to_ax (struct agent_expr *expr, struct axs_value *loc,
|
||||
if (regnum == -1)
|
||||
error (_("Unable to access DWARF register number %d"),
|
||||
(int) fs.regs.cfa_reg); /* FIXME */
|
||||
ax_reg (expr, regnum);
|
||||
|
||||
if (fs.regs.cfa_offset != 0)
|
||||
{
|
||||
if (fs.armcc_cfa_offsets_reversed)
|
||||
ax_const_l (expr, -fs.regs.cfa_offset);
|
||||
else
|
||||
ax_const_l (expr, fs.regs.cfa_offset);
|
||||
ax_simple (expr, aop_add);
|
||||
}
|
||||
*regnum_out = regnum;
|
||||
if (fs.armcc_cfa_offsets_reversed)
|
||||
*offset_out = -fs.regs.cfa_offset;
|
||||
else
|
||||
*offset_out = fs.regs.cfa_offset;
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case CFA_EXP:
|
||||
ax_const_l (expr, text_offset);
|
||||
dwarf2_compile_expr_to_ax (expr, loc, gdbarch, addr_size,
|
||||
fs.regs.cfa_exp,
|
||||
fs.regs.cfa_exp + fs.regs.cfa_exp_len,
|
||||
data);
|
||||
break;
|
||||
*text_offset_out = text_offset;
|
||||
*cfa_start_out = fs.regs.cfa_exp;
|
||||
*cfa_end_out = fs.regs.cfa_exp + fs.regs.cfa_exp_len;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
internal_error (__FILE__, __LINE__, _("Unknown CFA rule."));
|
||||
|
@ -120,15 +120,26 @@ extern const struct frame_base *
|
||||
|
||||
CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame);
|
||||
|
||||
/* Update the agent expression EXPR with code to compute the CFA for a
|
||||
frame at PC. GDBARCH is the architecture of the function at PC.
|
||||
This function may call dwarf2_compile_expr_to_ax; DATA is passed
|
||||
through to that function if needed. */
|
||||
/* Find the CFA information for PC.
|
||||
|
||||
extern void dwarf2_compile_cfa_to_ax (struct agent_expr *expr,
|
||||
struct axs_value *loc,
|
||||
struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc,
|
||||
struct dwarf2_per_cu_data *data);
|
||||
Return 1 if a register is used for the CFA, or 0 if another
|
||||
expression is used. Throw an exception on error.
|
||||
|
||||
GDBARCH is the architecture to use.
|
||||
DATA is the per-CU data.
|
||||
|
||||
REGNUM_OUT is an out parameter that is set to the register number.
|
||||
OFFSET_OUT is the offset to use from this register.
|
||||
These are only filled in when 1 is returned.
|
||||
|
||||
TEXT_OFFSET_OUT, CFA_START_OUT, and CFA_END_OUT describe the CFA
|
||||
in other cases. These are only used when 0 is returned. */
|
||||
|
||||
extern int dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
|
||||
struct dwarf2_per_cu_data *data,
|
||||
int *regnum_out, LONGEST *offset_out,
|
||||
CORE_ADDR *text_offset_out,
|
||||
const gdb_byte **cfa_start_out,
|
||||
const gdb_byte **cfa_end_out);
|
||||
|
||||
#endif /* dwarf2-frame.h */
|
||||
|
@ -3282,8 +3282,34 @@ dwarf2_compile_expr_to_ax (struct agent_expr *expr, struct axs_value *loc,
|
||||
break;
|
||||
|
||||
case DW_OP_call_frame_cfa:
|
||||
dwarf2_compile_cfa_to_ax (expr, loc, arch, expr->scope, per_cu);
|
||||
loc->kind = axs_lvalue_memory;
|
||||
{
|
||||
int regnum;
|
||||
CORE_ADDR text_offset;
|
||||
LONGEST off;
|
||||
const gdb_byte *cfa_start, *cfa_end;
|
||||
|
||||
if (dwarf2_fetch_cfa_info (arch, expr->scope, per_cu,
|
||||
®num, &off,
|
||||
&text_offset, &cfa_start, &cfa_end))
|
||||
{
|
||||
/* Register. */
|
||||
ax_reg (expr, regnum);
|
||||
if (off != 0)
|
||||
{
|
||||
ax_const_l (expr, off);
|
||||
ax_simple (expr, aop_add);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Another expression. */
|
||||
ax_const_l (expr, text_offset);
|
||||
dwarf2_compile_expr_to_ax (expr, loc, arch, addr_size,
|
||||
cfa_start, cfa_end, per_cu);
|
||||
}
|
||||
|
||||
loc->kind = axs_lvalue_memory;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_OP_GNU_push_tls_address:
|
||||
|
Loading…
Reference in New Issue
Block a user