diff options
| author | bjh21 <bjh21@NetBSD.org> | 2001-10-25 20:55:13 +0000 |
|---|---|---|
| committer | bjh21 <bjh21@NetBSD.org> | 2001-10-25 20:55:13 +0000 |
| commit | b685397e2d2d99d8946bf79c836fbd85628cc29f (patch) | |
| tree | 2e035389b4d82533018568b0f1a4defb202385e0 | |
| parent | 786a6026c691bc5abe01d7201f13f800f83bd11a (diff) | |
When fetching registers, if CPSR is zero (and hence we've just fetched from
a 26-bit target), split R15 into PC and CPSR. Similarly, when storing
registers, copy CPSR back into R15 if CPSR indicates a 26-bit mode.
This makes single-stepping work correctly on arm26.
Also, when fetching registers, set arm_apcs_32 based on the mode the target's
in. This removes the need to kludge it manually. The variable should really
be lost entirely, and arm-tdep.c should look at the mode bits in CPSR, but
the ARM Linux target is horribly broken in this area, and will either need
fixing or working around.
| -rw-r--r-- | gnu/dist/toolchain/gdb/armnbsd-nat.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/gnu/dist/toolchain/gdb/armnbsd-nat.c b/gnu/dist/toolchain/gdb/armnbsd-nat.c index 523ef216098..acedc6c8984 100644 --- a/gnu/dist/toolchain/gdb/armnbsd-nat.c +++ b/gnu/dist/toolchain/gdb/armnbsd-nat.c @@ -28,6 +28,14 @@ #include <machine/frame.h> #include "inferior.h" +#define R15_PSR 0xfc000003 +#define R15_PC 0x03fffffc + +#define PSR_MODE_32 0x00000010 + +/* From arm-tdep.c */ +extern int arm_apcs_32; + void fetch_inferior_registers (regno) int regno; @@ -36,6 +44,13 @@ fetch_inferior_registers (regno) struct fpreg inferior_fpregisters; ptrace (PT_GETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &inferior_registers, 0); + if (inferior_registers.r_cpsr == 0) + { + /* 26-bit target: split PC and PSR out of R15. */ + inferior_registers.r_cpsr = inferior_registers.r_pc & R15_PSR; + inferior_registers.r_pc = inferior_registers.r_pc & R15_PC; + } + arm_apcs_32 = (inferior_registers.r_cpsr & PSR_MODE_32) != 0; memcpy (®isters[REGISTER_BYTE (0)], &inferior_registers, 16 * sizeof (unsigned int)); memcpy (®isters[REGISTER_BYTE (PS_REGNUM)], &inferior_registers.r_cpsr, @@ -59,6 +74,12 @@ store_inferior_registers (regno) 16 * sizeof (unsigned int)); memcpy (&inferior_registers.r_cpsr, ®isters[REGISTER_BYTE (PS_REGNUM)], sizeof (unsigned int)); + if ((inferior_registers.r_cpsr & PSR_MODE_32) == 0) + { + /* Target is in 26-bit mode. Merge PSR into R15. */ + inferior_registers.r_pc &= R15_PC; + inferior_registers.r_pc |= inferior_registers.r_cpsr & R15_PSR; + } ptrace (PT_SETREGS, inferior_pid, (PTRACE_ARG3_TYPE) &inferior_registers, 0); /* XXX Set FP regs. */ @@ -79,6 +100,13 @@ fetch_core_registers (core_reg_sect, core_reg_size, which, ignore) { struct md_core *core_reg = (struct md_core *) core_reg_sect; + if (core_reg->intreg.r_cpsr == 0) + { + /* 26-bit target: split PC and PSR out of R15. */ + core_reg->intreg.r_cpsr = core_reg->intreg.r_pc & R15_PSR; + core_reg->intreg.r_pc = core_reg->intreg.r_pc & R15_PC; + } + arm_apcs_32 = (core_reg->intreg.r_cpsr & PSR_MODE_32) != 0; /* integer registers */ memcpy (®isters[REGISTER_BYTE (0)], &core_reg->intreg, sizeof (struct reg)); @@ -95,25 +123,3 @@ get_longjmp_target (CORE_ADDR *addr) { return 0; } - -extern int arm_apcs_32; - -void -_initialize_armnbsd_nat (void) -{ - int mib[2]; - char machine[16]; - size_t len; - - /* XXX Grotty hack to guess whether this is a 26-bit system. This - should really be determined on the fly, to allow debugging a - 32-bit core on a 26-bit machine, or a 26-bit process on a 32-bit - machine. For now, users will just have to use "set apcs32" as - appropriate. */ - mib[0] = CTL_HW; - mib[1] = HW_MACHINE; - len = sizeof (machine); - if (sysctl (mib, 2, machine, &len, NULL, 0) == 0 && - strcmp (machine, "arm26") == 0) - arm_apcs_32 = 0; -} |
