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

@ -1,3 +1,44 @@
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.
2016-11-08 Yao Qi <yao.qi@linaro.org> 2016-11-08 Yao Qi <yao.qi@linaro.org>
* arm-linux-tdep.c (arm_linux_software_single_step): Write * arm-linux-tdep.c (arm_linux_software_single_step): Write

View file

@ -2224,11 +2224,10 @@ value_of_aarch64_user_reg (struct frame_info *frame, const void *baton)
/* Implement the "software_single_step" gdbarch method, needed to /* Implement the "software_single_step" gdbarch method, needed to
single step through atomic sequences on AArch64. */ single step through atomic sequences on AArch64. */
static int static VEC (CORE_ADDR) *
aarch64_software_single_step (struct frame_info *frame) aarch64_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
struct address_space *aspace = get_frame_address_space (frame);
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);
const int insn_size = 4; const int insn_size = 4;
const int atomic_sequence_length = 16; /* Instruction sequence length. */ const int atomic_sequence_length = 16; /* Instruction sequence length. */
@ -2243,13 +2242,14 @@ aarch64_software_single_step (struct frame_info *frame)
int bc_insn_count = 0; /* Conditional branch instruction count. */ int bc_insn_count = 0; /* Conditional branch instruction count. */
int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
aarch64_inst inst; aarch64_inst inst;
VEC (CORE_ADDR) *next_pcs = NULL;
if (aarch64_decode_insn (insn, &inst, 1) != 0) if (aarch64_decode_insn (insn, &inst, 1) != 0)
return 0; return NULL;
/* Look for a Load Exclusive instruction which begins the sequence. */ /* Look for a Load Exclusive instruction which begins the sequence. */
if (inst.opcode->iclass != ldstexcl || bit (insn, 22) == 0) if (inst.opcode->iclass != ldstexcl || bit (insn, 22) == 0)
return 0; return NULL;
for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count) for (insn_count = 0; insn_count < atomic_sequence_length; ++insn_count)
{ {
@ -2258,14 +2258,14 @@ aarch64_software_single_step (struct frame_info *frame)
byte_order_for_code); byte_order_for_code);
if (aarch64_decode_insn (insn, &inst, 1) != 0) if (aarch64_decode_insn (insn, &inst, 1) != 0)
return 0; return NULL;
/* Check if the instruction is a conditional branch. */ /* Check if the instruction is a conditional branch. */
if (inst.opcode->iclass == condbranch) if (inst.opcode->iclass == condbranch)
{ {
gdb_assert (inst.operands[0].type == AARCH64_OPND_ADDR_PCREL19); gdb_assert (inst.operands[0].type == AARCH64_OPND_ADDR_PCREL19);
if (bc_insn_count >= 1) if (bc_insn_count >= 1)
return 0; return NULL;
/* It is, so we'll try to set a breakpoint at the destination. */ /* It is, so we'll try to set a breakpoint at the destination. */
breaks[1] = loc + inst.operands[0].imm.value; breaks[1] = loc + inst.operands[0].imm.value;
@ -2284,7 +2284,7 @@ aarch64_software_single_step (struct frame_info *frame)
/* We didn't find a closing Store Exclusive instruction, fall back. */ /* We didn't find a closing Store Exclusive instruction, fall back. */
if (!closing_insn) if (!closing_insn)
return 0; return NULL;
/* Insert breakpoint after the end of the atomic sequence. */ /* Insert breakpoint after the end of the atomic sequence. */
breaks[0] = loc + insn_size; breaks[0] = loc + insn_size;
@ -2299,9 +2299,9 @@ aarch64_software_single_step (struct frame_info *frame)
/* Insert the breakpoint at the end of the sequence, and one at the /* Insert the breakpoint at the end of the sequence, and one at the
destination of the conditional branch, if it exists. */ destination of the conditional branch, if it exists. */
for (index = 0; index <= last_breakpoint; index++) 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;
} }
struct displaced_step_closure struct displaced_step_closure

View file

@ -765,11 +765,10 @@ static const int stq_c_opcode = 0x2f;
is found, attempt to step through it. A breakpoint is placed at the end of is found, attempt to step through it. A breakpoint is placed at the end of
the sequence. */ the sequence. */
static int static VEC (CORE_ADDR) *
alpha_deal_with_atomic_sequence (struct frame_info *frame) alpha_deal_with_atomic_sequence (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
struct address_space *aspace = get_frame_address_space (frame);
CORE_ADDR pc = get_frame_pc (frame); CORE_ADDR pc = get_frame_pc (frame);
CORE_ADDR breaks[2] = {-1, -1}; CORE_ADDR breaks[2] = {-1, -1};
CORE_ADDR loc = pc; CORE_ADDR loc = pc;
@ -780,11 +779,12 @@ alpha_deal_with_atomic_sequence (struct frame_info *frame)
int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
const int atomic_sequence_length = 16; /* Instruction sequence length. */ const int atomic_sequence_length = 16; /* Instruction sequence length. */
int bc_insn_count = 0; /* Conditional branch instruction count. */ int bc_insn_count = 0; /* Conditional branch instruction count. */
VEC (CORE_ADDR) *next_pcs = NULL;
/* Assume all atomic sequences start with a LDL_L/LDQ_L instruction. */ /* Assume all atomic sequences start with a LDL_L/LDQ_L instruction. */
if (INSN_OPCODE (insn) != ldl_l_opcode if (INSN_OPCODE (insn) != ldl_l_opcode
&& INSN_OPCODE (insn) != ldq_l_opcode) && INSN_OPCODE (insn) != ldq_l_opcode)
return 0; return NULL;
/* Assume that no atomic sequence is longer than "atomic_sequence_length" /* Assume that no atomic sequence is longer than "atomic_sequence_length"
instructions. */ instructions. */
@ -803,8 +803,8 @@ alpha_deal_with_atomic_sequence (struct frame_info *frame)
immediate = (immediate ^ 0x400000) - 0x400000; immediate = (immediate ^ 0x400000) - 0x400000;
if (bc_insn_count >= 1) if (bc_insn_count >= 1)
return 0; /* More than one branch found, fallback return NULL; /* More than one branch found, fallback
to the standard single-step code. */ to the standard single-step code. */
breaks[1] = loc + ALPHA_INSN_SIZE + immediate; breaks[1] = loc + ALPHA_INSN_SIZE + immediate;
@ -820,7 +820,7 @@ alpha_deal_with_atomic_sequence (struct frame_info *frame)
/* Assume that the atomic sequence ends with a STL_C/STQ_C instruction. */ /* Assume that the atomic sequence ends with a STL_C/STQ_C instruction. */
if (INSN_OPCODE (insn) != stl_c_opcode if (INSN_OPCODE (insn) != stl_c_opcode
&& INSN_OPCODE (insn) != stq_c_opcode) && INSN_OPCODE (insn) != stq_c_opcode)
return 0; return NULL;
closing_insn = loc; closing_insn = loc;
loc += ALPHA_INSN_SIZE; loc += ALPHA_INSN_SIZE;
@ -835,11 +835,10 @@ alpha_deal_with_atomic_sequence (struct frame_info *frame)
|| (breaks[1] >= pc && breaks[1] <= closing_insn))) || (breaks[1] >= pc && breaks[1] <= closing_insn)))
last_breakpoint = 0; last_breakpoint = 0;
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++) 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;
} }
@ -1718,18 +1717,17 @@ alpha_next_pc (struct frame_info *frame, CORE_ADDR pc)
return (pc + ALPHA_INSN_SIZE); return (pc + ALPHA_INSN_SIZE);
} }
int VEC (CORE_ADDR) *
alpha_software_single_step (struct frame_info *frame) alpha_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
struct address_space *aspace = get_frame_address_space (frame); CORE_ADDR pc;
CORE_ADDR pc, next_pc; VEC (CORE_ADDR) *next_pcs = NULL;
pc = get_frame_pc (frame); pc = get_frame_pc (frame);
next_pc = alpha_next_pc (frame, pc);
insert_single_step_breakpoint (gdbarch, aspace, next_pc); VEC_safe_push (CORE_ADDR, next_pcs, alpha_next_pc (frame, pc));
return 1; return next_pcs;
} }

View file

@ -103,7 +103,7 @@ struct gdbarch_tdep
}; };
extern unsigned int alpha_read_insn (struct gdbarch *gdbarch, CORE_ADDR pc); extern unsigned int alpha_read_insn (struct gdbarch *gdbarch, CORE_ADDR pc);
extern int alpha_software_single_step (struct frame_info *frame); extern VEC (CORE_ADDR) *alpha_software_single_step (struct frame_info *frame);
extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc); extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc);
extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *);

View file

@ -921,12 +921,11 @@ arm_linux_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self)
/* Insert a single step breakpoint at the next executed instruction. */ /* Insert a single step breakpoint at the next executed instruction. */
static int static VEC (CORE_ADDR) *
arm_linux_software_single_step (struct frame_info *frame) arm_linux_software_single_step (struct frame_info *frame)
{ {
struct regcache *regcache = get_current_regcache (); struct regcache *regcache = get_current_regcache ();
struct gdbarch *gdbarch = get_regcache_arch (regcache); struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct address_space *aspace = get_regcache_aspace (regcache);
struct arm_get_next_pcs next_pcs_ctx; struct arm_get_next_pcs next_pcs_ctx;
CORE_ADDR pc; CORE_ADDR pc;
int i; int i;
@ -936,7 +935,7 @@ arm_linux_software_single_step (struct frame_info *frame)
/* If the target does have hardware single step, GDB doesn't have /* If the target does have hardware single step, GDB doesn't have
to bother software single step. */ to bother software single step. */
if (target_can_do_single_step () == 1) if (target_can_do_single_step () == 1)
return 0; return NULL;
old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs); old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs);
@ -955,12 +954,9 @@ arm_linux_software_single_step (struct frame_info *frame)
VEC_replace (CORE_ADDR, next_pcs, i, pc); VEC_replace (CORE_ADDR, next_pcs, i, pc);
} }
for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++) discard_cleanups (old_chain);
insert_single_step_breakpoint (gdbarch, aspace, pc);
do_cleanups (old_chain); return next_pcs;
return 1;
} }
/* Support for displaced stepping of Linux SVC instructions. */ /* Support for displaced stepping of Linux SVC instructions. */

View file

@ -6286,12 +6286,11 @@ arm_get_next_pcs_is_thumb (struct arm_get_next_pcs *self)
single-step support. We find the target of the coming instructions single-step support. We find the target of the coming instructions
and breakpoint them. */ and breakpoint them. */
int VEC (CORE_ADDR) *
arm_software_single_step (struct frame_info *frame) arm_software_single_step (struct frame_info *frame)
{ {
struct regcache *regcache = get_current_regcache (); struct regcache *regcache = get_current_regcache ();
struct gdbarch *gdbarch = get_regcache_arch (regcache); struct gdbarch *gdbarch = get_regcache_arch (regcache);
struct address_space *aspace = get_regcache_aspace (regcache);
struct arm_get_next_pcs next_pcs_ctx; struct arm_get_next_pcs next_pcs_ctx;
CORE_ADDR pc; CORE_ADDR pc;
int i; int i;
@ -6313,12 +6312,9 @@ arm_software_single_step (struct frame_info *frame)
VEC_replace (CORE_ADDR, next_pcs, i, pc); VEC_replace (CORE_ADDR, next_pcs, i, pc);
} }
for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++) discard_cleanups (old_chain);
insert_single_step_breakpoint (gdbarch, aspace, pc);
do_cleanups (old_chain); return next_pcs;
return 1;
} }
/* Cleanup/copy SVC (SWI) instructions. These two functions are overridden /* Cleanup/copy SVC (SWI) instructions. These two functions are overridden

View file

@ -259,7 +259,7 @@ CORE_ADDR arm_get_next_pcs_addr_bits_remove (struct arm_get_next_pcs *self,
int arm_get_next_pcs_is_thumb (struct arm_get_next_pcs *self); int arm_get_next_pcs_is_thumb (struct arm_get_next_pcs *self);
int arm_software_single_step (struct frame_info *); VEC (CORE_ADDR) *arm_software_single_step (struct frame_info *);
int arm_is_thumb (struct regcache *regcache); int arm_is_thumb (struct regcache *regcache);
int arm_frame_is_thumb (struct frame_info *frame); int arm_frame_is_thumb (struct frame_info *frame);

View file

@ -15232,6 +15232,33 @@ insert_single_step_breakpoint (struct gdbarch *gdbarch,
update_global_location_list (UGLL_INSERT); update_global_location_list (UGLL_INSERT);
} }
/* Insert single step breakpoints according to the current state. */
int
insert_single_step_breakpoints (struct gdbarch *gdbarch)
{
struct frame_info *frame = get_current_frame ();
VEC (CORE_ADDR) * next_pcs;
next_pcs = gdbarch_software_single_step (gdbarch, frame);
if (next_pcs != NULL)
{
int i;
CORE_ADDR pc;
struct address_space *aspace = get_frame_address_space (frame);
for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++)
insert_single_step_breakpoint (gdbarch, aspace, pc);
VEC_free (CORE_ADDR, next_pcs);
return 1;
}
else
return 0;
}
/* See breakpoint.h. */ /* See breakpoint.h. */
int int

View file

@ -1530,6 +1530,12 @@ extern void delete_command (char *arg, int from_tty);
extern void insert_single_step_breakpoint (struct gdbarch *, extern void insert_single_step_breakpoint (struct gdbarch *,
struct address_space *, struct address_space *,
CORE_ADDR); CORE_ADDR);
/* Insert all software single step breakpoints for the current frame.
Return true if any software single step breakpoints are inserted,
otherwise, return false. */
extern int insert_single_step_breakpoints (struct gdbarch *);
/* Check if any hardware watchpoints have triggered, according to the /* Check if any hardware watchpoints have triggered, according to the
target. */ target. */
int watchpoints_triggered (struct target_waitstatus *); int watchpoints_triggered (struct target_waitstatus *);

View file

@ -2060,12 +2060,12 @@ find_step_target (struct frame_info *frame, inst_env_type *inst_env)
digs through the opcodes in order to find all possible targets. digs through the opcodes in order to find all possible targets.
Either one ordinary target or two targets for branches may be found. */ Either one ordinary target or two targets for branches may be found. */
static int static VEC (CORE_ADDR) *
cris_software_single_step (struct frame_info *frame) cris_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
struct address_space *aspace = get_frame_address_space (frame);
inst_env_type inst_env; inst_env_type inst_env;
VEC (CORE_ADDR) *next_pcs = NULL;
/* Analyse the present instruction environment and insert /* Analyse the present instruction environment and insert
breakpoints. */ breakpoints. */
@ -2082,18 +2082,19 @@ cris_software_single_step (struct frame_info *frame)
and possibly another one for a branch, jump, etc. */ and possibly another one for a branch, jump, etc. */
CORE_ADDR next_pc CORE_ADDR next_pc
= (CORE_ADDR) inst_env.reg[gdbarch_pc_regnum (gdbarch)]; = (CORE_ADDR) inst_env.reg[gdbarch_pc_regnum (gdbarch)];
insert_single_step_breakpoint (gdbarch, aspace, next_pc);
VEC_safe_push (CORE_ADDR, next_pcs, next_pc);
if (inst_env.branch_found if (inst_env.branch_found
&& (CORE_ADDR) inst_env.branch_break_address != next_pc) && (CORE_ADDR) inst_env.branch_break_address != next_pc)
{ {
CORE_ADDR branch_target_address CORE_ADDR branch_target_address
= (CORE_ADDR) inst_env.branch_break_address; = (CORE_ADDR) inst_env.branch_break_address;
insert_single_step_breakpoint (gdbarch,
aspace, branch_target_address); VEC_safe_push (CORE_ADDR, next_pcs, branch_target_address);
} }
} }
return 1; return next_pcs;
} }
/* Calculates the prefix value for quick offset addressing mode. */ /* Calculates the prefix value for quick offset addressing mode. */

View file

@ -3165,7 +3165,7 @@ gdbarch_software_single_step_p (struct gdbarch *gdbarch)
return gdbarch->software_single_step != NULL; return gdbarch->software_single_step != NULL;
} }
int VEC (CORE_ADDR) *
gdbarch_software_single_step (struct gdbarch *gdbarch, struct frame_info *frame) gdbarch_software_single_step (struct gdbarch *gdbarch, struct frame_info *frame)
{ {
gdb_assert (gdbarch != NULL); gdb_assert (gdbarch != NULL);

View file

@ -677,18 +677,19 @@ extern void set_gdbarch_addr_bits_remove (struct gdbarch *gdbarch, gdbarch_addr_
FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
target can single step. If not, then implement single step using breakpoints. target can single step. If not, then implement single step using breakpoints.
A return value of 1 means that the software_single_step breakpoints Return a vector of addresses on which the software single step
were inserted; 0 means they were not. Multiple breakpoints may be breakpoints should be inserted. NULL means software single step is
inserted for some instructions such as conditional branch. However, not used.
each implementation must always evaluate the condition and only put Multiple breakpoints may be inserted for some instructions such as
the breakpoint at the branch destination if the condition is true, so conditional branch. However, each implementation must always evaluate
that we ensure forward progress when stepping past a conditional the condition and only put the breakpoint at the branch destination if
branch to self. */ the condition is true, so that we ensure forward progress when stepping
past a conditional branch to self. */
extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch); extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch);
typedef int (gdbarch_software_single_step_ftype) (struct frame_info *frame); typedef VEC (CORE_ADDR) * (gdbarch_software_single_step_ftype) (struct frame_info *frame);
extern int gdbarch_software_single_step (struct gdbarch *gdbarch, struct frame_info *frame); extern VEC (CORE_ADDR) * gdbarch_software_single_step (struct gdbarch *gdbarch, struct frame_info *frame);
extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step); extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step);
/* Return non-zero if the processor is executing a delay slot and a /* Return non-zero if the processor is executing a delay slot and a

View file

@ -626,14 +626,15 @@ m:CORE_ADDR:addr_bits_remove:CORE_ADDR addr:addr::core_addr_identity::0
# FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the # FIXME/cagney/2001-01-18: The logic is backwards. It should be asking if the
# target can single step. If not, then implement single step using breakpoints. # target can single step. If not, then implement single step using breakpoints.
# #
# A return value of 1 means that the software_single_step breakpoints # Return a vector of addresses on which the software single step
# were inserted; 0 means they were not. Multiple breakpoints may be # breakpoints should be inserted. NULL means software single step is
# inserted for some instructions such as conditional branch. However, # not used.
# each implementation must always evaluate the condition and only put # Multiple breakpoints may be inserted for some instructions such as
# the breakpoint at the branch destination if the condition is true, so # conditional branch. However, each implementation must always evaluate
# that we ensure forward progress when stepping past a conditional # the condition and only put the breakpoint at the branch destination if
# branch to self. # the condition is true, so that we ensure forward progress when stepping
F:int:software_single_step:struct frame_info *frame:frame # past a conditional branch to self.
F:VEC (CORE_ADDR) *:software_single_step:struct frame_info *frame:frame
# Return non-zero if the processor is executing a delay slot and a # Return non-zero if the processor is executing a delay slot and a
# further single-step is needed before the instruction finishes. # further single-step is needed before the instruction finishes.

View file

@ -2254,11 +2254,9 @@ maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc)
int hw_step = 1; int hw_step = 1;
if (execution_direction == EXEC_FORWARD if (execution_direction == EXEC_FORWARD
&& gdbarch_software_single_step_p (gdbarch) && gdbarch_software_single_step_p (gdbarch))
&& gdbarch_software_single_step (gdbarch, get_current_frame ())) hw_step = !insert_single_step_breakpoints (gdbarch);
{
hw_step = 0;
}
return hw_step; return hw_step;
} }

View file

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

View file

@ -154,7 +154,7 @@ enum
}; };
/* Single step based on where the current instruction will take us. */ /* Single step based on where the current instruction will take us. */
extern int mips_software_single_step (struct frame_info *frame); extern VEC (CORE_ADDR) *mips_software_single_step (struct frame_info *frame);
/* Strip the ISA (compression) bit off from ADDR. */ /* Strip the ISA (compression) bit off from ADDR. */
extern CORE_ADDR mips_unmake_compact_addr (CORE_ADDR addr); extern CORE_ADDR mips_unmake_compact_addr (CORE_ADDR addr);

View file

@ -299,11 +299,10 @@ moxie_process_readu (CORE_ADDR addr, gdb_byte *buf,
/* Insert a single step breakpoint. */ /* Insert a single step breakpoint. */
static int static VEC (CORE_ADDR) *
moxie_software_single_step (struct frame_info *frame) moxie_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
struct address_space *aspace = get_frame_address_space (frame);
CORE_ADDR addr; CORE_ADDR addr;
gdb_byte buf[4]; gdb_byte buf[4];
uint16_t inst; uint16_t inst;
@ -311,6 +310,7 @@ moxie_software_single_step (struct frame_info *frame)
ULONGEST fp; ULONGEST fp;
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
struct regcache *regcache = get_current_regcache (); struct regcache *regcache = get_current_regcache ();
VEC (CORE_ADDR) *next_pcs = NULL;
addr = get_frame_pc (frame); addr = get_frame_pc (frame);
@ -338,8 +338,9 @@ moxie_software_single_step (struct frame_info *frame)
case 0x09: /* bleu */ case 0x09: /* bleu */
/* Insert breaks on both branches, because we can't currently tell /* Insert breaks on both branches, because we can't currently tell
which way things will go. */ which way things will go. */
insert_single_step_breakpoint (gdbarch, aspace, addr + 2); VEC_safe_push (CORE_ADDR, next_pcs, addr + 2);
insert_single_step_breakpoint (gdbarch, aspace, addr + 2 + INST2OFFSET(inst)); VEC_safe_push (CORE_ADDR, next_pcs,
addr + 2 + INST2OFFSET(inst));
break; break;
default: default:
{ {
@ -351,7 +352,7 @@ moxie_software_single_step (struct frame_info *frame)
else else
{ {
/* This is a Form 2 instruction. They are all 16 bits. */ /* This is a Form 2 instruction. They are all 16 bits. */
insert_single_step_breakpoint (gdbarch, aspace, addr + 2); VEC_safe_push (CORE_ADDR, next_pcs, addr + 2);
} }
} }
else else
@ -398,7 +399,7 @@ moxie_software_single_step (struct frame_info *frame)
case 0x32: /* udiv.l */ case 0x32: /* udiv.l */
case 0x33: /* mod.l */ case 0x33: /* mod.l */
case 0x34: /* umod.l */ case 0x34: /* umod.l */
insert_single_step_breakpoint (gdbarch, aspace, addr + 2); VEC_safe_push (CORE_ADDR, next_pcs, addr + 2);
break; break;
/* 32-bit instructions. */ /* 32-bit instructions. */
@ -408,7 +409,7 @@ moxie_software_single_step (struct frame_info *frame)
case 0x37: /* sto.b */ case 0x37: /* sto.b */
case 0x38: /* ldo.s */ case 0x38: /* ldo.s */
case 0x39: /* sto.s */ case 0x39: /* sto.s */
insert_single_step_breakpoint (gdbarch, aspace, addr + 4); VEC_safe_push (CORE_ADDR, next_pcs, addr + 4);
break; break;
/* 48-bit instructions. */ /* 48-bit instructions. */
@ -421,32 +422,27 @@ moxie_software_single_step (struct frame_info *frame)
case 0x20: /* ldi.s (immediate) */ case 0x20: /* ldi.s (immediate) */
case 0x22: /* lda.s */ case 0x22: /* lda.s */
case 0x24: /* sta.s */ case 0x24: /* sta.s */
insert_single_step_breakpoint (gdbarch, aspace, addr + 6); VEC_safe_push (CORE_ADDR, next_pcs, addr + 6);
break; break;
/* Control flow instructions. */ /* Control flow instructions. */
case 0x03: /* jsra */ case 0x03: /* jsra */
case 0x1a: /* jmpa */ case 0x1a: /* jmpa */
insert_single_step_breakpoint (gdbarch, aspace, VEC_safe_push (CORE_ADDR, next_pcs,
moxie_process_readu (addr + 2, moxie_process_readu (addr + 2, buf, 4, byte_order));
buf, 4,
byte_order));
break; break;
case 0x04: /* ret */ case 0x04: /* ret */
regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp); regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp);
insert_single_step_breakpoint (gdbarch, aspace, VEC_safe_push (CORE_ADDR, next_pcs,
moxie_process_readu (fp + 4, moxie_process_readu (fp + 4, buf, 4, byte_order));
buf, 4,
byte_order));
break; break;
case 0x19: /* jsr */ case 0x19: /* jsr */
case 0x25: /* jmp */ case 0x25: /* jmp */
regcache_raw_read (regcache, regcache_raw_read (regcache,
(inst >> 4) & 0xf, (gdb_byte *) & tmpu32); (inst >> 4) & 0xf, (gdb_byte *) & tmpu32);
insert_single_step_breakpoint (gdbarch, aspace, VEC_safe_push (CORE_ADDR, next_pcs, tmpu32);
tmpu32);
break; break;
case 0x30: /* swi */ case 0x30: /* swi */
@ -456,7 +452,7 @@ moxie_software_single_step (struct frame_info *frame)
} }
} }
return 1; return next_pcs;
} }
/* Implement the "read_pc" gdbarch method. */ /* Implement the "read_pc" gdbarch method. */

View file

@ -2219,16 +2219,16 @@ nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
/* Implement the software_single_step gdbarch method. */ /* Implement the software_single_step gdbarch method. */
static int static VEC (CORE_ADDR) *
nios2_software_single_step (struct frame_info *frame) nios2_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
struct address_space *aspace = get_frame_address_space (frame);
CORE_ADDR next_pc = nios2_get_next_pc (frame, get_frame_pc (frame)); CORE_ADDR next_pc = nios2_get_next_pc (frame, get_frame_pc (frame));
VEC (CORE_ADDR) *next_pcs = NULL;
insert_single_step_breakpoint (gdbarch, aspace, next_pc); VEC_safe_push (CORE_ADDR, next_pcs, next_pc);
return 1; return next_pcs;
} }
/* Implement the get_longjump_target gdbarch method. */ /* Implement the get_longjump_target gdbarch method. */

View file

@ -76,7 +76,7 @@ int ppc_altivec_support_p (struct gdbarch *gdbarch);
/* Return non-zero if the architecture described by GDBARCH has /* Return non-zero if the architecture described by GDBARCH has
VSX registers (vsr0 --- vsr63). */ VSX registers (vsr0 --- vsr63). */
int vsx_support_p (struct gdbarch *gdbarch); int vsx_support_p (struct gdbarch *gdbarch);
int ppc_deal_with_atomic_sequence (struct frame_info *frame); VEC (CORE_ADDR) *ppc_deal_with_atomic_sequence (struct frame_info *frame);
/* Register set description. */ /* Register set description. */

View file

@ -976,17 +976,7 @@ record_full_resume (struct target_ops *ops, ptid_t ptid, int step,
record_full_resume_step = 1; record_full_resume_step = 1;
} }
else else
{ step = !insert_single_step_breakpoints (gdbarch);
/* This is a continue.
Try to insert a soft single step breakpoint. */
if (!gdbarch_software_single_step (gdbarch,
get_current_frame ()))
{
/* This system don't want use soft single step.
Use hard sigle step. */
step = 1;
}
}
} }
} }
@ -1168,9 +1158,9 @@ record_full_wait_1 (struct target_ops *ops,
If insert success, set step to 0. */ If insert success, set step to 0. */
set_executing (inferior_ptid, 0); set_executing (inferior_ptid, 0);
reinit_frame_cache (); reinit_frame_cache ();
if (gdbarch_software_single_step (gdbarch,
get_current_frame ())) step = !insert_single_step_breakpoints (gdbarch);
step = 0;
set_executing (inferior_ptid, 1); set_executing (inferior_ptid, 1);
} }

View file

@ -669,7 +669,7 @@ branch_dest (struct frame_info *frame, int opcode, int instr,
/* AIX does not support PT_STEP. Simulate it. */ /* AIX does not support PT_STEP. Simulate it. */
static int static VEC (CORE_ADDR) *
rs6000_software_single_step (struct frame_info *frame) rs6000_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
@ -679,13 +679,15 @@ rs6000_software_single_step (struct frame_info *frame)
CORE_ADDR loc; CORE_ADDR loc;
CORE_ADDR breaks[2]; CORE_ADDR breaks[2];
int opcode; int opcode;
VEC (CORE_ADDR) *next_pcs;
loc = get_frame_pc (frame); loc = get_frame_pc (frame);
insn = read_memory_integer (loc, 4, byte_order); insn = read_memory_integer (loc, 4, byte_order);
if (ppc_deal_with_atomic_sequence (frame)) next_pcs = ppc_deal_with_atomic_sequence (frame);
return 1; if (next_pcs != NULL)
return next_pcs;
breaks[0] = loc + PPC_INSN_SIZE; breaks[0] = loc + PPC_INSN_SIZE;
opcode = insn >> 26; opcode = insn >> 26;
@ -700,12 +702,12 @@ rs6000_software_single_step (struct frame_info *frame)
/* ignore invalid breakpoint. */ /* ignore invalid breakpoint. */
if (breaks[ii] == -1) if (breaks[ii] == -1)
continue; continue;
insert_single_step_breakpoint (gdbarch, aspace, breaks[ii]); VEC_safe_push (CORE_ADDR, next_pcs, breaks[ii]);
} }
errno = 0; /* FIXME, don't ignore errors! */ errno = 0; /* FIXME, don't ignore errors! */
/* What errors? {read,write}_memory call error(). */ /* What errors? {read,write}_memory call error(). */
return 1; return next_pcs;
} }
/* Implement the "auto_wide_charset" gdbarch method for this platform. */ /* Implement the "auto_wide_charset" gdbarch method for this platform. */

View file

@ -1143,7 +1143,7 @@ ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch,
is found, attempt to step through it. A breakpoint is placed at the end of is found, attempt to step through it. A breakpoint is placed at the end of
the sequence. */ the sequence. */
int VEC (CORE_ADDR) *
ppc_deal_with_atomic_sequence (struct frame_info *frame) ppc_deal_with_atomic_sequence (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
@ -1159,11 +1159,12 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */
const int atomic_sequence_length = 16; /* Instruction sequence length. */ const int atomic_sequence_length = 16; /* Instruction sequence length. */
int bc_insn_count = 0; /* Conditional branch instruction count. */ int bc_insn_count = 0; /* Conditional branch instruction count. */
VEC (CORE_ADDR) *next_pcs = NULL;
/* Assume all atomic sequences start with a lwarx/ldarx instruction. */ /* Assume all atomic sequences start with a lwarx/ldarx instruction. */
if ((insn & LWARX_MASK) != LWARX_INSTRUCTION if ((insn & LWARX_MASK) != LWARX_INSTRUCTION
&& (insn & LWARX_MASK) != LDARX_INSTRUCTION) && (insn & LWARX_MASK) != LDARX_INSTRUCTION)
return 0; return NULL;
/* Assume that no atomic sequence is longer than "atomic_sequence_length" /* Assume that no atomic sequence is longer than "atomic_sequence_length"
instructions. */ instructions. */
@ -1201,7 +1202,7 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
/* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */ /* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */
if ((insn & STWCX_MASK) != STWCX_INSTRUCTION if ((insn & STWCX_MASK) != STWCX_INSTRUCTION
&& (insn & STWCX_MASK) != STDCX_INSTRUCTION) && (insn & STWCX_MASK) != STDCX_INSTRUCTION)
return 0; return NULL;
closing_insn = loc; closing_insn = loc;
loc += PPC_INSN_SIZE; loc += PPC_INSN_SIZE;
@ -1217,11 +1218,10 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame)
|| (breaks[1] >= pc && breaks[1] <= closing_insn))) || (breaks[1] >= pc && breaks[1] <= closing_insn)))
last_breakpoint = 0; last_breakpoint = 0;
/* Effectively inserts the breakpoints. */
for (index = 0; index <= last_breakpoint; index++) 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;
} }

View file

@ -722,7 +722,7 @@ s390_is_partial_instruction (struct gdbarch *gdbarch, CORE_ADDR loc, int *len)
process about 4kiB of it each time, leading to O(n**2) memory and time process about 4kiB of it each time, leading to O(n**2) memory and time
complexity. */ complexity. */
static int static VEC (CORE_ADDR) *
s390_software_single_step (struct frame_info *frame) s390_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
@ -731,33 +731,33 @@ s390_software_single_step (struct frame_info *frame)
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
int len; int len;
uint16_t insn; uint16_t insn;
VEC (CORE_ADDR) *next_pcs = NULL;
/* Special handling only if recording. */ /* Special handling only if recording. */
if (!record_full_is_used ()) if (!record_full_is_used ())
return 0; return NULL;
/* First, match a partial instruction. */ /* First, match a partial instruction. */
if (!s390_is_partial_instruction (gdbarch, loc, &len)) if (!s390_is_partial_instruction (gdbarch, loc, &len))
return 0; return NULL;
loc += len; loc += len;
/* Second, look for a branch back to it. */ /* Second, look for a branch back to it. */
insn = read_memory_integer (loc, 2, byte_order); insn = read_memory_integer (loc, 2, byte_order);
if (insn != 0xa714) /* BRC with mask 1 */ if (insn != 0xa714) /* BRC with mask 1 */
return 0; return NULL;
insn = read_memory_integer (loc + 2, 2, byte_order); insn = read_memory_integer (loc + 2, 2, byte_order);
if (insn != (uint16_t) -(len / 2)) if (insn != (uint16_t) -(len / 2))
return 0; return NULL;
loc += 4; loc += 4;
/* Found it, step past the whole thing. */ /* Found it, step past the whole thing. */
VEC_safe_push (CORE_ADDR, next_pcs, loc);
insert_single_step_breakpoint (gdbarch, aspace, loc); return next_pcs;
return 1;
} }
static int static int

View file

@ -1599,7 +1599,7 @@ sparc_step_trap (struct frame_info *frame, unsigned long insn)
return 0; return 0;
} }
static int static VEC (CORE_ADDR) *
sparc_software_single_step (struct frame_info *frame) sparc_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *arch = get_frame_arch (frame); struct gdbarch *arch = get_frame_arch (frame);
@ -1608,6 +1608,7 @@ sparc_software_single_step (struct frame_info *frame)
CORE_ADDR npc, nnpc; CORE_ADDR npc, nnpc;
CORE_ADDR pc, orig_npc; CORE_ADDR pc, orig_npc;
VEC (CORE_ADDR) *next_pcs = NULL;
pc = get_frame_register_unsigned (frame, tdep->pc_regnum); pc = get_frame_register_unsigned (frame, tdep->pc_regnum);
orig_npc = npc = get_frame_register_unsigned (frame, tdep->npc_regnum); orig_npc = npc = get_frame_register_unsigned (frame, tdep->npc_regnum);
@ -1615,10 +1616,10 @@ sparc_software_single_step (struct frame_info *frame)
/* Analyze the instruction at PC. */ /* Analyze the instruction at PC. */
nnpc = sparc_analyze_control_transfer (frame, pc, &npc); nnpc = sparc_analyze_control_transfer (frame, pc, &npc);
if (npc != 0) if (npc != 0)
insert_single_step_breakpoint (arch, aspace, npc); VEC_safe_push (CORE_ADDR, next_pcs, npc);
if (nnpc != 0) if (nnpc != 0)
insert_single_step_breakpoint (arch, aspace, nnpc); VEC_safe_push (CORE_ADDR, next_pcs, nnpc);
/* Assert that we have set at least one breakpoint, and that /* Assert that we have set at least one breakpoint, and that
they're not set at the same spot - unless we're going they're not set at the same spot - unless we're going
@ -1626,7 +1627,7 @@ sparc_software_single_step (struct frame_info *frame)
gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0); gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0);
gdb_assert (nnpc != npc || orig_npc == 0); gdb_assert (nnpc != npc || orig_npc == 0);
return 1; return next_pcs;
} }
static void static void

View file

@ -1610,17 +1610,17 @@ spu_memory_remove_breakpoint (struct gdbarch *gdbarch,
/* Software single-stepping support. */ /* Software single-stepping support. */
static int static VEC (CORE_ADDR) *
spu_software_single_step (struct frame_info *frame) spu_software_single_step (struct frame_info *frame)
{ {
struct gdbarch *gdbarch = get_frame_arch (frame); struct gdbarch *gdbarch = get_frame_arch (frame);
struct address_space *aspace = get_frame_address_space (frame);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
CORE_ADDR pc, next_pc; CORE_ADDR pc, next_pc;
unsigned int insn; unsigned int insn;
int offset, reg; int offset, reg;
gdb_byte buf[4]; gdb_byte buf[4];
ULONGEST lslr; ULONGEST lslr;
VEC (CORE_ADDR) *next_pcs = NULL;
pc = get_frame_pc (frame); pc = get_frame_pc (frame);
@ -1643,8 +1643,7 @@ spu_software_single_step (struct frame_info *frame)
else else
next_pc = (SPUADDR_ADDR (pc) + 4) & lslr; next_pc = (SPUADDR_ADDR (pc) + 4) & lslr;
insert_single_step_breakpoint (gdbarch, VEC_safe_push (CORE_ADDR, next_pcs, SPUADDR (SPUADDR_SPU (pc), next_pc));
aspace, SPUADDR (SPUADDR_SPU (pc), next_pc));
if (is_branch (insn, &offset, &reg)) if (is_branch (insn, &offset, &reg))
{ {
@ -1674,11 +1673,11 @@ spu_software_single_step (struct frame_info *frame)
target = target & lslr; target = target & lslr;
if (target != next_pc) if (target != next_pc)
insert_single_step_breakpoint (gdbarch, aspace, VEC_safe_push (CORE_ADDR, next_pcs, SPUADDR (SPUADDR_SPU (pc),
SPUADDR (SPUADDR_SPU (pc), target)); target));
} }
return 1; return next_pcs;
} }

View file

@ -699,16 +699,15 @@ tic6x_get_next_pc (struct frame_info *frame, CORE_ADDR pc)
/* This is the implementation of gdbarch method software_single_step. */ /* This is the implementation of gdbarch method software_single_step. */
static int static VEC (CORE_ADDR) *
tic6x_software_single_step (struct frame_info *frame) tic6x_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 next_pc = tic6x_get_next_pc (frame, get_frame_pc (frame)); CORE_ADDR next_pc = tic6x_get_next_pc (frame, get_frame_pc (frame));
VEC (CORE_ADDR) *next_pcs = NULL;
insert_single_step_breakpoint (gdbarch, aspace, next_pc); VEC_safe_push (CORE_ADDR, next_pcs, next_pc);
return 1; return next_pcs;
} }
/* This is the implementation of gdbarch method frame_align. */ /* This is the implementation of gdbarch method frame_align. */