From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1511 invoked by alias); 9 Jun 2010 14:03:38 -0000 Received: (qmail 30510 invoked by uid 22791); 9 Jun 2010 14:03:18 -0000 X-SWARE-Spam-Status: No, hits= required= tests= Received: from gateway.codesourcery.com (HELO henry1.codesourcery.com) (38.113.113.105) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 09 Jun 2010 14:03:15 +0000 Received: by henry1.codesourcery.com (Postfix, from userid 1009) id 291855664EF; Wed, 9 Jun 2010 07:03:12 -0700 (PDT) To: gdb-patches@sourceware.org CC: dan@codesourcery.com Subject: [patch] Add support for ARMv7M devices. Message-Id: <20100609140312.291855664EF@henry1.codesourcery.com> Date: Wed, 09 Jun 2010 14:03:00 -0000 From: kazu@codesourcery.com (Kazu Hirata) Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2010-06/txt/msg00229.txt.bz2 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 Kazu Hirata * 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. */