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:
Tom Tromey 2017-10-07 18:23:36 -06:00
parent 04ec7890fc
commit f7b7ed97a2
13 changed files with 366 additions and 409 deletions

View file

@ -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> 2017-10-12 Simon Marchi <simon.marchi@ericsson.com>
* linux-nat.h (linux_nat_set_delete_thread): New declaration. * linux-nat.h (linux_nat_set_delete_thread): New declaration.

View file

@ -234,13 +234,10 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
int i; int i;
/* Track X registers and D registers in prologue. */ /* Track X registers and D registers in prologue. */
pv_t regs[AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT]; 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++) for (i = 0; i < AARCH64_X_REGISTER_COUNT + AARCH64_D_REGISTER_COUNT; i++)
regs[i] = pv_register (i, 0); regs[i] = pv_register (i, 0);
stack = make_pv_area (AARCH64_SP_REGNUM, gdbarch_addr_bit (gdbarch)); pv_area stack (AARCH64_SP_REGNUM, gdbarch_addr_bit (gdbarch));
back_to = make_cleanup_free_pv_area (stack);
for (; start < limit; start += 4) 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].type == AARCH64_OPND_ADDR_SIMM9);
gdb_assert (!inst.operands[1].addr.offset.is_reg); gdb_assert (!inst.operands[1].addr.offset.is_reg);
pv_area_store (stack, pv_add_constant (regs[rn], stack.store (pv_add_constant (regs[rn],
inst.operands[1].addr.offset.imm), inst.operands[1].addr.offset.imm),
is64 ? 8 : 4, regs[rt]); is64 ? 8 : 4, regs[rt]);
} }
else if ((inst.opcode->iclass == ldstpair_off else if ((inst.opcode->iclass == ldstpair_off
|| (inst.opcode->iclass == ldstpair_indexed || (inst.opcode->iclass == ldstpair_indexed
@ -370,12 +367,10 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
/* If recording this store would invalidate the store area /* If recording this store would invalidate the store area
(perhaps because rn is not known) then we should abandon (perhaps because rn is not known) then we should abandon
further prologue analysis. */ further prologue analysis. */
if (pv_area_store_would_trash (stack, if (stack.store_would_trash (pv_add_constant (regs[rn], imm)))
pv_add_constant (regs[rn], imm)))
break; break;
if (pv_area_store_would_trash (stack, if (stack.store_would_trash (pv_add_constant (regs[rn], imm + 8)))
pv_add_constant (regs[rn], imm + 8)))
break; break;
rt1 = inst.operands[0].reg.regno; rt1 = inst.operands[0].reg.regno;
@ -389,10 +384,10 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
rt2 += AARCH64_X_REGISTER_COUNT; rt2 += AARCH64_X_REGISTER_COUNT;
} }
pv_area_store (stack, pv_add_constant (regs[rn], imm), 8, stack.store (pv_add_constant (regs[rn], imm), 8,
regs[rt1]); regs[rt1]);
pv_area_store (stack, pv_add_constant (regs[rn], imm + 8), 8, stack.store (pv_add_constant (regs[rn], imm + 8), 8,
regs[rt2]); regs[rt2]);
if (inst.operands[2].addr.writeback) if (inst.operands[2].addr.writeback)
regs[rn] = pv_add_constant (regs[rn], imm); regs[rn] = pv_add_constant (regs[rn], imm);
@ -422,8 +417,8 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
rt += AARCH64_X_REGISTER_COUNT; rt += AARCH64_X_REGISTER_COUNT;
} }
pv_area_store (stack, pv_add_constant (regs[rn], imm), stack.store (pv_add_constant (regs[rn], imm),
is64 ? 8 : 4, regs[rt]); is64 ? 8 : 4, regs[rt]);
if (inst.operands[1].addr.writeback) if (inst.operands[1].addr.writeback)
regs[rn] = pv_add_constant (regs[rn], imm); regs[rn] = pv_add_constant (regs[rn], imm);
} }
@ -445,10 +440,7 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
} }
if (cache == NULL) if (cache == NULL)
{ return start;
do_cleanups (back_to);
return start;
}
if (pv_is_register (regs[AARCH64_FP_REGNUM], AARCH64_SP_REGNUM)) if (pv_is_register (regs[AARCH64_FP_REGNUM], AARCH64_SP_REGNUM))
{ {
@ -473,7 +465,7 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
{ {
CORE_ADDR offset; 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; cache->saved_regs[i].addr = offset;
} }
@ -482,12 +474,11 @@ aarch64_analyze_prologue (struct gdbarch *gdbarch,
int regnum = gdbarch_num_regs (gdbarch); int regnum = gdbarch_num_regs (gdbarch);
CORE_ADDR offset; CORE_ADDR offset;
if (pv_area_find_reg (stack, gdbarch, i + AARCH64_X_REGISTER_COUNT, if (stack.find_reg (gdbarch, i + AARCH64_X_REGISTER_COUNT,
&offset)) &offset))
cache->saved_regs[i + regnum + AARCH64_D0_REGNUM].addr = offset; cache->saved_regs[i + regnum + AARCH64_D0_REGNUM].addr = offset;
} }
do_cleanups (back_to);
return start; return start;
} }

View file

@ -1014,7 +1014,7 @@ arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn,
addr = pv_add_constant (regs[base_reg], addr = pv_add_constant (regs[base_reg],
arc_insn_get_memory_offset (insn)); arc_insn_get_memory_offset (insn));
if (pv_area_store_would_trash (stack, addr)) if (stack->store_would_trash (addr))
return false; return false;
if (insn.data_size_mode != ARC_SCALING_D) 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 else
size = ARC_REGISTER_SIZE; size = ARC_REGISTER_SIZE;
pv_area_store (stack, addr, size, store_value); stack->store (addr, size, store_value);
} }
else 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. */ /* 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_value1 = regs[insn.operands[0].value];
pv_t store_value2 = regs[insn.operands[0].value + 1]; pv_t store_value2 = regs[insn.operands[0].value + 1];
pv_area_store (stack, addr, ARC_REGISTER_SIZE, store_value1); stack->store (addr, ARC_REGISTER_SIZE, store_value1);
pv_area_store (stack, stack->store (pv_add_constant (addr, ARC_REGISTER_SIZE),
pv_add_constant (addr, ARC_REGISTER_SIZE), ARC_REGISTER_SIZE, store_value2);
ARC_REGISTER_SIZE, store_value2);
} }
else else
{ {
pv_t store_value pv_t store_value
= pv_constant (arc_insn_get_operand_value (insn, 0)); = 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, /* Assume that if the last register (closest to new SP) can be written,
then it is possible to write all of them. */ 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; return false;
/* Current store address. */ /* Current store address. */
@ -1145,21 +1144,21 @@ arc_is_in_prologue (struct gdbarch *gdbarch, const struct arc_instruction &insn,
if (is_fp_saved) if (is_fp_saved)
{ {
addr = pv_add_constant (addr, -ARC_REGISTER_SIZE); 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. */ /* 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--) for (int i = ARC_R13_REGNUM + regs_saved - 1; i >= ARC_R13_REGNUM; i--)
{ {
addr = pv_add_constant (addr, -ARC_REGISTER_SIZE); 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) if (is_blink_saved)
{ {
addr = pv_add_constant (addr, -ARC_REGISTER_SIZE); addr = pv_add_constant (addr, -ARC_REGISTER_SIZE);
pv_area_store (stack, addr, ARC_REGISTER_SIZE, stack->store (addr, ARC_REGISTER_SIZE,
regs[ARC_BLINK_REGNUM]); regs[ARC_BLINK_REGNUM]);
} }
gdb_assert (pv_is_identical (addr, new_sp)); 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]; pv_t regs[ARC_LAST_CORE_REGNUM + 1];
for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++) for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++)
regs[i] = pv_register (i, 0); regs[i] = pv_register (i, 0);
struct pv_area *stack = make_pv_area (ARC_SP_REGNUM, pv_area stack (ARC_SP_REGNUM, gdbarch_addr_bit (gdbarch));
gdbarch_addr_bit (gdbarch));
struct cleanup *back_to = make_cleanup_free_pv_area (stack);
CORE_ADDR current_prologue_end = entrypoint; 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 /* If this instruction is in the prologue, fields in the cache will be
updated, and the saved registers mask may be updated. */ 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. */ /* Found an instruction that is not in the prologue. */
if (arc_debug) 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++) for (int i = 0; i <= ARC_LAST_CORE_REGNUM; i++)
{ {
CORE_ADDR offset; 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; cache->saved_regs[i].addr = offset;
} }
} }
do_cleanups (back_to);
return current_prologue_end; return current_prologue_end;
} }

View file

@ -647,15 +647,12 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
int i; int i;
pv_t regs[16]; pv_t regs[16];
struct pv_area *stack;
struct cleanup *back_to;
CORE_ADDR offset; CORE_ADDR offset;
CORE_ADDR unrecognized_pc = 0; CORE_ADDR unrecognized_pc = 0;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
regs[i] = pv_register (i, 0); regs[i] = pv_register (i, 0);
stack = make_pv_area (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch)); pv_area stack (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));
back_to = make_cleanup_free_pv_area (stack);
while (start < limit) while (start < limit)
{ {
@ -668,7 +665,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
int regno; int regno;
int mask; int mask;
if (pv_area_store_would_trash (stack, regs[ARM_SP_REGNUM])) if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
break; break;
/* Bits 0-7 contain a mask for registers R0-R7. Bit 8 says /* 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], regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM],
-4); -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 */ else if ((insn & 0xff80) == 0xb080) /* sub sp, #imm */
@ -735,10 +732,10 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
offset = (insn & 0xff) << 2; offset = (insn & 0xff) << 2;
addr = pv_add_constant (regs[ARM_SP_REGNUM], offset); addr = pv_add_constant (regs[ARM_SP_REGNUM], offset);
if (pv_area_store_would_trash (stack, addr)) if (stack.store_would_trash (addr))
break; break;
pv_area_store (stack, addr, 4, regs[regno]); stack.store (addr, 4, regs[regno]);
} }
else if ((insn & 0xf800) == 0x6000) /* str rd, [rn, #off] */ 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; offset = bits (insn, 6, 10) << 2;
addr = pv_add_constant (regs[rn], offset); addr = pv_add_constant (regs[rn], offset);
if (pv_area_store_would_trash (stack, addr)) if (stack.store_would_trash (addr))
break; break;
pv_area_store (stack, addr, 4, regs[rd]); stack.store (addr, 4, regs[rd]);
} }
else if (((insn & 0xf800) == 0x7000 /* strb Rd, [Rn, #off] */ else if (((insn & 0xf800) == 0x7000 /* strb Rd, [Rn, #off] */
|| (insn & 0xf800) == 0x8000) /* strh 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)]; pv_t addr = regs[bits (insn, 0, 3)];
int regno; int regno;
if (pv_area_store_would_trash (stack, addr)) if (stack.store_would_trash (addr))
break; break;
/* Calculate offsets of saved registers. */ /* Calculate offsets of saved registers. */
@ -836,7 +833,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
if (inst2 & (1 << regno)) if (inst2 & (1 << regno))
{ {
addr = pv_add_constant (addr, -4); addr = pv_add_constant (addr, -4);
pv_area_store (stack, addr, 4, regs[regno]); stack.store (addr, 4, regs[regno]);
} }
if (insn & 0x0020) if (insn & 0x0020)
@ -857,12 +854,12 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
else else
addr = pv_add_constant (addr, -offset); addr = pv_add_constant (addr, -offset);
if (pv_area_store_would_trash (stack, addr)) if (stack.store_would_trash (addr))
break; break;
pv_area_store (stack, addr, 4, regs[regno1]); stack.store (addr, 4, regs[regno1]);
pv_area_store (stack, pv_add_constant (addr, 4), stack.store (pv_add_constant (addr, 4),
4, regs[regno2]); 4, regs[regno2]);
if (insn & 0x0020) if (insn & 0x0020)
regs[bits (insn, 0, 3)] = addr; regs[bits (insn, 0, 3)] = addr;
@ -881,10 +878,10 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
else else
addr = pv_add_constant (addr, -offset); addr = pv_add_constant (addr, -offset);
if (pv_area_store_would_trash (stack, addr)) if (stack.store_would_trash (addr))
break; break;
pv_area_store (stack, addr, 4, regs[regno]); stack.store (addr, 4, regs[regno]);
if (inst2 & 0x0100) if (inst2 & 0x0100)
regs[bits (insn, 0, 3)] = addr; regs[bits (insn, 0, 3)] = addr;
@ -899,10 +896,10 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
offset = inst2 & 0xfff; offset = inst2 & 0xfff;
addr = pv_add_constant (regs[bits (insn, 0, 3)], offset); 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; 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] */ else if ((insn & 0xffd0) == 0xf880 /* str{bh}.w Rt,[Rn,#imm] */
@ -1085,10 +1082,7 @@ thumb_analyze_prologue (struct gdbarch *gdbarch,
unrecognized_pc = start; unrecognized_pc = start;
if (cache == NULL) if (cache == NULL)
{ return unrecognized_pc;
do_cleanups (back_to);
return unrecognized_pc;
}
if (pv_is_register (regs[ARM_FP_REGNUM], ARM_SP_REGNUM)) 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++) 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; cache->saved_regs[i].addr = offset;
do_cleanups (back_to);
return unrecognized_pc; return unrecognized_pc;
} }
@ -1489,8 +1482,6 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
int regno; int regno;
CORE_ADDR offset, current_pc; CORE_ADDR offset, current_pc;
pv_t regs[ARM_FPS_REGNUM]; pv_t regs[ARM_FPS_REGNUM];
struct pv_area *stack;
struct cleanup *back_to;
CORE_ADDR unrecognized_pc = 0; CORE_ADDR unrecognized_pc = 0;
/* Search the prologue looking for instructions that set up the /* 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++) for (regno = 0; regno < ARM_FPS_REGNUM; regno++)
regs[regno] = pv_register (regno, 0); regs[regno] = pv_register (regno, 0);
stack = make_pv_area (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch)); pv_area stack (ARM_SP_REGNUM, gdbarch_addr_bit (gdbarch));
back_to = make_cleanup_free_pv_area (stack);
for (current_pc = prologue_start; for (current_pc = prologue_start;
current_pc < prologue_end; current_pc < prologue_end;
@ -1543,11 +1533,11 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
else if ((insn & 0xffff0fff) == 0xe52d0004) /* str Rd, else if ((insn & 0xffff0fff) == 0xe52d0004) /* str Rd,
[sp, #-4]! */ [sp, #-4]! */
{ {
if (pv_area_store_would_trash (stack, regs[ARM_SP_REGNUM])) if (stack.store_would_trash (regs[ARM_SP_REGNUM]))
break; break;
regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -4); regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -4);
pv_area_store (stack, regs[ARM_SP_REGNUM], 4, stack.store (regs[ARM_SP_REGNUM], 4,
regs[bits (insn, 12, 15)]); regs[bits (insn, 12, 15)]);
continue; continue;
} }
else if ((insn & 0xffff0000) == 0xe92d0000) else if ((insn & 0xffff0000) == 0xe92d0000)
@ -1557,7 +1547,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
{ {
int mask = insn & 0xffff; 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; break;
/* Calculate offsets of saved registers. */ /* Calculate offsets of saved registers. */
@ -1566,7 +1556,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
{ {
regs[ARM_SP_REGNUM] regs[ARM_SP_REGNUM]
= pv_add_constant (regs[ARM_SP_REGNUM], -4); = 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] */ else if ((insn & 0xffff0000) == 0xe54b0000 /* strb rx,[r11,#-n] */
@ -1608,12 +1598,12 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
[sp, -#c]! */ [sp, -#c]! */
&& gdbarch_tdep (gdbarch)->have_fpa_registers) && 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; break;
regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12); regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12);
regno = ARM_F0_REGNUM + ((insn >> 12) & 0x07); 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, else if ((insn & 0xffbf0fff) == 0xec2d0200 /* sfmfd f0, 4,
[sp!] */ [sp!] */
@ -1622,7 +1612,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
int n_saved_fp_regs; int n_saved_fp_regs;
unsigned int fp_start_reg, fp_bound_reg; 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; break;
if ((insn & 0x800) == 0x800) /* N0 is set */ 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++) for (; fp_start_reg < fp_bound_reg; fp_start_reg++)
{ {
regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12); regs[ARM_SP_REGNUM] = pv_add_constant (regs[ARM_SP_REGNUM], -12);
pv_area_store (stack, regs[ARM_SP_REGNUM], 12, stack.store (regs[ARM_SP_REGNUM], 12,
regs[fp_start_reg++]); regs[fp_start_reg++]);
} }
} }
else if ((insn & 0xff000000) == 0xeb000000 && cache == NULL) /* bl */ else if ((insn & 0xff000000) == 0xeb000000 && cache == NULL) /* bl */
@ -1726,7 +1716,7 @@ arm_analyze_prologue (struct gdbarch *gdbarch,
cache->framesize = framesize; cache->framesize = framesize;
for (regno = 0; regno < ARM_FPS_REGNUM; regno++) 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; 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", fprintf_unfiltered (gdb_stdlog, "Prologue scan stopped at %s\n",
paddress (gdbarch, unrecognized_pc)); paddress (gdbarch, unrecognized_pc));
do_cleanups (back_to);
return unrecognized_pc; return unrecognized_pc;
} }

View file

@ -1079,11 +1079,11 @@ struct m32c_pv_state
static int static int
m32c_pv_push (struct m32c_pv_state *state, pv_t value, int size) 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; return 1;
state->sp = pv_add_constant (state->sp, -size); 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; return 0;
} }
@ -1114,7 +1114,7 @@ static pv_t
m32c_srcdest_fetch (struct m32c_pv_state *state, struct srcdest loc, int size) m32c_srcdest_fetch (struct m32c_pv_state *state, struct srcdest loc, int size)
{ {
if (loc.kind == srcdest_mem) 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) else if (loc.kind == srcdest_partial_reg)
return pv_unknown (); return pv_unknown ();
else else
@ -1131,9 +1131,9 @@ m32c_srcdest_store (struct m32c_pv_state *state, struct srcdest loc,
{ {
if (loc.kind == srcdest_mem) 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; 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) else if (loc.kind == srcdest_partial_reg)
*loc.reg = pv_unknown (); *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 /* If simulating this store would require us to forget
everything we know about the stack frame in the name of everything we know about the stack frame in the name of
accuracy, it would be better to just quit now. */ 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; return 1;
if (m32c_pv_push (state, state->fb, tdep->push_addr_bytes)) 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) return (m32c_is_arg_reg (st, value)
&& loc.kind == srcdest_mem && loc.kind == srcdest_mem
&& pv_is_register (loc.addr, tdep->sp->num) && 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 /* 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); struct gdbarch_tdep *tdep = gdbarch_tdep (st->arch);
return (m32c_is_1st_arg_reg (st, value) 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 && loc.kind == srcdest_reg
&& (pv_is_register (*loc.reg, tdep->a0->num) && (pv_is_register (*loc.reg, tdep->a0->num)
|| pv_is_register (*loc.reg, tdep->a1->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 /* 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 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 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); struct gdbarch_tdep *tdep = gdbarch_tdep (arch);
unsigned long mach = gdbarch_bfd_arch_info (arch)->mach; unsigned long mach = gdbarch_bfd_arch_info (arch)->mach;
CORE_ADDR after_last_frame_related_insn; CORE_ADDR after_last_frame_related_insn;
struct cleanup *back_to;
struct m32c_pv_state st; struct m32c_pv_state st;
st.arch = arch; st.arch = arch;
@ -1560,8 +1559,8 @@ m32c_analyze_prologue (struct gdbarch *arch,
st.fb = pv_register (tdep->fb->num, 0); st.fb = pv_register (tdep->fb->num, 0);
st.sp = pv_register (tdep->sp->num, 0); st.sp = pv_register (tdep->sp->num, 0);
st.pc = pv_register (tdep->pc->num, 0); st.pc = pv_register (tdep->pc->num, 0);
st.stack = make_pv_area (tdep->sp->num, gdbarch_addr_bit (arch)); pv_area stack (tdep->sp->num, gdbarch_addr_bit (arch));
back_to = make_cleanup_free_pv_area (st.stack); st.stack = &stack;
/* Record that the call instruction has saved the return address on /* Record that the call instruction has saved the return address on
the stack. */ the stack. */
@ -1812,11 +1811,9 @@ m32c_analyze_prologue (struct gdbarch *arch,
prologue->kind = prologue_first_frame; prologue->kind = prologue_first_frame;
/* Record where all the registers were saved. */ /* 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; prologue->prologue_end = after_last_frame_related_insn;
do_cleanups (back_to);
} }

View file

@ -1640,12 +1640,12 @@ is_arg_spill (struct gdbarch *gdbarch, pv_t value, pv_t addr,
{ {
return (is_arg_reg (value) return (is_arg_reg (value)
&& pv_is_register (addr, MEP_SP_REGNUM) && 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 /* 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 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 offset from the frame base, and SIZE indicates that the whole
@ -1675,8 +1675,6 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
int rn; int rn;
int found_lp = 0; int found_lp = 0;
pv_t reg[MEP_NUM_REGS]; pv_t reg[MEP_NUM_REGS];
struct pv_area *stack;
struct cleanup *back_to;
CORE_ADDR after_last_frame_setup_insn = start_pc; CORE_ADDR after_last_frame_setup_insn = start_pc;
memset (result, 0, sizeof (*result)); memset (result, 0, sizeof (*result));
@ -1688,8 +1686,7 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
result->reg_offset[rn] = 1; result->reg_offset[rn] = 1;
} }
stack = make_pv_area (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch)); pv_area stack (MEP_SP_REGNUM, gdbarch_addr_bit (gdbarch));
back_to = make_cleanup_free_pv_area (stack);
pc = start_pc; pc = start_pc;
while (pc < limit_pc) while (pc < limit_pc)
@ -1741,13 +1738,13 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
/* If simulating this store would require us to forget /* If simulating this store would require us to forget
everything we know about the stack frame in the name of everything we know about the stack frame in the name of
accuracy, it would be better to just quit now. */ 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; 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; 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)) 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 /* If simulating this store would require us to forget
everything we know about the stack frame in the name of everything we know about the stack frame in the name of
accuracy, it would be better to just quit now. */ accuracy, it would be better to just quit now. */
if (pv_area_store_would_trash (stack, addr)) if (stack.store_would_trash (addr))
break; 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; 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)) else if (IS_MOV (insn))
{ {
@ -1786,13 +1783,13 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
: (gdb_assert (IS_SW (insn)), 4)); : (gdb_assert (IS_SW (insn)), 4));
pv_t addr = pv_add_constant (reg[rm], disp); pv_t addr = pv_add_constant (reg[rm], disp);
if (pv_area_store_would_trash (stack, addr)) if (stack.store_would_trash (addr))
break; 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; 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)) else if (IS_LDC (insn))
{ {
@ -1808,7 +1805,7 @@ mep_analyze_prologue (struct gdbarch *gdbarch,
int offset = LW_OFFSET (insn); int offset = LW_OFFSET (insn);
pv_t addr = pv_add_constant (reg[rm], offset); 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) 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. */ /* 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; result->prologue_end = after_last_frame_setup_insn;
do_cleanups (back_to);
} }

View file

@ -337,7 +337,7 @@ static void
push_reg (pv_t *regs, struct pv_area *stack, int regnum) push_reg (pv_t *regs, struct pv_area *stack, int regnum)
{ {
regs[E_SP_REGNUM] = pv_add_constant (regs[E_SP_REGNUM], -4); 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 /* Translate an "r" register number extracted from an instruction encoding
@ -356,7 +356,7 @@ translate_rreg (int rreg)
return E_E0_REGNUM + 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 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 offset from the frame base, and SIZE indicates that the whole
@ -386,8 +386,6 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
CORE_ADDR pc; CORE_ADDR pc;
int rn; int rn;
pv_t regs[MN10300_MAX_NUM_REGS]; pv_t regs[MN10300_MAX_NUM_REGS];
struct pv_area *stack;
struct cleanup *back_to;
CORE_ADDR after_last_frame_setup_insn = start_pc; CORE_ADDR after_last_frame_setup_insn = start_pc;
int am33_mode = AM33_MODE (gdbarch); int am33_mode = AM33_MODE (gdbarch);
@ -399,16 +397,15 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
regs[rn] = pv_register (rn, 0); regs[rn] = pv_register (rn, 0);
result->reg_offset[rn] = 1; result->reg_offset[rn] = 1;
} }
stack = make_pv_area (E_SP_REGNUM, gdbarch_addr_bit (gdbarch)); pv_area stack (E_SP_REGNUM, gdbarch_addr_bit (gdbarch));
back_to = make_cleanup_free_pv_area (stack);
/* The typical call instruction will have saved the return address on the /* The typical call instruction will have saved the return address on the
stack. Space for the return address has already been preallocated in 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 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 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 have no chance of deciphering the frame. DWARF info can save the day
when this happens. */ when this happens. */
pv_area_store (stack, regs[E_SP_REGNUM], 4, regs[E_PC_REGNUM]); stack.store (regs[E_SP_REGNUM], 4, regs[E_PC_REGNUM]);
pc = start_pc; pc = start_pc;
while (pc < limit_pc) while (pc < limit_pc)
@ -432,42 +429,42 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
if ((save_mask & movm_exreg0_bit) && am33_mode) if ((save_mask & movm_exreg0_bit) && am33_mode)
{ {
push_reg (regs, stack, E_E2_REGNUM); push_reg (regs, &stack, E_E2_REGNUM);
push_reg (regs, stack, E_E3_REGNUM); push_reg (regs, &stack, E_E3_REGNUM);
} }
if ((save_mask & movm_exreg1_bit) && am33_mode) if ((save_mask & movm_exreg1_bit) && am33_mode)
{ {
push_reg (regs, stack, E_E4_REGNUM); push_reg (regs, &stack, E_E4_REGNUM);
push_reg (regs, stack, E_E5_REGNUM); push_reg (regs, &stack, E_E5_REGNUM);
push_reg (regs, stack, E_E6_REGNUM); push_reg (regs, &stack, E_E6_REGNUM);
push_reg (regs, stack, E_E7_REGNUM); push_reg (regs, &stack, E_E7_REGNUM);
} }
if ((save_mask & movm_exother_bit) && am33_mode) if ((save_mask & movm_exother_bit) && am33_mode)
{ {
push_reg (regs, stack, E_E0_REGNUM); push_reg (regs, &stack, E_E0_REGNUM);
push_reg (regs, stack, E_E1_REGNUM); push_reg (regs, &stack, E_E1_REGNUM);
push_reg (regs, stack, E_MDRQ_REGNUM); push_reg (regs, &stack, E_MDRQ_REGNUM);
push_reg (regs, stack, E_MCRH_REGNUM); push_reg (regs, &stack, E_MCRH_REGNUM);
push_reg (regs, stack, E_MCRL_REGNUM); push_reg (regs, &stack, E_MCRL_REGNUM);
push_reg (regs, stack, E_MCVF_REGNUM); push_reg (regs, &stack, E_MCVF_REGNUM);
} }
if (save_mask & movm_d2_bit) 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) 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) 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) 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) if (save_mask & movm_other_bit)
{ {
push_reg (regs, stack, E_D0_REGNUM); push_reg (regs, &stack, E_D0_REGNUM);
push_reg (regs, stack, E_D1_REGNUM); push_reg (regs, &stack, E_D1_REGNUM);
push_reg (regs, stack, E_A0_REGNUM); push_reg (regs, &stack, E_A0_REGNUM);
push_reg (regs, stack, E_A1_REGNUM); push_reg (regs, &stack, E_A1_REGNUM);
push_reg (regs, stack, E_MDR_REGNUM); push_reg (regs, &stack, E_MDR_REGNUM);
push_reg (regs, stack, E_LIR_REGNUM); push_reg (regs, &stack, E_LIR_REGNUM);
push_reg (regs, stack, E_LAR_REGNUM); push_reg (regs, &stack, E_LAR_REGNUM);
/* The `other' bit leaves a blank area of four bytes at /* The `other' bit leaves a blank area of four bytes at
the beginning of its block of saved registers, making the beginning of its block of saved registers, making
it 32 bytes long in total. */ it 32 bytes long in total. */
@ -653,8 +650,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
rN = buf[0] & 0x0f; rN = buf[0] & 0x0f;
fsM = (Y << 4) | sM; fsM = (Y << 4) | sM;
pv_area_store (stack, regs[translate_rreg (rN)], 4, stack.store (regs[translate_rreg (rN)], 4,
regs[E_FS0_REGNUM + fsM]); regs[E_FS0_REGNUM + fsM]);
pc += 3; pc += 3;
} }
@ -673,8 +670,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
sM = (buf[0] & 0xf0) >> 4; sM = (buf[0] & 0xf0) >> 4;
fsM = (Y << 4) | sM; fsM = (Y << 4) | sM;
pv_area_store (stack, regs[E_SP_REGNUM], 4, stack.store (regs[E_SP_REGNUM], 4,
regs[E_FS0_REGNUM + fsM]); regs[E_FS0_REGNUM + fsM]);
pc += 3; pc += 3;
} }
@ -695,10 +692,9 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
Z = (buf[1] & 0x02) >> 1; Z = (buf[1] & 0x02) >> 1;
fsM = (Z << 4) | sM; fsM = (Z << 4) | sM;
pv_area_store (stack, stack.store (pv_add (regs[translate_rreg (rN)],
pv_add (regs[translate_rreg (rN)], regs[translate_rreg (rI)]),
regs[translate_rreg (rI)]), 4, regs[E_FS0_REGNUM + fsM]);
4, regs[E_FS0_REGNUM + fsM]);
pc += 4; pc += 4;
} }
@ -720,9 +716,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
fsM = (Y << 4) | sM; fsM = (Y << 4) | sM;
d8 = extract_signed_integer (&buf[1], 1, byte_order); d8 = extract_signed_integer (&buf[1], 1, byte_order);
pv_area_store (stack, stack.store (pv_add_constant (regs[translate_rreg (rN)], d8),
pv_add_constant (regs[translate_rreg (rN)], d8), 4, regs[E_FS0_REGNUM + fsM]);
4, regs[E_FS0_REGNUM + fsM]);
pc += 4; pc += 4;
} }
@ -744,9 +739,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
fsM = (Y << 4) | sM; fsM = (Y << 4) | sM;
d24 = extract_signed_integer (&buf[1], 3, byte_order); d24 = extract_signed_integer (&buf[1], 3, byte_order);
pv_area_store (stack, stack.store (pv_add_constant (regs[translate_rreg (rN)], d24),
pv_add_constant (regs[translate_rreg (rN)], d24), 4, regs[E_FS0_REGNUM + fsM]);
4, regs[E_FS0_REGNUM + fsM]);
pc += 6; pc += 6;
} }
@ -768,9 +762,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
fsM = (Y << 4) | sM; fsM = (Y << 4) | sM;
d32 = extract_signed_integer (&buf[1], 4, byte_order); d32 = extract_signed_integer (&buf[1], 4, byte_order);
pv_area_store (stack, stack.store (pv_add_constant (regs[translate_rreg (rN)], d32),
pv_add_constant (regs[translate_rreg (rN)], d32), 4, regs[E_FS0_REGNUM + fsM]);
4, regs[E_FS0_REGNUM + fsM]);
pc += 7; pc += 7;
} }
@ -791,9 +784,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
fsM = (Y << 4) | sM; fsM = (Y << 4) | sM;
d8 = extract_signed_integer (&buf[1], 1, byte_order); d8 = extract_signed_integer (&buf[1], 1, byte_order);
pv_area_store (stack, stack.store (pv_add_constant (regs[E_SP_REGNUM], d8),
pv_add_constant (regs[E_SP_REGNUM], d8), 4, regs[E_FS0_REGNUM + fsM]);
4, regs[E_FS0_REGNUM + fsM]);
pc += 4; pc += 4;
} }
@ -814,9 +806,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
fsM = (Y << 4) | sM; fsM = (Y << 4) | sM;
d24 = extract_signed_integer (&buf[1], 3, byte_order); d24 = extract_signed_integer (&buf[1], 3, byte_order);
pv_area_store (stack, stack.store (pv_add_constant (regs[E_SP_REGNUM], d24),
pv_add_constant (regs[E_SP_REGNUM], d24), 4, regs[E_FS0_REGNUM + fsM]);
4, regs[E_FS0_REGNUM + fsM]);
pc += 6; pc += 6;
} }
@ -837,9 +828,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
fsM = (Y << 4) | sM; fsM = (Y << 4) | sM;
d32 = extract_signed_integer (&buf[1], 4, byte_order); d32 = extract_signed_integer (&buf[1], 4, byte_order);
pv_area_store (stack, stack.store (pv_add_constant (regs[E_SP_REGNUM], d32),
pv_add_constant (regs[E_SP_REGNUM], d32), 4, regs[E_FS0_REGNUM + fsM]);
4, regs[E_FS0_REGNUM + fsM]);
pc += 7; pc += 7;
} }
@ -861,8 +851,8 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
rN_regnum = translate_rreg (rN); rN_regnum = translate_rreg (rN);
pv_area_store (stack, regs[rN_regnum], 4, stack.store (regs[rN_regnum], 4,
regs[E_FS0_REGNUM + fsM]); regs[E_FS0_REGNUM + fsM]);
regs[rN_regnum] = pv_add_constant (regs[rN_regnum], 4); regs[rN_regnum] = pv_add_constant (regs[rN_regnum], 4);
pc += 3; pc += 3;
@ -887,7 +877,7 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
rN_regnum = translate_rreg (rN); 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); regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm8);
pc += 4; pc += 4;
@ -912,7 +902,7 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
rN_regnum = translate_rreg (rN); 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); regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm24);
pc += 6; pc += 6;
@ -937,7 +927,7 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
rN_regnum = translate_rreg (rN); 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); regs[rN_regnum] = pv_add_constant (regs[rN_regnum], imm32);
pc += 7; pc += 7;
@ -1044,11 +1034,9 @@ mn10300_analyze_prologue (struct gdbarch *gdbarch,
} }
/* Record where all the registers were saved. */ /* 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; result->prologue_end = after_last_frame_setup_insn;
do_cleanups (back_to);
} }
/* Function: skip_prologue /* Function: skip_prologue

View file

@ -311,7 +311,7 @@ msp430_get_opcode_byte (void *handle)
} }
/* Function for finding saved registers in a 'struct pv_area'; this /* 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 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 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; CORE_ADDR pc, next_pc;
int rn; int rn;
pv_t reg[MSP430_NUM_TOTAL_REGS]; pv_t reg[MSP430_NUM_TOTAL_REGS];
struct pv_area *stack;
struct cleanup *back_to;
CORE_ADDR after_last_frame_setup_insn = start_pc; CORE_ADDR after_last_frame_setup_insn = start_pc;
int code_model = gdbarch_tdep (gdbarch)->code_model; int code_model = gdbarch_tdep (gdbarch)->code_model;
int sz; int sz;
@ -353,13 +351,12 @@ msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
result->reg_offset[rn] = 1; result->reg_offset[rn] = 1;
} }
stack = make_pv_area (MSP430_SP_REGNUM, gdbarch_addr_bit (gdbarch)); pv_area stack (MSP430_SP_REGNUM, gdbarch_addr_bit (gdbarch));
back_to = make_cleanup_free_pv_area (stack);
/* The call instruction has saved the return address on the stack. */ /* The call instruction has saved the return address on the stack. */
sz = code_model == MSP_LARGE_CODE_MODEL ? 4 : 2; sz = code_model == MSP_LARGE_CODE_MODEL ? 4 : 2;
reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -sz); 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; pc = start_pc;
while (pc < limit_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; int rsrc = opc.op[0].reg;
reg[MSP430_SP_REGNUM] = pv_add_constant (reg[MSP430_SP_REGNUM], -2); 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; after_last_frame_setup_insn = next_pc;
} }
else if (opc.id == MSO_push /* PUSHM */ 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] reg[MSP430_SP_REGNUM]
= pv_add_constant (reg[MSP430_SP_REGNUM], -size); = 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--; rsrc--;
count--; count--;
} }
@ -428,11 +425,9 @@ msp430_analyze_prologue (struct gdbarch *gdbarch, CORE_ADDR start_pc,
result->frame_size = reg[MSP430_SP_REGNUM].k; result->frame_size = reg[MSP430_SP_REGNUM].k;
/* Record where all the registers were saved. */ /* 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; result->prologue_end = after_last_frame_setup_insn;
do_cleanups (back_to);
} }
/* Implement the "skip_prologue" gdbarch method. */ /* Implement the "skip_prologue" gdbarch method. */

View file

@ -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 The entry with the lowest offset simply follows the entry with the
highest offset. Entries may abut, but never overlap. The area's highest offset. Entries may abut, but never overlap. The area's
'entry' pointer points to an arbitrary node in the ring. */ 'entry' pointer points to an arbitrary node in the ring. */
struct area_entry struct pv_area::area_entry
{ {
/* Links in the doubly-linked ring. */ /* Links in the doubly-linked ring. */
struct area_entry *prev, *next; 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. */ void
static void pv_area::clear_entries ()
clear_entries (struct pv_area *area)
{ {
struct area_entry *e = area->entry; struct area_entry *e = m_entry;
if (e) if (e)
{ {
@ -347,37 +326,23 @@ clear_entries (struct pv_area *area)
xfree (e); xfree (e);
e = next; e = next;
} }
while (e != area->entry); while (e != m_entry);
area->entry = 0; m_entry = 0;
} }
} }
void pv_area::~pv_area ()
free_pv_area (struct pv_area *area)
{ {
clear_entries (area); clear_entries ();
xfree (area);
} }
static void /* See prologue-value.h. */
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);
}
int 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, /* It may seem odd that pvk_constant appears here --- after all,
that's the case where we know the most about the address! But 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. */ constants. */
return (addr.kind == pvk_unknown return (addr.kind == pvk_unknown
|| addr.kind == pvk_constant || 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 /* See prologue-value.h. */
OFFSET and going forward.
This may return zero, if AREA has no entries. struct pv_area::area_entry *
pv_area::find_entry (CORE_ADDR offset)
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 area_entry *e = area->entry; struct area_entry *e = m_entry;
if (! e) if (! e)
return 0; 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 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 make sure both things we're comparing are on the same side of the
discontinuity. */ discontinuity. */
while (((e->next->offset - offset) & area->addr_mask) while (((e->next->offset - offset) & m_addr_mask)
< ((e->offset - offset) & area->addr_mask)) < ((e->offset - offset) & m_addr_mask))
e = e->next; e = e->next;
/* If the previous entry would be better than the current one, then /* If the previous entry would be better than the current one, then
scan backwards. */ scan backwards. */
while (((e->prev->offset - offset) & area->addr_mask) while (((e->prev->offset - offset) & m_addr_mask)
< ((e->offset - offset) & area->addr_mask)) < ((e->offset - offset) & m_addr_mask))
e = e->prev; e = e->prev;
/* In case there's some locality to the searches, set the area's /* In case there's some locality to the searches, set the area's
pointer to the entry we've found. */ pointer to the entry we've found. */
area->entry = e; m_entry = e;
return e; return e;
} }
/* Return non-zero if the SIZE bytes at OFFSET would overlap ENTRY; /* See prologue-value.h. */
return zero otherwise. AREA is the area to which ENTRY belongs. */
static int int
overlaps (struct pv_area *area, pv_area::overlaps (struct area_entry *entry, CORE_ADDR offset, CORE_ADDR size)
struct area_entry *entry,
CORE_ADDR offset,
CORE_ADDR size)
{ {
/* Think carefully about wrap-around before simplifying this. */ /* Think carefully about wrap-around before simplifying this. */
return (((entry->offset - offset) & area->addr_mask) < size return (((entry->offset - offset) & m_addr_mask) < size
|| ((offset - entry->offset) & area->addr_mask) < entry->size); || ((offset - entry->offset) & m_addr_mask) < entry->size);
} }
/* See prologue-value.h. */
void void
pv_area_store (struct pv_area *area, pv_area::store (pv_t addr, CORE_ADDR size, pv_t value)
pv_t addr,
CORE_ADDR size,
pv_t value)
{ {
/* Remove any (potentially) overlapping entries. */ /* Remove any (potentially) overlapping entries. */
if (pv_area_store_would_trash (area, addr)) if (store_would_trash (addr))
clear_entries (area); clear_entries ();
else else
{ {
CORE_ADDR offset = addr.k; 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. */ /* 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; 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 /* Move the area's pointer to the next remaining entry. This
will also zero the pointer if we've deleted all the entries. */ 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 either zero or pointing at the closest entry after us. We can
just insert ourselves before that. just insert ourselves before that.
@ -496,33 +450,35 @@ pv_area_store (struct pv_area *area,
e->size = size; e->size = size;
e->value = value; e->value = value;
if (area->entry) if (m_entry)
{ {
e->prev = area->entry->prev; e->prev = m_entry->prev;
e->next = area->entry; e->next = m_entry;
e->prev->next = e->next->prev = e; e->prev->next = e->next->prev = e;
} }
else else
{ {
e->prev = e->next = e; e->prev = e->next = e;
area->entry = e; m_entry = e;
} }
} }
} }
/* See prologue-value.h. */
pv_t 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 /* If we have no entries, or we can't decide how ADDR relates to the
entries we do have, then the value is unknown. */ entries we do have, then the value is unknown. */
if (! area->entry if (! m_entry
|| pv_area_store_would_trash (area, addr)) || store_would_trash (addr))
return pv_unknown (); return pv_unknown ();
else else
{ {
CORE_ADDR offset = addr.k; 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 /* If this entry exactly matches what we're looking for, then
we're set. Otherwise, say it's unknown. */ 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 int
pv_area_find_reg (struct pv_area *area, pv_area::find_reg (struct gdbarch *gdbarch, int reg, CORE_ADDR *offset_p)
struct gdbarch *gdbarch,
int reg,
CORE_ADDR *offset_p)
{ {
struct area_entry *e = area->entry; struct area_entry *e = m_entry;
if (e) if (e)
do do
@ -557,25 +512,26 @@ pv_area_find_reg (struct pv_area *area,
e = e->next; e = e->next;
} }
while (e != area->entry); while (e != m_entry);
return 0; return 0;
} }
/* See prologue-value.h. */
void void
pv_area_scan (struct pv_area *area, pv_area::scan (void (*func) (void *closure,
void (*func) (void *closure, pv_t addr,
pv_t addr, CORE_ADDR size,
CORE_ADDR size, pv_t value),
pv_t value), void *closure)
void *closure)
{ {
struct area_entry *e = area->entry; struct area_entry *e = m_entry;
pv_t addr; pv_t addr;
addr.kind = pvk_register; addr.kind = pvk_register;
addr.reg = area->base_reg; addr.reg = m_base_reg;
if (e) if (e)
do do
@ -584,5 +540,5 @@ pv_area_scan (struct pv_area *area,
func (closure, addr, e->size, e->value); func (closure, addr, e->size, e->value);
e = e->next; e = e->next;
} }
while (e != area->entry); while (e != m_entry);
} }

View file

@ -221,83 +221,110 @@ enum pv_boolean pv_is_array_ref (pv_t addr, CORE_ADDR size,
int *i); int *i);
/* A 'struct pv_area' keeps track of values stored in a particular /* A 'pv_area' keeps track of values stored in a particular region of
region of memory. */ memory. */
struct pv_area; class pv_area
{
public:
/* Create a new area, tracking stores relative to the original value /* Create a new area, tracking stores relative to the original value
of BASE_REG. If BASE_REG is SP, then this effectively records the 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 contents of the stack frame: the original value of the SP is the
frame's CFA, or some constant offset from it. frame's CFA, or some constant offset from it.
Stores to constant addresses, unknown addresses, or to addresses Stores to constant addresses, unknown addresses, or to addresses
relative to registers other than BASE_REG will trash this area; see relative to registers other than BASE_REG will trash this area; see
pv_area_store_would_trash. pv_area::store_would_trash.
To check whether a pointer refers to this area, only the low To check whether a pointer refers to this area, only the low
ADDR_BIT bits will be compared. */ ADDR_BIT bits will be compared. */
struct pv_area *make_pv_area (int base_reg, int addr_bit); pv_area (int base_reg, int addr_bit);
/* Free AREA. */ ~pv_area ();
void free_pv_area (struct pv_area *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. */ /* For every part of AREA whose value we know, apply FUNC to CLOSURE,
struct cleanup *make_cleanup_free_pv_area (struct pv_area *area); 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 /* Delete all entries from AREA. */
creating AREA, then we can't tell which values here the stored void clear_entries ();
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);
/* Return the SIZE-byte value at ADDR in AREA. This may return /* Return a pointer to the first entry we hit in AREA starting at
pv_unknown (). */ OFFSET and going forward.
pv_t pv_area_fetch (struct pv_area *area, pv_t addr, CORE_ADDR size);
/* Return true if storing to address ADDR in AREA would force us to This may return zero, if AREA has no entries.
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 And since the entries are a ring, this may return an entry that
prologue analysis, and return the information you've gathered, entirely precedes OFFSET. This is the correct behavior: depending
instead of losing all that information, most of which is probably on the sizes involved, we could still overlap such an area, with
okay. */ wrap-around. */
int pv_area_store_would_trash (struct pv_area *area, pv_t addr); 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 /* This area's base register. */
it, return zero; if we can find it, return a non-zero value, and if int m_base_reg;
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 /* The mask to apply to addresses, to make the wrap-around happen at
items stored in AREA. If you plan to gather a lot of information the right place. */
about registers saved in AREA, consider calling pv_area_scan CORE_ADDR m_addr_mask;
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);
/* An element of the doubly-linked ring of entries, or zero if we
have none. */
struct area_entry *m_entry;
};
#endif /* PROLOGUE_VALUE_H */ #endif /* PROLOGUE_VALUE_H */

View file

@ -883,7 +883,7 @@ rl78_get_opcode_byte (void *handle)
} }
/* Function for finding saved registers in a 'struct pv_area'; this /* 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 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 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; CORE_ADDR pc, next_pc;
int rn; int rn;
pv_t reg[RL78_NUM_TOTAL_REGS]; pv_t reg[RL78_NUM_TOTAL_REGS];
struct pv_area *stack;
struct cleanup *back_to;
CORE_ADDR after_last_frame_setup_insn = start_pc; CORE_ADDR after_last_frame_setup_insn = start_pc;
int bank = 0; int bank = 0;
@ -925,12 +923,11 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
result->reg_offset[rn] = 1; result->reg_offset[rn] = 1;
} }
stack = make_pv_area (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ())); pv_area stack (RL78_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
back_to = make_cleanup_free_pv_area (stack);
/* The call instruction has saved the return address on the stack. */ /* The call instruction has saved the return address on the stack. */
reg[RL78_SP_REGNUM] = pv_add_constant (reg[RL78_SP_REGNUM], -4); 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; pc = start_pc;
while (pc < limit_pc) while (pc < limit_pc)
@ -954,12 +951,12 @@ rl78_analyze_prologue (CORE_ADDR start_pc,
&& opc.op[1].type == RL78_Operand_Register) && opc.op[1].type == RL78_Operand_Register)
{ {
int rsrc = (bank * RL78_REGS_PER_BANK) 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); 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); 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; after_last_frame_setup_insn = next_pc;
} }
else if (opc.id == RLO_sub 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; result->frame_size = reg[RL78_SP_REGNUM].k;
/* Record where all the registers were saved. */ /* 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; result->prologue_end = after_last_frame_setup_insn;
do_cleanups (back_to);
} }
/* Implement the "addr_bits_remove" gdbarch method. */ /* Implement the "addr_bits_remove" gdbarch method. */

View file

@ -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 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 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 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; CORE_ADDR pc, next_pc;
int rn; int rn;
pv_t reg[RX_NUM_REGS]; pv_t reg[RX_NUM_REGS];
struct pv_area *stack;
struct cleanup *back_to;
CORE_ADDR after_last_frame_setup_insn = start_pc; CORE_ADDR after_last_frame_setup_insn = start_pc;
memset (result, 0, sizeof (*result)); 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; result->reg_offset[rn] = 1;
} }
stack = make_pv_area (RX_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ())); pv_area stack (RX_SP_REGNUM, gdbarch_addr_bit (target_gdbarch ()));
back_to = make_cleanup_free_pv_area (stack);
if (frame_type == RX_FRAME_TYPE_FAST_INTERRUPT) 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) if (frame_type == RX_FRAME_TYPE_EXCEPTION)
{ {
reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4); 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 /* The call instruction (or an exception/interrupt) has saved the return
address on the stack. */ address on the stack. */
reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4); 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--) for (r = r2; r >= r1; r--)
{ {
reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4); 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; 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; rsrc = opc.op[1].reg;
reg[RX_SP_REGNUM] = pv_add_constant (reg[RX_SP_REGNUM], -4); 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; after_last_frame_setup_insn = next_pc;
} }
else if (opc.id == RXO_add /* add #const, rsrc, rdst */ 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. */ /* 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; result->prologue_end = after_last_frame_setup_insn;
do_cleanups (back_to);
} }

View file

@ -1375,8 +1375,8 @@ s390_store (struct s390_prologue_data *data,
/* Check whether we are storing a register into the stack. */ /* Check whether we are storing a register into the stack. */
if (!pv_area_store_would_trash (data->stack, addr)) if (!data->stack->store_would_trash (addr))
pv_area_store (data->stack, addr, size, value); data->stack->store (addr, size, value);
/* Note: If this is some store we cannot identify, you might think we /* 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. */ /* 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 /* 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 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 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. */ /* The address of the next instruction after that. */
CORE_ADDR next_pc; 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. */ /* Set up everything's initial value. */
{ {
int i; 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 /* 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 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). */ (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. */ /* Record where all the registers were saved. */
pv_area_scan (data->stack, s390_check_for_saved, data); data->stack->scan (s390_check_for_saved, data);
free_pv_area (data->stack);
data->stack = NULL;
return result; return result;
} }