From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13513 invoked by alias); 8 Jul 2010 19:26:36 -0000 Received: (qmail 13499 invoked by uid 22791); 8 Jul 2010 19:26:34 -0000 X-SWARE-Spam-Status: No, hits=-0.4 required=5.0 tests=AWL,BAYES_50,TW_EG,TW_VF,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from hagrid.ecoscentric.com (HELO mail.ecoscentric.com) (212.13.207.197) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 08 Jul 2010 19:26:27 +0000 Received: from localhost (hagrid.ecoscentric.com [127.0.0.1]) by mail.ecoscentric.com (Postfix) with ESMTP id D7E542F78004 for ; Thu, 8 Jul 2010 20:26:24 +0100 (BST) Received: from mail.ecoscentric.com ([127.0.0.1]) by localhost (hagrid.ecoscentric.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3bBFHtrcgU8e; Thu, 8 Jul 2010 20:26:19 +0100 (BST) Message-ID: <4C362657.9040001@eCosCentric.com> Date: Thu, 08 Jul 2010 19:26:00 -0000 From: Jonathan Larmour User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100430 Fedora/3.0.4-2.fc12 Lightning/1.0b2pre Thunderbird/3.0.4 MIME-Version: 1.0 To: gdb-patches@sourceware.org Subject: Cortex-M CPSR thumb bit fix Content-Type: multipart/mixed; boundary="------------020801080303030402060007" 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-07/txt/msg00158.txt.bz2 This is a multi-part message in MIME format. --------------020801080303030402060007 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-length: 1255 I posted a patch in 2008 here: http://sourceware.org/ml/gdb-patches/2008-10/msg00462.html but unfortunately it wasn't applied. Without it, GDB cannot debug Cortex-M processors as the thumb bit is in a different place in the CPSR register. I have updated it for GDB 7.1, as per the attached mail and updated ChangeLog below. I do have a copyright assignment, as well as the ability to commit. Can someone review please? Jifl 2010-07-08 Jonathan Larmour * arm-tdep.h (CPSR_T): define as function-like macro, checking for M-profile, which affects T_bit position, e.g. for Cortex-M. (struct gdbarch_tdep): add arm_eabi_cpu_arch and arm_eabi_cpu_arch_profile members. * arm-tdep.c (arm_frame_is_thumb, arm_prologue_prev_register, arm_dwarf2_prev_register, displaced_in_arm_mode, bx_write_pc, arm_write_pc): Get tdep and use with updated CPSR_T macro. (arm_gdbarch_init): If EABI, extract architecture and profile attributes and store in tdep. -- eCosCentric Limited http://www.eCosCentric.com/ The eCos experts Barnwell House, Barnwell Drive, Cambridge, UK. Tel: +44 1223 245571 Registered in England and Wales: Reg No 4422071. ------["Si fractum non sit, noli id reficere"]------ Opinions==mine --------------020801080303030402060007 Content-Type: text/plain; name="arm.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="arm.patch" Content-length: 7451 --- gdb-7.1.clean/gdb/arm-tdep.c 2010-02-26 20:45:33.000000000 +0000 +++ gdb-7.1/gdb/arm-tdep.c 2010-06-23 04:17:50.000000000 +0100 @@ -256,6 +256,7 @@ static int arm_frame_is_thumb (struct frame_info *frame) { CORE_ADDR cpsr; + struct gdbarch_tdep *tdep = gdbarch_tdep(get_frame_arch(frame)); /* Every ARM frame unwinder can unwind the T bit of the CPSR, either directly (from a signal frame or dummy frame) or by interpreting @@ -263,7 +264,7 @@ arm_frame_is_thumb (struct frame_info *f trust the unwinders. */ cpsr = get_frame_register_unsigned (frame, ARM_PS_REGNUM); - return (cpsr & CPSR_T) != 0; + return (cpsr & CPSR_T(tdep)) != 0; } /* Callback for VEC_lower_bound. */ @@ -1113,6 +1114,7 @@ arm_prologue_prev_register (struct frame int prev_regnum) { struct gdbarch *gdbarch = get_frame_arch (this_frame); + struct gdbarch_tdep *tdep = gdbarch_tdep(gdbarch); struct arm_prologue_cache *cache; if (*this_cache == NULL) @@ -1154,9 +1156,9 @@ arm_prologue_prev_register (struct frame cpsr = get_frame_register_unsigned (this_frame, prev_regnum); lr = frame_unwind_register_unsigned (this_frame, ARM_LR_REGNUM); if (IS_THUMB_ADDR (lr)) - cpsr |= CPSR_T; + cpsr |= CPSR_T(tdep); else - cpsr &= ~CPSR_T; + cpsr &= ~CPSR_T(tdep); return frame_unwind_got_constant (this_frame, prev_regnum, cpsr); } @@ -1283,6 +1285,7 @@ arm_dwarf2_prev_register (struct frame_i { struct gdbarch * gdbarch = get_frame_arch (this_frame); CORE_ADDR lr, cpsr; + struct gdbarch_tdep *tdep = gdbarch_tdep(gdbarch); switch (regnum) { @@ -1300,9 +1303,9 @@ arm_dwarf2_prev_register (struct frame_i cpsr = get_frame_register_unsigned (this_frame, regnum); lr = frame_unwind_register_unsigned (this_frame, ARM_LR_REGNUM); if (IS_THUMB_ADDR (lr)) - cpsr |= CPSR_T; + cpsr |= CPSR_T(tdep); else - cpsr &= ~CPSR_T; + cpsr &= ~CPSR_T(tdep); return frame_unwind_got_constant (this_frame, regnum, cpsr); default: @@ -3185,11 +3188,12 @@ displaced_read_reg (struct regcache *reg static int displaced_in_arm_mode (struct regcache *regs) { + struct gdbarch_tdep *tdep = gdbarch_tdep(get_regcache_arch(regs)); ULONGEST ps; regcache_cooked_read_unsigned (regs, ARM_PS_REGNUM, &ps); - return (ps & CPSR_T) == 0; + return (ps & CPSR_T(tdep)) == 0; } /* Write to the PC as from a branch instruction. */ @@ -3210,19 +3214,20 @@ branch_write_pc (struct regcache *regs, static void bx_write_pc (struct regcache *regs, ULONGEST val) { + struct gdbarch_tdep *tdep = gdbarch_tdep(get_regcache_arch(regs)); ULONGEST ps; regcache_cooked_read_unsigned (regs, ARM_PS_REGNUM, &ps); if ((val & 1) == 1) { - regcache_cooked_write_unsigned (regs, ARM_PS_REGNUM, ps | CPSR_T); + regcache_cooked_write_unsigned (regs, ARM_PS_REGNUM, ps | CPSR_T(tdep)); regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM, val & 0xfffffffe); } else if ((val & 2) == 0) { regcache_cooked_write_unsigned (regs, ARM_PS_REGNUM, - ps & ~(ULONGEST) CPSR_T); + ps & ~(ULONGEST) CPSR_T(tdep)); regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM, val); } else @@ -3231,7 +3236,7 @@ bx_write_pc (struct regcache *regs, ULON mode, align dest to 4 bytes). */ warning (_("Single-stepping BX to non-word-aligned ARM instruction.")); regcache_cooked_write_unsigned (regs, ARM_PS_REGNUM, - ps & ~(ULONGEST) CPSR_T); + ps & ~(ULONGEST) CPSR_T(tdep)); regcache_cooked_write_unsigned (regs, ARM_PC_REGNUM, val & 0xfffffffc); } } @@ -5862,6 +5867,8 @@ arm_record_special_symbol (struct gdbarc static void arm_write_pc (struct regcache *regcache, CORE_ADDR pc) { + struct gdbarch_tdep *tdep = gdbarch_tdep(get_regcache_arch(regcache)); + regcache_cooked_write_unsigned (regcache, ARM_PC_REGNUM, pc); /* If necessary, set the T bit. */ @@ -5870,10 +5877,10 @@ 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); + regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM, val | CPSR_T(tdep)); else regcache_cooked_write_unsigned (regcache, ARM_PS_REGNUM, - val & ~(ULONGEST) CPSR_T); + val & ~(ULONGEST) CPSR_T(tdep)); } } @@ -6058,6 +6065,8 @@ arm_gdbarch_init (struct gdbarch_info in int have_vfp_registers = 0, have_vfp_pseudos = 0, have_neon_pseudos = 0; int have_neon = 0; int have_fpa_registers = 1; + int arm_eabi_cpu_arch = -1; + int arm_eabi_cpu_arch_profile = -1; /* Check any target description for validity. */ if (tdesc_has_registers (info.target_desc)) @@ -6248,6 +6257,7 @@ arm_gdbarch_init (struct gdbarch_info in else if (ei_osabi == ELFOSABI_NONE) { int eabi_ver = EF_ARM_EABI_VERSION (e_flags); + int attr; switch (eabi_ver) { @@ -6305,8 +6315,24 @@ arm_gdbarch_init (struct gdbarch_info in warning (_("unknown ARM EABI version 0x%x"), eabi_ver); break; } - } + /* Cortex-M has different CPSR layout. Use object tags to determine + * if this was generated for the Microcontroller (M) profile. + * Cortex-A has a CPSR like previous ARM cores. + * Cortex-R is unknown. + */ + + attr = bfd_elf_get_obj_attr_int(info.abfd, OBJ_ATTR_PROC, Tag_CPU_arch); + if (attr > 0) + arm_eabi_cpu_arch = attr; + if (arm_eabi_cpu_arch >= TAG_CPU_ARCH_V7) /* Profile n/a before V7 */ + { + attr = bfd_elf_get_obj_attr_int(info.abfd, OBJ_ATTR_PROC, Tag_CPU_arch_profile); + if (attr > 0) + arm_eabi_cpu_arch_profile = attr; + } + + } if (fp_model == ARM_FLOAT_AUTO) { int e_flags = elf_elfheader (info.abfd)->e_flags; @@ -6383,6 +6409,8 @@ arm_gdbarch_init (struct gdbarch_info in tdep->have_vfp_pseudos = have_vfp_pseudos; tdep->have_neon_pseudos = have_neon_pseudos; tdep->have_neon = have_neon; + tdep->arm_eabi_cpu_arch = arm_eabi_cpu_arch; + tdep->arm_eabi_cpu_arch_profile = arm_eabi_cpu_arch_profile; /* Breakpoints. */ switch (info.byte_order_for_code) --- gdb-7.1.clean/gdb/arm-tdep.h 2010-02-01 16:13:15.000000000 +0000 +++ gdb-7.1/gdb/arm-tdep.h 2010-06-23 03:34:34.000000000 +0100 @@ -105,7 +105,8 @@ enum gdb_regnum { #define FLAG_C 0x20000000 #define FLAG_V 0x10000000 -#define CPSR_T 0x20 +/* CPSR T-bit for Architecture v7+ Microcontroller Profile is different from others */ +#define CPSR_T(tdep) ((tdep)->arm_eabi_cpu_arch_profile==(int)'M' ? 0x01000000 : 0x20) /* 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 @@ -192,6 +193,9 @@ struct gdbarch_tdep struct type *arm_ext_type; struct type *neon_double_type; struct type *neon_quad_type; + + int arm_eabi_cpu_arch; /* Arch version from EABI attribute (-1 == unknown) */ + int arm_eabi_cpu_arch_profile; /* Arch profile from EABI attribute (-1 == unknown) */ }; /* Structures used for displaced stepping. */ --------------020801080303030402060007--