[RFC,5/5] HACK frame inner than comparison for Arm M-profile sec ext
Commit Message
!!This change is not intended to be merged to the GDB code!!
Arm M-profile can use two stacks or four stack with the security
extension. core_addr_lessthan() used in set_gdbarch_inner_than()
can break stack unwinding with a false warning
"previous frame inner to this frame (corrupt stack?)"
when the active stack is switched to another one located below
the first one.
Unfortunately the settable comparison function used
in set_gdbarch_inner_than() takes just lhs and rhs addresses as arguments.
Therefore the possibility to avoid the comparison of addresses
from two different stack is very limited or impossible.
This hack abuses the internal RAM mapping to non-secure and secure/callable
areas used in STM32L5 device to prevent false unwinding fails
when switching secure/non-secure mode.
How to solve the problem correctly? Please advise...
Add a settable value
"set arm unwind-inner-check 0"
to switch off the inner frame check on user request?
Rework frame_id_inner() and gdbarch to allow a smarter comparator
with access to frame details?
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
---
gdb/arm-tdep.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
@@ -876,6 +876,16 @@ class target_arm_instruction_reader : public arm_instruction_reader
}
}
+static int
+arm_m_sec_ext_inner_than (CORE_ADDR lhs, CORE_ADDR rhs)
+{
+ if ((lhs & 0xfff00000) == 0x20000000
+ && (rhs & 0xfff00000) == 0x30000000)
+ return false;
+
+ return (lhs < rhs);
+}
+
/* Remove useless bits from addresses in a running program. */
static CORE_ADDR
arm_addr_bits_remove (struct gdbarch *gdbarch, CORE_ADDR val)
@@ -10725,7 +10735,9 @@ enum arm_vfp_cprc_base_type
set_gdbarch_skip_trampoline_code (gdbarch, arm_skip_stub);
/* The stack grows downward. */
- set_gdbarch_inner_than (gdbarch, core_addr_lessthan);
+ set_gdbarch_inner_than (gdbarch, have_sec_ext ?
+ arm_m_sec_ext_inner_than :
+ core_addr_lessthan);
/* Breakpoint manipulation. */
set_gdbarch_breakpoint_kind_from_pc (gdbarch, arm_breakpoint_kind_from_pc);