--- 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. */