From: Jason R Thorpe <thorpej@wasabisystems.com>
To: gdb-patches@sources.redhat.com
Subject: [PATCH/RFA] arm-netbsdelf cross-debugging fixes
Date: Sun, 01 Sep 2002 16:58:00 -0000 [thread overview]
Message-ID: <20020901165843.B4034@dr-evil.shagadelic.org> (raw)
[-- Attachment #1: Type: text/plain, Size: 2242 bytes --]
This fixes a bunch of cross-debugging issues for the arm-netbsdelf
target, and makes it more like the other NetBSD targets I've worked
on recently.
Unfortunately, the change disables "gdb_multi_arch=yes" for the
arm-*-netbsd* entry in configure.tgt. The reason for this is that
the tm file needs to include "solib.h". As far as I can tell, no
platforms with shared libraries can be fully multi-arch until all
the solib stuff is multi-arch'd.
I need approval for a change to the shared ARM target code. I needed
to add a function to deconstruct/reconstruct the R15 register on the
26-bit ARM CPUs. The new functions:
* Split a 26-bit R15 into PC and a 32-bit-format PSR.
* Take a PC and a 32-bit-format PSR and combine them back
into a 26-bit R15.
While there, I also fixed a problem with arm_addr_bits_remove -- No
26-bit systems can run in Thumb mode, and so doing an arm_pc_is_thumb
on them is unnecessary (and could return incorrect results if debugging
code which runs in FIQ mode, since (pc & 1) == FIQ mode on those CPUs).
* Makefile.in (armnbsd_tdep_h): New header variable.
(armnbsd-nat.o): Remove $(gdbcore_h) from and
add $(armnbsd_tdep_h) to dependency list.
(armnbsd-tdep.o): Add $(gdbcore_h), $(regcache_h), $(target_h),
$(value_h), and $(armnbsd_tdep_h) to dependency list.
* arm-tdep.c (arm_addr_bits_remove): Don't check for Thumb mode
if arm_apcs_32 is false.
(arm_extract_26bit_r15, arm_store_26bit_r15): New functions.
* arm-tdep.h (arm_extract_26bit_r15, arm_store_26bit_r15): New
prototypes.
* armnbsd-nat.c: Rewrite.
* armnbsd-tdep.c (armnbsd_supply_reg, armnbsd_fill_reg)
(armnbsd_supply_fpreg, armnbsd_fill_fpreg)
(fetch_core_registers, fetch_elfcore_registers): New functions.
(_initialize_arm_netbsd_tdep): Register armnbsd_core_fns
and armnbsd_elfcore_fns.
* armnbsd-tdep.h: New file.
* configure.tgt (arm*-*-netbsd*): Don't get gdb_multi_arch. Add
a comment to explain why we can't do this yet.
* config/arm/nbsd.mt (TDEPFILES): Add corelow.o.
(TM_FILE): Set to tm-nbsd.h.
* config/arm/nbsdaout.mh (NATDEPFILES): Remove corelow.o.
* config/arm/nbsdelf.mh (NATDEPFILES): Likewise.
* config/arm/tm-nbsd.h: New file.
--
-- Jason R. Thorpe <thorpej@wasabisystems.com>
[-- Attachment #2: arm-gdb-patch --]
[-- Type: text/plain, Size: 30648 bytes --]
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.256
diff -c -r1.256 Makefile.in
*** Makefile.in 1 Sep 2002 23:24:19 -0000 1.256
--- Makefile.in 1 Sep 2002 23:51:47 -0000
***************
*** 611,616 ****
--- 611,617 ----
annotate_h = annotate.h $(symtab_h) $(gdbtypes_h)
arch_utils_h = arch-utils.h
arm_tdep_h = arm-tdep.h $(osabi_h)
+ armnbsd_tdep_h = armnbsd-tdep.h
ax_gdb_h = ax-gdb.h
ax_h = ax.h $(doublest_h)
bcache_h = bcache.h
***************
*** 1521,1529 ****
$(doublest_h) $(value_h) $(arch_utils_h) $(solib_svr4_h) \
$(arm_tdep_h) $(gdb_sim_arm_h) $(elf_bfd_h) $(coff_internal_h) \
$(elf_arm_h) $(gdb_assert_h) $(bfd_in2_h) $(libcoff_h)
! armnbsd-nat.o: armnbsd-nat.c $(defs_h) $(arm_tdep_h) $(inferior_h) \
! $(regcache_h) $(gdbcore_h)
! armnbsd-tdep.o: armnbsd-tdep.c $(defs_h) $(arm_tdep_h) $(nbsd_tdep_h) \
$(solib_svr4_h)
avr-tdep.o: avr-tdep.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) $(inferior_h) \
$(symfile_h) $(arch_utils_h) $(regcache_h) $(gdb_string_h)
--- 1522,1531 ----
$(doublest_h) $(value_h) $(arch_utils_h) $(solib_svr4_h) \
$(arm_tdep_h) $(gdb_sim_arm_h) $(elf_bfd_h) $(coff_internal_h) \
$(elf_arm_h) $(gdb_assert_h) $(bfd_in2_h) $(libcoff_h)
! armnbsd-nat.o: armnbsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \
! $(arm_tdep_h) $(armnbsd_tdep_h)
! armnbsd-tdep.o: armnbsd-tdep.c $(defs_h) $(gdbcore_h) $(regcache_h) \
! $(target_h) $(value_h) $(arm_tdep_h) $(armnbsd_tdep_h) $(nbsd_tdep_h) \
$(solib_svr4_h)
avr-tdep.o: avr-tdep.c $(defs_h) $(gdbcmd_h) $(gdbcore_h) $(inferior_h) \
$(symfile_h) $(arch_utils_h) $(regcache_h) $(gdb_string_h)
Index: arm-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.c,v
retrieving revision 1.69
diff -c -r1.69 arm-tdep.c
*** arm-tdep.c 24 Aug 2002 00:21:34 -0000 1.69
--- arm-tdep.c 1 Sep 2002 23:51:50 -0000
***************
*** 225,234 ****
static CORE_ADDR
arm_addr_bits_remove (CORE_ADDR val)
{
! if (arm_pc_is_thumb (val))
! return (val & (arm_apcs_32 ? 0xfffffffe : 0x03fffffe));
else
! return (val & (arm_apcs_32 ? 0xfffffffc : 0x03fffffc));
}
/* When reading symbols, we need to zap the low bit of the address,
--- 225,287 ----
static CORE_ADDR
arm_addr_bits_remove (CORE_ADDR val)
{
! if (arm_apcs_32)
! return (val & (arm_pc_is_thumb (val) ? 0xfffffffe : 0xfffffffc));
else
! return (val & 0x03fffffc);
! }
!
! /* These map to the corresponding bit positions in the 32-bit CPSR. */
! #define ARM26_R15_MODE 0x00000003
! #define ARM26_R15_FLAGS 0xf0000000
!
! /* ...and these do not. */
! #define ARM26_R15_IF 0x0c000000
! #define ARM26_R15_IF_SHIFT 20
! #define ARM32_PSR_IF 0x000000c0
!
! /* Extract the parts of a 26-bit R15 into a PC and a PSR value. The PSR
! value is converted to 32-bit format. */
! void
! arm_extract_26bit_r15 (char *r15, char *pc, char *psr)
! {
! ULONGEST r15_val, pc_val, psr_val;
!
! r15_val = extract_unsigned_integer (r15, 4);
!
! pc_val = r15_val & 0x03fffffc;
!
! psr_val = (r15_val & (ARM26_R15_MODE|ARM26_R15_FLAGS)) |
! ((r15_val & ARM26_R15_IF) >> ARM26_R15_IF_SHIFT);
!
! if (pc != NULL)
! store_unsigned_integer (pc, 4, pc_val);
! if (psr != NULL)
! store_unsigned_integer (psr, 4, psr_val);
! }
!
! void
! arm_store_26bit_r15 (char *r15, char *pc, char *psr)
! {
! ULONGEST r15_val, pc_val, psr_val;
!
! r15_val = extract_unsigned_integer (r15, 4);
!
! if (pc != NULL)
! {
! pc_val = extract_unsigned_integer (pc, 4) & 0x03fffffc;
! r15_val = (r15_val & ~0x03fffffc) | pc_val;
! }
!
! if (psr != NULL)
! {
! psr_val = extract_unsigned_integer (psr, 4);
! r15_val = (r15_val & 0x03fffffc) |
! (psr_val & (ARM26_R15_MODE|ARM26_R15_FLAGS)) |
! ((psr_val & ARM32_PSR_IF) << ARM26_R15_IF_SHIFT);
! }
!
! store_unsigned_integer (r15, 4, r15_val);
}
/* When reading symbols, we need to zap the low bit of the address,
Index: arm-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/arm-tdep.h,v
retrieving revision 1.9
diff -c -r1.9 arm-tdep.h
*** arm-tdep.h 21 May 2002 15:36:03 -0000 1.9
--- arm-tdep.h 1 Sep 2002 23:51:50 -0000
***************
*** 154,156 ****
--- 154,159 ----
CORE_ADDR thumb_get_next_pc (CORE_ADDR);
CORE_ADDR arm_get_next_pc (CORE_ADDR);
+
+ void arm_extract_26bit_r15 (char *, char *, char *);
+ void arm_store_26bit_r15 (char *, char *, char *);
Index: armnbsd-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/armnbsd-nat.c,v
retrieving revision 1.8
diff -c -r1.8 armnbsd-nat.c
*** armnbsd-nat.c 21 Feb 2002 12:19:55 -0000 1.8
--- armnbsd-nat.c 1 Sep 2002 23:51:50 -0000
***************
*** 1,6 ****
! /* Native-dependent code for BSD Unix running on ARM's, for GDB.
! Copyright 1988, 1989, 1991, 1992, 1994, 1996, 1999, 2002
! Free Software Foundation, Inc.
This file is part of GDB.
--- 1,5 ----
! /* Native-dependent code for ARM systems running NetBSD.
! Copyright 2002 Free Software Foundation, Inc.
This file is part of GDB.
***************
*** 20,464 ****
Boston, MA 02111-1307, USA. */
#include "defs.h"
!
! #ifndef FETCH_INFERIOR_REGISTERS
! #error Not FETCH_INFERIOR_REGISTERS
! #endif /* !FETCH_INFERIOR_REGISTERS */
#include "arm-tdep.h"
#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
- #include <machine/frame.h>
- #include "inferior.h"
- #include "regcache.h"
- #include "gdbcore.h"
-
- extern int arm_apcs_32;
-
- static void
- supply_gregset (struct reg *gregset)
- {
- int regno;
- CORE_ADDR r_pc;
-
- /* Integer registers. */
- for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
- supply_register (regno, (char *) &gregset->r[regno]);
-
- supply_register (ARM_SP_REGNUM, (char *) &gregset->r_sp);
- supply_register (ARM_LR_REGNUM, (char *) &gregset->r_lr);
- /* This is ok: we're running native... */
- r_pc = ADDR_BITS_REMOVE (gregset->r_pc);
- supply_register (ARM_PC_REGNUM, (char *) &r_pc);
-
- if (arm_apcs_32)
- supply_register (ARM_PS_REGNUM, (char *) &gregset->r_cpsr);
- else
- supply_register (ARM_PS_REGNUM, (char *) &gregset->r_pc);
- }
-
- static void
- supply_fparegset (struct fpreg *fparegset)
- {
- int regno;
-
- for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
- supply_register
- (regno, (char *) &fparegset->fpr[regno - ARM_F0_REGNUM]);
-
- supply_register (ARM_FPS_REGNUM, (char *) &fparegset->fpr_fpsr);
- }
-
- static void
- fetch_register (int regno)
- {
- struct reg inferior_registers;
- int ret;
-
- ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
- (PTRACE_ARG3_TYPE) &inferior_registers, 0);
-
- if (ret < 0)
- {
- warning ("unable to fetch general register");
- return;
- }
-
- switch (regno)
- {
- case ARM_SP_REGNUM:
- supply_register (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
- break;
-
- case ARM_LR_REGNUM:
- supply_register (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
- break;
-
- case ARM_PC_REGNUM:
- /* This is ok: we're running native... */
- inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
- supply_register (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
- break;
-
- case ARM_PS_REGNUM:
- if (arm_apcs_32)
- supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
- else
- supply_register (ARM_PS_REGNUM, (char *) &inferior_registers.r_pc);
- break;
-
- default:
- supply_register (regno, (char *) &inferior_registers.r[regno]);
- break;
- }
- }
-
- static void
- fetch_regs (void)
- {
- struct reg inferior_registers;
- int ret;
- int regno;
-
- ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
- (PTRACE_ARG3_TYPE) &inferior_registers, 0);
-
- if (ret < 0)
- {
- warning ("unable to fetch general registers");
- return;
- }
-
- supply_gregset (&inferior_registers);
- }
! static void
! fetch_fp_register (int regno)
{
! struct fpreg inferior_fp_registers;
! int ret;
!
! ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
!
! if (ret < 0)
! {
! warning ("unable to fetch floating-point register");
! return;
! }
!
! switch (regno)
! {
! case ARM_FPS_REGNUM:
! supply_register (ARM_FPS_REGNUM,
! (char *) &inferior_fp_registers.fpr_fpsr);
! break;
!
! default:
! supply_register
! (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
! break;
! }
}
! static void
! fetch_fp_regs (void)
{
! struct fpreg inferior_fp_registers;
! int ret;
! int regno;
!
! ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
!
! if (ret < 0)
! {
! warning ("unable to fetch general registers");
! return;
! }
!
! supply_fparegset (&inferior_fp_registers);
}
void
fetch_inferior_registers (int regno)
{
! if (regno >= 0)
{
! if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
! fetch_register (regno);
! else
! fetch_fp_register (regno);
! }
! else
! {
! fetch_regs ();
! fetch_fp_regs ();
! }
! }
!
!
! static void
! store_register (int regno)
! {
! struct reg inferior_registers;
! int ret;
! ret = ptrace (PT_GETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_registers, 0);
! if (ret < 0)
! {
! warning ("unable to fetch general registers");
! return;
! }
!
! switch (regno)
! {
! case ARM_SP_REGNUM:
! regcache_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
! break;
!
! case ARM_LR_REGNUM:
! regcache_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
! break;
!
! case ARM_PC_REGNUM:
! if (arm_apcs_32)
! regcache_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
! else
! {
! unsigned pc_val;
!
! regcache_collect (ARM_PC_REGNUM, (char *) &pc_val);
!
! pc_val = ADDR_BITS_REMOVE (pc_val);
! inferior_registers.r_pc
! ^= ADDR_BITS_REMOVE (inferior_registers.r_pc);
! inferior_registers.r_pc |= pc_val;
! }
! break;
!
! case ARM_PS_REGNUM:
! if (arm_apcs_32)
! regcache_collect (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
! else
! {
! unsigned psr_val;
!
! regcache_collect (ARM_PS_REGNUM, (char *) &psr_val);
!
! psr_val ^= ADDR_BITS_REMOVE (psr_val);
! inferior_registers.r_pc = ADDR_BITS_REMOVE (inferior_registers.r_pc);
! inferior_registers.r_pc |= psr_val;
! }
! break;
!
! default:
! regcache_collect (regno, (char *) &inferior_registers.r[regno]);
! break;
}
! ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_registers, 0);
!
! if (ret < 0)
! warning ("unable to write register %d to inferior", regno);
! }
!
! static void
! store_regs (void)
! {
! struct reg inferior_registers;
! int ret;
! int regno;
!
!
! for (regno = ARM_A1_REGNUM; regno < ARM_SP_REGNUM; regno++)
! regcache_collect (regno, (char *) &inferior_registers.r[regno]);
!
! regcache_collect (ARM_SP_REGNUM, (char *) &inferior_registers.r_sp);
! regcache_collect (ARM_LR_REGNUM, (char *) &inferior_registers.r_lr);
!
! if (arm_apcs_32)
! {
! regcache_collect (ARM_PC_REGNUM, (char *) &inferior_registers.r_pc);
! regcache_collect (ARM_PS_REGNUM, (char *) &inferior_registers.r_cpsr);
! }
! else
{
! unsigned pc_val;
! unsigned psr_val;
!
! regcache_collect (ARM_PC_REGNUM, (char *) &pc_val);
! regcache_collect (ARM_PS_REGNUM, (char *) &psr_val);
!
! pc_val = ADDR_BITS_REMOVE (pc_val);
! psr_val ^= ADDR_BITS_REMOVE (psr_val);
!
! inferior_registers.r_pc = pc_val | psr_val;
! }
! ret = ptrace (PT_SETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_registers, 0);
! if (ret < 0)
! warning ("unable to store general registers");
! }
!
! static void
! store_fp_register (int regno)
! {
! struct fpreg inferior_fp_registers;
! int ret;
!
! ret = ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
!
! if (ret < 0)
! {
! warning ("unable to fetch floating-point registers");
! return;
! }
!
! switch (regno)
! {
! case ARM_FPS_REGNUM:
! regcache_collect (ARM_FPS_REGNUM,
! (char *) &inferior_fp_registers.fpr_fpsr);
! break;
!
! default:
! regcache_collect
! (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
! break;
}
-
- ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
- (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
-
- if (ret < 0)
- warning ("unable to write register %d to inferior", regno);
- }
-
- static void
- store_fp_regs (void)
- {
- struct fpreg inferior_fp_registers;
- int ret;
- int regno;
-
-
- for (regno = ARM_F0_REGNUM; regno <= ARM_F7_REGNUM; regno++)
- regcache_collect
- (regno, (char *) &inferior_fp_registers.fpr[regno - ARM_F0_REGNUM]);
-
- regcache_collect (ARM_FPS_REGNUM, (char *) &inferior_fp_registers.fpr_fpsr);
-
- ret = ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
- (PTRACE_ARG3_TYPE) &inferior_fp_registers, 0);
-
- if (ret < 0)
- warning ("unable to store floating-point registers");
}
void
store_inferior_registers (int regno)
{
! if (regno >= 0)
{
! if (regno < ARM_F0_REGNUM || regno > ARM_FPS_REGNUM)
! store_register (regno);
! else
! store_fp_register (regno);
! }
! else
! {
! store_regs ();
! store_fp_regs ();
! }
! }
! struct md_core
! {
! struct reg intreg;
! struct fpreg freg;
! };
!
! static void
! fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
! int which, CORE_ADDR ignore)
! {
! struct md_core *core_reg = (struct md_core *) core_reg_sect;
! int regno;
! CORE_ADDR r_pc;
! supply_gregset (&core_reg->intreg);
! supply_fparegset (&core_reg->freg);
! }
! static void
! fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size,
! int which, CORE_ADDR ignore)
! {
! struct reg gregset;
! struct fpreg fparegset;
! switch (which)
! {
! case 0: /* Integer registers. */
! if (core_reg_size != sizeof (struct reg))
! warning ("wrong size of register set in core file");
! else
! {
! /* The memcpy may be unnecessary, but we can't really be sure
! of the alignment of the data in the core file. */
! memcpy (&gregset, core_reg_sect, sizeof (gregset));
! supply_gregset (&gregset);
! }
! break;
!
! case 2:
! if (core_reg_size != sizeof (struct fpreg))
! warning ("wrong size of FPA register set in core file");
! else
! {
! /* The memcpy may be unnecessary, but we can't really be sure
! of the alignment of the data in the core file. */
! memcpy (&fparegset, core_reg_sect, sizeof (fparegset));
! supply_fparegset (&fparegset);
! }
! break;
!
! default:
! /* Don't know what kind of register request this is; just ignore it. */
! break;
}
- }
! static struct core_fns arm_netbsd_core_fns =
! {
! bfd_target_unknown_flavour, /* core_flovour. */
! default_check_format, /* check_format. */
! default_core_sniffer, /* core_sniffer. */
! fetch_core_registers, /* core_read_registers. */
! NULL
! };
! static struct core_fns arm_netbsd_elfcore_fns =
! {
! bfd_target_elf_flavour, /* core_flovour. */
! default_check_format, /* check_format. */
! default_core_sniffer, /* core_sniffer. */
! fetch_elfcore_registers, /* core_read_registers. */
! NULL
! };
! void
! _initialize_arm_netbsd_nat (void)
! {
! add_core_fns (&arm_netbsd_core_fns);
! add_core_fns (&arm_netbsd_elfcore_fns);
}
--- 19,113 ----
Boston, MA 02111-1307, USA. */
#include "defs.h"
! #include "inferior.h"
! #include "regcache.h"
#include "arm-tdep.h"
+ #include "armnbsd-tdep.h"
#include <sys/types.h>
#include <sys/ptrace.h>
#include <machine/reg.h>
! /* Determine if PT_GETREGS fetches this register. */
! static int
! getregs_supplies (int regno)
{
! return ((regno >= ARM_A1_REGNUM && regno <= ARM_PC_REGNUM)
! || regno == ARM_PS_REGNUM);
}
! /* Determine if PT_GETFPREGS fetches this register. */
! static int
! getfpregs_supplies (int regno)
{
! return ((regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM)
! || regno == ARM_FPS_REGNUM);
}
void
fetch_inferior_registers (int regno)
{
! if (regno == -1 || getregs_supplies (regno))
{
! struct reg regs;
! if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) ®s, 0) == -1)
! perror_with_name ("Couldn't get registers");
! armnbsd_supply_reg ((char *) ®s, regno);
! if (regno != -1)
! return;
}
! if (regno == -1 || getfpregs_supplies (regno))
{
! struct fpreg fpregs;
! if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
! perror_with_name ("Couldn't get floating point registers");
! armnbsd_supply_fpreg ((char *) &fpregs, regno);
! if (regno != -1)
! return;
}
}
void
store_inferior_registers (int regno)
{
! if (regno == -1 || getregs_supplies (regno))
{
! struct reg regs;
! if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) ®s, 0) == -1)
! perror_with_name ("Couldn't get registers");
! armnbsd_fill_reg ((char *) ®s, regno);
! if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) ®s, 0) == -1)
! perror_with_name ("Couldn't write registers");
! if (regno != -1)
! return;
}
! if (regno == -1 || getfpregs_supplies (regno))
! {
! struct fpreg fpregs;
! if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
! perror_with_name ("Couldn't get floating point registers");
! armnbsd_fill_fpreg ((char *) &fpregs, regno);
!
! if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
! (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
! perror_with_name ("Couldn't write floating point registers");
! }
}
Index: armnbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/armnbsd-tdep.c,v
retrieving revision 1.6
diff -c -r1.6 armnbsd-tdep.c
*** armnbsd-tdep.c 22 May 2002 03:59:53 -0000 1.6
--- armnbsd-tdep.c 1 Sep 2002 23:51:50 -0000
***************
*** 19,29 ****
--- 19,38 ----
Boston, MA 02111-1307, USA. */
#include "defs.h"
+ #include "gdbcore.h"
+ #include "regcache.h"
+ #include "target.h"
+ #include "value.h"
#include "arm-tdep.h"
+ #include "armnbsd-tdep.h"
#include "nbsd-tdep.h"
+
#include "solib-svr4.h"
+ /* from arm-tdep.c */
+ extern int arm_apcs_32;
+
/* Description of the longjmp buffer. */
#define JB_PC 24
#define JB_ELEMENT_SIZE INT_REGISTER_RAW_SIZE
***************
*** 32,37 ****
--- 41,232 ----
override the default little-endian breakpoint. */
static const char arm_nbsd_arm_le_breakpoint[] = {0x11, 0x00, 0x00, 0xe6};
+ #define REG_PC_OFFSET (15 * 4)
+ #define REG_CPSR_OFFSET (16 * 4)
+
+ #define SIZEOF_STRUCT_REG (17 * 4)
+
+ #define FPREG_FPSR_OFFSET (0 * 4)
+ #define FPREG_FPR0_OFFSET (1 * 4)
+
+ #define SIZEOF_STRUCT_FPREG (9 * 4)
+
+ #define PSR_MODE_32 0x00000010
+
+ void
+ armnbsd_supply_reg (char *regs, int regno)
+ {
+ ULONGEST cpsr;
+ int i;
+
+ /* Registers 0-14 can be supplied as-is. */
+ if ((regno >= ARM_A1_REGNUM && regno <= ARM_LR_REGNUM) || regno == -1)
+ {
+ for (i = ARM_A1_REGNUM; i <= ARM_LR_REGNUM; i++)
+ if (regno == i || regno == -1)
+ supply_register (i, regs + (i * 4));
+ }
+
+ /* R15 must be handled differently for 26-bit vs. 32-bit. In 26-bit
+ mode, the CPSR in the "reg" structure will be zero (32-bit indication
+ will not be set). Update arm_apcs_32 based on this. */
+ cpsr = extract_unsigned_integer (regs + REG_CPSR_OFFSET, 4);
+ arm_apcs_32 = (cpsr & PSR_MODE_32) != 0;
+
+ if (arm_apcs_32)
+ {
+ if (regno == ARM_PC_REGNUM || regno == -1)
+ supply_register (ARM_PC_REGNUM, regs + REG_PC_OFFSET);
+ if (regno == ARM_PS_REGNUM || regno == -1)
+ supply_register (ARM_PS_REGNUM, regs + REG_CPSR_OFFSET);
+ }
+ else
+ {
+ char pc[4], psr[4];
+
+ arm_extract_26bit_r15 (regs + REG_PC_OFFSET, pc, psr);
+
+ if (regno == ARM_PC_REGNUM || regno == -1)
+ supply_register (ARM_PC_REGNUM, pc);
+ if (regno == ARM_PS_REGNUM || regno == -1)
+ supply_register (ARM_PS_REGNUM, psr);
+ }
+ }
+
+ void
+ armnbsd_fill_reg (char *regs, int regno)
+ {
+ int i;
+
+ if ((regno >= ARM_A1_REGNUM && regno <= ARM_LR_REGNUM) || regno == -1)
+ {
+ for (i = ARM_A1_REGNUM; i <= ARM_LR_REGNUM; i++)
+ if (regno == i || regno == -1)
+ regcache_collect (i, regs + (i * 4));
+ }
+
+ if (arm_apcs_32)
+ {
+ if (regno == ARM_PC_REGNUM || regno == -1)
+ regcache_collect (ARM_PC_REGNUM, regs + REG_PC_OFFSET);
+ if (regno == ARM_PS_REGNUM || regno == -1)
+ regcache_collect (ARM_PS_REGNUM, regs + REG_CPSR_OFFSET);
+ }
+ else
+ {
+ char pc[4], *pcp, psr[4], *psrp;
+
+ if (regno == ARM_PC_REGNUM || regno == -1)
+ {
+ regcache_collect (ARM_PC_REGNUM, pc);
+ pcp = pc;
+ }
+ else
+ pcp = NULL;
+
+ if (regno == ARM_PS_REGNUM || regno == -1)
+ {
+ regcache_collect (ARM_PS_REGNUM, psr);
+ psrp = psr;
+ }
+ else
+ psrp = NULL;
+
+ arm_store_26bit_r15 (regs + REG_PC_OFFSET, pcp, psrp);
+ }
+ }
+
+ void
+ armnbsd_supply_fpreg (char *fpregs, int regno)
+ {
+ int i;
+
+ if ((regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) || regno == -1)
+ {
+ for (i = ARM_F0_REGNUM; i <= ARM_F7_REGNUM; i++)
+ if (regno == i || regno == -1)
+ supply_register (i, fpregs + FPREG_FPR0_OFFSET +
+ ((i - ARM_F0_REGNUM) * 4));
+ }
+
+ if (regno == ARM_FPS_REGNUM || regno == -1)
+ supply_register (ARM_FPS_REGNUM, fpregs + FPREG_FPSR_OFFSET);
+ }
+
+ void
+ armnbsd_fill_fpreg (char *fpregs, int regno)
+ {
+ int i;
+
+ if ((regno >= ARM_F0_REGNUM && regno <= ARM_F7_REGNUM) || regno == -1)
+ {
+ for (i = ARM_F0_REGNUM; i <= ARM_F7_REGNUM; i++)
+ if (regno == i || regno == -1)
+ regcache_collect (i, fpregs + FPREG_FPR0_OFFSET +
+ ((i - ARM_F0_REGNUM) * 4));
+ }
+
+ if (regno == ARM_FPS_REGNUM || regno == -1)
+ regcache_collect (ARM_FPS_REGNUM, fpregs + FPREG_FPSR_OFFSET);
+ }
+
+ static void
+ fetch_core_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+ {
+ char *regs, *fpregs;
+
+ regs = core_reg_sect;
+ fpregs = core_reg_sect + SIZEOF_STRUCT_REG;
+
+ armnbsd_supply_reg (regs, -1);
+ armnbsd_supply_fpreg (fpregs, -1);
+ }
+
+ static void
+ fetch_elfcore_registers (char *core_reg_sect, unsigned core_reg_size, int which,
+ CORE_ADDR ignore)
+ {
+ switch (which)
+ {
+ case 0: /* Integer registers. */
+ if (core_reg_size != SIZEOF_STRUCT_REG)
+ warning ("wrong size of register set in core file");
+ else
+ armnbsd_supply_reg (core_reg_sect, -1);
+ break;
+
+ case 1: /* FPA registers. */
+ if (core_reg_size != SIZEOF_STRUCT_FPREG)
+ warning ("wrong size of FPA register set in core file");
+ else
+ armnbsd_supply_fpreg (core_reg_sect, -1);
+ break;
+
+ default:
+ /* Don't know what kind of register request this is; just ignore it. */
+ break;
+ }
+ }
+
+ static struct core_fns armnbsd_core_fns =
+ {
+ bfd_target_unknown_flavour, /* core_flovour. */
+ default_check_format, /* check_format. */
+ default_core_sniffer, /* core_sniffer. */
+ fetch_core_registers, /* core_read_registers. */
+ NULL
+ };
+
+ static struct core_fns armnbsd_elfcore_fns =
+ {
+ bfd_target_elf_flavour, /* core_flovour. */
+ default_check_format, /* check_format. */
+ default_core_sniffer, /* core_sniffer. */
+ fetch_elfcore_registers, /* core_read_registers. */
+ NULL
+ };
+
static int
arm_netbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
{
***************
*** 101,104 ****
--- 296,302 ----
arm_netbsd_aout_init_abi);
gdbarch_register_osabi (bfd_arch_arm, GDB_OSABI_NETBSD_ELF,
arm_netbsd_elf_init_abi);
+
+ add_core_fns (&armnbsd_core_fns);
+ add_core_fns (&armnbsd_elfcore_fns);
}
Index: armnbsd-tdep.h
===================================================================
RCS file: armnbsd-tdep.h
diff -N armnbsd-tdep.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- armnbsd-tdep.h 1 Sep 2002 23:51:50 -0000
***************
*** 0 ****
--- 1,30 ----
+ /* Target-specific functions for ARM running under NetBSD.
+ Copyright 2002 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+ #ifndef ARMNBSD_TDEP_H
+ #define ARMNBSD_TDEP_H
+
+ void armnbsd_supply_reg (char *, int);
+ void armnbsd_fill_reg (char *, int);
+
+ void armnbsd_supply_fpreg (char *, int);
+ void armnbsd_fill_fpreg (char *, int);
+
+ #endif /* ARMNBSD_TDEP_H */
Index: configure.tgt
===================================================================
RCS file: /cvs/src/src/gdb/configure.tgt,v
retrieving revision 1.84
diff -c -r1.84 configure.tgt
*** configure.tgt 22 Aug 2002 21:52:44 -0000 1.84
--- configure.tgt 1 Sep 2002 23:51:53 -0000
***************
*** 51,57 ****
build_gdbserver=yes
;;
arm*-*-netbsd*) gdb_target=nbsd
! gdb_multi_arch=yes ;;
arm*-*-* | thumb*-*-* | strongarm*-*-*)
gdb_target=embed
configdirs="$configdirs rdi-share"
--- 51,60 ----
build_gdbserver=yes
;;
arm*-*-netbsd*) gdb_target=nbsd
! # FIXME: We need to include "solib.h" in tm.h for
! # cross-debugger to work.
! # gdb_multi_arch=yes
! ;;
arm*-*-* | thumb*-*-* | strongarm*-*-*)
gdb_target=embed
configdirs="$configdirs rdi-share"
Index: config/arm/nbsd.mt
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/nbsd.mt,v
retrieving revision 1.5
diff -c -r1.5 nbsd.mt
*** config/arm/nbsd.mt 22 May 2002 03:59:54 -0000 1.5
--- config/arm/nbsd.mt 1 Sep 2002 23:51:57 -0000
***************
*** 1,2 ****
# Target: ARM running NetBSD
! TDEPFILES= arm-tdep.o armnbsd-tdep.o solib.o solib-svr4.o nbsd-tdep.o
--- 1,3 ----
# Target: ARM running NetBSD
! TDEPFILES= arm-tdep.o armnbsd-tdep.o corelow.o solib.o solib-svr4.o nbsd-tdep.o
! TM_FILE= tm-nbsd.h
Index: config/arm/nbsdaout.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/nbsdaout.mh,v
retrieving revision 1.1
diff -c -r1.1 nbsdaout.mh
*** config/arm/nbsdaout.mh 22 May 2002 03:59:54 -0000 1.1
--- config/arm/nbsdaout.mh 1 Sep 2002 23:51:57 -0000
***************
*** 1,5 ****
# Host ARM running NetBSD
! NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o armnbsd-nat.o \
! solib-sunos.o
XM_FILE=xm-nbsd.h
NAT_FILE=nm-nbsdaout.h
--- 1,4 ----
# Host ARM running NetBSD
! NATDEPFILES= fork-child.o infptrace.o inftarg.o armnbsd-nat.o solib-sunos.o
XM_FILE=xm-nbsd.h
NAT_FILE=nm-nbsdaout.h
Index: config/arm/nbsdelf.mh
===================================================================
RCS file: /cvs/src/src/gdb/config/arm/nbsdelf.mh,v
retrieving revision 1.1
diff -c -r1.1 nbsdelf.mh
*** config/arm/nbsdelf.mh 22 May 2002 03:59:54 -0000 1.1
--- config/arm/nbsdelf.mh 1 Sep 2002 23:51:57 -0000
***************
*** 1,4 ****
# Host ARM running NetBSD
! NATDEPFILES= fork-child.o infptrace.o inftarg.o corelow.o armnbsd-nat.o
XM_FILE=xm-nbsd.h
NAT_FILE=nm-nbsd.h
--- 1,4 ----
# Host ARM running NetBSD
! NATDEPFILES= fork-child.o infptrace.o inftarg.o armnbsd-nat.o
XM_FILE=xm-nbsd.h
NAT_FILE=nm-nbsd.h
Index: config/arm/tm-nbsd.h
===================================================================
RCS file: config/arm/tm-nbsd.h
diff -N config/arm/tm-nbsd.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- config/arm/tm-nbsd.h 1 Sep 2002 23:51:57 -0000
***************
*** 0 ****
--- 1,27 ----
+ /* Target-dependent definitions for ARM running NetBSD, for GDB.
+ Copyright 2002 Free Software Foundation, Inc.
+
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+ #ifndef TM_NBSD_H
+ #define TM_NBSD_H
+
+ #include "arm/tm-arm.h"
+ #include "solib.h"
+
+ #endif /* TM_NBSD_H */
next reply other threads:[~2002-09-01 23:58 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-09-01 16:58 Jason R Thorpe [this message]
2002-09-02 12:56 ` Andrew Cagney
2002-09-03 12:23 ` Richard Earnshaw
2002-09-03 12:34 ` Jason R Thorpe
2002-09-04 4:10 ` Richard Earnshaw
2002-09-03 15:40 ` Jason R Thorpe
2002-09-04 2:56 ` Richard Earnshaw
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020901165843.B4034@dr-evil.shagadelic.org \
--to=thorpej@wasabisystems.com \
--cc=gdb-patches@sources.redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox