summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gnu/usr.bin/binutils/gdb/bsd-kvm.c211
-rw-r--r--gnu/usr.bin/binutils/gdb/bsd-kvm.h30
-rw-r--r--gnu/usr.bin/binutils/gdb/config/nm-bsd.h29
-rw-r--r--gnu/usr.bin/binutils/gdb/config/powerpc/obsd.mt4
-rw-r--r--gnu/usr.bin/binutils/gdb/hppabsd-nat.c125
-rw-r--r--gnu/usr.bin/binutils/gdb/m68kbsd-nat.c218
-rw-r--r--gnu/usr.bin/binutils/gdb/m68kbsd-tdep.c228
-rw-r--r--gnu/usr.bin/binutils/gdb/ppcobsd-tdep.c305
-rw-r--r--gnu/usr.bin/binutils/gdb/ppcobsd-tdep.h74
-rw-r--r--gnu/usr.bin/binutils/gdb/vaxbsd-nat.c94
-rw-r--r--gnu/usr.bin/binutils/gdb/vaxnbsd-tdep.c75
11 files changed, 1393 insertions, 0 deletions
diff --git a/gnu/usr.bin/binutils/gdb/bsd-kvm.c b/gnu/usr.bin/binutils/gdb/bsd-kvm.c
new file mode 100644
index 00000000000..b8ef075b831
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/bsd-kvm.c
@@ -0,0 +1,211 @@
+/* BSD Kernel Data Access Library (libkvm) interface.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "frame.h"
+#include "regcache.h"
+#include "target.h"
+
+#include "gdb_assert.h"
+#include <fcntl.h>
+#include <kvm.h>
+#include <nlist.h>
+#include "readline/readline.h"
+#include <sys/param.h>
+#include <sys/user.h>
+
+#include "bsd-kvm.h"
+
+/* Kernel memory interface descriptor. */
+kvm_t *core_kd;
+
+/* Address of process control block. */
+struct pcb *bsd_kvm_paddr;
+
+/* Target ops for libkvm interface. */
+struct target_ops bsd_kvm_ops;
+
+static void
+bsd_kvm_open (char *filename, int from_tty)
+{
+ char errbuf[_POSIX2_LINE_MAX];
+ char *execfile = NULL;
+ kvm_t *temp_kd;
+
+ target_preopen (from_tty);
+
+ if (filename)
+ {
+ char *temp;
+
+ filename = tilde_expand (filename);
+ if (filename[0] != '/')
+ {
+ temp = concat (current_directory, "/", filename, NULL);
+ xfree (filename);
+ filename = temp;
+ }
+ }
+
+ temp_kd = kvm_openfiles (execfile, filename, NULL, O_RDONLY, errbuf);
+ if (temp_kd == NULL)
+ error ("%s", errbuf);
+
+ unpush_target (&bsd_kvm_ops);
+ core_kd = temp_kd;
+ push_target (&bsd_kvm_ops);
+
+ target_fetch_registers (-1);
+
+ flush_cached_frames ();
+ select_frame (get_current_frame ());
+ print_stack_frame (get_selected_frame (), -1, 1);
+}
+
+static void
+bsd_kvm_close (int quitting)
+{
+ if (core_kd)
+ {
+ if (kvm_close (core_kd) == -1)
+ warning ("%s", kvm_geterr(core_kd));
+ core_kd = NULL;
+ }
+}
+
+static int
+bsd_kvm_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+ int write, struct mem_attrib *attrib,
+ struct target_ops *ops)
+{
+ if (write)
+ return kvm_write (core_kd, memaddr, myaddr, len);
+ else
+ return kvm_read (core_kd, memaddr, myaddr, len);
+
+ return -1;
+}
+
+static int
+bsd_kvm_fetch_pcb (struct pcb *paddr)
+{
+ struct pcb pcb;
+
+ if (kvm_read (core_kd, (unsigned long) paddr, &pcb, sizeof pcb) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ gdb_assert (bsd_kvm_supply_pcb);
+ return bsd_kvm_supply_pcb (current_regcache, &pcb);
+}
+
+static void
+bsd_kvm_fetch_registers (int regnum)
+{
+ struct nlist nl[2];
+
+ if (bsd_kvm_paddr)
+ bsd_kvm_fetch_pcb (bsd_kvm_paddr);
+
+ /* On dumping core, BSD kernels store the faulting context (PCB)
+ in the variable "dumppcb". */
+ memset (nl, 0, sizeof nl);
+ nl[0].n_name = "_dumppcb";
+
+ if (kvm_nlist (core_kd, nl) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ if (nl[0].n_value != 0)
+ {
+ /* Found dumppcb. If it contains a valid context, return
+ immediately. */
+ if (bsd_kvm_fetch_pcb ((struct pcb *) nl[0].n_value))
+ return;
+ }
+
+ /* Traditional BSD kernels have a process proc0 that should always
+ be present. The address of proc0's PCB is stored in the variable
+ "proc0paddr". */
+
+ memset (nl, 0, sizeof nl);
+ nl[0].n_name = "_proc0paddr";
+
+ if (kvm_nlist (core_kd, nl) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ if (nl[0].n_value != 0)
+ {
+ struct pcb *paddr;
+
+ /* Found proc0paddr. */
+ if (kvm_read (core_kd, nl[0].n_value, &paddr, sizeof paddr) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ bsd_kvm_fetch_pcb (paddr);
+ return;
+ }
+
+#ifdef HAVE_STRUCT_THREAD_TD_PCB
+ /* In FreeBSD kernels for 5.0-RELEASE and later, the PCB no longer
+ lives in `struct proc' but in `struct thread'. The `struct
+ thread' for the initial thread for proc0 can be found in the
+ variable "thread0". */
+
+ memset (nl, 0, sizeof nl);
+ nl[0].n_name = "_thread0";
+
+ if (kvm_nlist (core_kd, nl) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ if (nl[0].n_value != 0)
+ {
+ struct pcb *paddr;
+
+ /* Found thread0. */
+ nl[1].n_value += offsetof (struct thread, td_pcb);
+ if (kvm_read (core_kd, nl[1].n_value, &paddr, sizeof paddr) == -1)
+ error ("%s", kvm_geterr (core_kd));
+
+ bsd_kvm_fetch_pcb (paddr);
+ return;
+ }
+#endif
+
+ error ("Cannot find a valid PCB");
+}
+
+void
+_initialize_bsd_kvm (void)
+{
+ bsd_kvm_ops.to_shortname = "kvm";
+ bsd_kvm_ops.to_longname = "Kernel memory interface";
+ bsd_kvm_ops.to_doc = "XXX";
+ bsd_kvm_ops.to_open = bsd_kvm_open;
+ bsd_kvm_ops.to_close = bsd_kvm_close;
+ bsd_kvm_ops.to_fetch_registers = bsd_kvm_fetch_registers;
+ bsd_kvm_ops.to_xfer_memory = bsd_kvm_xfer_memory;
+ bsd_kvm_ops.to_stratum = process_stratum;
+ bsd_kvm_ops.to_has_memory = 1;
+ bsd_kvm_ops.to_has_stack = 1;
+ bsd_kvm_ops.to_has_registers = 1;
+ bsd_kvm_ops.to_magic = OPS_MAGIC;
+
+ add_target (&bsd_kvm_ops);
+}
diff --git a/gnu/usr.bin/binutils/gdb/bsd-kvm.h b/gnu/usr.bin/binutils/gdb/bsd-kvm.h
new file mode 100644
index 00000000000..129a2f20c72
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/bsd-kvm.h
@@ -0,0 +1,30 @@
+/* BSD Kernel Data Access Library (libkvm) interface.
+
+ Copyright 2004 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 BSD_KVM_H
+#define BSD_KVM_H
+
+struct pcb;
+struct regcache;
+
+extern int bsd_kvm_supply_pcb (struct regcache *regache, struct pcb *pcb);
+
+#endif /* bsd-kvm.h */
diff --git a/gnu/usr.bin/binutils/gdb/config/nm-bsd.h b/gnu/usr.bin/binutils/gdb/config/nm-bsd.h
new file mode 100644
index 00000000000..b44dd5eff1d
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/config/nm-bsd.h
@@ -0,0 +1,29 @@
+/* Native-dependent definitions for *BSD.
+
+ Copyright 2001, 2004 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. */
+
+/* Type of the third argument to the `ptrace' system call. */
+#define PTRACE_ARG3_TYPE caddr_t
+
+/* Override copies of {fetch,store}_inferior_registers in `infptrace.c'. */
+#define FETCH_INFERIOR_REGISTERS
+
+/* We can attach and detach. */
+#define ATTACH_DETACH
diff --git a/gnu/usr.bin/binutils/gdb/config/powerpc/obsd.mt b/gnu/usr.bin/binutils/gdb/config/powerpc/obsd.mt
new file mode 100644
index 00000000000..44418325270
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/config/powerpc/obsd.mt
@@ -0,0 +1,4 @@
+# Target: OpenBSD/powerpc
+TDEPFILES= rs6000-tdep.o ppc-sysv-tdep.o ppcobsd-tdep.o \
+ corelow.o solib.o solib-svr4.o
+TM_FILE= tm-nbsd.h
diff --git a/gnu/usr.bin/binutils/gdb/hppabsd-nat.c b/gnu/usr.bin/binutils/gdb/hppabsd-nat.c
new file mode 100644
index 00000000000..4db3ab864de
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/hppabsd-nat.c
@@ -0,0 +1,125 @@
+/* Native-dependent code for HP PA-RISC BSD's.
+
+ Copyright 2004 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. */
+
+#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"
+
+static int
+hppabsd_gregset_supplies_p (int regnum)
+{
+ return (regnum >= HPPA_R0_REGNUM && regnum <= HPPA_PCOQ_TAIL_REGNUM);
+}
+
+static int
+hppabsd_fpregset_supplies_p (int regnum)
+{
+ return 0;
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+hppabsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = 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);
+ regcache_raw_supply (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+ regcache_raw_supply (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+hppabsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = HPPA_R1_REGNUM; i <= HPPA_R31_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, regnum, regs + i * 4);
+ }
+
+ if (regnum == -1 || regnum == HPPA_SAR_REGNUM)
+ regcache_raw_collect (regcache, HPPA_SAR_REGNUM, regs);
+ if (regnum == -1 || regnum == HPPA_PCOQ_HEAD_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_HEAD_REGNUM, regs + 32 * 4);
+ if (regnum == -1 || regnum == HPPA_PCOQ_TAIL_REGNUM)
+ regcache_raw_collect (regcache, HPPA_PCOQ_TAIL_REGNUM, regs + 33 * 4);
+}
+
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+void
+fetch_inferior_registers (int regnum)
+{
+ struct regcache *regcache = current_regcache;
+
+ if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ hppabsd_supply_gregset (regcache, &regs);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+void
+store_inferior_registers (int regnum)
+{
+ if (regnum == -1 || hppabsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ hppabsd_collect_gregset (current_regcache, &regs, regnum);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+ }
+}
diff --git a/gnu/usr.bin/binutils/gdb/m68kbsd-nat.c b/gnu/usr.bin/binutils/gdb/m68kbsd-nat.c
new file mode 100644
index 00000000000..8954a164189
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/m68kbsd-nat.c
@@ -0,0 +1,218 @@
+/* Native-dependent code for Motorola 68000 BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "gdbcore.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include "gdb_assert.h"
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "m68k-tdep.h"
+
+static int
+m68kbsd_gregset_supplies_p (int regnum)
+{
+ return (regnum >= M68K_D0_REGNUM && regnum <= M68K_PC_REGNUM);
+}
+
+static int
+m68kbsd_fpregset_supplies_p (int regnum)
+{
+ return (regnum >= M68K_FP0_REGNUM && regnum <= M68K_FPI_REGNUM);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+m68kbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = M68K_D0_REGNUM; regnum <= M68K_PC_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
+
+static void
+m68kbsd_supply_fpregset (struct regcache *regcache, const void *fpregs)
+{
+ const char *regs = fpregs;
+ int regnum;
+
+ for (regnum = M68K_FP0_REGNUM; regnum <= M68K_FPI_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum,
+ regs + m68kbsd_fpreg_offset (regnum));
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+m68kbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, regnum, regs + i * 4);
+ }
+}
+
+/* Collect the floating-point registers from REGCACHE and store them
+ in FPREGS. */
+
+static void
+m68kbsd_collect_fpregset (struct regcache *regcache,
+ void *fpregs, int regnum)
+{
+ char *regs = fpregs;
+ int i;
+
+ for (i = M68K_FP0_REGNUM; i <= M68K_FPI_REGNUM; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, regnum,
+ regs + m68kbsd_fpreg_offset (i));
+ }
+}
+
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers (including the floating-point registers). */
+
+void
+fetch_inferior_registers (int regnum)
+{
+ if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ m68kbsd_supply_gregset (current_regcache, &regs);
+ }
+
+ if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ m68kbsd_supply_fpregset (current_regcache, &fpregs);
+ }
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers (including the floating-point registers). */
+
+void
+store_inferior_registers (int regnum)
+{
+ if (regnum == -1 || m68kbsd_gregset_supplies_p (regnum))
+ {
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ m68kbsd_collect_gregset (current_regcache, &regs, regnum);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+ }
+
+ if (regnum == -1 || m68kbsd_fpregset_supplies_p (regnum))
+ {
+ struct fpreg fpregs;
+
+ if (ptrace (PT_GETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't get floating point status");
+
+ m68kbsd_collect_fpregset (current_regcache, &fpregs, regnum);
+
+ if (ptrace (PT_SETFPREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &fpregs, 0) == -1)
+ perror_with_name ("Couldn't write floating point status");
+ }
+}
+
+
+/* Support for debugging kernel virtual memory images. */
+
+#include <sys/types.h>
+#include <machine/pcb.h>
+
+#include "bsd-kvm.h"
+
+/* OpenBSD doesn't have these. */
+#ifndef PCB_REGS_FP
+#define PCB_REGS_FP 10
+#endif
+#ifndef PCB_REGS_SP
+#define PCB_REGS_SP 11
+#endif
+
+int
+bsd_kvm_supply_pcb (struct regcache *regcache, struct pcb *pcb)
+{
+ int regnum, tmp;
+ int i = 0;
+
+ /* The following is true for NetBSD 1.6.2:
+
+ The pcb contains %d2...%d7, %a2...%a7 and %ps. This accounts for
+ all callee-saved registers. From this information we reconstruct
+ the register state as it would look when we just returned from
+ cpu_switch(). */
+
+ /* The stack pointer shouldn't be zero. */
+ if (pcb->pcb_regs[PCB_REGS_SP] == 0)
+ return 0;
+
+ for (regnum = M68K_D2_REGNUM; regnum <= M68K_D7_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
+ for (regnum = M68K_A2_REGNUM; regnum <= M68K_SP_REGNUM; regnum++)
+ regcache_raw_supply (regcache, regnum, &pcb->pcb_regs[i++]);
+
+ tmp = pcb->pcb_ps & 0xffff;
+ regcache_raw_supply (regcache, M68K_PS_REGNUM, &tmp);
+
+ read_memory (pcb->pcb_regs[PCB_REGS_FP] + 4, (char *) &tmp, sizeof tmp);
+ regcache_raw_supply (regcache, M68K_PC_REGNUM, &tmp);
+
+ return 1;
+}
diff --git a/gnu/usr.bin/binutils/gdb/m68kbsd-tdep.c b/gnu/usr.bin/binutils/gdb/m68kbsd-tdep.c
new file mode 100644
index 00000000000..40606684537
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/m68kbsd-tdep.c
@@ -0,0 +1,228 @@
+/* Target-dependent code for Motorola 68000 BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "gdb_assert.h"
+#include "gdb_string.h"
+
+#include "m68k-tdep.h"
+#include "solib-svr4.h"
+
+/* Core file support. */
+
+/* Sizeof `struct reg' in <machine/reg.h>. */
+#define M68KBSD_SIZEOF_GREGS (18 * 4)
+
+/* Sizeof `struct fpreg' in <machine/reg.h. */
+#define M68KBSD_SIZEOF_FPREGS (((8 * 3) + 3) * 4)
+
+int
+m68kbsd_fpreg_offset (int regnum)
+{
+ if (regnum >= M68K_FPC_REGNUM)
+ return 8 * 12 + (regnum - M68K_FPC_REGNUM) * 4;
+
+ return (regnum - M68K_FP0_REGNUM) * 12;
+}
+
+/* Supply register REGNUM from the buffer specified by FPREGS and LEN
+ in the floating-point register set REGSET to register cache
+ REGCACHE. If REGNUM is -1, do this for all registers in REGSET. */
+
+static void
+m68kbsd_supply_fpregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ const char *regs = fpregs;
+ int i;
+
+ gdb_assert (len >= M68KBSD_SIZEOF_FPREGS);
+
+ for (i = M68K_FP0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + m68kbsd_fpreg_offset (i));
+ }
+}
+
+/* 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
+m68kbsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ const char *regs = gregs;
+ int i;
+
+ gdb_assert (len >= M68KBSD_SIZEOF_GREGS);
+
+ for (i = M68K_D0_REGNUM; i <= M68K_PC_REGNUM; i++)
+ {
+ if (regnum == i || regnum == -1)
+ regcache_raw_supply (regcache, i, regs + i * 4);
+ }
+
+ if (len >= M68KBSD_SIZEOF_GREGS + M68KBSD_SIZEOF_FPREGS)
+ {
+ regs += M68KBSD_SIZEOF_GREGS;
+ len -= M68KBSD_SIZEOF_GREGS;
+ m68kbsd_supply_fpregset (regset, regcache, regnum, regs, len);
+ }
+}
+
+/* Motorola 68000 register sets. */
+
+static struct regset m68kbsd_gregset =
+{
+ NULL,
+ m68kbsd_supply_gregset
+};
+
+static struct regset m68kbsd_fpregset =
+{
+ NULL,
+ m68kbsd_supply_fpregset
+};
+
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+static const struct regset *
+m68kbsd_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0 && sect_size >= M68KBSD_SIZEOF_GREGS)
+ return &m68kbsd_gregset;
+
+ if (strcmp (sect_name, ".reg2") == 0 && sect_size >= M68KBSD_SIZEOF_FPREGS)
+ return &m68kbsd_fpregset;
+
+ return NULL;
+}
+
+
+/* Support for shared libraries. */
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+
+int
+m68kbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ return (name && !strcmp (name, "_DYNAMIC"));
+}
+
+
+static void
+m68kbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ tdep->jb_pc = 5;
+ tdep->jb_elt_size = 4;
+
+ set_gdbarch_regset_from_core_section
+ (gdbarch, m68kbsd_regset_from_core_section);
+}
+
+/* OpenBSD and NetBSD a.out. */
+
+static void
+m68kbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ m68kbsd_init_abi (info, gdbarch);
+
+ tdep->struct_return = reg_struct_return;
+
+ /* Assume SunOS-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, m68kbsd_aout_in_solib_call_trampoline);
+}
+
+/* NetBSD ELF. */
+
+static void
+m68kbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ m68kbsd_init_abi (info, gdbarch);
+
+ /* NetBSD ELF uses the SVR4 ABI. */
+ m68k_svr4_init_abi (info, gdbarch);
+ tdep->struct_return = pcc_struct_return;
+
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, generic_in_solib_call_trampoline);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+
+static enum gdb_osabi
+m68kbsd_aout_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "a.out-m68k-netbsd") == 0
+ || strcmp (bfd_get_target (abfd), "a.out-m68k4k-netbsd") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+static enum gdb_osabi
+m68kbsd_core_osabi_sniffer (bfd *abfd)
+{
+ if (strcmp (bfd_get_target (abfd), "netbsd-core") == 0)
+ return GDB_OSABI_NETBSD_AOUT;
+
+ return GDB_OSABI_UNKNOWN;
+}
+
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_m68kbsd_tdep (void);
+
+void
+_initialize_m68kbsd_tdep (void)
+{
+ gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_aout_flavour,
+ m68kbsd_aout_osabi_sniffer);
+
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_m68k, bfd_target_unknown_flavour,
+ m68kbsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_AOUT,
+ m68kbsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_m68k, 0, GDB_OSABI_NETBSD_ELF,
+ m68kbsd_elf_init_abi);
+}
diff --git a/gnu/usr.bin/binutils/gdb/ppcobsd-tdep.c b/gnu/usr.bin/binutils/gdb/ppcobsd-tdep.c
new file mode 100644
index 00000000000..dd6afddd7ad
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/ppcobsd-tdep.c
@@ -0,0 +1,305 @@
+/* Target-dependent code for OpenBSD/powerpc.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+#include "regcache.h"
+#include "regset.h"
+
+#include "gdb_string.h"
+
+#include "ppc-tdep.h"
+#include "ppcobsd-tdep.h"
+#include "solib-svr4.h"
+
+
+/* Register set support functions. */
+
+/* FIXME: kettenis/20040418: There is nothing OpenBSD-specific about
+ the functions on this page; they were written to be as general as
+ possible. This stuff should probably be moved to rs6000-tdep.c or
+ perhaps a new ppc-tdep.c. */
+
+static void
+ppc_supply_reg (struct regcache *regcache, int regnum,
+ const char *regs, size_t offset)
+{
+ if (regnum != -1 && offset != -1)
+ regcache_raw_supply (regcache, regnum, regs + offset);
+}
+
+static void
+ppc_collect_reg (const struct regcache *regcache, int regnum,
+ char *regs, size_t offset)
+{
+ if (regnum != -1 && offset != -1)
+ regcache_raw_collect (regcache, regnum, regs + offset);
+}
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+void
+ppc_supply_gregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *gregs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const struct ppc_reg_offsets *offsets = regset->descr;
+ size_t offset;
+ int i;
+
+ for (i = 0, offset = offsets->r0_offset; i < 32; i++, offset += 4)
+ {
+ if (regnum == -1 || regnum == i)
+ ppc_supply_reg (regcache, i, gregs, offset);
+ }
+
+ if (regnum == -1 || regnum == PC_REGNUM)
+ ppc_supply_reg (regcache, PC_REGNUM, gregs, offsets->pc_offset);
+ if (regnum == -1 || regnum == tdep->ppc_ps_regnum)
+ ppc_supply_reg (regcache, tdep->ppc_ps_regnum,
+ gregs, offsets->ps_offset);
+ if (regnum == -1 || regnum == tdep->ppc_cr_regnum)
+ ppc_supply_reg (regcache, tdep->ppc_cr_regnum,
+ gregs, offsets->cr_offset);
+ if (regnum == -1 || regnum == tdep->ppc_lr_regnum)
+ ppc_supply_reg (regcache, tdep->ppc_lr_regnum,
+ gregs, offsets->lr_offset);
+ if (regnum == -1 || regnum == tdep->ppc_ctr_regnum)
+ ppc_supply_reg (regcache, tdep->ppc_ctr_regnum,
+ gregs, offsets->ctr_offset);
+ if (regnum == -1 || regnum == tdep->ppc_xer_regnum)
+ ppc_supply_reg (regcache, tdep->ppc_xer_regnum,
+ gregs, offsets->cr_offset);
+ if (regnum == -1 || regnum == tdep->ppc_mq_regnum)
+ ppc_supply_reg (regcache, tdep->ppc_mq_regnum, gregs, offsets->mq_offset);
+}
+
+/* Supply the floating-point registers stored in FPREGS to REGCACHE. */
+
+void
+ppc_supply_fpregset (const struct regset *regset, struct regcache *regcache,
+ int regnum, const void *fpregs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const struct ppc_reg_offsets *offsets = regset->descr;
+ size_t offset;
+ int i;
+
+ offset = offsets->f0_offset;
+ for (i = FP0_REGNUM; i < FP0_REGNUM + 32; i++, offset += 4)
+ {
+ if (regnum == -1 || regnum == i)
+ ppc_supply_reg (regcache, i, fpregs, offset);
+ }
+
+ if (regnum == -1 || regnum == tdep->ppc_fpscr_regnum)
+ ppc_supply_reg (regcache, tdep->ppc_fpscr_regnum,
+ fpregs, offsets->fpscr_offset);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+void
+ppc_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const struct ppc_reg_offsets *offsets = &ppcobsd_reg_offsets;
+ size_t offset;
+ int i;
+
+ offset = offsets->r0_offset;
+ for (i = 0; i <= 32; i++, offset += 4)
+ {
+ if (regnum == -1 || regnum == i)
+ ppc_collect_reg (regcache, regnum, gregs, offset);
+ }
+
+ if (regnum == -1 || regnum == PC_REGNUM)
+ ppc_collect_reg (regcache, PC_REGNUM, gregs, offsets->pc_offset);
+ if (regnum == -1 || regnum == tdep->ppc_ps_regnum)
+ ppc_collect_reg (regcache, tdep->ppc_ps_regnum,
+ gregs, offsets->ps_offset);
+ if (regnum == -1 || regnum == tdep->ppc_cr_regnum)
+ ppc_collect_reg (regcache, tdep->ppc_cr_regnum,
+ gregs, offsets->cr_offset);
+ if (regnum == -1 || regnum == tdep->ppc_lr_regnum)
+ ppc_collect_reg (regcache, tdep->ppc_lr_regnum,
+ gregs, offsets->lr_offset);
+ if (regnum == -1 || regnum == tdep->ppc_ctr_regnum)
+ ppc_collect_reg (regcache, tdep->ppc_ctr_regnum,
+ gregs, offsets->ctr_offset);
+ if (regnum == -1 || regnum == tdep->ppc_xer_regnum)
+ ppc_collect_reg (regcache, tdep->ppc_xer_regnum,
+ gregs, offsets->xer_offset);
+ if (regnum == -1 || regnum == tdep->ppc_mq_regnum)
+ ppc_collect_reg (regcache, tdep->ppc_mq_regnum,
+ gregs, offsets->mq_offset);
+}
+
+/* Collect the floating-point registers from REGCACHE and store them
+ in FPREGS. */
+
+void
+ppc_collect_fpregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *fpregs, size_t len)
+{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ const struct ppc_reg_offsets *offsets = &ppcobsd_reg_offsets;
+ size_t offset;
+ int i;
+
+ offset = offsets->f0_offset;
+ for (i = FP0_REGNUM; i <= FP0_REGNUM + 32; i++, offset += 4)
+ {
+ if (regnum == -1 || regnum == i)
+ ppc_collect_reg (regcache, regnum, fpregs, offset);
+ }
+
+ if (regnum == -1 || regnum == tdep->ppc_fpscr_regnum)
+ ppc_collect_reg (regcache, tdep->ppc_fpscr_regnum,
+ fpregs, offsets->fpscr_offset);
+}
+
+
+/* Register offsets from <machine/reg.h>. */
+struct ppc_reg_offsets ppcobsd_reg_offsets;
+
+
+/* Core file support. */
+
+/* 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. */
+
+void
+ppcobsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len)
+{
+ ppc_supply_gregset (regset, regcache, regnum, gregs, len);
+ ppc_supply_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+void
+ppcobsd_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache, int regnum,
+ void *gregs, size_t len)
+{
+ ppc_collect_gregset (regset, regcache, regnum, gregs, len);
+ ppc_collect_fpregset (regset, regcache, regnum, gregs, len);
+}
+
+/* OpenBS/macppc register set. */
+
+struct regset ppcobsd_gregset =
+{
+ &ppcobsd_reg_offsets,
+ ppcobsd_supply_gregset
+};
+
+/* Return the appropriate register set for the core section identified
+ by SECT_NAME and SECT_SIZE. */
+
+static const struct regset *
+ppcobsd_regset_from_core_section (struct gdbarch *gdbarch,
+ const char *sect_name, size_t sect_size)
+{
+ if (strcmp (sect_name, ".reg") == 0 && sect_size >= 412)
+ return &ppcobsd_gregset;
+
+ return NULL;
+}
+
+
+static void
+ppcobsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* OpenBSD uses SVR4-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, generic_in_solib_call_trampoline);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+
+ set_gdbarch_regset_from_core_section
+ (gdbarch, ppcobsd_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
+ppcobsd_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_ppcobsd_tdep (void);
+
+void
+_initialize_ppcobsd_tdep (void)
+{
+ /* BFD doesn't set a flavour for NetBSD style a.out core files. */
+ gdbarch_register_osabi_sniffer (bfd_arch_powerpc, bfd_target_unknown_flavour,
+ ppcobsd_core_osabi_sniffer);
+
+ gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_OPENBSD_ELF,
+ ppcobsd_init_abi);
+
+ /* Avoid initializing the register offsets again if they were
+ already initailized by ppcobsd-nat.c. */
+ if (ppcobsd_reg_offsets.pc_offset == 0)
+ {
+ /* General-purpose registers. */
+ ppcobsd_reg_offsets.r0_offset = 0;
+ ppcobsd_reg_offsets.pc_offset = 384;
+ ppcobsd_reg_offsets.ps_offset = 388;
+ ppcobsd_reg_offsets.cr_offset = 392;
+ ppcobsd_reg_offsets.lr_offset = 396;
+ ppcobsd_reg_offsets.ctr_offset = 400;
+ ppcobsd_reg_offsets.xer_offset = 404;
+ ppcobsd_reg_offsets.mq_offset = 408;
+
+ /* Floating-point registers. */
+ ppcobsd_reg_offsets.f0_offset = 128;
+ ppcobsd_reg_offsets.fpscr_offset = -1;
+
+ /* AltiVec registers. */
+ ppcobsd_reg_offsets.vr0_offset = 0;
+ ppcobsd_reg_offsets.vscr_offset = 512;
+ ppcobsd_reg_offsets.vrsave_offset = 520;
+ }
+}
diff --git a/gnu/usr.bin/binutils/gdb/ppcobsd-tdep.h b/gnu/usr.bin/binutils/gdb/ppcobsd-tdep.h
new file mode 100644
index 00000000000..4fd7fdbf6f5
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/ppcobsd-tdep.h
@@ -0,0 +1,74 @@
+/* Target-dependent code for OpenBSD/powerpc.
+
+ Copyright 2004 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 PPCOBSD_TDEP_H
+#define PPCOBSD_TDEP_H
+
+#include <stddef.h>
+
+struct regset;
+struct regcache;
+
+/* Register set description. */
+
+/* FIXME: kettenis/20040418: There is nothing OpenBSD-specific about
+ this structure; it was written to be as general as possible. This
+ stuff should probably be moved to ppc-tdep.h. */
+
+struct ppc_reg_offsets
+{
+ /* General-purpose registers. */
+ int r0_offset;
+ int pc_offset;
+ int ps_offset;
+ int cr_offset;
+ int lr_offset;
+ int ctr_offset;
+ int xer_offset;
+ int mq_offset;
+
+ /* Floating-point registers. */
+ int f0_offset;
+ int fpscr_offset;
+
+ /* AltiVec registers. */
+ int vr0_offset;
+ int vscr_offset;
+ int vrsave_offset;
+};
+
+
+/* Register offsets for OpenBSD/macppc. */
+extern struct ppc_reg_offsets ppcobsd_reg_offsets;
+
+/* Register sets for OpenBSD/macppc. */
+extern struct regset ppcobsd_gregset;
+
+
+extern void ppcobsd_supply_gregset (const struct regset *regset,
+ struct regcache *regcache, int regnum,
+ const void *gregs, size_t len);
+
+extern void ppcobsd_collect_gregset (const struct regset *regset,
+ const struct regcache *regcache,
+ int regnum, void *gregs, size_t len);
+
+#endif /* ppcobsd-tdep.h */
diff --git a/gnu/usr.bin/binutils/gdb/vaxbsd-nat.c b/gnu/usr.bin/binutils/gdb/vaxbsd-nat.c
new file mode 100644
index 00000000000..d3516f6b86b
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/vaxbsd-nat.c
@@ -0,0 +1,94 @@
+/* Native-dependent code for VAX BSD's.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "inferior.h"
+#include "regcache.h"
+
+#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <machine/reg.h>
+
+#include "vax-tdep.h"
+
+/* Supply the general-purpose registers stored in GREGS to REGCACHE. */
+
+static void
+vaxbsd_supply_gregset (struct regcache *regcache, const void *gregs)
+{
+ const char *regs = gregs;
+ int regnum;
+
+ for (regnum = 0; regnum < VAX_NUM_REGS; regnum++)
+ regcache_raw_supply (regcache, regnum, regs + regnum * 4);
+}
+
+/* Collect the general-purpose registers from REGCACHE and store them
+ in GREGS. */
+
+static void
+vaxbsd_collect_gregset (const struct regcache *regcache,
+ void *gregs, int regnum)
+{
+ char *regs = gregs;
+ int i;
+
+ for (i = 0; i <= VAX_NUM_REGS; i++)
+ {
+ if (regnum == -1 || regnum == i)
+ regcache_raw_collect (regcache, regnum, regs + i * 4);
+ }
+}
+
+
+/* Fetch register REGNUM from the inferior. If REGNUM is -1, do this
+ for all registers. */
+
+void
+fetch_inferior_registers (int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ vaxbsd_supply_gregset (current_regcache, &regs);
+}
+
+/* Store register REGNUM back into the inferior. If REGNUM is -1, do
+ this for all registers. */
+
+void
+store_inferior_registers (int regnum)
+{
+ struct reg regs;
+
+ if (ptrace (PT_GETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't get registers");
+
+ vaxbsd_collect_gregset (current_regcache, &regs, regnum);
+
+ if (ptrace (PT_SETREGS, PIDGET (inferior_ptid),
+ (PTRACE_ARG3_TYPE) &regs, 0) == -1)
+ perror_with_name ("Couldn't write registers");
+}
diff --git a/gnu/usr.bin/binutils/gdb/vaxnbsd-tdep.c b/gnu/usr.bin/binutils/gdb/vaxnbsd-tdep.c
new file mode 100644
index 00000000000..c324da8cd43
--- /dev/null
+++ b/gnu/usr.bin/binutils/gdb/vaxnbsd-tdep.c
@@ -0,0 +1,75 @@
+/* Target-dependent code for NetBSD/vax.
+
+ Copyright 2004 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. */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "osabi.h"
+
+#include "vax-tdep.h"
+#include "solib-svr4.h"
+
+#include "gdb_string.h"
+
+/* Support for shared libraries. */
+
+/* Return non-zero if we are in a shared library trampoline code stub. */
+
+int
+vaxnbsd_aout_in_solib_call_trampoline (CORE_ADDR pc, char *name)
+{
+ return (name && !strcmp (name, "_DYNAMIC"));
+}
+
+
+/* NetBSD a.out. */
+
+static void
+vaxnbsd_aout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* Assume SunOS-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, vaxnbsd_aout_in_solib_call_trampoline);
+}
+
+/* NetBSD ELF. */
+
+static void
+vaxnbsd_elf_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
+{
+ /* NetBSD ELF uses SVR4-style shared libraries. */
+ set_gdbarch_in_solib_call_trampoline
+ (gdbarch, generic_in_solib_call_trampoline);
+ set_solib_svr4_fetch_link_map_offsets
+ (gdbarch, svr4_ilp32_fetch_link_map_offsets);
+}
+
+
+/* Provide a prototype to silence -Wmissing-prototypes. */
+void _initialize_vaxnbsd_tdep (void);
+
+void
+_initialize_vaxnbsd_tdep (void)
+{
+ gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD_AOUT,
+ vaxnbsd_aout_init_abi);
+ gdbarch_register_osabi (bfd_arch_vax, 0, GDB_OSABI_NETBSD_ELF,
+ vaxnbsd_elf_init_abi);
+}