From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22333 invoked by alias); 14 Apr 2007 18:13:00 -0000 Received: (qmail 22320 invoked by uid 22791); 14 Apr 2007 18:12:57 -0000 X-Spam-Check-By: sourceware.org Received: from mtagate8.de.ibm.com (HELO mtagate8.de.ibm.com) (195.212.29.157) by sourceware.org (qpsmtpd/0.31) with ESMTP; Sat, 14 Apr 2007 19:12:52 +0100 Received: from d12nrmr1607.megacenter.de.ibm.com (d12nrmr1607.megacenter.de.ibm.com [9.149.167.49]) by mtagate8.de.ibm.com (8.13.8/8.13.8) with ESMTP id l3EICn7V043394 for ; Sat, 14 Apr 2007 18:12:49 GMT Received: from d12av02.megacenter.de.ibm.com (d12av02.megacenter.de.ibm.com [9.149.165.228]) by d12nrmr1607.megacenter.de.ibm.com (8.13.8/8.13.8/NCO v8.3) with ESMTP id l3EICn9x4165838 for ; Sat, 14 Apr 2007 20:12:49 +0200 Received: from d12av02.megacenter.de.ibm.com (loopback [127.0.0.1]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.13.3) with ESMTP id l3EICmR7016356 for ; Sat, 14 Apr 2007 20:12:49 +0200 Received: from tuxmaker.boeblingen.de.ibm.com (tuxmaker.boeblingen.de.ibm.com [9.152.85.9]) by d12av02.megacenter.de.ibm.com (8.12.11.20060308/8.12.11) with SMTP id l3EICmef016353; Sat, 14 Apr 2007 20:12:48 +0200 Message-Id: <200704141812.l3EICmef016353@d12av02.megacenter.de.ibm.com> Received: by tuxmaker.boeblingen.de.ibm.com (sSMTP sendmail emulation); Sat, 14 Apr 2007 20:12:48 +0200 Subject: [commit] Update software_single_step arguments To: drow@false.org (Daniel Jacobowitz) Date: Sat, 14 Apr 2007 18:50:00 -0000 From: "Ulrich Weigand" Cc: gdb-patches@sourceware.org In-Reply-To: <20070412204824.GA8168@caradoc.them.org> from "Daniel Jacobowitz" at Apr 12, 2007 04:48:24 PM X-Mailer: ELM [version 2.5 PL2] MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2007-04/txt/msg00219.txt.bz2 Daniel Jacobowitz wrote: > On Thu, Apr 12, 2007 at 10:09:10PM +0200, Ulrich Weigand wrote: > > I thought "resume" (where this is called) too low-level for > > a frame to make sense. You cannot single-step anywhere but > > in the innermost frame, so a regcache seemed more appropriate. > > (How would I actually get hold of a frame in resume?) > > I guess you'd just use the current one, but a regcache is fine too. The following patch implements this change. It should be strictly mechanical and have no impact on the behaviour of any target. Tested on spu-elf, and by running gdb_mbuild.sh. Committed to mainline. Bye, Ulrich ChangeLog: * gdbarch.sh (software_single_step): Remove "insert_breakpoints_p" and "sig" arguments, add "regcache" argument. * gdbarch.c, gdbarch.h: Regenerate. * infrun.c (resume): Update SOFTWARE_SINGLE_STEP call arguments. (handle_inferior_event): Call remove_single_step_breakpoints directly instead of calling SOFTWARE_SINGLE_STEP to remove breakpoints. * alpha-tdep.c (alpha_software_single_step): Update argument list. Remove handling of !insert_breakpoints_p case. * arm-tdep.c (arm_software_single_step): Likewise. * cris-tdep.c (cris_software_single_step): Likewise. * mips-tdep.c (mips_software_single_step): Likewise. * rs6000-tdep.c (rs6000_software_single_step): Likewise. * sparc-tdep.c (sparc_software_single_step): Likewise. * spu-tdep.c (spu_software_single_step): Likewise. * alpha-tdep.h (alpha_software_single_step): Update prototype. * mips-tdep.h (mips_software_single_step): Likewise. * rs6000-tdep.h (rs6000_software_single_step): Likewise. * sparc-tdep.h (sparc_software_single_step): Likewise. diff -urNp gdb-orig/gdb/alpha-tdep.c gdb-head/gdb/alpha-tdep.c --- gdb-orig/gdb/alpha-tdep.c 2007-04-12 22:31:33.120201000 +0200 +++ gdb-head/gdb/alpha-tdep.c 2007-04-13 00:09:42.503230088 +0200 @@ -1391,10 +1391,7 @@ fp_register_sign_bit (LONGEST reg) /* alpha_software_single_step() is called just before we want to resume the inferior, if we want to single-step it but there is no hardware or kernel single-step support (NetBSD on Alpha, for example). We find - the target of the coming instruction and breakpoint it. - - single_step is also called just after the inferior stops. If we had - set up a simulated single-step, we undo our damage. */ + the target of the coming instruction and breakpoint it. */ static CORE_ADDR alpha_next_pc (CORE_ADDR pc) @@ -1519,22 +1516,14 @@ alpha_next_pc (CORE_ADDR pc) } int -alpha_software_single_step (enum target_signal sig, int insert_breakpoints_p) +alpha_software_single_step (struct regcache *regcache) { - CORE_ADDR next_pc; - CORE_ADDR pc; + CORE_ADDR pc, next_pc; - if (insert_breakpoints_p) - { - pc = read_pc (); - next_pc = alpha_next_pc (pc); + pc = read_pc (); + next_pc = alpha_next_pc (pc); - insert_single_step_breakpoint (next_pc); - } - else - { - remove_single_step_breakpoints (); - } + insert_single_step_breakpoint (next_pc); return 1; } diff -urNp gdb-orig/gdb/alpha-tdep.h gdb-head/gdb/alpha-tdep.h --- gdb-orig/gdb/alpha-tdep.h 2007-04-12 16:26:43.507223000 +0200 +++ gdb-head/gdb/alpha-tdep.h 2007-04-13 00:14:17.918173176 +0200 @@ -107,7 +107,7 @@ struct gdbarch_tdep }; extern unsigned int alpha_read_insn (CORE_ADDR pc); -extern int alpha_software_single_step (enum target_signal, int); +extern int alpha_software_single_step (struct regcache *regcache); extern CORE_ADDR alpha_after_prologue (CORE_ADDR pc); extern void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); diff -urNp gdb-orig/gdb/arm-tdep.c gdb-head/gdb/arm-tdep.c --- gdb-orig/gdb/arm-tdep.c 2007-04-12 16:26:43.532219000 +0200 +++ gdb-head/gdb/arm-tdep.c 2007-04-13 00:05:27.326141168 +0200 @@ -1902,26 +1902,17 @@ arm_get_next_pc (CORE_ADDR pc) /* single_step() is called just before we want to resume the inferior, if we want to single-step it but there is no hardware or kernel single-step support. We find the target of the coming instruction - and breakpoint it. - - single_step() is also called just after the inferior stops. If we - had set up a simulated single-step, we undo our damage. */ + and breakpoint it. */ static int -arm_software_single_step (enum target_signal sig, int insert_bpt) +arm_software_single_step (struct regcache *regcache) { /* NOTE: This may insert the wrong breakpoint instruction when single-stepping over a mode-changing instruction, if the CPSR heuristics are used. */ - if (insert_bpt) - { - CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM)); - - insert_single_step_breakpoint (next_pc); - } - else - remove_single_step_breakpoints (); + CORE_ADDR next_pc = arm_get_next_pc (read_register (ARM_PC_REGNUM)); + insert_single_step_breakpoint (next_pc); return 1; } diff -urNp gdb-orig/gdb/cris-tdep.c gdb-head/gdb/cris-tdep.c --- gdb-orig/gdb/cris-tdep.c 2007-04-12 16:26:43.568213000 +0200 +++ gdb-head/gdb/cris-tdep.c 2007-04-13 00:08:37.860203488 +0200 @@ -2120,38 +2120,33 @@ find_step_target (inst_env_type *inst_en Either one ordinary target or two targets for branches may be found. */ static int -cris_software_single_step (enum target_signal ignore, int insert_breakpoints) +cris_software_single_step (struct regcache *regcache) { inst_env_type inst_env; - if (insert_breakpoints) - { - /* Analyse the present instruction environment and insert - breakpoints. */ - int status = find_step_target (&inst_env); - if (status == -1) - { - /* Could not find a target. Things are likely to go downhill - from here. */ - warning (_("CRIS software single step could not find a step target.")); - } - else - { - /* Insert at most two breakpoints. One for the next PC content - and possibly another one for a branch, jump, etc. */ - CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM]; - insert_single_step_breakpoint (next_pc); - if (inst_env.branch_found - && (CORE_ADDR) inst_env.branch_break_address != next_pc) - { - CORE_ADDR branch_target_address - = (CORE_ADDR) inst_env.branch_break_address; - insert_single_step_breakpoint (branch_target_address); - } - } + /* Analyse the present instruction environment and insert + breakpoints. */ + int status = find_step_target (&inst_env); + if (status == -1) + { + /* Could not find a target. Things are likely to go downhill + from here. */ + warning (_("CRIS software single step could not find a step target.")); } else - remove_single_step_breakpoints (); + { + /* Insert at most two breakpoints. One for the next PC content + and possibly another one for a branch, jump, etc. */ + CORE_ADDR next_pc = (CORE_ADDR) inst_env.reg[PC_REGNUM]; + insert_single_step_breakpoint (next_pc); + if (inst_env.branch_found + && (CORE_ADDR) inst_env.branch_break_address != next_pc) + { + CORE_ADDR branch_target_address + = (CORE_ADDR) inst_env.branch_break_address; + insert_single_step_breakpoint (branch_target_address); + } + } return 1; } diff -urNp gdb-orig/gdb/gdbarch.c gdb-head/gdb/gdbarch.c --- gdb-orig/gdb/gdbarch.c 2007-04-12 16:26:43.581211000 +0200 +++ gdb-head/gdb/gdbarch.c 2007-04-13 00:02:56.327194976 +0200 @@ -1522,8 +1522,8 @@ gdbarch_dump (struct gdbarch *current_gd #ifdef SOFTWARE_SINGLE_STEP fprintf_unfiltered (file, "gdbarch_dump: %s # %s\n", - "SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p)", - XSTRING (SOFTWARE_SINGLE_STEP (sig, insert_breakpoints_p))); + "SOFTWARE_SINGLE_STEP(regcache)", + XSTRING (SOFTWARE_SINGLE_STEP (regcache))); #endif fprintf_unfiltered (file, "gdbarch_dump: software_single_step = <0x%lx>\n", @@ -3290,13 +3290,13 @@ gdbarch_software_single_step_p (struct g } int -gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p) +gdbarch_software_single_step (struct gdbarch *gdbarch, struct regcache *regcache) { gdb_assert (gdbarch != NULL); gdb_assert (gdbarch->software_single_step != NULL); if (gdbarch_debug >= 2) fprintf_unfiltered (gdb_stdlog, "gdbarch_software_single_step called\n"); - return gdbarch->software_single_step (sig, insert_breakpoints_p); + return gdbarch->software_single_step (regcache); } void diff -urNp gdb-orig/gdb/gdbarch.h gdb-head/gdb/gdbarch.h --- gdb-orig/gdb/gdbarch.h 2007-04-12 16:26:43.590210000 +0200 +++ gdb-head/gdb/gdbarch.h 2007-04-13 00:02:49.271202424 +0200 @@ -1173,14 +1173,14 @@ extern int gdbarch_software_single_step_ #define SOFTWARE_SINGLE_STEP_P() (gdbarch_software_single_step_p (current_gdbarch)) #endif -typedef int (gdbarch_software_single_step_ftype) (enum target_signal sig, int insert_breakpoints_p); -extern int gdbarch_software_single_step (struct gdbarch *gdbarch, enum target_signal sig, int insert_breakpoints_p); +typedef int (gdbarch_software_single_step_ftype) (struct regcache *regcache); +extern int gdbarch_software_single_step (struct gdbarch *gdbarch, struct regcache *regcache); extern void set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch_software_single_step_ftype *software_single_step); #if !defined (GDB_TM_FILE) && defined (SOFTWARE_SINGLE_STEP) #error "Non multi-arch definition of SOFTWARE_SINGLE_STEP" #endif #if !defined (SOFTWARE_SINGLE_STEP) -#define SOFTWARE_SINGLE_STEP(sig, insert_breakpoints_p) (gdbarch_software_single_step (current_gdbarch, sig, insert_breakpoints_p)) +#define SOFTWARE_SINGLE_STEP(regcache) (gdbarch_software_single_step (current_gdbarch, regcache)) #endif /* Return non-zero if the processor is executing a delay slot and a diff -urNp gdb-orig/gdb/gdbarch.sh gdb-head/gdb/gdbarch.sh --- gdb-orig/gdb/gdbarch.sh 2007-04-12 16:26:43.610207000 +0200 +++ gdb-head/gdb/gdbarch.sh 2007-04-13 00:02:11.913156520 +0200 @@ -628,7 +628,7 @@ f:=:CORE_ADDR:smash_text_address:CORE_AD # # A return value of 1 means that the software_single_step breakpoints # were inserted; 0 means they were not. -F:=:int:software_single_step:enum target_signal sig, int insert_breakpoints_p:sig, insert_breakpoints_p +F:=:int:software_single_step:struct regcache *regcache:regcache # Return non-zero if the processor is executing a delay slot and a # further single-step is needed before the instruction finishes. diff -urNp gdb-orig/gdb/infrun.c gdb-head/gdb/infrun.c --- gdb-orig/gdb/infrun.c 2007-04-12 16:26:43.622205000 +0200 +++ gdb-head/gdb/infrun.c 2007-04-13 00:18:33.741163272 +0200 @@ -548,7 +548,7 @@ resume (int step, enum target_signal sig if (SOFTWARE_SINGLE_STEP_P () && step) { /* Do it the hard way, w/temp breakpoints */ - if (SOFTWARE_SINGLE_STEP (sig, 1 /*insert-breakpoints */ )) + if (SOFTWARE_SINGLE_STEP (current_regcache)) { /* ...and don't ask hardware to do it. */ step = 0; @@ -1571,7 +1571,7 @@ handle_inferior_event (struct execution_ if (debug_infrun) fprintf_unfiltered (gdb_stdlog, "infrun: stepping_past_singlestep_breakpoint\n"); /* Pull the single step breakpoints out of the target. */ - (void) SOFTWARE_SINGLE_STEP (0, 0); + remove_single_step_breakpoints (); singlestep_breakpoints_inserted_p = 0; ecs->random_signal = 0; @@ -1680,7 +1680,7 @@ handle_inferior_event (struct execution_ if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) { /* Pull the single step breakpoints out of the target. */ - (void) SOFTWARE_SINGLE_STEP (0, 0); + remove_single_step_breakpoints (); singlestep_breakpoints_inserted_p = 0; } @@ -1751,7 +1751,7 @@ handle_inferior_event (struct execution_ if (SOFTWARE_SINGLE_STEP_P () && singlestep_breakpoints_inserted_p) { /* Pull the single step breakpoints out of the target. */ - (void) SOFTWARE_SINGLE_STEP (0, 0); + remove_single_step_breakpoints (); singlestep_breakpoints_inserted_p = 0; } diff -urNp gdb-orig/gdb/mips-tdep.c gdb-head/gdb/mips-tdep.c --- gdb-orig/gdb/mips-tdep.c 2007-04-12 16:26:43.652201000 +0200 +++ gdb-head/gdb/mips-tdep.c 2007-04-13 00:09:23.118247720 +0200 @@ -2199,26 +2199,17 @@ mips_addr_bits_remove (CORE_ADDR addr) /* mips_software_single_step() is called just before we want to resume the inferior, if we want to single-step it but there is no hardware or kernel single-step support (MIPS on GNU/Linux for example). We find - the target of the coming instruction and breakpoint it. - - single_step is also called just after the inferior stops. If we had - set up a simulated single-step, we undo our damage. */ + the target of the coming instruction and breakpoint it. */ int -mips_software_single_step (enum target_signal sig, int insert_breakpoints_p) +mips_software_single_step (struct regcache *regcache) { CORE_ADDR pc, next_pc; - if (insert_breakpoints_p) - { - pc = read_register (mips_regnum (current_gdbarch)->pc); - next_pc = mips_next_pc (pc); - - insert_single_step_breakpoint (next_pc); - } - else - remove_single_step_breakpoints (); + pc = read_register (mips_regnum (current_gdbarch)->pc); + next_pc = mips_next_pc (pc); + insert_single_step_breakpoint (next_pc); return 1; } diff -urNp gdb-orig/gdb/mips-tdep.h gdb-head/gdb/mips-tdep.h --- gdb-orig/gdb/mips-tdep.h 2007-04-12 16:26:43.657200000 +0200 +++ gdb-head/gdb/mips-tdep.h 2007-04-13 00:14:07.262194368 +0200 @@ -100,7 +100,7 @@ enum }; /* Single step based on where the current instruction will take us. */ -extern int mips_software_single_step (enum target_signal, int); +extern int mips_software_single_step (struct regcache *regcache); /* Tell if the program counter value in MEMADDR is in a MIPS16 function. */ diff -urNp gdb-orig/gdb/rs6000-tdep.c gdb-head/gdb/rs6000-tdep.c --- gdb-orig/gdb/rs6000-tdep.c 2007-04-12 16:26:43.702193000 +0200 +++ gdb-head/gdb/rs6000-tdep.c 2007-04-13 00:11:55.894192088 +0200 @@ -723,8 +723,7 @@ rs6000_breakpoint_from_pc (CORE_ADDR *bp /* AIX does not support PT_STEP. Simulate it. */ int -rs6000_software_single_step (enum target_signal signal, - int insert_breakpoints_p) +rs6000_software_single_step (struct regcache *regcache) { CORE_ADDR dummy; int breakp_sz; @@ -734,30 +733,25 @@ rs6000_software_single_step (enum target CORE_ADDR breaks[2]; int opcode; - if (insert_breakpoints_p) - { - loc = read_pc (); + loc = read_pc (); - insn = read_memory_integer (loc, 4); + insn = read_memory_integer (loc, 4); - breaks[0] = loc + breakp_sz; - opcode = insn >> 26; - breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); + breaks[0] = loc + breakp_sz; + opcode = insn >> 26; + breaks[1] = branch_dest (opcode, insn, loc, breaks[0]); - /* Don't put two breakpoints on the same address. */ - if (breaks[1] == breaks[0]) - breaks[1] = -1; + /* Don't put two breakpoints on the same address. */ + if (breaks[1] == breaks[0]) + breaks[1] = -1; - for (ii = 0; ii < 2; ++ii) - { - /* ignore invalid breakpoint. */ - if (breaks[ii] == -1) - continue; - insert_single_step_breakpoint (breaks[ii]); - } + for (ii = 0; ii < 2; ++ii) + { + /* ignore invalid breakpoint. */ + if (breaks[ii] == -1) + continue; + insert_single_step_breakpoint (breaks[ii]); } - else - remove_single_step_breakpoints (); errno = 0; /* FIXME, don't ignore errors! */ /* What errors? {read,write}_memory call error(). */ diff -urNp gdb-orig/gdb/rs6000-tdep.h gdb-head/gdb/rs6000-tdep.h --- gdb-orig/gdb/rs6000-tdep.h 2007-04-12 16:26:43.661199000 +0200 +++ gdb-head/gdb/rs6000-tdep.h 2007-04-13 00:13:59.057243312 +0200 @@ -21,8 +21,7 @@ #include "defs.h" -extern int rs6000_software_single_step (enum target_signal signal, - int insert_breakpoints_p); +extern int rs6000_software_single_step (struct regcache *regcache); /* Hook in rs6000-tdep.c for determining the TOC address when calling functions in the inferior. */ diff -urNp gdb-orig/gdb/sparc-tdep.c gdb-head/gdb/sparc-tdep.c --- gdb-orig/gdb/sparc-tdep.c 2007-04-12 16:26:43.680196000 +0200 +++ gdb-head/gdb/sparc-tdep.c 2007-04-13 00:13:27.494247568 +0200 @@ -1330,35 +1330,30 @@ sparc_step_trap (unsigned long insn) } int -sparc_software_single_step (enum target_signal sig, int insert_breakpoints_p) +sparc_software_single_step (struct regcache *regcache) { struct gdbarch *arch = current_gdbarch; struct gdbarch_tdep *tdep = gdbarch_tdep (arch); CORE_ADDR npc, nnpc; - if (insert_breakpoints_p) - { - CORE_ADDR pc, orig_npc; + CORE_ADDR pc, orig_npc; - pc = sparc_address_from_register (tdep->pc_regnum); - orig_npc = npc = sparc_address_from_register (tdep->npc_regnum); + pc = sparc_address_from_register (tdep->pc_regnum); + orig_npc = npc = sparc_address_from_register (tdep->npc_regnum); - /* Analyze the instruction at PC. */ - nnpc = sparc_analyze_control_transfer (arch, pc, &npc); - if (npc != 0) - insert_single_step_breakpoint (npc); - - if (nnpc != 0) - insert_single_step_breakpoint (nnpc); - - /* Assert that we have set at least one breakpoint, and that - they're not set at the same spot - unless we're going - from here straight to NULL, i.e. a call or jump to 0. */ - gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0); - gdb_assert (nnpc != npc || orig_npc == 0); - } - else - remove_single_step_breakpoints (); + /* Analyze the instruction at PC. */ + nnpc = sparc_analyze_control_transfer (arch, pc, &npc); + if (npc != 0) + insert_single_step_breakpoint (npc); + + if (nnpc != 0) + insert_single_step_breakpoint (nnpc); + + /* Assert that we have set at least one breakpoint, and that + they're not set at the same spot - unless we're going + from here straight to NULL, i.e. a call or jump to 0. */ + gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0); + gdb_assert (nnpc != npc || orig_npc == 0); return 1; } diff -urNp gdb-orig/gdb/sparc-tdep.h gdb-head/gdb/sparc-tdep.h --- gdb-orig/gdb/sparc-tdep.h 2007-04-12 16:26:43.690195000 +0200 +++ gdb-head/gdb/sparc-tdep.h 2007-04-13 00:13:47.893209264 +0200 @@ -167,8 +167,7 @@ extern struct sparc_frame_cache * -extern int sparc_software_single_step (enum target_signal sig, - int insert_breakpoints_p); +extern int sparc_software_single_step (struct regcache *regcache); extern void sparc_supply_rwindow (struct regcache *regcache, CORE_ADDR sp, int regnum); diff -urNp gdb-orig/gdb/spu-tdep.c gdb-head/gdb/spu-tdep.c --- gdb-orig/gdb/spu-tdep.c 2007-04-12 16:26:43.709192000 +0200 +++ gdb-head/gdb/spu-tdep.c 2007-04-13 00:16:21.341184944 +0200 @@ -1079,52 +1079,47 @@ spu_breakpoint_from_pc (CORE_ADDR * pcpt /* Software single-stepping support. */ int -spu_software_single_step (enum target_signal signal, int insert_breakpoints_p) +spu_software_single_step (struct regcache *regcache) { - if (insert_breakpoints_p) - { - CORE_ADDR pc, next_pc; - unsigned int insn; - int offset, reg; - gdb_byte buf[4]; - - regcache_cooked_read (current_regcache, SPU_PC_REGNUM, buf); - /* Mask off interrupt enable bit. */ - pc = extract_unsigned_integer (buf, 4) & -4; - - if (target_read_memory (pc, buf, 4)) - return 1; - insn = extract_unsigned_integer (buf, 4); - - /* Next sequential instruction is at PC + 4, except if the current - instruction is a PPE-assisted call, in which case it is at PC + 8. - Wrap around LS limit to be on the safe side. */ - if ((insn & 0xffffff00) == 0x00002100) - next_pc = (pc + 8) & (SPU_LS_SIZE - 1); - else - next_pc = (pc + 4) & (SPU_LS_SIZE - 1); + CORE_ADDR pc, next_pc; + unsigned int insn; + int offset, reg; + gdb_byte buf[4]; + + regcache_cooked_read (regcache, SPU_PC_REGNUM, buf); + /* Mask off interrupt enable bit. */ + pc = extract_unsigned_integer (buf, 4) & -4; + + if (target_read_memory (pc, buf, 4)) + return 1; + insn = extract_unsigned_integer (buf, 4); + + /* Next sequential instruction is at PC + 4, except if the current + instruction is a PPE-assisted call, in which case it is at PC + 8. + Wrap around LS limit to be on the safe side. */ + if ((insn & 0xffffff00) == 0x00002100) + next_pc = (pc + 8) & (SPU_LS_SIZE - 1); + else + next_pc = (pc + 4) & (SPU_LS_SIZE - 1); - insert_single_step_breakpoint (next_pc); + insert_single_step_breakpoint (next_pc); - if (is_branch (insn, &offset, ®)) - { - CORE_ADDR target = offset; + if (is_branch (insn, &offset, ®)) + { + CORE_ADDR target = offset; - if (reg == SPU_PC_REGNUM) - target += pc; - else if (reg != -1) - { - regcache_cooked_read_part (current_regcache, reg, 0, 4, buf); - target += extract_unsigned_integer (buf, 4) & -4; - } - - target = target & (SPU_LS_SIZE - 1); - if (target != next_pc) - insert_single_step_breakpoint (target); + if (reg == SPU_PC_REGNUM) + target += pc; + else if (reg != -1) + { + regcache_cooked_read_part (regcache, reg, 0, 4, buf); + target += extract_unsigned_integer (buf, 4) & -4; } + + target = target & (SPU_LS_SIZE - 1); + if (target != next_pc) + insert_single_step_breakpoint (target); } - else - remove_single_step_breakpoints (); return 1; } -- Dr. Ulrich Weigand GNU Toolchain for Linux on System z and Cell BE Ulrich.Weigand@de.ibm.com