From: Jonathan Larmour <jifl@eCosCentric.com>
To: gdb-patches@sourceware.org
Subject: Cortex-M CPSR thumb bit fix
Date: Thu, 08 Jul 2010 19:26:00 -0000 [thread overview]
Message-ID: <4C362657.9040001@eCosCentric.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 1255 bytes --]
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 <jifl@eCosCentric.com>
* 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
[-- Attachment #2: arm.patch --]
[-- Type: text/plain, Size: 7451 bytes --]
--- 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. */
next reply other threads:[~2010-07-08 19:26 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-07-08 19:26 Jonathan Larmour [this message]
2010-07-08 21:37 ` Daniel Jacobowitz
2010-07-09 3:43 ` Jonathan Larmour
2010-07-09 3:51 ` Daniel Jacobowitz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C362657.9040001@eCosCentric.com \
--to=jifl@ecoscentric.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox