From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 23106 invoked by alias); 1 Sep 2002 23:58:45 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 23095 invoked from network); 1 Sep 2002 23:58:44 -0000 Received: from unknown (HELO dr-evil.shagadelic.org) (208.176.2.174) by sources.redhat.com with SMTP; 1 Sep 2002 23:58:44 -0000 Received: by dr-evil.shagadelic.org (Postfix, from userid 7518) id AC6CE9869; Sun, 1 Sep 2002 16:58:43 -0700 (PDT) Date: Sun, 01 Sep 2002 16:58:00 -0000 From: Jason R Thorpe To: gdb-patches@sources.redhat.com Subject: [PATCH/RFA] arm-netbsdelf cross-debugging fixes Message-ID: <20020901165843.B4034@dr-evil.shagadelic.org> Mail-Followup-To: Jason R Thorpe , gdb-patches@sources.redhat.com Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="3oCie2+XPXTnK5a5" Content-Disposition: inline User-Agent: Mutt/1.2.5i Organization: Wasabi Systems, Inc. X-SW-Source: 2002-09/txt/msg00014.txt.bz2 --3oCie2+XPXTnK5a5 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-length: 2242 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 --3oCie2+XPXTnK5a5 Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename=arm-gdb-patch Content-length: 30648 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 #include #include - #include - #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 #include #include ! /* 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 */ --3oCie2+XPXTnK5a5--