C++-ify prologue-value's pv_area
This patch is an initial C++-ification of pv_area, from prologue-value. It turns pv_area into a class with a constructor and destructor; renames the data members; and changes various functions to be member functions. This allows the removal of make_cleanup_free_pv_area. gdb/ChangeLog 2017-10-12 Tom Tromey <tom@tromey.com> * s390-linux-tdep.c (s390_store, s390_load) (s390_check_for_saved, s390_analyze_prologue): Update. * rx-tdep.c (check_for_saved, rx_analyze_prologue): Update. * rl78-tdep.c (rl78_analyze_prologue, check_for_saved): Update. * prologue-value.h (class pv_area): Move from prologue-value.c. Change names of members. Add constructor, destructor, member functions. (make_pv_area, free_pv_area, make_cleanup_free_pv_area) (pv_area_store, pv_area_fetch, pv_area_store_would_trash) (pv_area_fetch, pv_area_scan): Don't declare. * prologue-value.c (struct pv_area::area_entry): Now member of pv_area. (struct pv_area): Move to prologue-value.h. (pv_area::pv_area): Rename from make_pv_area. (pv_area::~pv_area): Rename from free_pv_area. (do_free_pv_area_cleanup, make_cleanup_free_pv_area): Remove. (clear_entries, find_entry, overlaps, store_would_trash, store) (fetch, find_reg, scan): Now member of pv_area. Remove "area" argument. Update. * msp430-tdep.c (check_for_saved, msp430_analyze_prologue): Update. * mn10300-tdep.c (push_reg, check_for_saved) (mn10300_analyze_prologue): Update. * mep-tdep.c (is_arg_spill, check_for_saved) (mep_analyze_prologue): Update. * m32c-tdep.c (m32c_pv_push, m32c_srcdest_fetch) (m32c_srcdest_store, m32c_pv_enter, m32c_is_arg_spill) (m32c_is_struct_return, m32c_analyze_prologue): Update. * arm-tdep.c (thumb_analyze_prologue, arm_analyze_prologue): Update. * arc-tdep.c (arc_is_in_prologue, arc_analyze_prologue): Update. * aarch64-tdep.c (aarch64_analyze_prologue): Update.
This commit is contained in:
parent
04ec7890fc
commit
f7b7ed97a2
@ -1,3 +1,38 @@
|
||||
2017-10-12 Tom Tromey <tom@tromey.com>
|
||||
|
||||
* s390-linux-tdep.c (s390_store, s390_load)
|
||||
(s390_check_for_saved, s390_analyze_prologue): Update.
|
||||
* rx-tdep.c (check_for_saved, rx_analyze_prologue): Update.
|
||||
* rl78-tdep.c (rl78_analyze_prologue, check_for_saved): Update.
|
||||
* prologue-value.h (class pv_area): Move from prologue-value.c.
|
||||
Change names of members. Add constructor, destructor, member
|
||||
functions.
|
||||
(make_pv_area, free_pv_area, make_cleanup_free_pv_area)
|
||||
(pv_area_store, pv_area_fetch, pv_area_store_would_trash)
|
||||
(pv_area_fetch, pv_area_scan): Don't declare.
|
||||
* prologue-value.c (struct pv_area::area_entry): Now member of
|
||||
pv_area.
|
||||
(struct pv_area): Move to prologue-value.h.
|
||||
(pv_area::pv_area): Rename from make_pv_area.
|
||||
(pv_area::~pv_area): Rename from free_pv_area.
|
||||
(do_free_pv_area_cleanup, make_cleanup_free_pv_area): Remove.
|
||||
(clear_entries, find_entry, overlaps, store_would_trash, store)
|
||||
(fetch, find_reg, scan): Now member of pv_area.
|
||||
Remove "area" argument. Update.
|
||||
* msp430-tdep.c (check_for_saved, msp430_analyze_prologue):
|
||||
Update.
|
||||
* mn10300-tdep.c (push_reg, check_for_saved)
|
||||
(mn10300_analyze_prologue): Update.
|
||||
* mep-tdep.c (is_arg_spill, check_for_saved)
|
||||
(mep_analyze_prologue): Update.
|
||||
* m32c-tdep.c (m32c_pv_push, m32c_srcdest_fetch)
|
||||
(m32c_srcdest_store, m32c_pv_enter, m32c_is_arg_spill)
|
||||
(m32c_is_struct_return, m32c_analyze_prologue): Update.
|
||||
* arm-tdep.c (thumb_analyze_prologue, arm_analyze_prologue):
|
||||
Update.
|
||||
* arc-tdep.c (arc_is_in_prologue, arc_analyze_prologue): Update.
|
||||
* aarch64-tdep.c (aarch64_analyze_prologue): Update.
|
||||
|
||||
2017-10-12 Simon Marchi <simon.marchi@ericsson.com>
|
||||
|
||||
* linux-nat.h (linux_nat_set_delete_thread): New declaration.
|
||||
|
@ -234,13 +234,10 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
|
||||
int i;
|
||||
/* Track X registers and D registers in prologue. */
|
||||
pv_t regs[AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT];
|
||||
struct pv_area *stack;
|
||||
struct cleanup *back_to;
|
||||
|
||||
for (i = 0; i < AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT; i++)
|
||||
regs[i] = pv_register (i, 0);
|
||||
stack = make_pv_area (AARCH64_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (AARCH64_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
|
||||
for (; start < limit; start += 4)
|
||||
{
|
||||
@ -345,9 +342,9 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
|
||||
gdb_assert (inst.operands[1].type == AARCH64_OPND_ADDR_SIMM9);
|
||||
gdb_assert (!inst.operands[1].addr.offset.is_reg);
|
||||
|
||||
pv_area_store (stack, pv_add_constant (regs[rn],
|
||||
inst.operands[1].addr.offset.imm),
|
||||
is64 ? 8 : 4, regs[rt]);
|
||||
stack.store (pv_add_constant (regs[rn],
|
||||
inst.operands[1].addr.offset.imm),
|
||||
is64 ? 8 : 4, regs[rt]);
|
||||
}
|
||||
else if ((inst.opcode->iclass == ldstpair_off
|
||||
|| (inst.opcode->iclass == ldstpair_indexed
|
||||
@ -370,12 +367,10 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
|
||||
/* If recording this store would invalidate the store area
|
||||
(perhaps because rn is not known) then we should abandon
|
||||
further prologue analysis. */
|
||||
if (pv_area_store_would_trash (stack,
|
||||
pv_add_constant (regs[rn], imm)))
|
||||
if (stack.store_would_trash (pv_add_constant (regs[rn], imm)))
|
||||
break;
|
||||
|
||||
if (pv_area_store_would_trash (stack,
|
||||
pv_add_constant (regs[rn], imm + 8)))
|
||||
if (stack.store_would_trash (pv_add_constant (regs[rn], imm + 8)))
|
||||
break;
|
||||
|
||||
rt1 = inst.operands[0].reg.regno;
|
||||
@ -389,10 +384,10 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
|
||||
rt2 += AARCH64_X_REGISTER_COUNT;
|
||||
}
|
||||
|
||||
pv_area_store (stack, pv_add_constant (regs[rn], imm), 8,
|
||||
regs[rt1]);
|
||||
pv_area_store (stack, pv_add_constant (regs[rn], imm + 8), 8,
|
||||
regs[rt2]);
|
||||
stack.store (pv_add_constant (regs[rn], imm), 8,
|
||||
regs[rt1]);
|
||||
stack.store (pv_add_constant (regs[rn], imm + 8), 8,
|
||||
regs[rt2]);
|
||||
|
||||
if (inst.operands[2].addr.writeback)
|
||||
regs[rn] = pv_add_constant (regs[rn], imm);
|
||||
@ -422,8 +417,8 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
|
||||
rt += AARCH64_X_REGISTER_COUNT;
|
||||
}
|
||||
|
||||
pv_area_store (stack, pv_add_constant (regs[rn], imm),
|
||||
is64 ? 8 : 4, regs[rt]);
|
||||
stack.store (pv_add_constant (regs[rn], imm),
|
||||
is64 ? 8 : 4, regs[rt]);
|
||||
if (inst.operands[1].addr.writeback)
|
||||
regs[rn] = pv_add_constant (regs[rn], imm);
|
||||
}
|
||||
@ -445,10 +440,7 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
if (cache == NULL)
|
||||
{
|
||||
do_cleanups (back_to);
|
||||
return start;
|
||||
}
|
||||
return start;
|
||||
|
||||
if (pv_is_register (regs[AARCH64_FP_REGNUM], AARCH64_SP_REGNUM))
|
||||
{
|
||||
@ -473,7 +465,7 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
|
||||
{
|
||||
CORE_ADDR offset;
|
||||
|
||||
if (pv_area_find_reg (stack, gdbarch, i, &offset))
|
||||
if (stack.find_reg (gdbarch, i, &offset))
|
||||
cache->saved_regs[i].addr = offset;
|
||||
}
|
||||
|
||||
@ -482,12 +474,11 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
|
||||
int regnum = gdbarch_num_regs (gdbarch);
|
||||
CORE_ADDR offset;
|
||||
|
||||
if (pv_area_find_reg (stack, gdbarch, i + AARCH64_X_REGISTER_COUNT,
|
||||
&offset))
|
||||
if (stack.find_reg (gdbarch, i + AARCH64_X_REGISTER_COUNT,
|
||||
&offset))
|
||||
cache->saved_regs[i + regnum + AARCH64_D0_REGNUM].addr = offset;
|
||||
}
|
||||
|
||||
do_cleanups (back_to);
|
||||
return start;
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1014,7 @@ arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn,
|
||||
addr = pv_add_constant (regs[base_reg],
|
||||
arc_insn_get_memory_offset (insn));
|
||||
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack->store_would_trash (addr))
|
||||
return false;
|
||||
|
||||
if (insn.data_size_mode != ARC_SCALING_D)
|
||||
@ -1031,7 +1031,7 @@ arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn,
|
||||
else
|
||||
size = ARC_REGISTER_SIZE;
|
||||
|
||||
pv_area_store (stack, addr, size, store_value);
|
||||
stack->store (addr, size, store_value);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1040,16 +1040,15 @@ arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn,
|
||||
/* If this is a double store, than write N+1 register as well. */
|
||||
pv_t store_value1 = regs[insn.operands[0].value];
|
||||
pv_t store_value2 = regs[insn.operands[0].value + 1];
|
||||
pv_area_store (stack, addr, ARC_REGISTER_SIZE, store_value1);
|
||||
pv_area_store (stack,
|
||||
pv_add_constant (addr, ARC_REGISTER_SIZE),
|
||||
ARC_REGISTER_SIZE, store_value2);
|
||||
stack->store (addr, ARC_REGISTER_SIZE, store_value1);
|
||||
stack->store (pv_add_constant (addr, ARC_REGISTER_SIZE),
|
||||
ARC_REGISTER_SIZE, store_value2);
|
||||
}
|
||||
else
|
||||
{
|
||||
pv_t store_value
|
||||
= pv_constant (arc_insn_get_operand_value (insn, 0));
|
||||
pv_area_store (stack, addr, ARC_REGISTER_SIZE * 2, store_value);
|
||||
stack->store (addr, ARC_REGISTER_SIZE * 2, store_value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1136,7 +1135,7 @@ arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn,
|
||||
|
||||
/* Assume that if the last register (closest to new SP) can be written,
|
||||
then it is possible to write all of them. */
|
||||
if (pv_area_store_would_trash (stack, new_sp))
|
||||
if (stack->store_would_trash (new_sp))
|
||||
return false;
|
||||
|
||||
/* Current store address. */
|
||||
@ -1145,21 +1144,21 @@ arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn,
|
||||
if (is_fp_saved)
|
||||
{
|
||||
addr = pv_add_constant (addr, -ARC_REGISTER_SIZE);
|
||||
pv_area_store (stack, addr, ARC_REGISTER_SIZE, regs[ARC_FP_REGNUM]);
|
||||
stack->store (addr, ARC_REGISTER_SIZE, regs[ARC_FP_REGNUM]);
|
||||
}
|
||||
|
||||
/* Registers are stored in backward order: from GP (R26) to R13. */
|
||||
for (int i = ARC_R13_REGNUM + regs_saved - 1; i >= ARC_R13_REGNUM; i--)
|
||||
{
|
||||
addr = pv_add_constant (addr, -ARC_REGISTER_SIZE);
|
||||
pv_area_store (stack, addr, ARC_REGISTER_SIZE, regs[i]);
|
||||
stack->store (addr, ARC_REGISTER_SIZE, regs[i]);
|
||||
}
|
||||
|
||||
if (is_blink_saved)
|
||||
{
|
||||
addr = pv_add_constant (addr, -ARC_REGISTER_SIZE);
|
||||
pv_area_store (stack, addr, ARC_REGISTER_SIZE,
|
||||
regs[ARC_BLINK_REGNUM]);
|
||||
stack->store (addr, ARC_REGISTER_SIZE,
|
||||
regs[ARC_BLINK_REGNUM]);
|
||||
}
|
||||
|
||||
gdb_assert (pv_is_identical (addr, new_sp));
|
||||
@ -1271,9 +1270,7 @@ arc_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR entrypoint,
|
||||
pv_t regs[ARC_LAST_CORE_REGNUM + 1];
|
||||
for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++)
|
||||
regs[i] = pv_register (i, 0);
|
||||
struct pv_area *stack = make_pv_area (ARC_SP_REGNUM,
|
||||
gdbarch_addr_bit (gdbarch));
|
||||
struct cleanup *back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (ARC_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
|
||||
CORE_ADDR current_prologue_end = entrypoint;
|
||||
|
||||
@ -1290,7 +1287,7 @@ arc_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR entrypoint,
|
||||
|
||||
/* If this instruction is in the prologue, fields in the cache will be
|
||||
updated, and the saved registers mask may be updated. */
|
||||
if (!arc_is_in_prologue (gdbarch, insn, regs, stack))
|
||||
if (!arc_is_in_prologue (gdbarch, insn, regs, &stack))
|
||||
{
|
||||
/* Found an instruction that is not in the prologue. */
|
||||
if (arc_debug)
|
||||
@ -1320,12 +1317,11 @@ arc_analyze_prologue (struct gdbarch *gdbarch, const CORE_ADDR entrypoint,
|
||||
for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++)
|
||||
{
|
||||
CORE_ADDR offset;
|
||||
if (pv_area_find_reg (stack, gdbarch, i, &offset))
|
||||
if (stack.find_reg (gdbarch, i, &offset))
|
||||
cache->saved_regs[i].addr = offset;
|
||||
}
|
||||
}
|
||||
|
||||
do_cleanups (back_to);
|
||||
return current_prologue_end;
|
||||
}
|
||||
|
||||
|
@ -647,15 +647,12 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
|
||||
int i;
|
||||
pv_t regs[16];
|
||||
struct pv_area *stack;
|
||||
struct cleanup *back_to;
|
||||
CORE_ADDR offset;
|
||||
CORE_ADDR unrecognized_pc = 0;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
regs[i] = pv_register (i, 0);
|
||||
stack = make_pv_area (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
|
||||
while (start < limit)
|
||||
{
|
||||
@ -668,7 +665,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
int regno;
|
||||
int mask;
|
||||
|
||||
if (pv_area_store_would_trash (stack, regs[ARM_SP_REGNUM]))
|
||||
if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
|
||||
break;
|
||||
|
||||
/* Bits 0-7 contain a mask for registers R0-R7. Bit 8 says
|
||||
@ -681,7 +678,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
{
|
||||
regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM],
|
||||
-4);
|
||||
pv_area_store (stack, regs[ARM_SP_REGNUM], 4, regs[regno]);
|
||||
stack.store (regs[ARM_SP_REGNUM], 4, regs[regno]);
|
||||
}
|
||||
}
|
||||
else if ((insn & 0xff80) == 0xb080) /* sub sp, #imm */
|
||||
@ -735,10 +732,10 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
offset = (insn & 0xff) << 2;
|
||||
addr = pv_add_constant (regs[ARM_SP_REGNUM], offset);
|
||||
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack.store_would_trash (addr))
|
||||
break;
|
||||
|
||||
pv_area_store (stack, addr, 4, regs[regno]);
|
||||
stack.store (addr, 4, regs[regno]);
|
||||
}
|
||||
else if ((insn & 0xf800) == 0x6000) /* str rd, [rn, #off] */
|
||||
{
|
||||
@ -749,10 +746,10 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
offset = bits (insn, 6, 10) << 2;
|
||||
addr = pv_add_constant (regs[rn], offset);
|
||||
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack.store_would_trash (addr))
|
||||
break;
|
||||
|
||||
pv_area_store (stack, addr, 4, regs[rd]);
|
||||
stack.store (addr, 4, regs[rd]);
|
||||
}
|
||||
else if (((insn & 0xf800) == 0x7000 /* strb Rd, [Rn, #off] */
|
||||
|| (insn & 0xf800) == 0x8000) /* strh Rd, [Rn, #off] */
|
||||
@ -828,7 +825,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
pv_t addr = regs[bits (insn, 0, 3)];
|
||||
int regno;
|
||||
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack.store_would_trash (addr))
|
||||
break;
|
||||
|
||||
/* Calculate offsets of saved registers. */
|
||||
@ -836,7 +833,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
if (inst2 & (1 << regno))
|
||||
{
|
||||
addr = pv_add_constant (addr, -4);
|
||||
pv_area_store (stack, addr, 4, regs[regno]);
|
||||
stack.store (addr, 4, regs[regno]);
|
||||
}
|
||||
|
||||
if (insn & 0x0020)
|
||||
@ -857,12 +854,12 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
else
|
||||
addr = pv_add_constant (addr, -offset);
|
||||
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack.store_would_trash (addr))
|
||||
break;
|
||||
|
||||
pv_area_store (stack, addr, 4, regs[regno1]);
|
||||
pv_area_store (stack, pv_add_constant (addr, 4),
|
||||
4, regs[regno2]);
|
||||
stack.store (addr, 4, regs[regno1]);
|
||||
stack.store (pv_add_constant (addr, 4),
|
||||
4, regs[regno2]);
|
||||
|
||||
if (insn & 0x0020)
|
||||
regs[bits (insn, 0, 3)] = addr;
|
||||
@ -881,10 +878,10 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
else
|
||||
addr = pv_add_constant (addr, -offset);
|
||||
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack.store_would_trash (addr))
|
||||
break;
|
||||
|
||||
pv_area_store (stack, addr, 4, regs[regno]);
|
||||
stack.store (addr, 4, regs[regno]);
|
||||
|
||||
if (inst2 & 0x0100)
|
||||
regs[bits (insn, 0, 3)] = addr;
|
||||
@ -899,10 +896,10 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
offset = inst2 & 0xfff;
|
||||
addr = pv_add_constant (regs[bits (insn, 0, 3)], offset);
|
||||
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack.store_would_trash (addr))
|
||||
break;
|
||||
|
||||
pv_area_store (stack, addr, 4, regs[regno]);
|
||||
stack.store (addr, 4, regs[regno]);
|
||||
}
|
||||
|
||||
else if ((insn & 0xffd0) == 0xf880 /* str{bh}.w Rt,[Rn,#imm] */
|
||||
@ -1085,10 +1082,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
unrecognized_pc = start;
|
||||
|
||||
if (cache == NULL)
|
||||
{
|
||||
do_cleanups (back_to);
|
||||
return unrecognized_pc;
|
||||
}
|
||||
return unrecognized_pc;
|
||||
|
||||
if (pv_is_register (regs[ARM_FP_REGNUM], ARM_SP_REGNUM))
|
||||
{
|
||||
@ -1110,10 +1104,9 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (pv_area_find_reg (stack, gdbarch, i, &offset))
|
||||
if (stack.find_reg (gdbarch, i, &offset))
|
||||
cache->saved_regs[i].addr = offset;
|
||||
|
||||
do_cleanups (back_to);
|
||||
return unrecognized_pc;
|
||||
}
|
||||
|
||||
@ -1489,8 +1482,6 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
int regno;
|
||||
CORE_ADDR offset, current_pc;
|
||||
pv_t regs[ARM_FPS_REGNUM];
|
||||
struct pv_area *stack;
|
||||
struct cleanup *back_to;
|
||||
CORE_ADDR unrecognized_pc = 0;
|
||||
|
||||
/* Search the prologue looking for instructions that set up the
|
||||
@ -1505,8 +1496,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
|
||||
for (regno = 0; regno < ARM_FPS_REGNUM; regno++)
|
||||
regs[regno] = pv_register (regno, 0);
|
||||
stack = make_pv_area (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
|
||||
for (current_pc = prologue_start;
|
||||
current_pc < prologue_end;
|
||||
@ -1543,11 +1533,11 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
else if ((insn & 0xffff0fff) == 0xe52d0004) /* str Rd,
|
||||
[sp, #-4]! */
|
||||
{
|
||||
if (pv_area_store_would_trash (stack, regs[ARM_SP_REGNUM]))
|
||||
if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
|
||||
break;
|
||||
regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -4);
|
||||
pv_area_store (stack, regs[ARM_SP_REGNUM], 4,
|
||||
regs[bits (insn, 12, 15)]);
|
||||
stack.store (regs[ARM_SP_REGNUM], 4,
|
||||
regs[bits (insn, 12, 15)]);
|
||||
continue;
|
||||
}
|
||||
else if ((insn & 0xffff0000) == 0xe92d0000)
|
||||
@ -1557,7 +1547,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
{
|
||||
int mask = insn & 0xffff;
|
||||
|
||||
if (pv_area_store_would_trash (stack, regs[ARM_SP_REGNUM]))
|
||||
if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
|
||||
break;
|
||||
|
||||
/* Calculate offsets of saved registers. */
|
||||
@ -1566,7 +1556,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
{
|
||||
regs[ARM_SP_REGNUM]
|
||||
= pv_add_constant (regs[ARM_SP_REGNUM], -4);
|
||||
pv_area_store (stack, regs[ARM_SP_REGNUM], 4, regs[regno]);
|
||||
stack.store (regs[ARM_SP_REGNUM], 4, regs[regno]);
|
||||
}
|
||||
}
|
||||
else if ((insn & 0xffff0000) == 0xe54b0000 /* strb rx,[r11,#-n] */
|
||||
@ -1608,12 +1598,12 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
[sp, -#c]! */
|
||||
&& gdbarch_tdep (gdbarch)->have_fpa_registers)
|
||||
{
|
||||
if (pv_area_store_would_trash (stack, regs[ARM_SP_REGNUM]))
|
||||
if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
|
||||
break;
|
||||
|
||||
regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12);
|
||||
regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07);
|
||||
pv_area_store (stack, regs[ARM_SP_REGNUM], 12, regs[regno]);
|
||||
stack.store (regs[ARM_SP_REGNUM], 12, regs[regno]);
|
||||
}
|
||||
else if ((insn & 0xffbf0fff) == 0xec2d0200 /* sfmfd f0, 4,
|
||||
[sp!] */
|
||||
@ -1622,7 +1612,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
int n_saved_fp_regs;
|
||||
unsigned int fp_start_reg, fp_bound_reg;
|
||||
|
||||
if (pv_area_store_would_trash (stack, regs[ARM_SP_REGNUM]))
|
||||
if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
|
||||
break;
|
||||
|
||||
if ((insn & 0x800) == 0x800) /* N0 is set */
|
||||
@ -1645,8 +1635,8 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
|
||||
{
|
||||
regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12);
|
||||
pv_area_store (stack, regs[ARM_SP_REGNUM], 12,
|
||||
regs[fp_start_reg++]);
|
||||
stack.store (regs[ARM_SP_REGNUM], 12,
|
||||
regs[fp_start_reg++]);
|
||||
}
|
||||
}
|
||||
else if ((insn & 0xff000000) == 0xeb000000 && cache == NULL) /* bl */
|
||||
@ -1726,7 +1716,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
cache->framesize = framesize;
|
||||
|
||||
for (regno = 0; regno < ARM_FPS_REGNUM; regno++)
|
||||
if (pv_area_find_reg (stack, gdbarch, regno, &offset))
|
||||
if (stack.find_reg (gdbarch, regno, &offset))
|
||||
cache->saved_regs[regno].addr = offset;
|
||||
}
|
||||
|
||||
@ -1734,7 +1724,6 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
|
||||
fprintf_unfiltered (gdb_stdlog, "Prologue scan stopped at %s\n",
|
||||
paddress (gdbarch, unrecognized_pc));
|
||||
|
||||
do_cleanups (back_to);
|
||||
return unrecognized_pc;
|
||||
}
|
||||
|
||||
|
@ -1079,11 +1079,11 @@ struct m32c_pv_state
|
||||
static int
|
||||
m32c_pv_push (struct m32c_pv_state *state, pv_t value, int size)
|
||||
{
|
||||
if (pv_area_store_would_trash (state->stack, state->sp))
|
||||
if (state->stack->store_would_trash (state->sp))
|
||||
return 1;
|
||||
|
||||
state->sp = pv_add_constant (state->sp, -size);
|
||||
pv_area_store (state->stack, state->sp, size, value);
|
||||
state->stack->store (state->sp, size, value);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1114,7 +1114,7 @@ static pv_t
|
||||
m32c_srcdest_fetch (struct m32c_pv_state *state, struct srcdest loc, int size)
|
||||
{
|
||||
if (loc.kind == srcdest_mem)
|
||||
return pv_area_fetch (state->stack, loc.addr, size);
|
||||
return state->stack->fetch (loc.addr, size);
|
||||
else if (loc.kind == srcdest_partial_reg)
|
||||
return pv_unknown ();
|
||||
else
|
||||
@ -1131,9 +1131,9 @@ m32c_srcdest_store (struct m32c_pv_state *state, struct srcdest loc,
|
||||
{
|
||||
if (loc.kind == srcdest_mem)
|
||||
{
|
||||
if (pv_area_store_would_trash (state->stack, loc.addr))
|
||||
if (state->stack->store_would_trash (loc.addr))
|
||||
return 1;
|
||||
pv_area_store (state->stack, loc.addr, size, value);
|
||||
state->stack->store (loc.addr, size, value);
|
||||
}
|
||||
else if (loc.kind == srcdest_partial_reg)
|
||||
*loc.reg = pv_unknown ();
|
||||
@ -1350,7 +1350,7 @@ m32c_pv_enter (struct m32c_pv_state *state, int size)
|
||||
/* If simulating this store would require us to forget
|
||||
everything we know about the stack frame in the name of
|
||||
accuracy, it would be better to just quit now. */
|
||||
if (pv_area_store_would_trash (state->stack, state->sp))
|
||||
if (state->stack->store_would_trash (state->sp))
|
||||
return 1;
|
||||
|
||||
if (m32c_pv_push (state, state->fb, tdep->push_addr_bytes))
|
||||
@ -1441,7 +1441,7 @@ m32c_is_arg_spill (struct m32c_pv_state *st,
|
||||
return (m32c_is_arg_reg (st, value)
|
||||
&& loc.kind == srcdest_mem
|
||||
&& pv_is_register (loc.addr, tdep->sp->num)
|
||||
&& ! pv_area_find_reg (st->stack, st->arch, value.reg, 0));
|
||||
&& ! st->stack->find_reg (st->arch, value.reg, 0));
|
||||
}
|
||||
|
||||
/* Return non-zero if a store of VALUE to LOC is probably
|
||||
@ -1462,7 +1462,7 @@ m32c_is_struct_return (struct m32c_pv_state *st,
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (st->arch);
|
||||
|
||||
return (m32c_is_1st_arg_reg (st, value)
|
||||
&& !pv_area_find_reg (st->stack, st->arch, value.reg, 0)
|
||||
&& !st->stack->find_reg (st->arch, value.reg, 0)
|
||||
&& loc.kind == srcdest_reg
|
||||
&& (pv_is_register (*loc.reg, tdep->a0->num)
|
||||
|| pv_is_register (*loc.reg, tdep->a1->num)));
|
||||
@ -1493,7 +1493,7 @@ m32c_pushm_is_reg_save (struct m32c_pv_state *st, int src)
|
||||
|
||||
|
||||
/* Function for finding saved registers in a 'struct pv_area'; we pass
|
||||
this to pv_area_scan.
|
||||
this to pv_area::scan.
|
||||
|
||||
If VALUE is a saved register, ADDR says it was saved at a constant
|
||||
offset from the frame base, and SIZE indicates that the whole
|
||||
@ -1546,7 +1546,6 @@ m32c_analyze_prologue (struct gdbarch *arch,
|
||||
struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
|
||||
unsigned long mach = gdbarch_bfd_arch_info (arch)->mach;
|
||||
CORE_ADDR after_last_frame_related_insn;
|
||||
struct cleanup *back_to;
|
||||
struct m32c_pv_state st;
|
||||
|
||||
st.arch = arch;
|
||||
@ -1560,8 +1559,8 @@ m32c_analyze_prologue (struct gdbarch *arch,
|
||||
st.fb = pv_register (tdep->fb->num, 0);
|
||||
st.sp = pv_register (tdep->sp->num, 0);
|
||||
st.pc = pv_register (tdep->pc->num, 0);
|
||||
st.stack = make_pv_area (tdep->sp->num, gdbarch_addr_bit (arch));
|
||||
back_to = make_cleanup_free_pv_area (st.stack);
|
||||
pv_area stack (tdep->sp->num, gdbarch_addr_bit (arch));
|
||||
st.stack = &stack;
|
||||
|
||||
/* Record that the call instruction has saved the return address on
|
||||
the stack. */
|
||||
@ -1812,11 +1811,9 @@ m32c_analyze_prologue (struct gdbarch *arch,
|
||||
prologue->kind = prologue_first_frame;
|
||||
|
||||
/* Record where all the registers were saved. */
|
||||
pv_area_scan (st.stack, check_for_saved, (void *) prologue);
|
||||
st.stack->scan (check_for_saved, (void *) prologue);
|
||||
|
||||
prologue->prologue_end = after_last_frame_related_insn;
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1640,12 +1640,12 @@ is_arg_spill (struct gdbarch *gdbarch, pv_t value, pv_t addr,
|
||||
{
|
||||
return (is_arg_reg (value)
|
||||
&& pv_is_register (addr, MEP_SP_REGNUM)
|
||||
&& ! pv_area_find_reg (stack, gdbarch, value.reg, 0));
|
||||
&& ! stack->find_reg (gdbarch, value.reg, 0));
|
||||
}
|
||||
|
||||
|
||||
/* Function for finding saved registers in a 'struct pv_area'; we pass
|
||||
this to pv_area_scan.
|
||||
this to pv_area::scan.
|
||||
|
||||
If VALUE is a saved register, ADDR says it was saved at a constant
|
||||
offset from the frame base, and SIZE indicates that the whole
|
||||
@ -1675,8 +1675,6 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
|
||||
int rn;
|
||||
int found_lp = 0;
|
||||
pv_t reg[MEP_NUM_REGS];
|
||||
struct pv_area *stack;
|
||||
struct cleanup *back_to;
|
||||
CORE_ADDR after_last_frame_setup_insn = start_pc;
|
||||
|
||||
memset (result, 0, sizeof (*result));
|
||||
@ -1688,8 +1686,7 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
|
||||
result->reg_offset[rn] = 1;
|
||||
}
|
||||
|
||||
stack = make_pv_area (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
|
||||
pc = start_pc;
|
||||
while (pc < limit_pc)
|
||||
@ -1741,13 +1738,13 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
|
||||
/* If simulating this store would require us to forget
|
||||
everything we know about the stack frame in the name of
|
||||
accuracy, it would be better to just quit now. */
|
||||
if (pv_area_store_would_trash (stack, reg[rm]))
|
||||
if (stack.store_would_trash (reg[rm]))
|
||||
break;
|
||||
|
||||
if (is_arg_spill (gdbarch, reg[rn], reg[rm], stack))
|
||||
if (is_arg_spill (gdbarch, reg[rn], reg[rm], &stack))
|
||||
after_last_frame_setup_insn = next_pc;
|
||||
|
||||
pv_area_store (stack, reg[rm], 4, reg[rn]);
|
||||
stack.store (reg[rm], 4, reg[rn]);
|
||||
}
|
||||
else if (IS_SW_IMMD (insn))
|
||||
{
|
||||
@ -1758,13 +1755,13 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
|
||||
/* If simulating this store would require us to forget
|
||||
everything we know about the stack frame in the name of
|
||||
accuracy, it would be better to just quit now. */
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack.store_would_trash (addr))
|
||||
break;
|
||||
|
||||
if (is_arg_spill (gdbarch, reg[rn], addr, stack))
|
||||
if (is_arg_spill (gdbarch, reg[rn], addr, &stack))
|
||||
after_last_frame_setup_insn = next_pc;
|
||||
|
||||
pv_area_store (stack, addr, 4, reg[rn]);
|
||||
stack.store (addr, 4, reg[rn]);
|
||||
}
|
||||
else if (IS_MOV (insn))
|
||||
{
|
||||
@ -1786,13 +1783,13 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
|
||||
: (gdb_assert (IS_SW (insn)), 4));
|
||||
pv_t addr = pv_add_constant (reg[rm], disp);
|
||||
|
||||
if (pv_area_store_would_trash (stack, addr))
|
||||
if (stack.store_would_trash (addr))
|
||||
break;
|
||||
|
||||
if (is_arg_spill (gdbarch, reg[rn], addr, stack))
|
||||
if (is_arg_spill (gdbarch, reg[rn], addr, &stack))
|
||||
after_last_frame_setup_insn = next_pc;
|
||||
|
||||
pv_area_store (stack, addr, size, reg[rn]);
|
||||
stack.store (addr, size, reg[rn]);
|
||||
}
|
||||
else if (IS_LDC (insn))
|
||||
{
|
||||
@ -1808,7 +1805,7 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
|
||||
int offset = LW_OFFSET (insn);
|
||||
pv_t addr = pv_add_constant (reg[rm], offset);
|
||||
|
||||
reg[rn] = pv_area_fetch (stack, addr, 4);
|
||||
reg[rn] = stack.fetch (addr, 4);
|
||||
}
|
||||
else if (IS_BRA (insn) && BRA_DISP (insn) > 0)
|
||||
{
|
||||
@ -1887,11 +1884,9 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
/* Record where all the registers were saved. */
|
||||
pv_area_scan (stack, check_for_saved, (void *) result);
|
||||
stack.scan (check_for_saved, (void *) result);
|
||||
|
||||
result->prologue_end = after_last_frame_setup_insn;
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
|
||||
|
@ -337,7 +337,7 @@ static void
|
||||
push_reg (pv_t *regs, struct pv_area *stack, int regnum)
|
||||
{
|
||||
regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], -4);
|
||||
pv_area_store (stack, regs[E_SP_REGNUM], 4, regs[regnum]);
|
||||
stack->store (regs[E_SP_REGNUM], 4, regs[regnum]);
|
||||
}
|
||||
|
||||
/* Translate an "r" register number extracted from an instruction encoding
|
||||
@ -356,7 +356,7 @@ translate_rreg (int rreg)
|
||||
return E_E0_REGNUM + rreg;
|
||||
}
|
||||
|
||||
/* Find saved registers in a 'struct pv_area'; we pass this to pv_area_scan.
|
||||
/* Find saved registers in a 'struct pv_area'; we pass this to pv_area::scan.
|
||||
|
||||
If VALUE is a saved register, ADDR says it was saved at a constant
|
||||
offset from the frame base, and SIZE indicates that the whole
|
||||
@ -386,8 +386,6 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
CORE_ADDR pc;
|
||||
int rn;
|
||||
pv_t regs[MN10300_MAX_NUM_REGS];
|
||||
struct pv_area *stack;
|
||||
struct cleanup *back_to;
|
||||
CORE_ADDR after_last_frame_setup_insn = start_pc;
|
||||
int am33_mode = AM33_MODE (gdbarch);
|
||||
|
||||
@ -399,16 +397,15 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
regs[rn] = pv_register (rn, 0);
|
||||
result->reg_offset[rn] = 1;
|
||||
}
|
||||
stack = make_pv_area (E_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (E_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
|
||||
/* The typical call instruction will have saved the return address on the
|
||||
stack. Space for the return address has already been preallocated in
|
||||
the caller's frame. It's possible, such as when using -mrelax with gcc
|
||||
that other registers were saved as well. If this happens, we really
|
||||
have no chance of deciphering the frame. DWARF info can save the day
|
||||
when this happens. */
|
||||
pv_area_store (stack, regs[E_SP_REGNUM], 4, regs[E_PC_REGNUM]);
|
||||
/* The typical call instruction will have saved the return address on the
|
||||
stack. Space for the return address has already been preallocated in
|
||||
the caller's frame. It's possible, such as when using -mrelax with gcc
|
||||
that other registers were saved as well. If this happens, we really
|
||||
have no chance of deciphering the frame. DWARF info can save the day
|
||||
when this happens. */
|
||||
stack.store (regs[E_SP_REGNUM], 4, regs[E_PC_REGNUM]);
|
||||
|
||||
pc = start_pc;
|
||||
while (pc < limit_pc)
|
||||
@ -432,42 +429,42 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
|
||||
if ((save_mask & movm_exreg0_bit) && am33_mode)
|
||||
{
|
||||
push_reg (regs, stack, E_E2_REGNUM);
|
||||
push_reg (regs, stack, E_E3_REGNUM);
|
||||
push_reg (regs, &stack, E_E2_REGNUM);
|
||||
push_reg (regs, &stack, E_E3_REGNUM);
|
||||
}
|
||||
if ((save_mask & movm_exreg1_bit) && am33_mode)
|
||||
{
|
||||
push_reg (regs, stack, E_E4_REGNUM);
|
||||
push_reg (regs, stack, E_E5_REGNUM);
|
||||
push_reg (regs, stack, E_E6_REGNUM);
|
||||
push_reg (regs, stack, E_E7_REGNUM);
|
||||
push_reg (regs, &stack, E_E4_REGNUM);
|
||||
push_reg (regs, &stack, E_E5_REGNUM);
|
||||
push_reg (regs, &stack, E_E6_REGNUM);
|
||||
push_reg (regs, &stack, E_E7_REGNUM);
|
||||
}
|
||||
if ((save_mask & movm_exother_bit) && am33_mode)
|
||||
{
|
||||
push_reg (regs, stack, E_E0_REGNUM);
|
||||
push_reg (regs, stack, E_E1_REGNUM);
|
||||
push_reg (regs, stack, E_MDRQ_REGNUM);
|
||||
push_reg (regs, stack, E_MCRH_REGNUM);
|
||||
push_reg (regs, stack, E_MCRL_REGNUM);
|
||||
push_reg (regs, stack, E_MCVF_REGNUM);
|
||||
push_reg (regs, &stack, E_E0_REGNUM);
|
||||
push_reg (regs, &stack, E_E1_REGNUM);
|
||||
push_reg (regs, &stack, E_MDRQ_REGNUM);
|
||||
push_reg (regs, &stack, E_MCRH_REGNUM);
|
||||
push_reg (regs, &stack, E_MCRL_REGNUM);
|
||||
push_reg (regs, &stack, E_MCVF_REGNUM);
|
||||
}
|
||||
if (save_mask & movm_d2_bit)
|
||||
push_reg (regs, stack, E_D2_REGNUM);
|
||||
push_reg (regs, &stack, E_D2_REGNUM);
|
||||
if (save_mask & movm_d3_bit)
|
||||
push_reg (regs, stack, E_D3_REGNUM);
|
||||
push_reg (regs, &stack, E_D3_REGNUM);
|
||||
if (save_mask & movm_a2_bit)
|
||||
push_reg (regs, stack, E_A2_REGNUM);
|
||||
push_reg (regs, &stack, E_A2_REGNUM);
|
||||
if (save_mask & movm_a3_bit)
|
||||
push_reg (regs, stack, E_A3_REGNUM);
|
||||
push_reg (regs, &stack, E_A3_REGNUM);
|
||||
if (save_mask & movm_other_bit)
|
||||
{
|
||||
push_reg (regs, stack, E_D0_REGNUM);
|
||||
push_reg (regs, stack, E_D1_REGNUM);
|
||||
push_reg (regs, stack, E_A0_REGNUM);
|
||||
push_reg (regs, stack, E_A1_REGNUM);
|
||||
push_reg (regs, stack, E_MDR_REGNUM);
|
||||
push_reg (regs, stack, E_LIR_REGNUM);
|
||||
push_reg (regs, stack, E_LAR_REGNUM);
|
||||
push_reg (regs, &stack, E_D0_REGNUM);
|
||||
push_reg (regs, &stack, E_D1_REGNUM);
|
||||
push_reg (regs, &stack, E_A0_REGNUM);
|
||||
push_reg (regs, &stack, E_A1_REGNUM);
|
||||
push_reg (regs, &stack, E_MDR_REGNUM);
|
||||
push_reg (regs, &stack, E_LIR_REGNUM);
|
||||
push_reg (regs, &stack, E_LAR_REGNUM);
|
||||
/* The `other' bit leaves a blank area of four bytes at
|
||||
the beginning of its block of saved registers, making
|
||||
it 32 bytes long in total. */
|
||||
@ -653,8 +650,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
rN = buf[0] & 0x0f;
|
||||
fsM = (Y << 4) | sM;
|
||||
|
||||
pv_area_store (stack, regs[translate_rreg (rN)], 4,
|
||||
regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (regs[translate_rreg (rN)], 4,
|
||||
regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 3;
|
||||
}
|
||||
@ -673,8 +670,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
sM = (buf[0] & 0xf0) >> 4;
|
||||
fsM = (Y << 4) | sM;
|
||||
|
||||
pv_area_store (stack, regs[E_SP_REGNUM], 4,
|
||||
regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (regs[E_SP_REGNUM], 4,
|
||||
regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 3;
|
||||
}
|
||||
@ -695,10 +692,9 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
Z = (buf[1] & 0x02) >> 1;
|
||||
fsM = (Z << 4) | sM;
|
||||
|
||||
pv_area_store (stack,
|
||||
pv_add (regs[translate_rreg (rN)],
|
||||
regs[translate_rreg (rI)]),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (pv_add (regs[translate_rreg (rN)],
|
||||
regs[translate_rreg (rI)]),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 4;
|
||||
}
|
||||
@ -720,9 +716,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
fsM = (Y << 4) | sM;
|
||||
d8 = extract_signed_integer (&buf[1], 1, byte_order);
|
||||
|
||||
pv_area_store (stack,
|
||||
pv_add_constant (regs[translate_rreg (rN)], d8),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (pv_add_constant (regs[translate_rreg (rN)], d8),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 4;
|
||||
}
|
||||
@ -744,9 +739,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
fsM = (Y << 4) | sM;
|
||||
d24 = extract_signed_integer (&buf[1], 3, byte_order);
|
||||
|
||||
pv_area_store (stack,
|
||||
pv_add_constant (regs[translate_rreg (rN)], d24),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (pv_add_constant (regs[translate_rreg (rN)], d24),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 6;
|
||||
}
|
||||
@ -768,9 +762,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
fsM = (Y << 4) | sM;
|
||||
d32 = extract_signed_integer (&buf[1], 4, byte_order);
|
||||
|
||||
pv_area_store (stack,
|
||||
pv_add_constant (regs[translate_rreg (rN)], d32),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (pv_add_constant (regs[translate_rreg (rN)], d32),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 7;
|
||||
}
|
||||
@ -791,9 +784,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
fsM = (Y << 4) | sM;
|
||||
d8 = extract_signed_integer (&buf[1], 1, byte_order);
|
||||
|
||||
pv_area_store (stack,
|
||||
pv_add_constant (regs[E_SP_REGNUM], d8),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (pv_add_constant (regs[E_SP_REGNUM], d8),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 4;
|
||||
}
|
||||
@ -814,9 +806,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
fsM = (Y << 4) | sM;
|
||||
d24 = extract_signed_integer (&buf[1], 3, byte_order);
|
||||
|
||||
pv_area_store (stack,
|
||||
pv_add_constant (regs[E_SP_REGNUM], d24),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (pv_add_constant (regs[E_SP_REGNUM], d24),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 6;
|
||||
}
|
||||
@ -837,9 +828,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
fsM = (Y << 4) | sM;
|
||||
d32 = extract_signed_integer (&buf[1], 4, byte_order);
|
||||
|
||||
pv_area_store (stack,
|
||||
pv_add_constant (regs[E_SP_REGNUM], d32),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (pv_add_constant (regs[E_SP_REGNUM], d32),
|
||||
4, regs[E_FS0_REGNUM + fsM]);
|
||||
|
||||
pc += 7;
|
||||
}
|
||||
@ -861,8 +851,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
|
||||
rN_regnum = translate_rreg (rN);
|
||||
|
||||
pv_area_store (stack, regs[rN_regnum], 4,
|
||||
regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (regs[rN_regnum], 4,
|
||||
regs[E_FS0_REGNUM + fsM]);
|
||||
regs[rN_regnum] = pv_add_constant (regs[rN_regnum], 4);
|
||||
|
||||
pc += 3;
|
||||
@ -887,7 +877,7 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
|
||||
rN_regnum = translate_rreg (rN);
|
||||
|
||||
pv_area_store (stack, regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]);
|
||||
regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm8);
|
||||
|
||||
pc += 4;
|
||||
@ -912,7 +902,7 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
|
||||
rN_regnum = translate_rreg (rN);
|
||||
|
||||
pv_area_store (stack, regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]);
|
||||
regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm24);
|
||||
|
||||
pc += 6;
|
||||
@ -937,7 +927,7 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
|
||||
rN_regnum = translate_rreg (rN);
|
||||
|
||||
pv_area_store (stack, regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]);
|
||||
stack.store (regs[rN_regnum], 4, regs[E_FS0_REGNUM + fsM]);
|
||||
regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm32);
|
||||
|
||||
pc += 7;
|
||||
@ -1044,11 +1034,9 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
/* Record where all the registers were saved. */
|
||||
pv_area_scan (stack, check_for_saved, (void *) result);
|
||||
stack.scan (check_for_saved, (void *) result);
|
||||
|
||||
result->prologue_end = after_last_frame_setup_insn;
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
/* Function: skip_prologue
|
||||
|
@ -311,7 +311,7 @@ msp430_get_opcode_byte (void *handle)
|
||||
}
|
||||
|
||||
/* Function for finding saved registers in a 'struct pv_area'; this
|
||||
function is passed to pv_area_scan.
|
||||
function is passed to pv_area::scan.
|
||||
|
||||
If VALUE is a saved register, ADDR says it was saved at a constant
|
||||
offset from the frame base, and SIZE indicates that the whole
|
||||
@ -339,8 +339,6 @@ msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
|
||||
CORE_ADDR pc, next_pc;
|
||||
int rn;
|
||||
pv_t reg[MSP430_NUM_TOTAL_REGS];
|
||||
struct pv_area *stack;
|
||||
struct cleanup *back_to;
|
||||
CORE_ADDR after_last_frame_setup_insn = start_pc;
|
||||
int code_model = gdbarch_tdep (gdbarch)->code_model;
|
||||
int sz;
|
||||
@ -353,13 +351,12 @@ msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
|
||||
result->reg_offset[rn] = 1;
|
||||
}
|
||||
|
||||
stack = make_pv_area (MSP430_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (MSP430_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
|
||||
/* The call instruction has saved the return address on the stack. */
|
||||
sz = code_model == MSP_LARGE_CODE_MODEL ? 4 : 2;
|
||||
reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -sz);
|
||||
pv_area_store (stack, reg[MSP430_SP_REGNUM], sz, reg[MSP430_PC_REGNUM]);
|
||||
stack.store (reg[MSP430_SP_REGNUM], sz, reg[MSP430_PC_REGNUM]);
|
||||
|
||||
pc = start_pc;
|
||||
while (pc < limit_pc)
|
||||
@ -378,7 +375,7 @@ msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
|
||||
int rsrc = opc.op[0].reg;
|
||||
|
||||
reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -2);
|
||||
pv_area_store (stack, reg[MSP430_SP_REGNUM], 2, reg[rsrc]);
|
||||
stack.store (reg[MSP430_SP_REGNUM], 2, reg[rsrc]);
|
||||
after_last_frame_setup_insn = next_pc;
|
||||
}
|
||||
else if (opc.id == MSO_push /* PUSHM */
|
||||
@ -393,7 +390,7 @@ msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
|
||||
{
|
||||
reg[MSP430_SP_REGNUM]
|
||||
= pv_add_constant (reg[MSP430_SP_REGNUM], -size);
|
||||
pv_area_store (stack, reg[MSP430_SP_REGNUM], size, reg[rsrc]);
|
||||
stack.store (reg[MSP430_SP_REGNUM], size, reg[rsrc]);
|
||||
rsrc--;
|
||||
count--;
|
||||
}
|
||||
@ -428,11 +425,9 @@ msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
|
||||
result->frame_size = reg[MSP430_SP_REGNUM].k;
|
||||
|
||||
/* Record where all the registers were saved. */
|
||||
pv_area_scan (stack, check_for_saved, result);
|
||||
stack.scan (check_for_saved, result);
|
||||
|
||||
result->prologue_end = after_last_frame_setup_insn;
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
/* Implement the "skip_prologue" gdbarch method. */
|
||||
|
@ -278,7 +278,7 @@ pv_is_array_ref (pv_t addr, CORE_ADDR size,
|
||||
The entry with the lowest offset simply follows the entry with the
|
||||
highest offset. Entries may abut, but never overlap. The area's
|
||||
'entry' pointer points to an arbitrary node in the ring. */
|
||||
struct area_entry
|
||||
struct pv_area::area_entry
|
||||
{
|
||||
/* Links in the doubly-linked ring. */
|
||||
struct area_entry *prev, *next;
|
||||
@ -296,44 +296,23 @@ struct area_entry
|
||||
};
|
||||
|
||||
|
||||
struct pv_area
|
||||
/* See prologue-value.h. */
|
||||
|
||||
pv_area::pv_area (int base_reg, int addr_bit)
|
||||
: m_base_reg (base_reg),
|
||||
/* Remember that shift amounts equal to the type's width are
|
||||
undefined. */
|
||||
m_addr_mask (((((CORE_ADDR) 1 << (addr_bit - 1)) - 1) << 1) | 1),
|
||||
m_entry (nullptr)
|
||||
{
|
||||
/* This area's base register. */
|
||||
int base_reg;
|
||||
|
||||
/* The mask to apply to addresses, to make the wrap-around happen at
|
||||
the right place. */
|
||||
CORE_ADDR addr_mask;
|
||||
|
||||
/* An element of the doubly-linked ring of entries, or zero if we
|
||||
have none. */
|
||||
struct area_entry *entry;
|
||||
};
|
||||
|
||||
|
||||
struct pv_area *
|
||||
make_pv_area (int base_reg, int addr_bit)
|
||||
{
|
||||
struct pv_area *a = XNEW (struct pv_area);
|
||||
|
||||
memset (a, 0, sizeof (*a));
|
||||
|
||||
a->base_reg = base_reg;
|
||||
a->entry = 0;
|
||||
|
||||
/* Remember that shift amounts equal to the type's width are
|
||||
undefined. */
|
||||
a->addr_mask = ((((CORE_ADDR) 1 << (addr_bit - 1)) - 1) << 1) | 1;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/* See prologue-value.h. */
|
||||
|
||||
/* Delete all entries from AREA. */
|
||||
static void
|
||||
clear_entries (struct pv_area *area)
|
||||
void
|
||||
pv_area::clear_entries ()
|
||||
{
|
||||
struct area_entry *e = area->entry;
|
||||
struct area_entry *e = m_entry;
|
||||
|
||||
if (e)
|
||||
{
|
||||
@ -347,37 +326,23 @@ clear_entries (struct pv_area *area)
|
||||
xfree (e);
|
||||
e = next;
|
||||
}
|
||||
while (e != area->entry);
|
||||
while (e != m_entry);
|
||||
|
||||
area->entry = 0;
|
||||
m_entry = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
free_pv_area (struct pv_area *area)
|
||||
pv_area::~pv_area ()
|
||||
{
|
||||
clear_entries (area);
|
||||
xfree (area);
|
||||
clear_entries ();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
do_free_pv_area_cleanup (void *arg)
|
||||
{
|
||||
free_pv_area ((struct pv_area *) arg);
|
||||
}
|
||||
|
||||
|
||||
struct cleanup *
|
||||
make_cleanup_free_pv_area (struct pv_area *area)
|
||||
{
|
||||
return make_cleanup (do_free_pv_area_cleanup, (void *) area);
|
||||
}
|
||||
|
||||
/* See prologue-value.h. */
|
||||
|
||||
int
|
||||
pv_area_store_would_trash (struct pv_area *area, pv_t addr)
|
||||
pv_area::store_would_trash (pv_t addr)
|
||||
{
|
||||
/* It may seem odd that pvk_constant appears here --- after all,
|
||||
that's the case where we know the most about the address! But
|
||||
@ -386,23 +351,16 @@ pv_area_store_would_trash (struct pv_area *area, pv_t addr)
|
||||
constants. */
|
||||
return (addr.kind == pvk_unknown
|
||||
|| addr.kind == pvk_constant
|
||||
|| (addr.kind == pvk_register && addr.reg != area->base_reg));
|
||||
|| (addr.kind == pvk_register && addr.reg != m_base_reg));
|
||||
}
|
||||
|
||||
|
||||
/* Return a pointer to the first entry we hit in AREA starting at
|
||||
OFFSET and going forward.
|
||||
/* See prologue-value.h. */
|
||||
|
||||
This may return zero, if AREA has no entries.
|
||||
|
||||
And since the entries are a ring, this may return an entry that
|
||||
entirely precedes OFFSET. This is the correct behavior: depending
|
||||
on the sizes involved, we could still overlap such an area, with
|
||||
wrap-around. */
|
||||
static struct area_entry *
|
||||
find_entry (struct pv_area *area, CORE_ADDR offset)
|
||||
struct pv_area::area_entry *
|
||||
pv_area::find_entry (CORE_ADDR offset)
|
||||
{
|
||||
struct area_entry *e = area->entry;
|
||||
struct area_entry *e = m_entry;
|
||||
|
||||
if (! e)
|
||||
return 0;
|
||||
@ -416,54 +374,50 @@ find_entry (struct pv_area *area, CORE_ADDR offset)
|
||||
with wrap-around. We have to subtract offset from both sides to
|
||||
make sure both things we're comparing are on the same side of the
|
||||
discontinuity. */
|
||||
while (((e->next->offset - offset) & area->addr_mask)
|
||||
< ((e->offset - offset) & area->addr_mask))
|
||||
while (((e->next->offset - offset) & m_addr_mask)
|
||||
< ((e->offset - offset) & m_addr_mask))
|
||||
e = e->next;
|
||||
|
||||
/* If the previous entry would be better than the current one, then
|
||||
scan backwards. */
|
||||
while (((e->prev->offset - offset) & area->addr_mask)
|
||||
< ((e->offset - offset) & area->addr_mask))
|
||||
while (((e->prev->offset - offset) & m_addr_mask)
|
||||
< ((e->offset - offset) & m_addr_mask))
|
||||
e = e->prev;
|
||||
|
||||
/* In case there's some locality to the searches, set the area's
|
||||
pointer to the entry we've found. */
|
||||
area->entry = e;
|
||||
m_entry = e;
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
/* Return non-zero if the SIZE bytes at OFFSET would overlap ENTRY;
|
||||
return zero otherwise. AREA is the area to which ENTRY belongs. */
|
||||
static int
|
||||
overlaps (struct pv_area *area,
|
||||
struct area_entry *entry,
|
||||
CORE_ADDR offset,
|
||||
CORE_ADDR size)
|
||||
/* See prologue-value.h. */
|
||||
|
||||
int
|
||||
pv_area::overlaps (struct area_entry *entry, CORE_ADDR offset, CORE_ADDR size)
|
||||
{
|
||||
/* Think carefully about wrap-around before simplifying this. */
|
||||
return (((entry->offset - offset) & area->addr_mask) < size
|
||||
|| ((offset - entry->offset) & area->addr_mask) < entry->size);
|
||||
return (((entry->offset - offset) & m_addr_mask) < size
|
||||
|| ((offset - entry->offset) & m_addr_mask) < entry->size);
|
||||
}
|
||||
|
||||
|
||||
/* See prologue-value.h. */
|
||||
|
||||
void
|
||||
pv_area_store (struct pv_area *area,
|
||||
pv_t addr,
|
||||
CORE_ADDR size,
|
||||
pv_t value)
|
||||
pv_area::store (pv_t addr, CORE_ADDR size, pv_t value)
|
||||
{
|
||||
/* Remove any (potentially) overlapping entries. */
|
||||
if (pv_area_store_would_trash (area, addr))
|
||||
clear_entries (area);
|
||||
if (store_would_trash (addr))
|
||||
clear_entries ();
|
||||
else
|
||||
{
|
||||
CORE_ADDR offset = addr.k;
|
||||
struct area_entry *e = find_entry (area, offset);
|
||||
struct area_entry *e = find_entry (offset);
|
||||
|
||||
/* Delete all entries that we would overlap. */
|
||||
while (e && overlaps (area, e, offset, size))
|
||||
while (e && overlaps (e, offset, size))
|
||||
{
|
||||
struct area_entry *next = (e->next == e) ? 0 : e->next;
|
||||
|
||||
@ -476,10 +430,10 @@ pv_area_store (struct pv_area *area,
|
||||
|
||||
/* Move the area's pointer to the next remaining entry. This
|
||||
will also zero the pointer if we've deleted all the entries. */
|
||||
area->entry = e;
|
||||
m_entry = e;
|
||||
}
|
||||
|
||||
/* Now, there are no entries overlapping us, and area->entry is
|
||||
/* Now, there are no entries overlapping us, and m_entry is
|
||||
either zero or pointing at the closest entry after us. We can
|
||||
just insert ourselves before that.
|
||||
|
||||
@ -496,33 +450,35 @@ pv_area_store (struct pv_area *area,
|
||||
e->size = size;
|
||||
e->value = value;
|
||||
|
||||
if (area->entry)
|
||||
if (m_entry)
|
||||
{
|
||||
e->prev = area->entry->prev;
|
||||
e->next = area->entry;
|
||||
e->prev = m_entry->prev;
|
||||
e->next = m_entry;
|
||||
e->prev->next = e->next->prev = e;
|
||||
}
|
||||
else
|
||||
{
|
||||
e->prev = e->next = e;
|
||||
area->entry = e;
|
||||
m_entry = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* See prologue-value.h. */
|
||||
|
||||
pv_t
|
||||
pv_area_fetch (struct pv_area *area, pv_t addr, CORE_ADDR size)
|
||||
pv_area::fetch (pv_t addr, CORE_ADDR size)
|
||||
{
|
||||
/* If we have no entries, or we can't decide how ADDR relates to the
|
||||
entries we do have, then the value is unknown. */
|
||||
if (! area->entry
|
||||
|| pv_area_store_would_trash (area, addr))
|
||||
if (! m_entry
|
||||
|| store_would_trash (addr))
|
||||
return pv_unknown ();
|
||||
else
|
||||
{
|
||||
CORE_ADDR offset = addr.k;
|
||||
struct area_entry *e = find_entry (area, offset);
|
||||
struct area_entry *e = find_entry (offset);
|
||||
|
||||
/* If this entry exactly matches what we're looking for, then
|
||||
we're set. Otherwise, say it's unknown. */
|
||||
@ -534,13 +490,12 @@ pv_area_fetch (struct pv_area *area, pv_t addr, CORE_ADDR size)
|
||||
}
|
||||
|
||||
|
||||
/* See prologue-value.h. */
|
||||
|
||||
int
|
||||
pv_area_find_reg (struct pv_area *area,
|
||||
struct gdbarch *gdbarch,
|
||||
int reg,
|
||||
CORE_ADDR *offset_p)
|
||||
pv_area::find_reg (struct gdbarch *gdbarch, int reg, CORE_ADDR *offset_p)
|
||||
{
|
||||
struct area_entry *e = area->entry;
|
||||
struct area_entry *e = m_entry;
|
||||
|
||||
if (e)
|
||||
do
|
||||
@ -557,25 +512,26 @@ pv_area_find_reg (struct pv_area *area,
|
||||
|
||||
e = e->next;
|
||||
}
|
||||
while (e != area->entry);
|
||||
while (e != m_entry);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* See prologue-value.h. */
|
||||
|
||||
void
|
||||
pv_area_scan (struct pv_area *area,
|
||||
void (*func) (void *closure,
|
||||
pv_t addr,
|
||||
CORE_ADDR size,
|
||||
pv_t value),
|
||||
void *closure)
|
||||
pv_area::scan (void (*func) (void *closure,
|
||||
pv_t addr,
|
||||
CORE_ADDR size,
|
||||
pv_t value),
|
||||
void *closure)
|
||||
{
|
||||
struct area_entry *e = area->entry;
|
||||
struct area_entry *e = m_entry;
|
||||
pv_t addr;
|
||||
|
||||
addr.kind = pvk_register;
|
||||
addr.reg = area->base_reg;
|
||||
addr.reg = m_base_reg;
|
||||
|
||||
if (e)
|
||||
do
|
||||
@ -584,5 +540,5 @@ pv_area_scan (struct pv_area *area,
|
||||
func (closure, addr, e->size, e->value);
|
||||
e = e->next;
|
||||
}
|
||||
while (e != area->entry);
|
||||
while (e != m_entry);
|
||||
}
|
||||
|
@ -221,83 +221,110 @@ enum pv_boolean pv_is_array_ref (pv_t addr, CORE_ADDR size,
|
||||
int *i);
|
||||
|
||||
|
||||
/* A 'struct pv_area' keeps track of values stored in a particular
|
||||
region of memory. */
|
||||
struct pv_area;
|
||||
/* A 'pv_area' keeps track of values stored in a particular region of
|
||||
memory. */
|
||||
class pv_area
|
||||
{
|
||||
public:
|
||||
|
||||
/* Create a new area, tracking stores relative to the original value
|
||||
of BASE_REG. If BASE_REG is SP, then this effectively records the
|
||||
contents of the stack frame: the original value of the SP is the
|
||||
frame's CFA, or some constant offset from it.
|
||||
/* Create a new area, tracking stores relative to the original value
|
||||
of BASE_REG. If BASE_REG is SP, then this effectively records the
|
||||
contents of the stack frame: the original value of the SP is the
|
||||
frame's CFA, or some constant offset from it.
|
||||
|
||||
Stores to constant addresses, unknown addresses, or to addresses
|
||||
relative to registers other than BASE_REG will trash this area; see
|
||||
pv_area_store_would_trash.
|
||||
Stores to constant addresses, unknown addresses, or to addresses
|
||||
relative to registers other than BASE_REG will trash this area; see
|
||||
pv_area::store_would_trash.
|
||||
|
||||
To check whether a pointer refers to this area, only the low
|
||||
ADDR_BIT bits will be compared. */
|
||||
struct pv_area *make_pv_area (int base_reg, int addr_bit);
|
||||
To check whether a pointer refers to this area, only the low
|
||||
ADDR_BIT bits will be compared. */
|
||||
pv_area (int base_reg, int addr_bit);
|
||||
|
||||
/* Free AREA. */
|
||||
void free_pv_area (struct pv_area *area);
|
||||
~pv_area ();
|
||||
|
||||
DISABLE_COPY_AND_ASSIGN (pv_area);
|
||||
|
||||
/* Store the SIZE-byte value VALUE at ADDR in AREA.
|
||||
|
||||
If ADDR is not relative to the same base register we used in
|
||||
creating AREA, then we can't tell which values here the stored
|
||||
value might overlap, and we'll have to mark everything as
|
||||
unknown. */
|
||||
void store (pv_t addr,
|
||||
CORE_ADDR size,
|
||||
pv_t value);
|
||||
|
||||
/* Return the SIZE-byte value at ADDR in AREA. This may return
|
||||
pv_unknown (). */
|
||||
pv_t fetch (pv_t addr, CORE_ADDR size);
|
||||
|
||||
/* Return true if storing to address ADDR in AREA would force us to
|
||||
mark the contents of the entire area as unknown. This could happen
|
||||
if, say, ADDR is unknown, since we could be storing anywhere. Or,
|
||||
it could happen if ADDR is relative to a different register than
|
||||
the other stores base register, since we don't know the relative
|
||||
values of the two registers.
|
||||
|
||||
If you've reached such a store, it may be better to simply stop the
|
||||
prologue analysis, and return the information you've gathered,
|
||||
instead of losing all that information, most of which is probably
|
||||
okay. */
|
||||
int store_would_trash (pv_t addr);
|
||||
|
||||
/* Search AREA for the original value of REGISTER. If we can't find
|
||||
it, return zero; if we can find it, return a non-zero value, and if
|
||||
OFFSET_P is non-zero, set *OFFSET_P to the register's offset within
|
||||
AREA. GDBARCH is the architecture of which REGISTER is a member.
|
||||
|
||||
In the worst case, this takes time proportional to the number of
|
||||
items stored in AREA. If you plan to gather a lot of information
|
||||
about registers saved in AREA, consider calling pv_area::scan
|
||||
instead, and collecting all your information in one pass. */
|
||||
int find_reg (struct gdbarch *gdbarch, int reg, CORE_ADDR *offset_p);
|
||||
|
||||
|
||||
/* Register a cleanup to free AREA. */
|
||||
struct cleanup *make_cleanup_free_pv_area (struct pv_area *area);
|
||||
/* For every part of AREA whose value we know, apply FUNC to CLOSURE,
|
||||
the value's address, its size, and the value itself. */
|
||||
void scan (void (*func) (void *closure,
|
||||
pv_t addr,
|
||||
CORE_ADDR size,
|
||||
pv_t value),
|
||||
void *closure);
|
||||
|
||||
private:
|
||||
|
||||
/* Store the SIZE-byte value VALUE at ADDR in AREA.
|
||||
struct area_entry;
|
||||
|
||||
If ADDR is not relative to the same base register we used in
|
||||
creating AREA, then we can't tell which values here the stored
|
||||
value might overlap, and we'll have to mark everything as
|
||||
unknown. */
|
||||
void pv_area_store (struct pv_area *area,
|
||||
pv_t addr,
|
||||
CORE_ADDR size,
|
||||
pv_t value);
|
||||
/* Delete all entries from AREA. */
|
||||
void clear_entries ();
|
||||
|
||||
/* Return the SIZE-byte value at ADDR in AREA. This may return
|
||||
pv_unknown (). */
|
||||
pv_t pv_area_fetch (struct pv_area *area, pv_t addr, CORE_ADDR size);
|
||||
/* Return a pointer to the first entry we hit in AREA starting at
|
||||
OFFSET and going forward.
|
||||
|
||||
/* Return true if storing to address ADDR in AREA would force us to
|
||||
mark the contents of the entire area as unknown. This could happen
|
||||
if, say, ADDR is unknown, since we could be storing anywhere. Or,
|
||||
it could happen if ADDR is relative to a different register than
|
||||
the other stores base register, since we don't know the relative
|
||||
values of the two registers.
|
||||
This may return zero, if AREA has no entries.
|
||||
|
||||
If you've reached such a store, it may be better to simply stop the
|
||||
prologue analysis, and return the information you've gathered,
|
||||
instead of losing all that information, most of which is probably
|
||||
okay. */
|
||||
int pv_area_store_would_trash (struct pv_area *area, pv_t addr);
|
||||
And since the entries are a ring, this may return an entry that
|
||||
entirely precedes OFFSET. This is the correct behavior: depending
|
||||
on the sizes involved, we could still overlap such an area, with
|
||||
wrap-around. */
|
||||
struct area_entry *find_entry (CORE_ADDR offset);
|
||||
|
||||
/* Return non-zero if the SIZE bytes at OFFSET would overlap ENTRY;
|
||||
return zero otherwise. AREA is the area to which ENTRY belongs. */
|
||||
int overlaps (struct area_entry *entry,
|
||||
CORE_ADDR offset,
|
||||
CORE_ADDR size);
|
||||
|
||||
/* Search AREA for the original value of REGISTER. If we can't find
|
||||
it, return zero; if we can find it, return a non-zero value, and if
|
||||
OFFSET_P is non-zero, set *OFFSET_P to the register's offset within
|
||||
AREA. GDBARCH is the architecture of which REGISTER is a member.
|
||||
/* This area's base register. */
|
||||
int m_base_reg;
|
||||
|
||||
In the worst case, this takes time proportional to the number of
|
||||
items stored in AREA. If you plan to gather a lot of information
|
||||
about registers saved in AREA, consider calling pv_area_scan
|
||||
instead, and collecting all your information in one pass. */
|
||||
int pv_area_find_reg (struct pv_area *area,
|
||||
struct gdbarch *gdbarch,
|
||||
int reg,
|
||||
CORE_ADDR *offset_p);
|
||||
|
||||
|
||||
/* For every part of AREA whose value we know, apply FUNC to CLOSURE,
|
||||
the value's address, its size, and the value itself. */
|
||||
void pv_area_scan (struct pv_area *area,
|
||||
void (*func) (void *closure,
|
||||
pv_t addr,
|
||||
CORE_ADDR size,
|
||||
pv_t value),
|
||||
void *closure);
|
||||
/* The mask to apply to addresses, to make the wrap-around happen at
|
||||
the right place. */
|
||||
CORE_ADDR m_addr_mask;
|
||||
|
||||
/* An element of the doubly-linked ring of entries, or zero if we
|
||||
have none. */
|
||||
struct area_entry *m_entry;
|
||||
};
|
||||
|
||||
#endif /* PROLOGUE_VALUE_H */
|
||||
|
@ -883,7 +883,7 @@ rl78_get_opcode_byte (void *handle)
|
||||
}
|
||||
|
||||
/* Function for finding saved registers in a 'struct pv_area'; this
|
||||
function is passed to pv_area_scan.
|
||||
function is passed to pv_area::scan.
|
||||
|
||||
If VALUE is a saved register, ADDR says it was saved at a constant
|
||||
offset from the frame base, and SIZE indicates that the whole
|
||||
@ -912,8 +912,6 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
|
||||
CORE_ADDR pc, next_pc;
|
||||
int rn;
|
||||
pv_t reg[RL78_NUM_TOTAL_REGS];
|
||||
struct pv_area *stack;
|
||||
struct cleanup *back_to;
|
||||
CORE_ADDR after_last_frame_setup_insn = start_pc;
|
||||
int bank = 0;
|
||||
|
||||
@ -925,12 +923,11 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
|
||||
result->reg_offset[rn] = 1;
|
||||
}
|
||||
|
||||
stack = make_pv_area (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
|
||||
back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
|
||||
|
||||
/* The call instruction has saved the return address on the stack. */
|
||||
reg[RL78_SP_REGNUM] = pv_add_constant (reg[RL78_SP_REGNUM], -4);
|
||||
pv_area_store (stack, reg[RL78_SP_REGNUM], 4, reg[RL78_PC_REGNUM]);
|
||||
stack.store (reg[RL78_SP_REGNUM], 4, reg[RL78_PC_REGNUM]);
|
||||
|
||||
pc = start_pc;
|
||||
while (pc < limit_pc)
|
||||
@ -954,12 +951,12 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
|
||||
&& opc.op[1].type == RL78_Operand_Register)
|
||||
{
|
||||
int rsrc = (bank * RL78_REGS_PER_BANK)
|
||||
+ 2 * (opc.op[1].reg - RL78_Reg_AX);
|
||||
+ 2 * (opc.op[1].reg - RL78_Reg_AX);
|
||||
|
||||
reg[RL78_SP_REGNUM] = pv_add_constant (reg[RL78_SP_REGNUM], -1);
|
||||
pv_area_store (stack, reg[RL78_SP_REGNUM], 1, reg[rsrc]);
|
||||
stack.store (reg[RL78_SP_REGNUM], 1, reg[rsrc]);
|
||||
reg[RL78_SP_REGNUM] = pv_add_constant (reg[RL78_SP_REGNUM], -1);
|
||||
pv_area_store (stack, reg[RL78_SP_REGNUM], 1, reg[rsrc + 1]);
|
||||
stack.store (reg[RL78_SP_REGNUM], 1, reg[rsrc + 1]);
|
||||
after_last_frame_setup_insn = next_pc;
|
||||
}
|
||||
else if (opc.id == RLO_sub
|
||||
@ -1016,11 +1013,9 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
|
||||
result->frame_size = reg[RL78_SP_REGNUM].k;
|
||||
|
||||
/* Record where all the registers were saved. */
|
||||
pv_area_scan (stack, check_for_saved, (void *) result);
|
||||
stack.scan (check_for_saved, (void *) result);
|
||||
|
||||
result->prologue_end = after_last_frame_setup_insn;
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
/* Implement the "addr_bits_remove" gdbarch method. */
|
||||
|
@ -230,7 +230,7 @@ rx_register_type (struct gdbarch *gdbarch, int reg_nr)
|
||||
|
||||
|
||||
/* Function for finding saved registers in a 'struct pv_area'; this
|
||||
function is passed to pv_area_scan.
|
||||
function is passed to pv_area::scan.
|
||||
|
||||
If VALUE is a saved register, ADDR says it was saved at a constant
|
||||
offset from the frame base, and SIZE indicates that the whole
|
||||
@ -287,8 +287,6 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
|
||||
CORE_ADDR pc, next_pc;
|
||||
int rn;
|
||||
pv_t reg[RX_NUM_REGS];
|
||||
struct pv_area *stack;
|
||||
struct cleanup *back_to;
|
||||
CORE_ADDR after_last_frame_setup_insn = start_pc;
|
||||
|
||||
memset (result, 0, sizeof (*result));
|
||||
@ -301,8 +299,7 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
|
||||
result->reg_offset[rn] = 1;
|
||||
}
|
||||
|
||||
stack = make_pv_area (RX_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
|
||||
back_to = make_cleanup_free_pv_area (stack);
|
||||
pv_area stack (RX_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
|
||||
|
||||
if (frame_type == RX_FRAME_TYPE_FAST_INTERRUPT)
|
||||
{
|
||||
@ -318,13 +315,13 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
|
||||
if (frame_type == RX_FRAME_TYPE_EXCEPTION)
|
||||
{
|
||||
reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4);
|
||||
pv_area_store (stack, reg[RX_SP_REGNUM], 4, reg[RX_PSW_REGNUM]);
|
||||
stack.store (reg[RX_SP_REGNUM], 4, reg[RX_PSW_REGNUM]);
|
||||
}
|
||||
|
||||
/* The call instruction (or an exception/interrupt) has saved the return
|
||||
address on the stack. */
|
||||
reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4);
|
||||
pv_area_store (stack, reg[RX_SP_REGNUM], 4, reg[RX_PC_REGNUM]);
|
||||
stack.store (reg[RX_SP_REGNUM], 4, reg[RX_PC_REGNUM]);
|
||||
|
||||
}
|
||||
|
||||
@ -353,7 +350,7 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
|
||||
for (r = r2; r >= r1; r--)
|
||||
{
|
||||
reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4);
|
||||
pv_area_store (stack, reg[RX_SP_REGNUM], 4, reg[r]);
|
||||
stack.store (reg[RX_SP_REGNUM], 4, reg[r]);
|
||||
}
|
||||
after_last_frame_setup_insn = next_pc;
|
||||
}
|
||||
@ -380,7 +377,7 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
|
||||
|
||||
rsrc = opc.op[1].reg;
|
||||
reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4);
|
||||
pv_area_store (stack, reg[RX_SP_REGNUM], 4, reg[rsrc]);
|
||||
stack.store (reg[RX_SP_REGNUM], 4, reg[rsrc]);
|
||||
after_last_frame_setup_insn = next_pc;
|
||||
}
|
||||
else if (opc.id == RXO_add /* add #const, rsrc, rdst */
|
||||
@ -456,11 +453,9 @@ rx_analyze_prologue (CORE_ADDR start_pc, CORE_ADDR limit_pc,
|
||||
}
|
||||
|
||||
/* Record where all the registers were saved. */
|
||||
pv_area_scan (stack, check_for_saved, (void *) result);
|
||||
stack.scan (check_for_saved, (void *) result);
|
||||
|
||||
result->prologue_end = after_last_frame_setup_insn;
|
||||
|
||||
do_cleanups (back_to);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1375,8 +1375,8 @@ s390_store (struct s390_prologue_data *data,
|
||||
|
||||
|
||||
/* Check whether we are storing a register into the stack. */
|
||||
if (!pv_area_store_would_trash (data->stack, addr))
|
||||
pv_area_store (data->stack, addr, size, value);
|
||||
if (!data->stack->store_would_trash (addr))
|
||||
data->stack->store (addr, size, value);
|
||||
|
||||
|
||||
/* Note: If this is some store we cannot identify, you might think we
|
||||
@ -1413,11 +1413,11 @@ s390_load (struct s390_prologue_data *data,
|
||||
}
|
||||
|
||||
/* Check whether we are accessing one of our save slots. */
|
||||
return pv_area_fetch (data->stack, addr, size);
|
||||
return data->stack->fetch (addr, size);
|
||||
}
|
||||
|
||||
/* Function for finding saved registers in a 'struct pv_area'; we pass
|
||||
this to pv_area_scan.
|
||||
this to pv_area::scan.
|
||||
|
||||
If VALUE is a saved register, ADDR says it was saved at a constant
|
||||
offset from the frame base, and SIZE indicates that the whole
|
||||
@ -1486,12 +1486,13 @@ s390_analyze_prologue (struct gdbarch *gdbarch,
|
||||
/* The address of the next instruction after that. */
|
||||
CORE_ADDR next_pc;
|
||||
|
||||
pv_area stack (S390_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
scoped_restore restore_stack = make_scoped_restore (&data->stack, &stack);
|
||||
|
||||
/* Set up everything's initial value. */
|
||||
{
|
||||
int i;
|
||||
|
||||
data->stack = make_pv_area (S390_SP_REGNUM, gdbarch_addr_bit (gdbarch));
|
||||
|
||||
/* For the purpose of prologue tracking, we consider the GPR size to
|
||||
be equal to the ABI word size, even if it is actually larger
|
||||
(i.e. when running a 32-bit binary under a 64-bit kernel). */
|
||||
@ -1730,10 +1731,7 @@ s390_analyze_prologue (struct gdbarch *gdbarch,
|
||||
}
|
||||
|
||||
/* Record where all the registers were saved. */
|
||||
pv_area_scan (data->stack, s390_check_for_saved, data);
|
||||
|
||||
free_pv_area (data->stack);
|
||||
data->stack = NULL;
|
||||
data->stack->scan (s390_check_for_saved, data);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user