gdbarch software_single_step returns VEC (CORE_ADDR) *

This patch changes gdbarch method software_single_step to return a
vector of addresses on which GDB should insert breakpoints, and don't
insert breakpoints.  Instead, the caller of
gdbarch_software_single_step inserts breakpoints if the returned
vector is not NULL.

gdb:

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

	* aarch64-tdep.c (aarch64_software_single_step): Return
	VEC (CORE_ADDR) *.  Return NULL instead of 0.  Don't call
	insert_single_step_breakpoint.
	* alpha-tdep.c (alpha_deal_with_atomic_sequence): Likewise.
	(alpha_software_single_step): Likewise.
	* alpha-tdep.h (alpha_software_single_step): Update declaration.
	* arm-linux-tdep.c (arm_linux_software_single_step): Return
	VEC (CORE_ADDR) *.  Return NULL instead of 0.
	* arm-tdep.c (arm_software_single_step): Return NULL instead of	0.
	* arm-tdep.h (arm_software_single_step): Update declaration.
	* breakpoint.c (insert_single_step_breakpoints): New function.
	* breakpoint.h (insert_single_step_breakpoints): Declare.
	* cris-tdep.c (cris_software_single_step): Return
	VEC (CORE_ADDR) *.  Don't call insert_single_step_breakpoint.
	* gdbarch.sh (software_single_step): Change it to return
	VEC (CORE_ADDR) *.
	* gdbarch.c, gdbarch.h: Regenerated.
	* infrun.c (maybe_software_singlestep): Adjust.
	* mips-tdep.c (mips_deal_with_atomic_sequence): Return
	VEC (CORE_ADDR) *.  Don't call insert_single_step_breakpoint.
	(micromips_deal_with_atomic_sequence): Likewise.
	(deal_with_atomic_sequence): Likewise.
	(mips_software_single_step): Likewise.
	* mips-tdep.h (mips_software_single_step): Update declaration.
	* moxie-tdep.c (moxie_software_single_step): Likewise.
	* nios2-tdep.c (nios2_software_single_step): Likewise.
	* ppc-tdep.h (ppc_deal_with_atomic_sequence): Update
	declaration.
	* record-full.c (record_full_resume): Adjust.
	(record_full_wait_1): Likewise.
	* rs6000-aix-tdep.c (rs6000_software_single_step): Return
	VEC (CORE_ADDR) *.  Don't call insert_single_step_breakpoint.
	* rs6000-tdep.c	(ppc_deal_with_atomic_sequence): Return
	VEC (CORE_ADDR) *.  Don't call insert_single_step_breakpoint.
	* s390-linux-tdep.c (s390_software_single_step): Likewise.
	* sparc-tdep.c (sparc_software_single_step): Likewise.
	* spu-tdep.c (spu_software_single_step): Likewise.
	* tic6x-tdep.c (tic6x_software_single_step): Likewise.
This commit is contained in:
Yao Qi 2016-11-08 14:28:32 +00:00
parent 0bc5d801ec
commit 93f9a11fbd
26 changed files with 225 additions and 173 deletions

View file

@ -3877,9 +3877,8 @@ mips_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR addr)
#define SC_OPCODE 0x38
#define SCD_OPCODE 0x3c
static int
mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
struct address_space *aspace, CORE_ADDR pc)
static VEC (CORE_ADDR) *
mips_deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
CORE_ADDR breaks[2] = {-1, -1};
CORE_ADDR loc = pc;
@ -3889,11 +3888,12 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
int index;
int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
const int atomic_sequence_length = 16; /* Instruction sequence length. */
VEC (CORE_ADDR) *next_pcs = NULL;
insn = mips_fetch_instruction (gdbarch, ISA_MIPS, loc, NULL);
/* Assume all atomic sequences start with a ll/lld instruction. */
if (itype_op (insn) != LL_OPCODE && itype_op (insn) != LLD_OPCODE)
return 0;
return NULL;
/* Assume that no atomic sequence is longer than "atomic_sequence_length"
instructions. */
@ -3957,7 +3957,7 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
/* Assume that the atomic sequence ends with a sc/scd instruction. */
if (itype_op (insn) != SC_OPCODE && itype_op (insn) != SCD_OPCODE)
return 0;
return NULL;
loc += MIPS_INSN32_SIZE;
@ -3971,14 +3971,13 @@ mips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
VEC_safe_push (CORE_ADDR, next_pcs, breaks[index]);
return 1;
return next_pcs;
}
static int
static VEC (CORE_ADDR) *
micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
struct address_space *aspace,
CORE_ADDR pc)
{
const int atomic_sequence_length = 16; /* Instruction sequence length. */
@ -3991,16 +3990,17 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
ULONGEST insn;
int insn_count;
int index;
VEC (CORE_ADDR) *next_pcs = NULL;
/* Assume all atomic sequences start with a ll/lld instruction. */
insn = mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
if (micromips_op (insn) != 0x18) /* POOL32C: bits 011000 */
return 0;
return NULL;
loc += MIPS_INSN16_SIZE;
insn <<= 16;
insn |= mips_fetch_instruction (gdbarch, ISA_MICROMIPS, loc, NULL);
if ((b12s4_op (insn) & 0xb) != 0x3) /* LL, LLD: bits 011000 0x11 */
return 0;
return NULL;
loc += MIPS_INSN16_SIZE;
/* Assume all atomic sequences end with an sc/scd instruction. Assume
@ -4097,24 +4097,24 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
&& b5s5_op (insn) != 0x18)
/* JRADDIUSP: bits 010001 11000 */
break;
return 0; /* Fall back to the standard single-step code. */
return NULL; /* Fall back to the standard single-step code. */
case 0x33: /* B16: bits 110011 */
return 0; /* Fall back to the standard single-step code. */
return NULL; /* Fall back to the standard single-step code. */
}
break;
}
if (is_branch)
{
if (last_breakpoint >= 1)
return 0; /* More than one branch found, fallback to the
return NULL; /* More than one branch found, fallback to the
standard single-step code. */
breaks[1] = branch_bp;
last_breakpoint++;
}
}
if (!sc_found)
return 0;
return NULL;
/* Insert a breakpoint right after the end of the atomic sequence. */
breaks[0] = loc;
@ -4126,21 +4126,20 @@ micromips_deal_with_atomic_sequence (struct gdbarch *gdbarch,
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++)
insert_single_step_breakpoint (gdbarch, aspace, breaks[index]);
VEC_safe_push (CORE_ADDR, next_pcs, breaks[index]);
return 1;
return next_pcs;
}
static int
deal_with_atomic_sequence (struct gdbarch *gdbarch,
struct address_space *aspace, CORE_ADDR pc)
static VEC (CORE_ADDR) *
deal_with_atomic_sequence (struct gdbarch *gdbarch, CORE_ADDR pc)
{
if (mips_pc_is_mips (pc))
return mips_deal_with_atomic_sequence (gdbarch, aspace, pc);
return mips_deal_with_atomic_sequence (gdbarch, pc);
else if (mips_pc_is_micromips (gdbarch, pc))
return micromips_deal_with_atomic_sequence (gdbarch, aspace, pc);
return micromips_deal_with_atomic_sequence (gdbarch, pc);
else
return 0;
return NULL;
}
/* mips_software_single_step() is called just before we want to resume
@ -4148,21 +4147,22 @@ deal_with_atomic_sequence (struct gdbarch *gdbarch,
or kernel single-step support (MIPS on GNU/Linux for example). We find
the target of the coming instruction and breakpoint it. */
int
VEC (CORE_ADDR) *
mips_software_single_step (struct frame_info *frame)
{
struct gdbarch *gdbarch = get_frame_arch (frame);
struct address_space *aspace = get_frame_address_space (frame);
CORE_ADDR pc, next_pc;
VEC (CORE_ADDR) *next_pcs;
pc = get_frame_pc (frame);
if (deal_with_atomic_sequence (gdbarch, aspace, pc))
return 1;
next_pcs = deal_with_atomic_sequence (gdbarch, pc);
if (next_pcs != NULL)
return next_pcs;
next_pc = mips_next_pc (frame, pc);
insert_single_step_breakpoint (gdbarch, aspace, next_pc);
return 1;
VEC_safe_push (CORE_ADDR, next_pcs, next_pc);
return next_pcs;
}
/* Test whether the PC points to the return instruction at the