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 support for ARMv7M devices.


Hi,

Attached is a patch to add support for ARMv7M devices.

The patch is bigger than it really is due to the signature change to
arm_pc_is_thumb.

Here are some highlights:

- arm_pc_is_thumb always returns 1 if the target is an ARMv7M device.

- arm_write_pc is adjusted so that it will set the Thumb bit in XPSR
  for an ARMv7M device.  Note that the position of Thumb bit in the
  status register is different between ARMv7M devices and older
  devices.

- arm_gdbarch_init looks for "org.gnu.gdb.arm.core-v7m".

Tested by running Hello, world on a Cortex-M3 device.  OK to apply?

Kazu Hirata

2010-06-08  Daniel Jacobowitz  <dan@codesourcery.com>
	    Kazu Hirata  <kazu@codesourcery.com>

	* arm-tdep.c (arm_pc_is_thumb): Return 1 if the target is an
	M-profile device.
	(arm_write_pc): Handle an M-profile device.
	(arm_gdbarch_init): Handle an M-profile device.
	* arm-tdep.h (XPSR_T): New.
	(gdbarch_tdep): Add is_m.

Index: gdb/arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.304
diff -u -d -p -r1.304 arm-tdep.c
--- gdb/arm-tdep.c	27 May 2010 19:06:12 -0000	1.304
+++ gdb/arm-tdep.c	9 Jun 2010 03:12:16 -0000
@@ -347,12 +347,16 @@ static CORE_ADDR arm_get_next_pc_raw (st
    any executing frame; otherwise, prefer arm_frame_is_thumb.  */
 
 static int
-arm_pc_is_thumb (CORE_ADDR memaddr)
+arm_pc_is_thumb (struct gdbarch *gdbarch, CORE_ADDR memaddr)
 {
   struct obj_section *sec;
   struct minimal_symbol *sym;
   char type;
 
+  /* ARMv7M is always in Thumb mode.  */
+  if (gdbarch_tdep (gdbarch)->is_m)
+    return 1;
+
   /* If bit 0 of the address is set, assume this is a Thumb address.  */
   if (IS_THUMB_ADDR (memaddr))
     return 1;
@@ -815,7 +819,7 @@ arm_skip_prologue (struct gdbarch *gdbar
 	     associate prologue code with the opening brace; so this
 	     lets us skip the first line if we think it is the opening
 	     brace.  */
-	  if (arm_pc_is_thumb (func_addr))
+	  if (arm_pc_is_thumb (gdbarch, func_addr))
 	    analyzed_limit = thumb_analyze_prologue (gdbarch, func_addr,
 						     post_prologue_pc, NULL);
 	  else
@@ -842,7 +846,7 @@ arm_skip_prologue (struct gdbarch *gdbar
 
 
   /* Check if this is Thumb code.  */
-  if (arm_pc_is_thumb (pc))
+  if (arm_pc_is_thumb (gdbarch, pc))
     return thumb_analyze_prologue (gdbarch, pc, limit_pc, NULL);
 
   for (skip_pc = pc; skip_pc < limit_pc; skip_pc += 4)
@@ -2008,7 +2012,7 @@ arm_push_dummy_call (struct gdbarch *gdb
 
   /* Set the return address.  For the ARM, the return breakpoint is
      always at BP_ADDR.  */
-  if (arm_pc_is_thumb (bp_addr))
+  if (arm_pc_is_thumb (gdbarch, bp_addr))
     bp_addr |= 1;
   regcache_cooked_write_unsigned (regcache, ARM_LR_REGNUM, bp_addr);
 
@@ -2147,7 +2151,7 @@ arm_push_dummy_call (struct gdbarch *gdb
 	  && TYPE_CODE_FUNC == TYPE_CODE (target_type))
 	{
 	  CORE_ADDR regval = extract_unsigned_integer (val, len, byte_order);
-	  if (arm_pc_is_thumb (regval))
+	  if (arm_pc_is_thumb (gdbarch, regval))
 	    {
 	      bfd_byte *copy = alloca (len);
 	      store_unsigned_integer (copy, len, byte_order,
@@ -3352,7 +3356,7 @@ arm_adjust_breakpoint_address (struct gd
     return bpaddr;
 
   /* ARM mode does not have this problem.  */
-  if (!arm_pc_is_thumb (bpaddr))
+  if (!arm_pc_is_thumb (gdbarch, bpaddr))
     return bpaddr;
 
   /* We are setting a breakpoint in Thumb code that could potentially
@@ -5345,7 +5349,9 @@ arm_displaced_step_fixup (struct gdbarch
 static int
 gdb_print_insn_arm (bfd_vma memaddr, disassemble_info *info)
 {
-  if (arm_pc_is_thumb (memaddr))
+  struct gdbarch *gdbarch = info->application_data;
+
+  if (arm_pc_is_thumb (gdbarch, memaddr))
     {
       static asymbol *asym;
       static combined_entry_type ce;
@@ -5435,7 +5441,7 @@ arm_breakpoint_from_pc (struct gdbarch *
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
   enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch);
 
-  if (arm_pc_is_thumb (*pcptr))
+  if (arm_pc_is_thumb (gdbarch, *pcptr))
     {
       *pcptr = UNMAKE_THUMB_ADDR (*pcptr);
 
@@ -5474,7 +5480,7 @@ arm_remote_breakpoint_from_pc (struct gd
 
   arm_breakpoint_from_pc (gdbarch, pcptr, kindptr);
 
-  if (arm_pc_is_thumb (*pcptr) && *kindptr == 4)
+  if (arm_pc_is_thumb (gdbarch, *pcptr) && *kindptr == 4)
     /* The documented magic value for a 32-bit Thumb-2 breakpoint, so
        that this is not confused with a 32-bit ARM breakpoint.  */
     *kindptr = 3;
@@ -6219,6 +6225,7 @@ arm_record_special_symbol (struct gdbarc
 static void
 arm_write_pc (struct regcache *regcache, CORE_ADDR pc)
 {
+  struct gdbarch *gdbarch = get_regcache_arch (regcache);
   regcache_cooked_write_unsigned (regcache, ARM_PC_REGNUM, pc);
 
   /* If necessary, set the T bit.  */
@@ -6226,11 +6233,18 @@ arm_write_pc (struct regcache *regcache,
     {
       ULONGEST val;
       regcache_cooked_read_unsigned (regcache, ARM_PS_REGNUM, &val);
-      if (arm_pc_is_thumb (pc))
-	regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM, val | CPSR_T);
+      if (!gdbarch_tdep (gdbarch)->is_m)
+	{
+	  if (arm_pc_is_thumb (gdbarch, pc))
+	    regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM,
+					    val | CPSR_T);
+	  else
+	    regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM,
+					    val & ~(ULONGEST) CPSR_T);
+	}
       else
 	regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM,
-					val & ~(ULONGEST) CPSR_T);
+					val | XPSR_T);
     }
 }
 
@@ -6411,7 +6425,7 @@ arm_gdbarch_init (struct gdbarch_info in
   enum arm_abi_kind arm_abi = arm_abi_global;
   enum arm_float_model fp_model = arm_fp_model;
   struct tdesc_arch_data *tdesc_data = NULL;
-  int i;
+  int i, is_m = 0;
   int have_vfp_registers = 0, have_vfp_pseudos = 0, have_neon_pseudos = 0;
   int have_neon = 0;
   int have_fpa_registers = 1;
@@ -6431,7 +6445,14 @@ arm_gdbarch_init (struct gdbarch_info in
       feature = tdesc_find_feature (info.target_desc,
 				    "org.gnu.gdb.arm.core");
       if (feature == NULL)
-	return NULL;
+	{
+	  feature = tdesc_find_feature (info.target_desc,
+					"org.gnu.gdb.arm.core-v7m");
+	  if (feature == NULL)
+	    return NULL;
+	  else
+	    is_m = 1;
+	}
 
       tdesc_data = tdesc_data_alloc ();
 
@@ -6448,8 +6469,12 @@ arm_gdbarch_init (struct gdbarch_info in
       valid_p &= tdesc_numbered_register_choices (feature, tdesc_data,
 						  ARM_PC_REGNUM,
 						  arm_pc_names);
-      valid_p &= tdesc_numbered_register (feature, tdesc_data,
-					  ARM_PS_REGNUM, "cpsr");
+      if (is_m)
+	valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					    ARM_PS_REGNUM, "xPSR");
+      else
+	valid_p &= tdesc_numbered_register (feature, tdesc_data,
+					    ARM_PS_REGNUM, "cpsr");
 
       if (!valid_p)
 	{
@@ -6735,6 +6760,7 @@ arm_gdbarch_init (struct gdbarch_info in
      These are gdbarch discriminators, like the OSABI.  */
   tdep->arm_abi = arm_abi;
   tdep->fp_model = fp_model;
+  tdep->is_m = is_m;
   tdep->have_fpa_registers = have_fpa_registers;
   tdep->have_vfp_registers = have_vfp_registers;
   tdep->have_vfp_pseudos = have_vfp_pseudos;
Index: gdb/arm-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.h,v
retrieving revision 1.40
diff -u -d -p -r1.40 arm-tdep.h
--- gdb/arm-tdep.h	12 Apr 2010 13:52:43 -0000	1.40
+++ gdb/arm-tdep.h	9 Jun 2010 03:12:16 -0000
@@ -108,6 +108,8 @@ enum gdb_regnum {
 
 #define CPSR_T		0x20
 
+#define XPSR_T		0x01000000
+
 /* Type of floating-point code in use by inferior.  There are really 3 models
    that are traditionally supported (plus the endianness issue), but gcc can
    only generate 2 of those.  The third is APCS_FLOAT, where arguments to
@@ -163,6 +165,7 @@ struct gdbarch_tdep
 				   have_vfp_pseudos.  */
   int have_neon;		/* Do we have a NEON unit?  */
 
+  int is_m;			/* Does the target follow the "M" profile.  */
   CORE_ADDR lowest_pc;		/* Lowest address at which instructions 
 				   will appear.  */
 


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