RFC: Use the ARM CPSR as a fallback to determine ARM/Thumb

Daniel Jacobowitz
2006-02-20T21:49:22Z

I'm fishing for comments on this change. In arm_pc_is_thumb, if we can not
find a symbol covering the supplied PC, we assume ARM mode; it seems that it
would be strictly more useful to assume the current mode.

This patch _should not be used_ as is! Paul Brook cleverly noticed that
this will mess up breakpoint_from_pc when removing breakpoints, causing us
to insert 2-byte breakpoints and remove 4-byte ones across a mode switch.
I'm going to have to mess with the target_remove_breakpoint interface
to fix that, so I wanted to get opinions on this patch first before I dig
in.

This is still a somewhat creepy thing to do. You can find quotes of me in
the gdb@ list archives saying that this is "the way to madness". However,
I've been debugging some code which jumps to Thumb-mode routines in ROM
today, and my GDB doesn't yet have symbol information for the ROM code; so
I'm well down the way to madness without this patch, and it's somewhat
better with.

Maybe there should be a "set" option for the default when no symbol is
found, allowing the user to throttle this back to ARM-only if that works
better for them?

--
Daniel Jacobowitz
CodeSourcery

2006-02-20 Daniel Jacobowitz <dan@codesourcery.com>

* arm-tdep.c (arm_pc_is_thumb): Fall back to the CPSR.

NOTE: NOT FOR COMMIT

Index: src/gdb/arm-tdep.c
===================================================================
--- src.orig/gdb/arm-tdep.c 2006-02-02 15:38:35.000000000 -0500
+++ src/gdb/arm-tdep.c 2006-02-20 16:11:02.000000000 -0500
@@ -184,13 +184,15 @@ arm_pc_is_thumb (CORE_ADDR memaddr)
/* Thumb functions have a "special" bit set in minimal symbols. */
sym = lookup_minimal_symbol_by_pc (memaddr);
if (sym)
- {
- return (MSYMBOL_IS_SPECIAL (sym));
- }
- else
- {
- return 0;
- }
+ return (MSYMBOL_IS_SPECIAL (sym));
+
+ /* If we couldn't find any symbol, but we're talking to a running
+ target, then trust the current value of $cpsr. */
+ if (target_has_registers)
+ return (read_register (ARM_PS_REGNUM) & 0x20) != 0;
+
+ /* Otherwise we're out of luck; we assume ARM. */
+ return 0;
}

/* Remove useless bits from addresses in a running program. */