From aeb75bf59899601bac25c58399dda7d4f171db6d Mon Sep 17 00:00:00 2001 From: Daniel Jacobowitz Date: Wed, 4 Jun 2008 19:51:51 +0000 Subject: [PATCH] * linux-arm-low.c (thumb_breakpoint, thumb_breakpoint_len): New. (arm_breakpoint_at): Handle Thumb. (the_low_target): Add comment. --- gdb/gdbserver/ChangeLog | 6 ++++++ gdb/gdbserver/linux-arm-low.c | 40 +++++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/gdb/gdbserver/ChangeLog b/gdb/gdbserver/ChangeLog index 7a7afcc61a1..72d857522e6 100644 --- a/gdb/gdbserver/ChangeLog +++ b/gdb/gdbserver/ChangeLog @@ -1,3 +1,9 @@ +2008-06-04 Daniel Jacobowitz + + * linux-arm-low.c (thumb_breakpoint, thumb_breakpoint_len): New. + (arm_breakpoint_at): Handle Thumb. + (the_low_target): Add comment. + 2008-05-29 Ulrich Weigand * linux-ppc-low.c (ppc_collect_ptrace_register): Clear buffer. diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c index d47ecbcbb6e..8aba59e2ba8 100644 --- a/gdb/gdbserver/linux-arm-low.c +++ b/gdb/gdbserver/linux-arm-low.c @@ -136,9 +136,11 @@ arm_set_pc (CORE_ADDR pc) supply_register_by_name ("pc", &newpc); } -/* Correct in either endianness. We do not support Thumb yet. */ +/* Correct in either endianness. */ static const unsigned long arm_breakpoint = 0xef9f0001; #define arm_breakpoint_len 4 +static const unsigned short thumb_breakpoint = 0xde01; +#define thumb_breakpoint_len 2 /* For new EABI binaries. We recognize it regardless of which ABI is used for gdbserver, so single threaded debugging should work @@ -149,17 +151,31 @@ static const unsigned long arm_eabi_breakpoint = 0xe7f001f0; static int arm_breakpoint_at (CORE_ADDR where) { - unsigned long insn; + unsigned long cpsr; - (*the_target->read_memory) (where, (unsigned char *) &insn, 4); - if (insn == arm_breakpoint) - return 1; + collect_register_by_name ("cpsr", &cpsr); - if (insn == arm_eabi_breakpoint) - return 1; + if (cpsr & 0x20) + { + /* Thumb mode. */ + unsigned short insn; - /* If necessary, recognize more trap instructions here. GDB only uses the - two. */ + (*the_target->read_memory) (where, (unsigned char *) &insn, 2); + if (insn == thumb_breakpoint) + return 1; + } + else + { + /* ARM mode. */ + unsigned long insn; + + (*the_target->read_memory) (where, (unsigned char *) &insn, 4); + if (insn == arm_breakpoint) + return 1; + + if (insn == arm_eabi_breakpoint) + return 1; + } return 0; } @@ -216,6 +232,12 @@ struct linux_target_ops the_low_target = { arm_cannot_store_register, arm_get_pc, arm_set_pc, + + /* Define an ARM-mode breakpoint; we only set breakpoints in the C + library, which is most likely to be ARM. If the kernel supports + clone events, we will never insert a breakpoint, so even a Thumb + C library will work; so will mixing EABI/non-EABI gdbserver and + application. */ #ifndef __ARM_EABI__ (const unsigned char *) &arm_breakpoint, #else -- 2.30.2