From patchwork Wed Mar 23 14:10:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 11481 Received: (qmail 32521 invoked by alias); 23 Mar 2016 14:10:31 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 31911 invoked by uid 89); 23 Mar 2016 14:10:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 spammy=Exclusive, inst, Form, nnpc X-HELO: mail-pf0-f193.google.com Received: from mail-pf0-f193.google.com (HELO mail-pf0-f193.google.com) (209.85.192.193) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Wed, 23 Mar 2016 14:10:15 +0000 Received: by mail-pf0-f193.google.com with SMTP id n5so4124669pfn.1 for ; Wed, 23 Mar 2016 07:10:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=8E2kh2rjWKFECK826Dyk4fQ4NQ1nUwk52XhJsVmdCCw=; b=aFhwvt9b82n72wrDGyRY/cU+miqD2YNPhe/aDV58Ocwaa1iKyMic0BUZyNyk3hsTwn Ucd2aFT2efY6/stE0RRMnYq0/QO4MKhCCryOM+sEk1ZUf4wki6bNtlOM7h6irN5FFC+G mvYF9IhMQ1La/tuydEpbJ/hcRZSReF1ijZPkcWMcr2zyJ7YD+CYZ7rIn7TOyXt0jVVpE Hu6lpNGdXdaHMjaB/4P08u4cqHIUA7GE1LrDX1Ko4MwFXSiFLNHo/Ryuee/XoKNggAKM dUscSwHrV/lDMS2m4vbuiZ4UHSzvBW9/nFrh8KwLqltvfUPs5fnEghd984yxnIvm47JS 6sew== X-Gm-Message-State: AD7BkJIG+mvpaRyBXXhjIeU3twfLYh1eyA+g4QjYVDxq50cFfZ3i2M4q1NYGGQc2+Gq/rw== X-Received: by 10.98.15.142 with SMTP id 14mr4661265pfp.6.1458742213301; Wed, 23 Mar 2016 07:10:13 -0700 (PDT) Received: from E107787-LIN.cambridge.arm.com (gcc1-power7.osuosl.org. [140.211.15.137]) by smtp.gmail.com with ESMTPSA id l11sm4666303pfb.56.2016.03.23.07.10.10 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 23 Mar 2016 07:10:12 -0700 (PDT) From: Yao Qi X-Google-Original-From: Yao Qi To: gdb-patches@sourceware.org Subject: [PATCH 1/2] gdbarch software_single_step returns VEC (CORE_ADDR) * Date: Wed, 23 Mar 2016 14:10:05 +0000 Message-Id: <1458742206-622-2-git-send-email-yao.qi@linaro.org> In-Reply-To: <1458742206-622-1-git-send-email-yao.qi@linaro.org> References: <1458742206-622-1-git-send-email-yao.qi@linaro.org> X-IsSubscribed: yes 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. However, breakpoint insertion in arm is a little different, which uses arm_insert_single_step_breakpoint, and it updates a global variable arm_override_mode, so that arm_pc_is_thumb can get the right arm thumb mode even the program is wrong (see gdb.arch/thumb-singlestep.exp). I failed to remove global variable arm_override_mode, so have to add a new gdbarch method insert_single_step_breakpoint, which is in default insert_single_step_breakpoint for all targets except arm. gdb: 2016-03-23 Yao Qi * 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. Don't call insert_single_step_breakpoint. * arm-tdep.c (arm_insert_single_step_breakpoint): Make it static. (arm_software_single_step): Return NULL instead of 0. Don't call arm_insert_single_step_breakpoint. (arm_gdbarch_init): Install gdbarch method insert_single_step_breakpoint. * arm-tdep.h (arm_insert_single_step_breakpoint): Remove declaration. (arm_software_single_step): Update declaration. * 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) *. (insert_single_step_breakpoint): New. * 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. --- gdb/aarch64-tdep.c | 18 ++++++++-------- gdb/alpha-tdep.c | 28 ++++++++++++------------- gdb/alpha-tdep.h | 2 +- gdb/arm-linux-tdep.c | 14 ++++--------- gdb/arm-tdep.c | 18 +++++++--------- gdb/arm-tdep.h | 4 +--- gdb/cris-tdep.c | 13 ++++++------ gdb/gdbarch.c | 25 +++++++++++++++++++++- gdb/gdbarch.h | 12 +++++++---- gdb/gdbarch.sh | 8 ++++--- gdb/infrun.c | 23 +++++++++++++++++--- gdb/mips-tdep.c | 58 +++++++++++++++++++++++++-------------------------- gdb/mips-tdep.h | 2 +- gdb/moxie-tdep.c | 34 +++++++++++++----------------- gdb/nios2-tdep.c | 8 +++---- gdb/ppc-tdep.h | 2 +- gdb/record-full.c | 46 +++++++++++++++++++++++++++++++++++----- gdb/rs6000-aix-tdep.c | 12 ++++++----- gdb/rs6000-tdep.c | 12 +++++------ gdb/s390-linux-tdep.c | 16 +++++++------- gdb/sparc-tdep.c | 9 ++++---- gdb/spu-tdep.c | 13 ++++++------ gdb/tic6x-tdep.c | 9 ++++---- 23 files changed, 226 insertions(+), 160 deletions(-) diff --git a/gdb/aarch64-tdep.c b/gdb/aarch64-tdep.c index 77155ef..1df6267 100644 --- a/gdb/aarch64-tdep.c +++ b/gdb/aarch64-tdep.c @@ -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 single step through atomic sequences on AArch64. */ -static int +static VEC (CORE_ADDR) * aarch64_software_single_step (struct frame_info *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); const int insn_size = 4; 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 last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ aarch64_inst inst; + VEC (CORE_ADDR) *next_pcs = NULL; if (aarch64_decode_insn (insn, &inst, 1) != 0) - return 0; + return NULL; /* Look for a Load Exclusive instruction which begins the sequence. */ if (inst.opcode->iclass != ldstexcl || bit (insn, 22) == 0) - return 0; + return NULL; 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); if (aarch64_decode_insn (insn, &inst, 1) != 0) - return 0; + return NULL; /* Check if the instruction is a conditional branch. */ if (inst.opcode->iclass == condbranch) { gdb_assert (inst.operands[0].type == AARCH64_OPND_ADDR_PCREL19); if (bc_insn_count >= 1) - return 0; + return NULL; /* It is, so we'll try to set a breakpoint at the destination. */ 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. */ if (!closing_insn) - return 0; + return NULL; /* Insert breakpoint after the end of the atomic sequence. */ 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 destination of the conditional branch, if it exists. */ 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 diff --git a/gdb/alpha-tdep.c b/gdb/alpha-tdep.c index 0206214..c944b6a 100644 --- a/gdb/alpha-tdep.c +++ b/gdb/alpha-tdep.c @@ -768,11 +768,10 @@ static const int stq_c_opcode = 0x2f; is found, attempt to step through it. A breakpoint is placed at the end of the sequence. */ -static int +static VEC (CORE_ADDR) * alpha_deal_with_atomic_sequence (struct frame_info *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 breaks[2] = {-1, -1}; CORE_ADDR loc = pc; @@ -783,11 +782,12 @@ alpha_deal_with_atomic_sequence (struct frame_info *frame) int last_breakpoint = 0; /* Defaults to 0 (no breakpoints placed). */ const int atomic_sequence_length = 16; /* Instruction sequence length. */ 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. */ if (INSN_OPCODE (insn) != ldl_l_opcode && INSN_OPCODE (insn) != ldq_l_opcode) - return 0; + return NULL; /* Assume that no atomic sequence is longer than "atomic_sequence_length" instructions. */ @@ -806,8 +806,8 @@ alpha_deal_with_atomic_sequence (struct frame_info *frame) immediate = (immediate ^ 0x400000) - 0x400000; if (bc_insn_count >= 1) - return 0; /* More than one branch found, fallback - to the standard single-step code. */ + return NULL; /* More than one branch found, fallback + to the standard single-step code. */ breaks[1] = loc + ALPHA_INSN_SIZE + immediate; @@ -823,7 +823,7 @@ alpha_deal_with_atomic_sequence (struct frame_info *frame) /* Assume that the atomic sequence ends with a STL_C/STQ_C instruction. */ if (INSN_OPCODE (insn) != stl_c_opcode && INSN_OPCODE (insn) != stq_c_opcode) - return 0; + return NULL; closing_insn = loc; loc += ALPHA_INSN_SIZE; @@ -838,11 +838,10 @@ alpha_deal_with_atomic_sequence (struct frame_info *frame) || (breaks[1] >= pc && breaks[1] <= closing_insn))) last_breakpoint = 0; - /* 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; } @@ -1721,18 +1720,17 @@ alpha_next_pc (struct frame_info *frame, CORE_ADDR pc) return (pc + ALPHA_INSN_SIZE); } -int +VEC (CORE_ADDR) * alpha_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; + CORE_ADDR pc; + VEC (CORE_ADDR) *next_pcs = NULL; pc = get_frame_pc (frame); - next_pc = alpha_next_pc (frame, pc); - insert_single_step_breakpoint (gdbarch, aspace, next_pc); - return 1; + VEC_safe_push (CORE_ADDR, next_pcs, alpha_next_pc (frame, pc)); + return next_pcs; } diff --git a/gdb/alpha-tdep.h b/gdb/alpha-tdep.h index abeb326..5b64861 100644 --- a/gdb/alpha-tdep.h +++ b/gdb/alpha-tdep.h @@ -103,7 +103,7 @@ struct gdbarch_tdep }; 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 void alpha_mdebug_init_abi (struct gdbarch_info, struct gdbarch *); diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c index 9b68315..a919358 100644 --- a/gdb/arm-linux-tdep.c +++ b/gdb/arm-linux-tdep.c @@ -923,22 +923,19 @@ arm_linux_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self) /* 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) { struct regcache *regcache = get_current_regcache (); struct gdbarch *gdbarch = get_regcache_arch (regcache); - struct address_space *aspace = get_regcache_aspace (regcache); struct arm_get_next_pcs next_pcs_ctx; - CORE_ADDR pc; - int i; VEC (CORE_ADDR) *next_pcs = NULL; struct cleanup *old_chain; /* If the target does have hardware single step, GDB doesn't have to bother software single step. */ if (target_can_do_single_step () == 1) - return 0; + return NULL; old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs); @@ -951,12 +948,9 @@ arm_linux_software_single_step (struct frame_info *frame) next_pcs = arm_get_next_pcs (&next_pcs_ctx); - for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++) - arm_insert_single_step_breakpoint (gdbarch, aspace, pc); - - do_cleanups (old_chain); + discard_cleanups (old_chain); - return 1; + return next_pcs; } /* Support for displaced stepping of Linux SVC instructions. */ diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index ad69834..d4d17f3 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -4089,7 +4089,7 @@ convert_to_extended (const struct floatformat *fmt, void *dbl, const void *ptr, of the appropriate mode (as encoded in the PC value), even if this differs from what would be expected according to the symbol tables. */ -void +static void arm_insert_single_step_breakpoint (struct gdbarch *gdbarch, struct address_space *aspace, CORE_ADDR pc) @@ -6156,15 +6156,12 @@ arm_get_next_pcs_is_thumb (struct arm_get_next_pcs *self) single-step support. We find the target of the coming instructions and breakpoint them. */ -int +VEC (CORE_ADDR) * arm_software_single_step (struct frame_info *frame) { struct regcache *regcache = get_current_regcache (); struct gdbarch *gdbarch = get_regcache_arch (regcache); - struct address_space *aspace = get_regcache_aspace (regcache); struct arm_get_next_pcs next_pcs_ctx; - CORE_ADDR pc; - int i; VEC (CORE_ADDR) *next_pcs = NULL; struct cleanup *old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs); @@ -6177,12 +6174,8 @@ arm_software_single_step (struct frame_info *frame) next_pcs = arm_get_next_pcs (&next_pcs_ctx); - for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++) - arm_insert_single_step_breakpoint (gdbarch, aspace, pc); - - do_cleanups (old_chain); - - return 1; + discard_cleanups (old_chain); + return next_pcs; } /* Cleanup/copy SVC (SWI) instructions. These two functions are overridden @@ -9274,6 +9267,9 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) dwarf2_frame_set_init_reg (gdbarch, arm_dwarf2_frame_init_reg); + set_gdbarch_insert_single_step_breakpoint (gdbarch, + arm_insert_single_step_breakpoint); + /* Add some default predicates. */ if (is_m) frame_unwind_append_unwinder (gdbarch, &arm_m_exception_unwind); diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index e5d13bb..10ab742 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -259,9 +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); -void arm_insert_single_step_breakpoint (struct gdbarch *, - struct address_space *, CORE_ADDR); -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_frame_is_thumb (struct frame_info *frame); diff --git a/gdb/cris-tdep.c b/gdb/cris-tdep.c index d350ce8..97b9ee5 100644 --- a/gdb/cris-tdep.c +++ b/gdb/cris-tdep.c @@ -2068,12 +2068,12 @@ find_step_target (struct frame_info *frame, inst_env_type *inst_env) digs through the opcodes in order to find all possible targets. 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) { struct gdbarch *gdbarch = get_frame_arch (frame); - struct address_space *aspace = get_frame_address_space (frame); inst_env_type inst_env; + VEC (CORE_ADDR) *next_pcs = NULL; /* Analyse the present instruction environment and insert breakpoints. */ @@ -2090,18 +2090,19 @@ cris_software_single_step (struct frame_info *frame) and possibly another one for a branch, jump, etc. */ CORE_ADDR next_pc = (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 && (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 (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. */ diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c index bd0b48c..04e5a48 100644 --- a/gdb/gdbarch.c +++ b/gdb/gdbarch.c @@ -245,6 +245,7 @@ struct gdbarch gdbarch_convert_from_func_ptr_addr_ftype *convert_from_func_ptr_addr; gdbarch_addr_bits_remove_ftype *addr_bits_remove; gdbarch_software_single_step_ftype *software_single_step; + gdbarch_insert_single_step_breakpoint_ftype *insert_single_step_breakpoint; gdbarch_single_step_through_delay_ftype *single_step_through_delay; gdbarch_print_insn_ftype *print_insn; gdbarch_skip_trampoline_code_ftype *skip_trampoline_code; @@ -404,6 +405,7 @@ gdbarch_alloc (const struct gdbarch_info *info, gdbarch->stabs_argument_has_addr = default_stabs_argument_has_addr; gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity; gdbarch->addr_bits_remove = core_addr_identity; + gdbarch->insert_single_step_breakpoint = insert_single_step_breakpoint; gdbarch->skip_trampoline_code = generic_skip_trampoline_code; gdbarch->skip_solib_resolver = generic_skip_solib_resolver; gdbarch->in_solib_return_trampoline = generic_in_solib_return_trampoline; @@ -591,6 +593,7 @@ verify_gdbarch (struct gdbarch *gdbarch) /* Skip verify of convert_from_func_ptr_addr, invalid_p == 0 */ /* Skip verify of addr_bits_remove, invalid_p == 0 */ /* Skip verify of software_single_step, has predicate. */ + /* Skip verify of insert_single_step_breakpoint, invalid_p == 0 */ /* Skip verify of single_step_through_delay, has predicate. */ if (gdbarch->print_insn == 0) fprintf_unfiltered (log, "\n\tprint_insn"); @@ -1077,6 +1080,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) "gdbarch_dump: inner_than = <%s>\n", host_address_to_string (gdbarch->inner_than)); fprintf_unfiltered (file, + "gdbarch_dump: insert_single_step_breakpoint = <%s>\n", + host_address_to_string (gdbarch->insert_single_step_breakpoint)); + fprintf_unfiltered (file, "gdbarch_dump: insn_is_call = <%s>\n", host_address_to_string (gdbarch->insn_is_call)); fprintf_unfiltered (file, @@ -3066,7 +3072,7 @@ gdbarch_software_single_step_p (struct gdbarch *gdbarch) return gdbarch->software_single_step != NULL; } -int +VEC (CORE_ADDR) * gdbarch_software_single_step (struct gdbarch *gdbarch, struct frame_info *frame) { gdb_assert (gdbarch != NULL); @@ -3083,6 +3089,23 @@ set_gdbarch_software_single_step (struct gdbarch *gdbarch, gdbarch->software_single_step = software_single_step; } +void +gdbarch_insert_single_step_breakpoint (struct gdbarch *gdbarch, struct address_space *aspace, CORE_ADDR pc) +{ + gdb_assert (gdbarch != NULL); + gdb_assert (gdbarch->insert_single_step_breakpoint != NULL); + if (gdbarch_debug >= 2) + fprintf_unfiltered (gdb_stdlog, "gdbarch_insert_single_step_breakpoint called\n"); + gdbarch->insert_single_step_breakpoint (gdbarch, aspace, pc); +} + +void +set_gdbarch_insert_single_step_breakpoint (struct gdbarch *gdbarch, + gdbarch_insert_single_step_breakpoint_ftype insert_single_step_breakpoint) +{ + gdbarch->insert_single_step_breakpoint = insert_single_step_breakpoint; +} + int gdbarch_single_step_through_delay_p (struct gdbarch *gdbarch) { diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h index 252fc4b..18da3ce 100644 --- a/gdb/gdbarch.h +++ b/gdb/gdbarch.h @@ -649,15 +649,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 target can single step. If not, then implement single step using breakpoints. - A return value of 1 means that the software_single_step breakpoints - were inserted; 0 means they were not. */ + Return a vector of addresses on which the software single step + breakpoints are inserted. NULL means software single step is not used. */ extern int gdbarch_software_single_step_p (struct gdbarch *gdbarch); -typedef int (gdbarch_software_single_step_ftype) (struct frame_info *frame); -extern int gdbarch_software_single_step (struct gdbarch *gdbarch, struct frame_info *frame); +typedef VEC (CORE_ADDR) * (gdbarch_software_single_step_ftype) (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); +typedef void (gdbarch_insert_single_step_breakpoint_ftype) (struct gdbarch *gdbarch, struct address_space *aspace, CORE_ADDR pc); +extern void gdbarch_insert_single_step_breakpoint (struct gdbarch *gdbarch, struct address_space *aspace, CORE_ADDR pc); +extern void set_gdbarch_insert_single_step_breakpoint (struct gdbarch *gdbarch, gdbarch_insert_single_step_breakpoint_ftype *insert_single_step_breakpoint); + /* Return non-zero if the processor is executing a delay slot and a further single-step is needed before the instruction finishes. */ diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh index 37f59b7..667c3f1 100755 --- a/gdb/gdbarch.sh +++ b/gdb/gdbarch.sh @@ -608,9 +608,11 @@ 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 # target can single step. If not, then implement single step using breakpoints. # -# A return value of 1 means that the software_single_step breakpoints -# were inserted; 0 means they were not. -F:int:software_single_step:struct frame_info *frame:frame +# Return a vector of addresses on which the software single step +# breakpoints are inserted. NULL means software single step is not used. +F:VEC (CORE_ADDR) *:software_single_step:struct frame_info *frame:frame + +m:void:insert_single_step_breakpoint:struct address_space *aspace, CORE_ADDR pc:aspace, pc::insert_single_step_breakpoint::0 # Return non-zero if the processor is executing a delay slot and a # further single-step is needed before the instruction finishes. diff --git a/gdb/infrun.c b/gdb/infrun.c index 696105d..5dbcf7a 100644 --- a/gdb/infrun.c +++ b/gdb/infrun.c @@ -2248,11 +2248,28 @@ maybe_software_singlestep (struct gdbarch *gdbarch, CORE_ADDR pc) int hw_step = 1; if (execution_direction == EXEC_FORWARD - && gdbarch_software_single_step_p (gdbarch) - && gdbarch_software_single_step (gdbarch, get_current_frame ())) + && gdbarch_software_single_step_p (gdbarch)) { - hw_step = 0; + 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); + + hw_step = 0; + + for (i = 0; VEC_iterate (CORE_ADDR, next_pcs, i, pc); i++) + gdbarch_insert_single_step_breakpoint (gdbarch, aspace, pc); + + VEC_free (CORE_ADDR, next_pcs); + } } + return hw_step; } diff --git a/gdb/mips-tdep.c b/gdb/mips-tdep.c index 178a163..0d115f4 100644 --- a/gdb/mips-tdep.c +++ b/gdb/mips-tdep.c @@ -3883,9 +3883,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; @@ -3895,11 +3894,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. */ @@ -3963,7 +3963,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; @@ -3977,14 +3977,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. */ @@ -3997,16 +3996,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 @@ -4103,24 +4103,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; @@ -4132,21 +4132,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 @@ -4154,21 +4153,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 diff --git a/gdb/mips-tdep.h b/gdb/mips-tdep.h index 2e4d194..df99c80 100644 --- a/gdb/mips-tdep.h +++ b/gdb/mips-tdep.h @@ -157,7 +157,7 @@ enum }; /* 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. */ extern CORE_ADDR mips_unmake_compact_addr (CORE_ADDR addr); diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c index 714734d..b7f3e41 100644 --- a/gdb/moxie-tdep.c +++ b/gdb/moxie-tdep.c @@ -306,11 +306,10 @@ moxie_process_readu (CORE_ADDR addr, gdb_byte *buf, /* Insert a single step breakpoint. */ -static int +static VEC (CORE_ADDR) * moxie_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 addr; gdb_byte buf[4]; uint16_t inst; @@ -318,6 +317,7 @@ moxie_software_single_step (struct frame_info *frame) ULONGEST fp; enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); struct regcache *regcache = get_current_regcache (); + VEC (CORE_ADDR) *next_pcs = NULL; addr = get_frame_pc (frame); @@ -345,8 +345,9 @@ moxie_software_single_step (struct frame_info *frame) case 0x09: /* bleu */ /* Insert breaks on both branches, because we can't currently tell which way things will go. */ - insert_single_step_breakpoint (gdbarch, aspace, addr + 2); - insert_single_step_breakpoint (gdbarch, aspace, addr + 2 + INST2OFFSET(inst)); + VEC_safe_push (CORE_ADDR, next_pcs, addr + 2); + VEC_safe_push (CORE_ADDR, next_pcs, + addr + 2 + INST2OFFSET(inst)); break; default: { @@ -358,7 +359,7 @@ moxie_software_single_step (struct frame_info *frame) else { /* 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 @@ -405,7 +406,7 @@ moxie_software_single_step (struct frame_info *frame) case 0x32: /* udiv.l */ case 0x33: /* mod.l */ case 0x34: /* umod.l */ - insert_single_step_breakpoint (gdbarch, aspace, addr + 2); + VEC_safe_push (CORE_ADDR, next_pcs, addr + 2); break; /* 32-bit instructions. */ @@ -415,7 +416,7 @@ moxie_software_single_step (struct frame_info *frame) case 0x37: /* sto.b */ case 0x38: /* ldo.s */ case 0x39: /* sto.s */ - insert_single_step_breakpoint (gdbarch, aspace, addr + 4); + VEC_safe_push (CORE_ADDR, next_pcs, addr + 4); break; /* 48-bit instructions. */ @@ -428,32 +429,27 @@ moxie_software_single_step (struct frame_info *frame) case 0x20: /* ldi.s (immediate) */ case 0x22: /* lda.s */ case 0x24: /* sta.s */ - insert_single_step_breakpoint (gdbarch, aspace, addr + 6); + VEC_safe_push (CORE_ADDR, next_pcs, addr + 6); break; /* Control flow instructions. */ case 0x03: /* jsra */ case 0x1a: /* jmpa */ - insert_single_step_breakpoint (gdbarch, aspace, - moxie_process_readu (addr + 2, - buf, 4, - byte_order)); + VEC_safe_push (CORE_ADDR, next_pcs, + moxie_process_readu (addr + 2, buf, 4, byte_order)); break; case 0x04: /* ret */ regcache_cooked_read_unsigned (regcache, MOXIE_FP_REGNUM, &fp); - insert_single_step_breakpoint (gdbarch, aspace, - moxie_process_readu (fp + 4, - buf, 4, - byte_order)); + VEC_safe_push (CORE_ADDR, next_pcs, + moxie_process_readu (fp + 4, buf, 4, byte_order)); break; case 0x19: /* jsr */ case 0x25: /* jmp */ regcache_raw_read (regcache, (inst >> 4) & 0xf, (gdb_byte *) & tmpu32); - insert_single_step_breakpoint (gdbarch, aspace, - tmpu32); + VEC_safe_push (CORE_ADDR, next_pcs, tmpu32); break; case 0x30: /* swi */ @@ -463,7 +459,7 @@ moxie_software_single_step (struct frame_info *frame) } } - return 1; + return next_pcs; } /* Implement the "read_pc" gdbarch method. */ diff --git a/gdb/nios2-tdep.c b/gdb/nios2-tdep.c index 9d92c55..ce23caf 100644 --- a/gdb/nios2-tdep.c +++ b/gdb/nios2-tdep.c @@ -2205,16 +2205,16 @@ nios2_get_next_pc (struct frame_info *frame, CORE_ADDR pc) /* Implement the software_single_step gdbarch method. */ -static int +static VEC (CORE_ADDR) * nios2_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 = 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. */ diff --git a/gdb/ppc-tdep.h b/gdb/ppc-tdep.h index 4a1cb0f..0249456 100644 --- a/gdb/ppc-tdep.h +++ b/gdb/ppc-tdep.h @@ -76,7 +76,7 @@ int ppc_altivec_support_p (struct gdbarch *gdbarch); /* Return non-zero if the architecture described by GDBARCH has VSX registers (vsr0 --- vsr63). */ 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. */ diff --git a/gdb/record-full.c b/gdb/record-full.c index f6023bf..c3c3add 100644 --- a/gdb/record-full.c +++ b/gdb/record-full.c @@ -985,15 +985,32 @@ record_full_resume (struct target_ops *ops, ptid_t ptid, int step, } else { + struct frame_info *frame = get_current_frame (); + VEC (CORE_ADDR) * next_pcs; + + next_pcs = gdbarch_software_single_step (gdbarch, frame); + /* This is a continue. Try to insert a soft single step breakpoint. */ - if (!gdbarch_software_single_step (gdbarch, - get_current_frame ())) + if (next_pcs == NULL) { /* This system don't want use soft single step. Use hard sigle step. */ step = 1; } + else + { + 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); + } } } } @@ -1163,13 +1180,32 @@ record_full_wait_1 (struct target_ops *ops, if (gdbarch_software_single_step_p (gdbarch)) { + VEC (CORE_ADDR) *next_pcs; + struct frame_info *frame; + /* Try to insert the software single step breakpoint. If insert success, set step to 0. */ set_executing (inferior_ptid, 0); reinit_frame_cache (); - if (gdbarch_software_single_step (gdbarch, - get_current_frame ())) - step = 0; + frame = get_current_frame (); + next_pcs + = gdbarch_software_single_step (gdbarch, frame); + if (next_pcs != NULL) + { + int i; + CORE_ADDR pc; + struct address_space *aspace; + + 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); + step = 0; + } set_executing (inferior_ptid, 1); } diff --git a/gdb/rs6000-aix-tdep.c b/gdb/rs6000-aix-tdep.c index f5e5489..6578e7a 100644 --- a/gdb/rs6000-aix-tdep.c +++ b/gdb/rs6000-aix-tdep.c @@ -671,7 +671,7 @@ branch_dest (struct frame_info *frame, int opcode, int instr, /* AIX does not support PT_STEP. Simulate it. */ -static int +static VEC (CORE_ADDR) * rs6000_software_single_step (struct frame_info *frame) { struct gdbarch *gdbarch = get_frame_arch (frame); @@ -681,13 +681,15 @@ rs6000_software_single_step (struct frame_info *frame) CORE_ADDR loc; CORE_ADDR breaks[2]; int opcode; + VEC (CORE_ADDR) *next_pcs; loc = get_frame_pc (frame); insn = read_memory_integer (loc, 4, byte_order); - if (ppc_deal_with_atomic_sequence (frame)) - return 1; + next_pcs = ppc_deal_with_atomic_sequence (frame); + if (next_pcs != NULL) + return next_pcs; breaks[0] = loc + PPC_INSN_SIZE; opcode = insn >> 26; @@ -702,12 +704,12 @@ rs6000_software_single_step (struct frame_info *frame) /* ignore invalid breakpoint. */ if (breaks[ii] == -1) 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! */ /* What errors? {read,write}_memory call error(). */ - return 1; + return next_pcs; } /* Implement the "auto_wide_charset" gdbarch method for this platform. */ diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c index 2460eb5..26c8ed9 100644 --- a/gdb/rs6000-tdep.c +++ b/gdb/rs6000-tdep.c @@ -1150,7 +1150,7 @@ ppc_displaced_step_hw_singlestep (struct gdbarch *gdbarch, is found, attempt to step through it. A breakpoint is placed at the end of the sequence. */ -int +VEC (CORE_ADDR) * ppc_deal_with_atomic_sequence (struct frame_info *frame) { struct gdbarch *gdbarch = get_frame_arch (frame); @@ -1167,11 +1167,12 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) const int atomic_sequence_length = 16; /* Instruction sequence length. */ int opcode; /* Branch instruction's OPcode. */ 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. */ if ((insn & LWARX_MASK) != LWARX_INSTRUCTION && (insn & LWARX_MASK) != LDARX_INSTRUCTION) - return 0; + return NULL; /* Assume that no atomic sequence is longer than "atomic_sequence_length" instructions. */ @@ -1209,7 +1210,7 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) /* Assume that the atomic sequence ends with a stwcx/stdcx instruction. */ if ((insn & STWCX_MASK) != STWCX_INSTRUCTION && (insn & STWCX_MASK) != STDCX_INSTRUCTION) - return 0; + return NULL; closing_insn = loc; loc += PPC_INSN_SIZE; @@ -1225,11 +1226,10 @@ ppc_deal_with_atomic_sequence (struct frame_info *frame) || (breaks[1] >= pc && breaks[1] <= closing_insn))) last_breakpoint = 0; - /* 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; } diff --git a/gdb/s390-linux-tdep.c b/gdb/s390-linux-tdep.c index fc57592..dd26ba6 100644 --- a/gdb/s390-linux-tdep.c +++ b/gdb/s390-linux-tdep.c @@ -721,7 +721,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 complexity. */ -static int +static VEC (CORE_ADDR) * s390_software_single_step (struct frame_info *frame) { struct gdbarch *gdbarch = get_frame_arch (frame); @@ -730,33 +730,33 @@ s390_software_single_step (struct frame_info *frame) enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); int len; uint16_t insn; + VEC (CORE_ADDR) *next_pcs = NULL; /* Special handling only if recording. */ if (!record_full_is_used ()) - return 0; + return NULL; /* First, match a partial instruction. */ if (!s390_is_partial_instruction (gdbarch, loc, &len)) - return 0; + return NULL; loc += len; /* Second, look for a branch back to it. */ insn = read_memory_integer (loc, 2, byte_order); if (insn != 0xa714) /* BRC with mask 1 */ - return 0; + return NULL; insn = read_memory_integer (loc + 2, 2, byte_order); if (insn != (uint16_t) -(len / 2)) - return 0; + return NULL; loc += 4; /* Found it, step past the whole thing. */ + VEC_safe_push (CORE_ADDR, next_pcs, loc); - insert_single_step_breakpoint (gdbarch, aspace, loc); - - return 1; + return next_pcs; } static int diff --git a/gdb/sparc-tdep.c b/gdb/sparc-tdep.c index 863ef8f..27a70fc 100644 --- a/gdb/sparc-tdep.c +++ b/gdb/sparc-tdep.c @@ -1605,7 +1605,7 @@ sparc_step_trap (struct frame_info *frame, unsigned long insn) return 0; } -static int +static VEC (CORE_ADDR) * sparc_software_single_step (struct frame_info *frame) { struct gdbarch *arch = get_frame_arch (frame); @@ -1614,6 +1614,7 @@ sparc_software_single_step (struct frame_info *frame) CORE_ADDR npc, nnpc; CORE_ADDR pc, orig_npc; + VEC (CORE_ADDR) *next_pcs = NULL; pc = get_frame_register_unsigned (frame, tdep->pc_regnum); orig_npc = npc = get_frame_register_unsigned (frame, tdep->npc_regnum); @@ -1621,10 +1622,10 @@ sparc_software_single_step (struct frame_info *frame) /* Analyze the instruction at PC. */ nnpc = sparc_analyze_control_transfer (frame, pc, &npc); if (npc != 0) - insert_single_step_breakpoint (arch, aspace, npc); + VEC_safe_push (CORE_ADDR, next_pcs, npc); 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 they're not set at the same spot - unless we're going @@ -1632,7 +1633,7 @@ sparc_software_single_step (struct frame_info *frame) gdb_assert (npc != 0 || nnpc != 0 || orig_npc == 0); gdb_assert (nnpc != npc || orig_npc == 0); - return 1; + return next_pcs; } static void diff --git a/gdb/spu-tdep.c b/gdb/spu-tdep.c index 8dad5c3..ac8fac8 100644 --- a/gdb/spu-tdep.c +++ b/gdb/spu-tdep.c @@ -1617,17 +1617,17 @@ spu_memory_remove_breakpoint (struct gdbarch *gdbarch, /* Software single-stepping support. */ -static int +static VEC (CORE_ADDR) * spu_software_single_step (struct frame_info *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); CORE_ADDR pc, next_pc; unsigned int insn; int offset, reg; gdb_byte buf[4]; ULONGEST lslr; + VEC (CORE_ADDR) *next_pcs = NULL; pc = get_frame_pc (frame); @@ -1650,8 +1650,7 @@ spu_software_single_step (struct frame_info *frame) else next_pc = (SPUADDR_ADDR (pc) + 4) & lslr; - insert_single_step_breakpoint (gdbarch, - aspace, SPUADDR (SPUADDR_SPU (pc), next_pc)); + VEC_safe_push (CORE_ADDR, next_pcs, SPUADDR (SPUADDR_SPU (pc), next_pc)); if (is_branch (insn, &offset, ®)) { @@ -1681,11 +1680,11 @@ spu_software_single_step (struct frame_info *frame) target = target & lslr; if (target != next_pc) - insert_single_step_breakpoint (gdbarch, aspace, - SPUADDR (SPUADDR_SPU (pc), target)); + VEC_safe_push (CORE_ADDR, next_pcs, SPUADDR (SPUADDR_SPU (pc), + target)); } - return 1; + return next_pcs; } diff --git a/gdb/tic6x-tdep.c b/gdb/tic6x-tdep.c index 4779bf0..54a6515 100644 --- a/gdb/tic6x-tdep.c +++ b/gdb/tic6x-tdep.c @@ -694,16 +694,15 @@ tic6x_get_next_pc (struct frame_info *frame, CORE_ADDR pc) /* This is the implementation of gdbarch method software_single_step. */ -static int +static VEC (CORE_ADDR) * 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)); + 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. */