This is the mail archive of the gdb-patches@sources.redhat.com 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]

[patch]: Software single-stepping on ARMs



This patch enables support for software single-stepping on ARM processors.  This is required for NetBSD, and a good idea on some older linux kernels, where single-stepping tended to work erratically.

<date> Richard Earnshaw <rearnsha@arm.com>

	* arm-tdep.c (arm_software_single_step): New function.
	(arm_get_next_pc, thumb_get_next_pc, bitcount, shifted_reg_val): Only
	needed for software single-stepping.
	


Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.16
diff -p -r1.16 arm-tdep.c
*** arm-tdep.c	2001/10/21 17:19:36	1.16
--- arm-tdep.c	2001/10/22 11:05:08
*************** condition_true (unsigned long cond, unsi
*** 1542,1547 ****
--- 1597,1604 ----
    return 1;
  }
  
+ #if SOFTWARE_SINGLE_STEP_P
+ /* Support routines for single stepping.  Calculate the next PC value.  */
  #define submask(x) ((1L << ((x) + 1)) - 1)
  #define bit(obj,st) (((obj) >> (st)) & 1)
  #define bits(obj,st,fn) (((obj) >> (st)) & submask ((fn) - (st)))
*************** arm_get_next_pc (CORE_ADDR pc)
*** 1875,1880 ****
--- 1949,1980 ----
  
    return nextpc;
  }
+ 
+ /* 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.  */
+ 
+ void
+ arm_software_single_step (ignore, insert_bpt)
+      int ignore; /* Signal, not needed */
+      int insert_bpt;
+ {
+   static int next_pc; /* State between setting and unsetting. */
+   static char break_mem[BREAKPOINT_MAX]; /* Temporary storage for mem@bpt */
+ 
+   if (insert_bpt)
+     {
+       next_pc = arm_get_next_pc (read_register (PC_REGNUM));
+       target_insert_breakpoint (next_pc, &break_mem);
+     }
+   else
+     target_remove_breakpoint (next_pc, &break_mem);
+ }
+ #endif /* SOFTWARE_SINGLE_STEP_P */
  
  #include "bfd-in2.h"
  #include "libcoff.h"
Index: config/arm/tm-arm.h
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/tm-arm.h,v
retrieving revision 1.7
diff -p -r1.7 tm-arm.h
*** tm-arm.h	2001/07/04 19:57:53	1.7
--- tm-arm.h	2001/10/22 11:05:49
*************** extern CORE_ADDR arm_saved_pc_after_call
*** 96,104 ****
     Even this may only true if the condition predicate is true. The
     following use a condition predicate of ALWAYS so it is always TRUE.
     
!    There are other ways of forcing a breakpoint.  ARM Linux, RisciX,
!    and I suspect NetBSD will all use a software interrupt rather than
!    an undefined instruction to force a trap.  This can be handled by
     redefining some or all of the following in a target dependent
     fashion.  */
  
--- 96,104 ----
     Even this may only true if the condition predicate is true. The
     following use a condition predicate of ALWAYS so it is always TRUE.
     
!    There are other ways of forcing a breakpoint.  ARM Linux, RISC iX,
!    and NetBSD will all use a software interrupt rather than an
!    undefined instruction to force a trap.  This can be handled by
     redefining some or all of the following in a target dependent
     fashion.  */
  
*************** extern int arm_call_dummy_breakpoint_off
*** 474,479 ****
--- 498,513 ----
  void arm_fix_call_dummy (char *dummy, CORE_ADDR pc, CORE_ADDR fun,
  			 int nargs, struct value ** args,
  			 struct type * type, int gcc_p);
+ 
+ /* Most ARMs don't have single stepping capability, so provide a 
+    single-stepping mechanism by default */
+ #ifndef SOFTWARE_SINGLE_STEP_P
+ #define SOFTWARE_SINGLE_STEP_P 1
+ #endif
+ #if SOFTWARE_SINGLE_STEP_P
+ #define SOFTWARE_SINGLE_STEP(sig,bpt) arm_software_single_step((sig), (bpt))
+ void arm_software_single_step PARAMS((int, int));
+ #endif
  
  CORE_ADDR arm_get_next_pc (CORE_ADDR pc);
  

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