From patchwork Sat Mar 25 22:23:11 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elouan Appere X-Patchwork-Id: 19728 Received: (qmail 53159 invoked by alias); 25 Mar 2017 22:23:19 -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 53138 invoked by uid 89); 25 Mar 2017 22:23:18 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.2 spammy=SVC, virtually, 1369, HAuthentication-Results:smtp.auth X-HELO: smtp26.services.sfr.fr Received: from smtp26.services.sfr.fr (HELO smtp26.services.sfr.fr) (93.17.128.10) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 25 Mar 2017 22:23:15 +0000 Received: from ElouanLaptop.enseeiht.fr (unknown [147.127.122.15]) by msfrf2627.sfr.fr (SMTP Server) with ESMTP id 535711C00042A; Sat, 25 Mar 2017 23:23:14 +0100 (CET) Received: from ElouanLaptop.enseeiht.fr (unknown [147.127.122.15]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: elouan.appere@club-internet.fr) by msfrf2627.sfr.fr (SMTP Server) with ESMTPSA; Sat, 25 Mar 2017 23:23:13 +0100 (CET) Authentication-Results: sfr.fr; auth=pass (LOGIN) smtp.auth=elouan.appere@club-internet.fr From: Elouan Appere To: gdb-patches@sourceware.org Cc: Elouan Appere Subject: [PATCH] Add proper single-step support for arm-none-eabi Date: Sat, 25 Mar 2017 23:23:11 +0100 Message-Id: <20170325222311.10596-1-elouan.appere@club-internet.fr> X-sfr-mailing: LEGIT MIME-Version: 1.0 This commit adds proper support for single-stepping on arm-none-eabi. arm_software_single_step is now always registered in arm_gdbarch_init (arm-tdep.c) before calling gdbarch_osabi_init. Additionally, arm_software_single_step now checks whether or not the target supports single-stepping itself (which is the case for most simulators, emulators, etc.). Following this change, we need to assume, without the knowledge the OS (if there is one), that SVC instructions return to the next user-mode instructions by default (arm_get_next_pcs_syscall_next_pc currently returns 0 which is virtually guaranteed to fail). gdb/Changelog: * arm-tdep.c (arm_software_single_step): Check whether the target actually has declared single-step support. Declare this function static. (arm_get_next_pcs_syscall_next_pc): Assume that SVC instructions return to the next user-mode instruction by default. (arm_gdbarch_init): register arm_software_single_step with set_gdbarch_software_single_step before calling gdbarch_osabi_init. * arm-tdep.h: remove the prototype of function arm_software_single_step accordingly to the changes above. * arm-nbsd-tdep.c: (arm_netbsd_init_eabi): Remove redundant call to set_gdbarch_software_single_step. * arm-obsd-tdep.c: (armobsd_init_eabi): Likewise. * arm-wince-tdep.c: (arm_wince_init_abi): Likewise. --- gdb/arm-nbsd-tdep.c | 3 --- gdb/arm-obsd-tdep.c | 3 --- gdb/arm-tdep.c | 32 +++++++++++++++++++++++++++++--- gdb/arm-tdep.h | 1 - gdb/arm-wince-tdep.c | 3 --- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/gdb/arm-nbsd-tdep.c b/gdb/arm-nbsd-tdep.c index 92d368ccec..3cbc79403f 100644 --- a/gdb/arm-nbsd-tdep.c +++ b/gdb/arm-nbsd-tdep.c @@ -65,9 +65,6 @@ arm_netbsd_init_abi_common (struct gdbarch_info info, tdep->jb_pc = ARM_NBSD_JB_PC; tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE; - - /* Single stepping. */ - set_gdbarch_software_single_step (gdbarch, arm_software_single_step); } static void diff --git a/gdb/arm-obsd-tdep.c b/gdb/arm-obsd-tdep.c index 6db5487020..73d068eff7 100644 --- a/gdb/arm-obsd-tdep.c +++ b/gdb/arm-obsd-tdep.c @@ -97,9 +97,6 @@ armobsd_init_abi (struct gdbarch_info info, /* OpenBSD/arm uses -fpcc-struct-return by default. */ tdep->struct_return = pcc_struct_return; - /* Single stepping. */ - set_gdbarch_software_single_step (gdbarch, arm_software_single_step); - /* Breakpoints. */ switch (info.byte_order) { diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 09f7b3a635..fa6eafd552 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -6279,7 +6279,24 @@ arm_get_next_pcs_addr_bits_remove (struct arm_get_next_pcs *self, static CORE_ADDR arm_get_next_pcs_syscall_next_pc (struct arm_get_next_pcs *self) { - return 0; + CORE_ADDR next_pc = 0; + CORE_ADDR pc = regcache_read_pc (self->regcache); + int is_thumb = arm_is_thumb (self->regcache); + + /* Without the knowledge of the OS (if any) we need to assume that the next + user-mode instruction is executed */ + + if (is_thumb) + { + next_pc = pc + 2; + } + + else + { + next_pc = pc + 4; + } + + return next_pc; } /* Wrapper over arm_is_thumb for use in arm_get_next_pcs. */ @@ -6295,7 +6312,7 @@ 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. */ -VEC (CORE_ADDR) * +static VEC (CORE_ADDR) * arm_software_single_step (struct regcache *regcache) { struct gdbarch *gdbarch = get_regcache_arch (regcache); @@ -6303,7 +6320,14 @@ arm_software_single_step (struct regcache *regcache) CORE_ADDR pc; int i; VEC (CORE_ADDR) *next_pcs = NULL; - struct cleanup *old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs); + 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 NULL; + + old_chain = make_cleanup (VEC_cleanup (CORE_ADDR), &next_pcs); arm_get_next_pcs_ctor (&next_pcs_ctx, &arm_get_next_pcs_ops, @@ -9452,6 +9476,8 @@ arm_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches) set_gdbarch_sw_breakpoint_from_kind (gdbarch, arm_sw_breakpoint_from_kind); set_gdbarch_breakpoint_kind_from_current_state (gdbarch, arm_breakpoint_kind_from_current_state); + set_gdbarch_software_single_step (gdbarch, arm_software_single_step); + /* Information about registers, etc. */ set_gdbarch_sp_regnum (gdbarch, ARM_SP_REGNUM); diff --git a/gdb/arm-tdep.h b/gdb/arm-tdep.h index 8125226362..bbc3809c35 100644 --- a/gdb/arm-tdep.h +++ b/gdb/arm-tdep.h @@ -259,7 +259,6 @@ 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); -VEC (CORE_ADDR) *arm_software_single_step (struct regcache *); int arm_is_thumb (struct regcache *regcache); int arm_frame_is_thumb (struct frame_info *frame); diff --git a/gdb/arm-wince-tdep.c b/gdb/arm-wince-tdep.c index 76bf08fd60..7286925ac8 100644 --- a/gdb/arm-wince-tdep.c +++ b/gdb/arm-wince-tdep.c @@ -136,9 +136,6 @@ arm_wince_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Shared library handling. */ set_gdbarch_skip_trampoline_code (gdbarch, arm_pe_skip_trampoline_code); - /* Single stepping. */ - set_gdbarch_software_single_step (gdbarch, arm_software_single_step); - /* Skip call to __gccmain that gcc places in main. */ set_gdbarch_skip_main_prologue (gdbarch, arm_wince_skip_main_prologue); }