Class-fy dwarf2_frame_state

This patch adds ctor and dtor to dwarf2_frame_state, so that we can
remove one cleanup "old_chain".

gdb:

2017-08-11  Yao Qi  <yao.qi@linaro.org>

	* dwarf2-frame.c (dwarf2_frame_state_free): Remove.
	(dwarf2_frame_state::dwarf2_frame_state): New.
	(dwarf2_frame_state::~dwarf2_frame_state): New.
	(dwarf2_fetch_cfa_info): Update.
	(dwarf2_frame_cache): Remove old_chain.  Change 'fs' to an object
	rather than a pointer.  Update code.
	* dwarf2-frame.h (struct dwarf2_frame_state): Declare ctor and
	dtor.
	<data_align, code_align, retaddr_column>: Change them to const.
	<armcc_cfa_offsets_sf, armcc_cfa_offsets_reversed>: Change them
	to bool.
This commit is contained in:
Yao Qi 2017-08-11 09:30:02 +01:00
parent b348037fd8
commit afe37d6be5
3 changed files with 71 additions and 66 deletions

View File

@ -1,3 +1,17 @@
2017-08-11 Yao Qi <yao.qi@linaro.org>
* dwarf2-frame.c (dwarf2_frame_state_free): Remove.
(dwarf2_frame_state::dwarf2_frame_state): New.
(dwarf2_frame_state::~dwarf2_frame_state): New.
(dwarf2_fetch_cfa_info): Update.
(dwarf2_frame_cache): Remove old_chain. Change 'fs' to an object
rather than a pointer. Update code.
* dwarf2-frame.h (struct dwarf2_frame_state): Declare ctor and
dtor.
<data_align, code_align, retaddr_column>: Change them to const.
<armcc_cfa_offsets_sf, armcc_cfa_offsets_reversed>: Change them
to bool.
2017-08-11 Yao Qi <yao.qi@linaro.org>
* dwarf2-frame.h (struct dwarf2_frame_state_reg) <exp_len>: Remove.

View File

@ -218,18 +218,19 @@ dwarf2_frame_state_free_regs (struct dwarf2_frame_state_reg_info *rs)
}
}
/* Release the memory allocated to the frame state FS. */
static void
dwarf2_frame_state_free (void *p)
dwarf2_frame_state::dwarf2_frame_state (CORE_ADDR pc_, struct dwarf2_cie *cie)
: pc (pc_), data_align (cie->data_alignment_factor),
code_align (cie->code_alignment_factor),
retaddr_column (cie->return_address_register)
{
struct dwarf2_frame_state *fs = (struct dwarf2_frame_state *) p;
}
dwarf2_frame_state_free_regs (fs->initial.prev);
dwarf2_frame_state_free_regs (fs->regs.prev);
xfree (fs->initial.reg);
xfree (fs->regs.reg);
xfree (fs);
dwarf2_frame_state::~dwarf2_frame_state ()
{
dwarf2_frame_state_free_regs (initial.prev);
dwarf2_frame_state_free_regs (regs.prev);
xfree (initial.reg);
xfree (regs.reg);
}
@ -865,21 +866,14 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
{
struct dwarf2_fde *fde;
CORE_ADDR text_offset;
struct dwarf2_frame_state fs;
memset (&fs, 0, sizeof (struct dwarf2_frame_state));
fs.pc = pc;
CORE_ADDR pc1 = pc;
/* Find the correct FDE. */
fde = dwarf2_frame_find_fde (&fs.pc, &text_offset);
fde = dwarf2_frame_find_fde (&pc1, &text_offset);
if (fde == NULL)
error (_("Could not compute CFA; needed to translate this expression"));
/* Extract any interesting information from the CIE. */
fs.data_align = fde->cie->data_alignment_factor;
fs.code_align = fde->cie->code_alignment_factor;
fs.retaddr_column = fde->cie->return_address_register;
dwarf2_frame_state fs (pc1, fde->cie);
/* Check for "quirks" - known bugs in producers. */
dwarf2_frame_find_quirks (&fs, fde);
@ -978,12 +972,11 @@ clear_pointer_cleanup (void *arg)
static struct dwarf2_frame_cache *
dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
{
struct cleanup *reset_cache_cleanup, *old_chain;
struct cleanup *reset_cache_cleanup;
struct gdbarch *gdbarch = get_frame_arch (this_frame);
const int num_regs = gdbarch_num_regs (gdbarch)
+ gdbarch_num_pseudo_regs (gdbarch);
struct dwarf2_frame_cache *cache;
struct dwarf2_frame_state *fs;
struct dwarf2_fde *fde;
CORE_ADDR entry_pc;
const gdb_byte *instr;
@ -997,10 +990,6 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
*this_cache = cache;
reset_cache_cleanup = make_cleanup (clear_pointer_cleanup, this_cache);
/* Allocate and initialize the frame state. */
fs = XCNEW (struct dwarf2_frame_state);
old_chain = make_cleanup (dwarf2_frame_state_free, fs);
/* Unwind the PC.
Note that if the next frame is never supposed to return (i.e. a call
@ -1016,41 +1005,40 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
get_frame_address_in_block does just this. It's not clear how
reliable the method is though; there is the potential for the
register state pre-call being different to that on return. */
fs->pc = get_frame_address_in_block (this_frame);
CORE_ADDR pc1 = get_frame_address_in_block (this_frame);
/* Find the correct FDE. */
fde = dwarf2_frame_find_fde (&fs->pc, &cache->text_offset);
fde = dwarf2_frame_find_fde (&pc1, &cache->text_offset);
gdb_assert (fde != NULL);
/* Extract any interesting information from the CIE. */
fs->data_align = fde->cie->data_alignment_factor;
fs->code_align = fde->cie->code_alignment_factor;
fs->retaddr_column = fde->cie->return_address_register;
/* Allocate and initialize the frame state. */
struct dwarf2_frame_state fs (pc1, fde->cie);
cache->addr_size = fde->cie->addr_size;
/* Check for "quirks" - known bugs in producers. */
dwarf2_frame_find_quirks (fs, fde);
dwarf2_frame_find_quirks (&fs, fde);
/* First decode all the insns in the CIE. */
execute_cfa_program (fde, fde->cie->initial_instructions,
fde->cie->end, gdbarch,
get_frame_address_in_block (this_frame), fs);
get_frame_address_in_block (this_frame), &fs);
/* Save the initialized register set. */
fs->initial = fs->regs;
fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs);
fs.initial = fs.regs;
fs.initial.reg = dwarf2_frame_state_copy_regs (&fs.regs);
if (get_frame_func_if_available (this_frame, &entry_pc))
{
/* Decode the insns in the FDE up to the entry PC. */
instr = execute_cfa_program (fde, fde->instructions, fde->end, gdbarch,
entry_pc, fs);
entry_pc, &fs);
if (fs->regs.cfa_how == CFA_REG_OFFSET
&& (dwarf_reg_to_regnum (gdbarch, fs->regs.cfa_reg)
if (fs.regs.cfa_how == CFA_REG_OFFSET
&& (dwarf_reg_to_regnum (gdbarch, fs.regs.cfa_reg)
== gdbarch_sp_regnum (gdbarch)))
{
cache->entry_cfa_sp_offset = fs->regs.cfa_offset;
cache->entry_cfa_sp_offset = fs.regs.cfa_offset;
cache->entry_cfa_sp_offset_p = 1;
}
}
@ -1059,24 +1047,24 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
/* Then decode the insns in the FDE up to our target PC. */
execute_cfa_program (fde, instr, fde->end, gdbarch,
get_frame_address_in_block (this_frame), fs);
get_frame_address_in_block (this_frame), &fs);
TRY
{
/* Calculate the CFA. */
switch (fs->regs.cfa_how)
switch (fs.regs.cfa_how)
{
case CFA_REG_OFFSET:
cache->cfa = read_addr_from_reg (this_frame, fs->regs.cfa_reg);
if (fs->armcc_cfa_offsets_reversed)
cache->cfa -= fs->regs.cfa_offset;
cache->cfa = read_addr_from_reg (this_frame, fs.regs.cfa_reg);
if (fs.armcc_cfa_offsets_reversed)
cache->cfa -= fs.regs.cfa_offset;
else
cache->cfa += fs->regs.cfa_offset;
cache->cfa += fs.regs.cfa_offset;
break;
case CFA_EXP:
cache->cfa =
execute_stack_op (fs->regs.cfa_exp, fs->regs.cfa_exp_len,
execute_stack_op (fs.regs.cfa_exp, fs.regs.cfa_exp_len,
cache->addr_size, cache->text_offset,
this_frame, 0, 0);
break;
@ -1090,7 +1078,6 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
if (ex.error == NOT_AVAILABLE_ERROR)
{
cache->unavailable_retaddr = 1;
do_cleanups (old_chain);
discard_cleanups (reset_cache_cleanup);
return cache;
}
@ -1114,7 +1101,7 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
{
int column; /* CFI speak for "register number". */
for (column = 0; column < fs->regs.num_regs; column++)
for (column = 0; column < fs.regs.num_regs; column++)
{
/* Use the GDB register number as the destination index. */
int regnum = dwarf_reg_to_regnum (gdbarch, column);
@ -1134,16 +1121,16 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache)
problems when a debug info register falls outside of the
table. We need a way of iterating through all the valid
DWARF2 register numbers. */
if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
if (fs.regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
{
if (cache->reg[regnum].how == DWARF2_FRAME_REG_UNSPECIFIED)
complaint (&symfile_complaints, _("\
incomplete CFI data; unspecified registers (e.g., %s) at %s"),
gdbarch_register_name (gdbarch, regnum),
paddress (gdbarch, fs->pc));
paddress (gdbarch, fs.pc));
}
else
cache->reg[regnum] = fs->regs.reg[column];
cache->reg[regnum] = fs.regs.reg[column];
}
}
@ -1158,7 +1145,7 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"),
|| cache->reg[regnum].how == DWARF2_FRAME_REG_RA_OFFSET)
{
struct dwarf2_frame_state_reg *retaddr_reg =
&fs->regs.reg[fs->retaddr_column];
&fs.regs.reg[fs.retaddr_column];
/* It seems rather bizarre to specify an "empty" column as
the return adress column. However, this is exactly
@ -1167,7 +1154,7 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"),
register corresponding to the return address column.
Incidentally, that's how we should treat a return
address column specifying "same value" too. */
if (fs->retaddr_column < fs->regs.num_regs
if (fs.retaddr_column < fs.regs.num_regs
&& retaddr_reg->how != DWARF2_FRAME_REG_UNSPECIFIED
&& retaddr_reg->how != DWARF2_FRAME_REG_SAME_VALUE)
{
@ -1180,12 +1167,12 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"),
{
if (cache->reg[regnum].how == DWARF2_FRAME_REG_RA)
{
cache->reg[regnum].loc.reg = fs->retaddr_column;
cache->reg[regnum].loc.reg = fs.retaddr_column;
cache->reg[regnum].how = DWARF2_FRAME_REG_SAVED_REG;
}
else
{
cache->retaddr_reg.loc.reg = fs->retaddr_column;
cache->retaddr_reg.loc.reg = fs.retaddr_column;
cache->retaddr_reg.how = DWARF2_FRAME_REG_SAVED_REG;
}
}
@ -1193,11 +1180,10 @@ incomplete CFI data; unspecified registers (e.g., %s) at %s"),
}
}
if (fs->retaddr_column < fs->regs.num_regs
&& fs->regs.reg[fs->retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED)
if (fs.retaddr_column < fs.regs.num_regs
&& fs.regs.reg[fs.retaddr_column].how == DWARF2_FRAME_REG_UNDEFINED)
cache->undefined_retaddr = 1;
do_cleanups (old_chain);
discard_cleanups (reset_cache_cleanup);
return cache;
}

View File

@ -106,35 +106,40 @@ struct dwarf2_frame_state_reg_info
struct dwarf2_frame_state_reg_info *prev;
};
struct dwarf2_cie;
/* Structure describing a frame state. */
struct dwarf2_frame_state
{
dwarf2_frame_state (CORE_ADDR pc, struct dwarf2_cie *cie);
~dwarf2_frame_state ();
/* Each register save state can be described in terms of a CFA slot,
another register, or a location expression. */
struct dwarf2_frame_state_reg_info regs;
struct dwarf2_frame_state_reg_info regs {};
/* The PC described by the current frame state. */
CORE_ADDR pc;
/* Initial register set from the CIE.
Used to implement DW_CFA_restore. */
struct dwarf2_frame_state_reg_info initial;
struct dwarf2_frame_state_reg_info initial {};
/* The information we care about from the CIE. */
LONGEST data_align;
ULONGEST code_align;
ULONGEST retaddr_column;
const LONGEST data_align;
const ULONGEST code_align;
const ULONGEST retaddr_column;
/* Flags for known producer quirks. */
/* The ARM compilers, in DWARF2 mode, assume that DW_CFA_def_cfa
and DW_CFA_def_cfa_offset takes a factored offset. */
int armcc_cfa_offsets_sf;
bool armcc_cfa_offsets_sf = false;
/* The ARM compilers, in DWARF2 or DWARF3 mode, may assume that
the CFA is defined as REG - OFFSET rather than REG + OFFSET. */
int armcc_cfa_offsets_reversed;
bool armcc_cfa_offsets_reversed = false;
};
/* Set the architecture-specific register state initialization