This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add proper single-step support for arm-none-eabi


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);
 }
-- 
2.12.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]