diff options
-rw-r--r-- | gdb/ChangeLog | 27 | ||||
-rw-r--r-- | gdb/Makefile.in | 18 | ||||
-rw-r--r-- | gdb/NEWS | 8 | ||||
-rw-r--r-- | gdb/config/pa/nbsd.mh | 2 | ||||
-rw-r--r-- | gdb/configure.host | 1 | ||||
-rw-r--r-- | gdb/configure.tgt | 7 | ||||
-rw-r--r-- | gdb/hppabsd-tdep.c | 104 | ||||
-rw-r--r-- | gdb/hppanbsd-nat.c | 245 | ||||
-rw-r--r-- | gdb/hppanbsd-tdep.c | 228 | ||||
-rw-r--r-- | gdb/hppaobsd-tdep.c | 128 |
10 files changed, 661 insertions, 107 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index e66df1e..7610074 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,30 @@ +2008-01-18 Nick Hudson <nick.hudson@dsl.pipex.com> + + Add NetBSD/hppa target and host support. + + * hppabsd-tdep.c (hppabsd_supply_gregset): Move to ... + (hppabsd_gregset): Move to ... + (hppabsd_regset_from_core_section): Rename + hppaobsd_regset_from_core_section and move to ... + (hppabsd_find_global_pointer): Update comment. + (hppabsd_init_abi): Make global. Do not register + hppabsd_regset_from_core_section. + (hppabsd_core_osabi_sniffer): Rename hppaobsd_core_osabi_sniffer and + move to ... + (_initialize_hppabsd_tdep): Move to ... + * hppaobsd-tdep.c: ... here. New file. + * hppnbsd-tdep.c: New file. + * hppnbsd-nat.c: New file. + * Makefile.in (ALL_TARGET_OBS): Add hppanbsd-tdep.o and hppaobsd-tdep.o. + (ALLDEPFILES): Add hppabsd-nat.c and hppabsd-tdep.c. + (hppabsd-nat.o, hppabsd-tdep.o): New dependencies. + (hppabsd-tdep.o, hppaobsd-tdep.o): Update dependencies. + * configure.host (hppa*-*-netbsd*): New entry. + * configure.tgt (hppa*-*-netbsd*): New entry. + (hppa*-*-openbsd*): Update. + * NEWS (New native configuration): Mention NetBSD/hppa. + (New targets): Mention NetBSD/hppa. + 2008-01-18 Markus Deuling <deuling@de.ibm.com> * gdbarch.sh (function_list): Add new property bits_big_endian to diff --git a/gdb/Makefile.in b/gdb/Makefile.in index bf4d1f1..e3c5bf4 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -451,7 +451,8 @@ ALL_TARGET_OBS = \ cris-tdep.o \ frv-linux-tdep.o frv-tdep.o \ h8300-tdep.o \ - hppabsd-tdep.o hppa-hpux-tdep.o hppa-linux-tdep.o hppa-tdep.o \ + hppabsd-tdep.o hppanbsd-tdep.o hppaobsd-tdep.o \ + hppa-hpux-tdep.o hppa-linux-tdep.o hppa-tdep.o \ i386bsd-tdep.o i386-cygwin-tdep.o i386fbsd-tdep.o i386gnu-tdep.o \ i386-linux-tdep.o i386nbsd-tdep.o i386-nto-tdep.o i386obsd-tdep.o \ i386-sol2-tdep.o i386-tdep.o i387-tdep.o \ @@ -1541,6 +1542,8 @@ ALLDEPFILES = \ hppa-tdep.c hppa-hpux-tdep.c hppa-hpux-nat.c \ hppa-linux-tdep.c hppa-linux-nat.c \ hppabsd-nat.c hppabsd-tdep.c \ + hppaobsd-tdep.c \ + hppanbsd-nat.c hppanbsd-tdep.c \ i386-tdep.c i386-linux-nat.c \ i386v4-nat.c i386-cygwin-tdep.c \ i386bsd-nat.c i386bsd-tdep.c i386fbsd-nat.c i386fbsd-tdep.c \ @@ -2165,11 +2168,16 @@ h8300-tdep.o: h8300-tdep.c $(defs_h) $(value_h) $(arch_utils_h) $(regcache_h) \ $(gdbcore_h) $(objfiles_h) $(gdb_assert_h) $(dis_asm_h) \ $(dwarf2_frame_h) $(frame_base_h) $(frame_unwind_h) hppabsd-nat.o: hppabsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \ + $(hppa_tdep_h) $(inf_ptrace_h) +hppabsd-tdep.o: hppabsd-tdep.c $(defs_h) $(objfiles_h) $(target_h) \ + $(value_h) $(elf_common_h) $(hppa_tdep_h) $(solib_svr4_h) +hppanbsd-nat.o: hppabsd-nat.c $(defs_h) $(inferior_h) $(regcache_h) \ $(target_h) $(hppa_tdep_h) $(inf_ptrace_h) -hppabsd-tdep.o: hppabsd-tdep.c $(defs_h) $(arch_utils_h) $(symtab_h) \ - $(objfiles_h) $(osabi_h) $(regcache_h) $(regset_h) $(target_h) \ - $(value_h) $(gdb_assert_h) $(gdb_string_h) $(elf_common_h) \ - $(hppa_tdep_h) $(solib_svr4_h) $(gdbtypes_h) +hppanbsd-tdep.o: hppanbsd-tdep.c $(defs_h) $(osabi_h) $(regcache_h) $(regset_h) \ + $(trad_frame_h) $(tramp_frame_h) $(gdb_assert_h) $(gdb_string_h) \ + $(hppa_tdep_h) +hppaobsd-tdep.o: hppaobsd-tdep.c $(defs_h) $(osabi_h) $(regcache_h) $(regset_h) \ + $(gdb_assert_h) $(gdb_string_h) $(hppa_tdep_h) hppa-hpux-nat.o: hppa-hpux-nat.c $(defs_h) $(inferior_h) $(regcache_h) \ $(target_h) $(gdb_assert_h) $(hppa_tdep_h) $(inf_ptrace_h) \ $(inf_ttrace_h) @@ -3,6 +3,14 @@ *** Changes since GDB 6.7 +* New native configurations + +NetBSD/hppa hppa*-*netbsd* + +* New targets + +NetBSD/hppa hppa*-*-netbsd* + * Change in command line behavior -- corefiles vs. process ids. When the '-p NUMBER' or '--pid NUMBER' options are used, and diff --git a/gdb/config/pa/nbsd.mh b/gdb/config/pa/nbsd.mh new file mode 100644 index 0000000..5cff698 --- /dev/null +++ b/gdb/config/pa/nbsd.mh @@ -0,0 +1,2 @@ +# Host: NetBSD/hppa +NATDEPFILES= fork-child.o inf-ptrace.o nbsd-nat.o hppanbsd-nat.o diff --git a/gdb/configure.host b/gdb/configure.host index d3b6713..672920d 100644 --- a/gdb/configure.host +++ b/gdb/configure.host @@ -79,6 +79,7 @@ arm*-*-openbsd*) gdb_host=nbsdelf ;; hppa*-*-hpux*) gdb_host=hpux ;; hppa*-*-linux*) gdb_host=linux ;; +hppa*-*-netbsd*) gdb_host=nbsd ;; hppa*-*-openbsd*) gdb_host=obsd ;; i[34567]86-*-freebsd* | i[34567]86-*-kfreebsd*-gnu) diff --git a/gdb/configure.tgt b/gdb/configure.tgt index c10d28a..d3c86d7 100644 --- a/gdb/configure.tgt +++ b/gdb/configure.tgt @@ -130,9 +130,14 @@ hppa*-*-linux*) gdb_target_obs="hppa-tdep.o hppa-linux-tdep.o glibc-tdep.o \ solib.o solib-svr4.o symfile-mem.o" ;; +hppa*-*-netbsd*) + # Target: NetBSD/hppa + gdb_target_obs="hppa-tdep.o hppabsd-tdep.o hppanbsd-tdep.o \ + corelow.o solib.o solib-svr4.o" + ;; hppa*-*-openbsd*) # Target: OpenBSD/hppa - gdb_target_obs="hppa-tdep.o hppabsd-tdep.o \ + gdb_target_obs="hppa-tdep.o hppabsd-tdep.o hppaobsd-tdep.o \ corelow.o solib.o solib-svr4.o" ;; hppa*-*-*) diff --git a/gdb/hppabsd-tdep.c b/gdb/hppabsd-tdep.c index 26605f3..f5a31cf 100644 --- a/gdb/hppabsd-tdep.c +++ b/gdb/hppabsd-tdep.c @@ -18,79 +18,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #include "defs.h" -#include "arch-utils.h" -#include "gdbtypes.h" -#include "symtab.h" #include "objfiles.h" -#include "osabi.h" -#include "regcache.h" -#include "regset.h" #include "target.h" #include "value.h" -#include "gdb_assert.h" -#include "gdb_string.h" - #include "elf/common.h" #include "hppa-tdep.h" #include "solib-svr4.h" -/* Core file support. */ - -/* Sizeof `struct reg' in <machine/reg.h>. */ -#define HPPABSD_SIZEOF_GREGS (34 * 4) - -/* Supply register REGNUM from the buffer specified by GREGS and LEN - in the general-purpose register set REGSET to register cache - REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ - -static void -hppabsd_supply_gregset (const struct regset *regset, struct regcache *regcache, - int regnum, const void *gregs, size_t len) -{ - const gdb_byte *regs = gregs; - size_t offset; - int i; - - gdb_assert (len >= HPPABSD_SIZEOF_GREGS); - - for (i = HPPA_R1_REGNUM, offset = 4; i <= HPPA_R31_REGNUM; i++, offset += 4) - { - if (regnum == -1 || regnum == i) - regcache_raw_supply (regcache, i, regs + offset); - } - - if (regnum == -1 || regnum == HPPA_SAR_REGNUM) - regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs); - if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM) - regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4); - if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM) - regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4); -} - -/* OpenBSD/hppa register set. */ - -static struct regset hppabsd_gregset = -{ - NULL, - hppabsd_supply_gregset -}; - -/* Return the appropriate register set for the core section identified - by SECT_NAME and SECT_SIZE. */ - -static const struct regset * -hppabsd_regset_from_core_section (struct gdbarch *gdbarch, - const char *sect_name, size_t sect_size) -{ - if (strcmp (sect_name, ".reg") == 0 && sect_size >= HPPABSD_SIZEOF_GREGS) - return &hppabsd_gregset; - - return NULL; -} - - CORE_ADDR hppabsd_find_global_pointer (struct value *function) { @@ -143,11 +79,12 @@ hppabsd_find_global_pointer (struct value *function) if (target_read_memory (addr + 4, buf, sizeof buf) != 0) break; - /* The OpenBSD ld.so doesn't relocate DT_PLTGOT, so + /* The NetBSD/OpenBSD ld.so doesn't relocate DT_PLTGOT, so we have to do it ourselves. */ pltgot = extract_unsigned_integer (buf, sizeof buf); pltgot += ANOFFSET (sec->objfile->section_offsets, SECT_OFF_TEXT (sec->objfile)); + return pltgot; } @@ -163,7 +100,7 @@ hppabsd_find_global_pointer (struct value *function) } -static void +void hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); @@ -172,10 +109,6 @@ hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_long_double_bit (gdbarch, 64); set_gdbarch_long_double_format (gdbarch, floatformats_ieee_double); - /* Core file support. */ - set_gdbarch_regset_from_core_section - (gdbarch, hppabsd_regset_from_core_section); - /* OpenBSD and NetBSD use ELF. */ tdep->is_elf = 1; tdep->find_global_pointer = hppabsd_find_global_pointer; @@ -186,34 +119,3 @@ hppabsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_solib_svr4_fetch_link_map_offsets (gdbarch, svr4_ilp32_fetch_link_map_offsets); } - - -/* OpenBSD uses uses the traditional NetBSD core file format, even for - ports that use ELF. */ -#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF - -static enum gdb_osabi -hppabsd_core_osabi_sniffer (bfd *abfd) -{ - if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0) - return GDB_OSABI_NETBSD_CORE; - - return GDB_OSABI_UNKNOWN; -} - - -/* Provide a prototype to silence -Wmissing-prototypes. */ -void _initialize_hppabsd_tdep (void); - -void -_initialize_hppabsd_tdep (void) -{ - /* BFD doesn't set a flavour for NetBSD style a.out core files. */ - gdbarch_register_osabi_sniffer (bfd_arch_hppa, bfd_target_unknown_flavour, - hppabsd_core_osabi_sniffer); - - gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD_ELF, - hppabsd_init_abi); - gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_OPENBSD_ELF, - hppabsd_init_abi); -} diff --git a/gdb/hppanbsd-nat.c b/gdb/hppanbsd-nat.c new file mode 100644 index 0000000..196dcca --- /dev/null +++ b/gdb/hppanbsd-nat.c @@ -0,0 +1,245 @@ +/* Native-dependent code for NetBSD/hppa. + + Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#include "defs.h" +#include "inferior.h" +#include "regcache.h" + +#include <sys/types.h> +#include <sys/ptrace.h> +#include <machine/reg.h> + +#include "hppa-tdep.h" +#include "inf-ptrace.h" + +#include "nbsd-nat.h" + +static int +hppanbsd_gregset_supplies_p (int regnum) +{ + return ((regnum >= HPPA_R0_REGNUM && regnum <= HPPA_R31_REGNUM) || + (regnum >= HPPA_SAR_REGNUM && regnum <= HPPA_PCSQ_TAIL_REGNUM) || + regnum == HPPA_IPSW_REGNUM || + (regnum >= HPPA_SR4_REGNUM && regnum <= HPPA_SR4_REGNUM + 5)); +} + +static int +hppanbsd_fpregset_supplies_p (int regnum) +{ + return (regnum >= HPPA_FP0_REGNUM && regnum <= HPPA_FP31R_REGNUM); +} + +/* Supply the general-purpose registers stored in GREGS to REGCACHE. */ + +static void +hppanbsd_supply_gregset (struct regcache *regcache, const void *gregs) +{ + const char *regs = gregs; + const int *r = gregs; + int regnum; + + for (regnum = HPPA_R1_REGNUM; regnum <= HPPA_R31_REGNUM; regnum++) + regcache_raw_supply (regcache, regnum, regs + regnum * 4); + + regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs + 32 * 4); + regcache_raw_supply (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4); + regcache_raw_supply (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4); + regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4); + regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4); + regcache_raw_supply (regcache, HPPA_IPSW_REGNUM, regs); + regcache_raw_supply (regcache, HPPA_SR4_REGNUM, regs + 41 * 4); + regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 1, regs + 37 * 4); + regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 2, regs + 38 * 4); + regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 3, regs + 39 * 4); + regcache_raw_supply (regcache, HPPA_SR4_REGNUM + 4, regs + 40 * 4); +} + +/* Supply the floating-point registers stored in FPREGS to REGCACHE. */ + +static void +hppanbsd_supply_fpregset (struct regcache *regcache, const void *fpregs) +{ + const char *regs = fpregs; + int regnum; + + for (regnum = HPPA_FP0_REGNUM; regnum <= HPPA_FP31R_REGNUM; + regnum += 2, regs += 8) + { + regcache_raw_supply (regcache, regnum, regs); + regcache_raw_supply (regcache, regnum + 1, regs + 4); + } +} + +/* Collect the general-purpose registers from REGCACHE and store them + in GREGS. */ + +static void +hppanbsd_collect_gregset (const struct regcache *regcache, + void *gregs, int regnum) +{ + char *regs = gregs; + int *r = gregs; + int i; + + for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++) + { + if (regnum == -1 || regnum == i) + regcache_raw_collect (regcache, i, regs + i * 4); + } + + if (regnum == -1 || regnum == HPPA_IPSW_REGNUM) + regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs); + if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM) + regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4); + if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM) + regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4); + + if (regnum == -1 || regnum == HPPA_SAR_REGNUM) + regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs + 32 * 4); + if (regnum == -1 || regnum == HPPA_PCSQ_HEAD_REGNUM) + regcache_raw_collect (regcache, HPPA_PCSQ_HEAD_REGNUM, regs + 33 * 4); + if (regnum == -1 || regnum == HPPA_PCSQ_TAIL_REGNUM) + regcache_raw_collect (regcache, HPPA_PCSQ_TAIL_REGNUM, regs + 34 * 4); + if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM) + regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 35 * 4); + if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM) + regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 36 * 4); + if (regnum == -1 || regnum == HPPA_IPSW_REGNUM) + regcache_raw_collect (regcache, HPPA_IPSW_REGNUM, regs); + if (regnum == -1 || regnum == HPPA_SR4_REGNUM) + regcache_raw_collect (regcache, HPPA_SR4_REGNUM, regs + 41 * 4); + if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 1) + regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 1, regs + 37 * 4); + if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 2) + regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 2, regs + 38 * 4); + if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 3) + regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 3, regs + 39 * 4); + if (regnum == -1 || regnum == HPPA_SR4_REGNUM + 4) + regcache_raw_collect (regcache, HPPA_SR4_REGNUM + 4, regs + 40 * 4); +} + +/* Collect the floating-point registers from REGCACHE and store them + in FPREGS. */ + +static void +hppanbsd_collect_fpregset (struct regcache *regcache, + void *fpregs, int regnum) +{ + char *regs = fpregs; + int i; + + for (i = HPPA_FP0_REGNUM; i <= HPPA_FP31R_REGNUM; i += 2, regs += 8) + { + if (regnum == -1 || regnum == i || regnum == i + 1) + { + regcache_raw_collect (regcache, i, regs); + regcache_raw_collect (regcache, i + 1, regs + 4); + } + } +} + + +/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this + for all registers (including the floating-point registers). */ + +static void +hppanbsd_fetch_registers (struct regcache *regcache, int regnum) + +{ + if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum)) + { + struct reg regs; + + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) ®s, 0) == -1) + perror_with_name (_("Couldn't get registers")); + + hppanbsd_supply_gregset (regcache, ®s); + } + + if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum)) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) + perror_with_name (_("Couldn't get floating point status")); + + hppanbsd_supply_fpregset (regcache, &fpregs); + } +} + +/* Store register REGNUM back into the inferior. If REGNUM is -1, do + this for all registers (including the floating-point registers). */ + +static void +hppanbsd_store_registers (struct regcache *regcache, int regnum) +{ + if (regnum == -1 || hppanbsd_gregset_supplies_p (regnum)) + { + struct reg regs; + + if (ptrace (PT_GETREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) ®s, 0) == -1) + perror_with_name (_("Couldn't get registers")); + + hppanbsd_collect_gregset (regcache, ®s, regnum); + + if (ptrace (PT_SETREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) ®s, 0) == -1) + perror_with_name (_("Couldn't write registers")); + } + + if (regnum == -1 || hppanbsd_fpregset_supplies_p (regnum)) + { + struct fpreg fpregs; + + if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) + perror_with_name (_("Couldn't get floating point status")); + + hppanbsd_collect_fpregset (regcache, &fpregs, regnum); + + if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid), + (PTRACE_TYPE_ARG3) &fpregs, 0) == -1) + perror_with_name (_("Couldn't write floating point status")); + } +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_hppanbsd_nat (void); + +void +_initialize_hppanbsd_nat (void) +{ + struct target_ops *t; + + /* Add some extra features to the ptrace target. */ + t = inf_ptrace_target (); + + t->to_fetch_registers = hppanbsd_fetch_registers; + t->to_store_registers = hppanbsd_store_registers; + + t->to_pid_to_exec_file = nbsd_pid_to_exec_file; + + add_target (t); +} diff --git a/gdb/hppanbsd-tdep.c b/gdb/hppanbsd-tdep.c new file mode 100644 index 0000000..e8c31f9 --- /dev/null +++ b/gdb/hppanbsd-tdep.c @@ -0,0 +1,228 @@ +/* Target-dependent code for NetBSD/hppa + + Copyright (C) 2008 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#include "defs.h" +#include "osabi.h" +#include "regcache.h" +#include "regset.h" + +#include "trad-frame.h" +#include "tramp-frame.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "hppa-tdep.h" + +/* From <machine/mcontext.h>. */ +static int hppanbsd_mc_reg_offset[] = +{ + /* r0 ... r31 */ + -1, 1 * 4, 2 * 4, 3 * 4, + 4 * 4, 5 * 4, 6 * 4, 7 * 4, + 8 * 4, 9 * 4, 10 * 4, 11 * 4, + 12 * 4, 13 * 4, 14 * 4, 15 * 4, + 16 * 4, 17 * 4, 18 * 4, 19 * 4, + 20 * 4, 21 * 4, 22 * 4, 23 * 4, + 24 * 4, 25 * 4, 26 * 4, 27 * 4, + 28 * 4, 29 * 4, 30 * 4, 31 * 4, + + 32 * 4, /* HPPA_SAR_REGNUM */ + 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */ + 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */ + 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */ + 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */ + -1, /* HPPA_EIEM_REGNUM */ + -1, /* HPPA_IIR_REGNUM */ + -1, /* HPPA_ISR_REGNUM */ + -1, /* HPPA_IOR_REGNUM */ + 0 * 4, /* HPPA_IPSW_REGNUM */ + -1, /* spare? */ + 41 * 4, /* HPPA_SR4_REGNUM */ + 37 * 4, /* sr0 */ + 38 * 4, /* sr1 */ + 39 * 4, /* sr2 */ + 40 * 4, /* sr3 */ + + /* more tbd */ +}; + +static void hppanbsd_sigtramp_cache_init (const struct tramp_frame *, + struct frame_info *, + struct trad_frame_cache *, + CORE_ADDR); + +static const struct tramp_frame hppanbsd_sigtramp_si4 = +{ + SIGTRAMP_FRAME, + 4, + { + { 0xc7d7c012, -1 }, /* bb,>=,n %arg3, 30, 1f */ + { 0xd6e01c1e, -1 }, /* depwi 0,31,2,%arg3 */ + { 0x0ee81093, -1 }, /* ldw 4(%arg3), %r19 */ + { 0x0ee01097, -1 }, /* ldw 0(%arg3), %arg3 */ + /* 1: */ + { 0xe8404000, -1 }, /* blr %r0, %rp */ + { 0xeae0c002, -1 }, /* bv,n %r0(%arg3) */ + { 0x08000240, -1 }, /* nop */ + + { 0x0803025a, -1 }, /* copy %r3, %arg0 */ + { 0x20200801, -1 }, /* ldil -40000000, %r1 */ + { 0xe420e008, -1 }, /* be,l 4(%sr7, %r1), %sr0, %r31 */ + { 0x34160268, -1 }, /* ldi 134, %t1 ; SYS_setcontext */ + + { 0x081c025a, -1 }, /* copy ret0, %arg0 */ + { 0x20200801, -1 }, /* ldil -40000000, %r1 */ + { 0xe420e008, -1 }, /* be,l 4(%sr7, %r1), %sr0, %r31 */ + { 0x34160002, -1 }, /* ldi 1, %t1 ; SYS_exit */ + { TRAMP_SENTINEL_INSN, -1 } + }, + hppanbsd_sigtramp_cache_init +}; + + +static void +hppanbsd_sigtramp_cache_init (const struct tramp_frame *self, + struct frame_info *next_frame, + struct trad_frame_cache *this_cache, + CORE_ADDR func) +{ + struct gdbarch *gdbarch = get_frame_arch (next_frame); + struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, HPPA_SP_REGNUM); + CORE_ADDR base; + int *reg_offset; + int num_regs; + int i; + + reg_offset = hppanbsd_mc_reg_offset; + num_regs = ARRAY_SIZE (hppanbsd_mc_reg_offset); + + /* frame pointer */ + base = sp - 0x280; + /* offsetof(struct sigframe_siginfo, sf_uc) = 128 */ + base += 128; + /* offsetof(ucontext_t, uc_mcontext) == 40 */ + base += 40; + + for (i = 0; i < num_regs; i++) + if (reg_offset[i] != -1) + trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]); + + /* Construct the frame ID using the function start. */ + trad_frame_set_id (this_cache, frame_id_build (sp, func)); +} + +/* Core file support. */ + +/* Sizeof `struct reg' in <machine/reg.h>. */ +#define HPPANBSD_SIZEOF_GREGS (44 * 4) + +static int hppanbsd_reg_offset[] = +{ + /* r0 ... r31 */ + -1, 1 * 4, 2 * 4, 3 * 4, + 4 * 4, 5 * 4, 6 * 4, 7 * 4, + 8 * 4, 9 * 4, 10 * 4, 11 * 4, + 12 * 4, 13 * 4, 14 * 4, 15 * 4, + 16 * 4, 17 * 4, 18 * 4, 19 * 4, + 20 * 4, 21 * 4, 22 * 4, 23 * 4, + 24 * 4, 25 * 4, 26 * 4, 27 * 4, + 28 * 4, 29 * 4, 30 * 4, 31 * 4, + + 32 * 4, /* HPPA_SAR_REGNUM */ + 35 * 4, /* HPPA_PCOQ_HEAD_REGNUM */ + 33 * 4, /* HPPA_PCSQ_HEAD_REGNUM */ + 36 * 4, /* HPPA_PCOQ_TAIL_REGNUM */ + 34 * 4, /* HPPA_PCSQ_TAIL_REGNUM */ + -1, /* HPPA_EIEM_REGNUM */ + -1, /* HPPA_IIR_REGNUM */ + -1, /* HPPA_ISR_REGNUM */ + -1, /* HPPA_IOR_REGNUM */ + 0 * 4, /* HPPA_IPSW_REGNUM */ +}; + +/* Supply register REGNUM from the buffer specified by GREGS and LEN + in the general-purpose register set REGSET to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ + +static void +hppanbsd_supply_gregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + const gdb_byte *regs = gregs; + size_t offset; + int i; + + gdb_assert (len >= HPPANBSD_SIZEOF_GREGS); + + for (i = 0; i < ARRAY_SIZE (hppanbsd_reg_offset); i++) + if (hppanbsd_reg_offset[i] != -1) + if (regnum == -1 || regnum == i) + regcache_raw_supply (regcache, i, regs + hppanbsd_reg_offset[i]); +} + +/* NetBSD/hppa register set. */ + +static struct regset hppanbsd_gregset = +{ + NULL, + hppanbsd_supply_gregset +}; + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ + +static const struct regset * +hppanbsd_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) +{ + if (strcmp (sect_name, ".reg") == 0 && sect_size >= HPPANBSD_SIZEOF_GREGS) + return &hppanbsd_gregset; + + return NULL; +} + +void hppabsd_init_abi (struct gdbarch_info, struct gdbarch *); + +static void +hppanbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + /* Obviously NetBSD is BSD-based. */ + hppabsd_init_abi (info, gdbarch); + + /* Core file support. */ + set_gdbarch_regset_from_core_section + (gdbarch, hppanbsd_regset_from_core_section); + + tramp_frame_prepend_unwinder (gdbarch, &hppanbsd_sigtramp_si4); +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_hppabsd_tdep (void); + +void +_initialize_hppanbsd_tdep (void) +{ + gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_NETBSD_ELF, + hppanbsd_init_abi); +} diff --git a/gdb/hppaobsd-tdep.c b/gdb/hppaobsd-tdep.c new file mode 100644 index 0000000..bc4c8e7 --- /dev/null +++ b/gdb/hppaobsd-tdep.c @@ -0,0 +1,128 @@ +/* Target-dependent code for OpenBSD/hppa + + Copyright (C) 2004, 2005, 2006, 2008 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ + +#include "defs.h" +#include "osabi.h" +#include "regcache.h" +#include "regset.h" + +#include "gdb_assert.h" +#include "gdb_string.h" + +#include "hppa-tdep.h" + +/* Core file support. */ + +/* Sizeof `struct reg' in <machine/reg.h>. */ +#define HPPABSD_SIZEOF_GREGS (34 * 4) + +/* Supply register REGNUM from the buffer specified by GREGS and LEN + in the general-purpose register set REGSET to register cache + REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */ + +static void +hppabsd_supply_gregset (const struct regset *regset, struct regcache *regcache, + int regnum, const void *gregs, size_t len) +{ + const gdb_byte *regs = gregs; + size_t offset; + int i; + + gdb_assert (len >= HPPABSD_SIZEOF_GREGS); + + for (i = HPPA_R1_REGNUM, offset = 4; i <= HPPA_R31_REGNUM; i++, offset += 4) + { + if (regnum == -1 || regnum == i) + regcache_raw_supply (regcache, i, regs + offset); + } + + if (regnum == -1 || regnum == HPPA_SAR_REGNUM) + regcache_raw_supply (regcache, HPPA_SAR_REGNUM, regs); + if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM) + regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4); + if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM) + regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4); +} + +/* OpenBSD/hppa register set. */ + +static struct regset hppabsd_gregset = +{ + NULL, + hppabsd_supply_gregset +}; + +/* Return the appropriate register set for the core section identified + by SECT_NAME and SECT_SIZE. */ + +static const struct regset * +hppaobsd_regset_from_core_section (struct gdbarch *gdbarch, + const char *sect_name, size_t sect_size) +{ + if (strcmp (sect_name, ".reg") == 0 && sect_size >= HPPABSD_SIZEOF_GREGS) + return &hppabsd_gregset; + + return NULL; +} + + +void hppabsd_init_abi (struct gdbarch_info, struct gdbarch *); + +void +hppaobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) +{ + /* Obviously OpenBSD is BSD-based. */ + hppabsd_init_abi (info, gdbarch); + + /* Core file support. */ + set_gdbarch_regset_from_core_section + (gdbarch, hppaobsd_regset_from_core_section); + +} + + +/* OpenBSD uses uses the traditional NetBSD core file format, even for + ports that use ELF. */ +#define GDB_OSABI_NETBSD_CORE GDB_OSABI_OPENBSD_ELF + +static enum gdb_osabi +hppaobsd_core_osabi_sniffer (bfd *abfd) +{ + if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0) + return GDB_OSABI_NETBSD_CORE; + + return GDB_OSABI_UNKNOWN; +} + + +/* Provide a prototype to silence -Wmissing-prototypes. */ +void _initialize_hppabsd_tdep (void); + +void +_initialize_hppabsd_tdep (void) +{ + /* BFD doesn't set a flavour for NetBSD style a.out core files. */ + gdbarch_register_osabi_sniffer (bfd_arch_hppa, bfd_target_unknown_flavour, + hppaobsd_core_osabi_sniffer); + + gdbarch_register_osabi (bfd_arch_hppa, 0, GDB_OSABI_OPENBSD_ELF, + hppaobsd_init_abi); +} |