* linux-arm-low.c (thumb_breakpoint, thumb_breakpoint_len): New.

(arm_breakpoint_at): Handle Thumb.
	(the_low_target): Add comment.
This commit is contained in:
Daniel Jacobowitz 2008-06-04 19:51:51 +00:00
parent 83bd74026c
commit aeb75bf598
2 changed files with 37 additions and 9 deletions

View file

@ -1,3 +1,9 @@
2008-06-04 Daniel Jacobowitz <dan@codesourcery.com>
* 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 <uweigand@de.ibm.com> 2008-05-29 Ulrich Weigand <uweigand@de.ibm.com>
* linux-ppc-low.c (ppc_collect_ptrace_register): Clear buffer. * linux-ppc-low.c (ppc_collect_ptrace_register): Clear buffer.

View file

@ -136,9 +136,11 @@ arm_set_pc (CORE_ADDR pc)
supply_register_by_name ("pc", &newpc); 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; static const unsigned long arm_breakpoint = 0xef9f0001;
#define arm_breakpoint_len 4 #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 /* For new EABI binaries. We recognize it regardless of which ABI
is used for gdbserver, so single threaded debugging should work is used for gdbserver, so single threaded debugging should work
@ -149,6 +151,22 @@ static const unsigned long arm_eabi_breakpoint = 0xe7f001f0;
static int static int
arm_breakpoint_at (CORE_ADDR where) arm_breakpoint_at (CORE_ADDR where)
{ {
unsigned long cpsr;
collect_register_by_name ("cpsr", &cpsr);
if (cpsr & 0x20)
{
/* Thumb mode. */
unsigned short insn;
(*the_target->read_memory) (where, (unsigned char *) &insn, 2);
if (insn == thumb_breakpoint)
return 1;
}
else
{
/* ARM mode. */
unsigned long insn; unsigned long insn;
(*the_target->read_memory) (where, (unsigned char *) &insn, 4); (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
@ -157,9 +175,7 @@ arm_breakpoint_at (CORE_ADDR where)
if (insn == arm_eabi_breakpoint) if (insn == arm_eabi_breakpoint)
return 1; return 1;
}
/* If necessary, recognize more trap instructions here. GDB only uses the
two. */
return 0; return 0;
} }
@ -216,6 +232,12 @@ struct linux_target_ops the_low_target = {
arm_cannot_store_register, arm_cannot_store_register,
arm_get_pc, arm_get_pc,
arm_set_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__ #ifndef __ARM_EABI__
(const unsigned char *) &arm_breakpoint, (const unsigned char *) &arm_breakpoint,
#else #else