summaryrefslogtreecommitdiff
path: root/devel/gdb66/files/patch-kvm-fbsd.c
diff options
context:
space:
mode:
authorMark Peek <mp@FreeBSD.org>2002-10-13 21:22:39 +0000
committerMark Peek <mp@FreeBSD.org>2002-10-13 21:22:39 +0000
commit838ce26f5fda580254c3b64f81e5d676a688d714 (patch)
tree6f9a248ee4c5dba60973a912c14049cf643cf7a8 /devel/gdb66/files/patch-kvm-fbsd.c
parent- Use MASTER_SITE_SUBDIR. (diff)
Patches to get FreeBSD changes working with gdb-5.3.
Diffstat (limited to 'devel/gdb66/files/patch-kvm-fbsd.c')
-rw-r--r--devel/gdb66/files/patch-kvm-fbsd.c1209
1 files changed, 419 insertions, 790 deletions
diff --git a/devel/gdb66/files/patch-kvm-fbsd.c b/devel/gdb66/files/patch-kvm-fbsd.c
index e5a83f189cfb..0bee0da4b20c 100644
--- a/devel/gdb66/files/patch-kvm-fbsd.c
+++ b/devel/gdb66/files/patch-kvm-fbsd.c
@@ -1,8 +1,9 @@
---- gdb/kvm-fbsd.c Mon Jun 3 11:32:24 2002
-+++ gdb/kvm-fbsd.c Mon Jun 3 11:30:35 2002
-@@ -0,0 +1,1055 @@
-+/* Live and postmortem kernel debugging functions for FreeBSD.
-+ Copyright 1996 Free Software Foundation, Inc.
+--- gdb/kvm-fbsd.c Wed Dec 31 16:00:00 1969
++++ gdb/kvm-fbsd.c Sun Oct 13 13:57:00 2002
+@@ -0,0 +1,684 @@
++/* Kernel core dump functions below target vector, for GDB.
++ Copyright 1986, 1987, 1989, 1991, 1992, 1993, 1994, 1995
++ Free Software Foundation, Inc.
+
+This file is part of GDB.
+
@@ -18,22 +19,38 @@
+
+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. */
++Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
++*/
+
-+/* $FreeBSD: /tmp/pcvs/ports/devel/gdb66/files/Attic/patch-kvm-fbsd.c,v 1.1 2002-06-06 03:56:34 mp Exp $ */
++/* $FreeBSD: /tmp/pcvs/ports/devel/gdb66/files/Attic/patch-kvm-fbsd.c,v 1.2 2002-10-13 21:22:39 mp Exp $ */
+
-+#include "defs.h"
++/*
++ * This works like "remote" but, you use it like this:
++ * target kcore /dev/mem
++ * or
++ * target kcore /var/crash/host/core.0
++ *
++ * This way makes it easy to short-circut the whole bfd monster,
++ * and direct the inferior stuff to our libkvm implementation.
++ *
++ */
+
++#include <sys/param.h>
++#include <sys/time.h>
++#include <sys/proc.h>
++#include <sys/user.h>
+#include <ctype.h>
+#include <errno.h>
+#include <signal.h>
+#include <fcntl.h>
-+#include <paths.h>
++#include <kvm.h>
+#include <sys/sysctl.h>
-+#include <sys/param.h>
-+#include <sys/time.h>
-+#include <sys/proc.h>
-+#include <sys/user.h>
++#include <paths.h>
++#include <readline/tilde.h>
++#include <machine/frame.h>
++
++#include "defs.h"
++#include "gdb_string.h"
+#include "frame.h" /* required by inferior.h */
+#include "inferior.h"
+#include "symtab.h"
@@ -43,254 +60,199 @@
+#include "bfd.h"
+#include "target.h"
+#include "gdbcore.h"
-+#include <sys/stat.h>
-+#include <unistd.h>
-+#include <vm/vm.h>
-+#include <vm/vm_param.h>
-+
-+#include <machine/vmparam.h>
-+#include <machine/pcb.h>
-+#include <machine/tss.h>
-+#include <machine/frame.h>
-+
-+#if __FreeBSD_version >= 500032 && defined(i386)
-+#define _KERNEL
-+#include <sys/pcpu.h>
-+#undef _KERNEL
-+
-+static void kcore_files_info PARAMS ((struct target_ops *));
-+
-+static void kcore_close PARAMS ((int));
-+
-+static void get_kcore_registers PARAMS ((int));
++#include "regcache.h"
+
-+static int kcore_xfer_kmem PARAMS ((CORE_ADDR, char *, int, int, struct mem_attrib *attrib, struct target_ops *));
-+
-+static int xfer_umem PARAMS ((CORE_ADDR, char *, int, int));
-+
-+static CORE_ADDR ksym_lookup PARAMS ((const char *));
-+
-+static int read_pcb PARAMS ((int, CORE_ADDR));
-+
-+static struct proc * curProc PARAMS ((void));
-+
-+static int set_proc_context PARAMS ((CORE_ADDR paddr));
-+
-+static void kcore_open PARAMS ((char *filename, int from_tty));
-+
-+static void kcore_detach PARAMS ((char *args, int from_tty));
-+
-+static void set_proc_cmd PARAMS ((char *arg, int from_tty));
-+
-+static void set_cpu_cmd PARAMS ((char *arg, int from_tty));
++static void
++kcore_files_info (struct target_ops *);
+
-+static CORE_ADDR kvtophys PARAMS ((int, CORE_ADDR));
++static void
++kcore_close (int);
+
-+static int physrd PARAMS ((int, u_int, char*, int));
++static void
++get_kcore_registers (int);
+
-+static int kvm_open PARAMS ((const char *efile, char *cfile, char *sfile,
-+ int perm, char *errout));
++static int
++xfer_mem (CORE_ADDR, char *, int, int, struct mem_attrib *,
++ struct target_ops *);
+
-+static int kvm_close PARAMS ((int fd));
++static int
++xfer_umem (CORE_ADDR, char *, int, int);
+
-+static int kvm_write PARAMS ((int core_kd, CORE_ADDR memaddr,
-+ char *myaddr, int len));
++static char *core_file;
++static kvm_t *core_kd;
++static struct pcb cur_pcb;
++static struct kinfo_proc *cur_proc;
+
-+static int kvm_read PARAMS ((int core_kd, CORE_ADDR memaddr,
-+ char *myaddr, int len));
++static struct target_ops kcore_ops;
+
-+static int kvm_uread PARAMS ((int core_kd, struct proc *p,
-+ CORE_ADDR memaddr, char *myaddr,
-+ int len));
++int kernel_debugging;
++int kernel_writablecore;
+
-+static int kernel_core_file_hook PARAMS ((int fd, CORE_ADDR addr,
-+ char *buf, int len));
++/* Read the "thing" at kernel address 'addr' into the space pointed to
++ by point. The length of the "thing" is determined by the type of p.
++ Result is non-zero if transfer fails. */
+
-+static CORE_ADDR kvm_getpcpu PARAMS ((int cfd, int cpuid));
++#define kvread(addr, p) \
++ (target_read_memory ((CORE_ADDR) (addr), (char *) (p), sizeof (*(p))))
+
-+static struct kinfo_proc * kvm_getprocs PARAMS ((int cfd, int op,
-+ CORE_ADDR proc, int *cnt));
++static CORE_ADDR
++ksym_kernbase (void)
++{
++ static CORE_ADDR kernbase;
++ struct minimal_symbol *sym;
+
-+extern struct target_ops kcore_ops; /* Forward decl */
++ if (kernbase == 0)
++ {
++ sym = lookup_minimal_symbol ("kernbase", NULL, NULL);
++ if (sym == NULL) {
++ kernbase = KERNBASE;
++ } else {
++ kernbase = SYMBOL_VALUE_ADDRESS (sym);
++ }
++ }
++ return kernbase;
++}
+
-+/* Non-zero means we are debugging a kernel core file */
-+int kernel_debugging = 0;
-+int kernel_writablecore = 0;
++#define KERNOFF (ksym_kernbase ())
++#define INKERNEL(x) ((x) >= KERNOFF)
+
-+static char *core_file;
-+static int core_kd = -1;
-+static struct proc *cur_proc;
-+static CORE_ADDR kernel_start;
++CORE_ADDR
++ksym_lookup(const char *name)
++{
++ struct minimal_symbol *sym;
+
-+static CORE_ADDR pcpu;
-+#define PCPU_OFFSET(name) \
-+ offsetof(struct pcpu, pc_ ## name)
++ sym = lookup_minimal_symbol (name, NULL, NULL);
++ if (sym == NULL)
++ error ("kernel symbol `%s' not found.", name);
+
-+/*
-+ * Symbol names of kernel entry points. Use special frames.
-+ */
-+#define KSYM_TRAP "calltrap"
-+#define KSYM_INTR "Xintr"
-+#define KSYM_FASTINTR "Xfastintr"
-+#define KSYM_SYSCALL "Xsyscall"
++ return SYMBOL_VALUE_ADDRESS (sym);
++}
+
-+/*
-+ * Read the "thing" at kernel address 'addr' into the space pointed to
-+ * by point. The length of the "thing" is determined by the type of p.
-+ * Result is non-zero if transfer fails.
-+ */
-+#define kvread(addr, p) \
-+ (target_read_memory ((CORE_ADDR)(addr), (char *)(p), sizeof(*(p))))
++/* Provide the address of an initial PCB to use.
++ If this is a crash dump, try for "dumppcb".
++ If no "dumppcb" or it's /dev/mem, use proc0.
++ Return the core address of the PCB we found. */
+
++static CORE_ADDR
++initial_pcb (void)
++{
++ struct minimal_symbol *sym;
++ CORE_ADDR addr;
++ void *val;
+
++ /* Make sure things are open... */
++ if (!core_kd || !core_file)
++ return (0);
+
-+/*
-+ * The following is FreeBSD-specific hackery to decode special frames
-+ * and elide the assembly-language stub. This could be made faster by
-+ * defining a frame_type field in the machine-dependent frame information,
-+ * but we don't think that's too important right now.
-+ */
-+enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall };
++ /* If this is NOT /dev/mem try for dumppcb. */
++ if (strncmp (core_file, _PATH_DEV, sizeof _PATH_DEV - 1))
++ {
++ sym = lookup_minimal_symbol ("dumppcb", NULL, NULL);
++ if (sym != NULL)
++ {
++ addr = SYMBOL_VALUE_ADDRESS (sym);
++ return (addr);
++ }
++ }
+
-+CORE_ADDR
-+fbsd_kern_frame_saved_pc (fr)
-+struct frame_info *fr;
-+{
-+ struct minimal_symbol *sym;
-+ CORE_ADDR this_saved_pc;
-+ enum frametype frametype;
-+
-+ this_saved_pc = read_memory_integer (fr->frame + 4, 4);
-+ sym = lookup_minimal_symbol_by_pc (this_saved_pc);
-+ frametype = tf_normal;
-+ if (sym != NULL) {
-+ if (strcmp (SYMBOL_NAME(sym), KSYM_TRAP) == 0)
-+ frametype = tf_trap;
-+ else if (strncmp (SYMBOL_NAME(sym), KSYM_INTR,
-+ strlen(KSYM_INTR)) == 0 || strncmp (SYMBOL_NAME(sym),
-+ KSYM_FASTINTR, strlen(KSYM_FASTINTR)) == 0)
-+ frametype = tf_interrupt;
-+ else if (strcmp (SYMBOL_NAME(sym), KSYM_SYSCALL) == 0)
-+ frametype = tf_syscall;
-+ }
-+
-+ switch (frametype) {
-+ case tf_normal:
-+ return (this_saved_pc);
-+
-+#define oEIP offsetof(struct trapframe, tf_eip)
-+
-+ case tf_trap:
-+ return (read_memory_integer (fr->frame + 8 + oEIP, 4));
-+
-+ case tf_interrupt:
-+ return (read_memory_integer (fr->frame + 12 + oEIP, 4));
-+
-+ case tf_syscall:
-+ return (read_memory_integer (fr->frame + 8 + oEIP, 4));
-+#undef oEIP
-+ }
-+}
++ /* OK, just use thread0's pcb. Note that curproc might
++ not exist, and if it does, it will point to gdb.
++ Therefore, just use proc0 and let the user set
++ some other context if they care about it. */
+
-+static CORE_ADDR
-+ksym_lookup (name)
-+const char *name;
-+{
-+ struct minimal_symbol *sym;
++ addr = ksym_lookup ("thread0");
++ if (kvread (addr, &val))
++ {
++ error ("cannot read thread0 pointer at %x\n", addr);
++ val = 0;
++ }
++ else
++ {
++ /* Read the PCB address in thread structure. */
++ addr += offsetof (struct thread, td_pcb);
++ if (kvread (addr, &val))
++ {
++ error ("cannot read thread0->td_pcb pointer at %x\n", addr);
++ val = 0;
++ }
++ }
+
-+ sym = lookup_minimal_symbol (name, NULL, NULL);
-+ if (sym == NULL)
-+ error ("kernel symbol `%s' not found.", name);
++ /* thread0 is wholly in the kernel and cur_proc is only used for
++ reading user mem, so no point in setting this up. */
++ cur_proc = 0;
+
-+ return SYMBOL_VALUE_ADDRESS (sym);
++ return ((CORE_ADDR)val);
+}
+
-+static struct proc *
-+curProc ()
-+{
-+ struct proc *p;
-+ struct thread *td;
-+ CORE_ADDR addr = pcpu + PCPU_OFFSET (curthread);
-+
-+ if (kvread (addr, &td))
-+ error ("cannot read thread pointer at %x\n", addr);
-+ addr = (CORE_ADDR)td + offsetof(struct thread, td_proc);
-+ if (kvread (addr, &p))
-+ error ("cannot read proc pointer at %x\n", addr);
-+ return p;
-+}
++/* Set the current context to that of the PCB struct at the system address
++ passed. */
+
-+/*
-+ * Set the process context to that of the proc structure at
-+ * system address paddr.
-+ */
+static int
-+set_proc_context (paddr)
-+ CORE_ADDR paddr;
++set_context (CORE_ADDR addr)
+{
-+ struct proc p;
++ CORE_ADDR procaddr = 0;
+
-+ if (paddr < kernel_start)
-+ return (1);
-+
-+ cur_proc = (struct proc *)paddr;
-+#ifdef notyet
-+ set_kernel_boundaries (cur_proc);
-+#endif
++ if (kvread (addr, &cur_pcb))
++ error ("cannot read pcb at %#x", addr);
+
-+ /* Fetch all registers from core file */
++ /* Fetch all registers from core file. */
+ target_fetch_registers (-1);
+
-+ /* Now, set up the frame cache, and print the top of stack */
++ /* Now, set up the frame cache, and print the top of stack. */
+ flush_cached_frames ();
+ set_current_frame (create_new_frame (read_fp (), read_pc ()));
-+ select_frame (get_current_frame (), 0);
++ select_frame (get_current_frame ());
+ return (0);
+}
+
-+/* Discard all vestiges of any previous core file
-+ and mark data and stack spaces as empty. */
++/* Discard all vestiges of any previous core file and mark data and stack
++ spaces as empty. */
+
+/* ARGSUSED */
+static void
-+kcore_close (quitting)
-+ int quitting;
++kcore_close (int quitting)
+{
-+ inferior_ptid = null_ptid; /* Avoid confusion from thread stuff */
++
++ inferior_ptid = null_ptid; /* Avoid confusion from thread stuff. */
+
+ if (core_kd)
+ {
+ kvm_close (core_kd);
+ free (core_file);
+ core_file = NULL;
-+ core_kd = -1;
++ core_kd = NULL;
+ }
+}
+
-+/* This routine opens and sets up the core file bfd */
++/* This routine opens and sets up the core file bfd. */
+
+static void
-+kcore_open (filename, from_tty)
-+ char *filename;
-+ int from_tty;
++kcore_open (char *filename /* the core file */, int from_tty)
+{
++ kvm_t *kd;
+ const char *p;
+ struct cleanup *old_chain;
+ char buf[256], *cp;
+ int ontop;
+ CORE_ADDR addr;
-+ struct pcb pcb;
+
+ target_preopen (from_tty);
+
-+ unpush_target (&kcore_ops);
++ /* The exec file is required for symbols. */
++ if (exec_bfd == NULL)
++ error ("No kernel exec file specified");
++
++ if (core_kd)
++ {
++ error ("No core file specified."
++ " (Use `detach' to stop debugging a core file.)");
++ return;
++ }
+
+ if (!filename)
+ {
-+ /*error (core_kd?*/
-+ error ( (core_kd >= 0)?
-+ "No core file specified. (Use `detach' to stop debugging a core file.)"
-+ : "No core file specified.");
++ error ("No core file specified.");
++ return;
+ }
+
+ filename = tilde_expand (filename);
@@ -303,76 +265,66 @@
+
+ old_chain = make_cleanup (free, filename);
+
-+ /*
-+ * gdb doesn't really do anything if the exec-file couldn't
-+ * be opened (in that case exec_bfd is NULL). Usually that's
-+ * no big deal, but kvm_open needs the exec-file's name,
-+ * which results in dereferencing a NULL pointer, a real NO-NO !
-+ * So, check here if the open of the exec-file succeeded.
-+ */
-+ if (exec_bfd == NULL) /* the open failed */
-+ error ("kgdb could not open the exec-file, please check the name you used !");
-+
-+ core_kd = kvm_open (exec_bfd->filename, filename, NULL,
-+ kernel_writablecore? O_RDWR : O_RDONLY, "kgdb: ");
-+ if (core_kd < 0)
-+ perror_with_name (filename);
++ kd = kvm_open (bfd_get_filename(exec_bfd), filename, NULL,
++ kernel_writablecore ? O_RDWR: O_RDONLY, 0);
++ if (kd == NULL)
++ {
++ perror_with_name (filename);
++ return;
++ }
+
-+ /* Looks semi-reasonable. Toss the old core file and work on the new. */
++ /* Looks semi-reasonable. Toss the old core file and work on the new. */
+
-+ discard_cleanups (old_chain); /* Don't free filename any more */
++ discard_cleanups (old_chain); /* Don't free filename any more. */
+ core_file = filename;
++ unpush_target (&kcore_ops);
+ ontop = !push_target (&kcore_ops);
+
-+ kernel_start = bfd_get_start_address (exec_bfd); /* XXX */
++ /* Note unpush_target (above) calls kcore_close. */
++ core_kd = kd;
+
-+ /* print out the panic string if there is one */
-+ if (kvread (ksym_lookup ("panicstr"), &addr) == 0
-+ && addr != 0
-+ && target_read_memory (addr, buf, sizeof (buf)) == 0)
++ /* Print out the panic string if there is one. */
++ if (kvread (ksym_lookup ("panicstr"), &addr) == 0 &&
++ addr != 0 &&
++ target_read_memory (addr, buf, sizeof(buf)) == 0)
+ {
-+ for (cp = buf; cp < &buf[sizeof (buf)] && *cp; cp++)
++
++ for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)
+ if (!isascii (*cp) || (!isprint (*cp) && !isspace (*cp)))
+ *cp = '?';
+ *cp = '\0';
+ if (buf[0] != '\0')
-+ printf ("panicstr: %s\n", buf);
++ printf_filtered ("panic: %s\n", buf);
+ }
+
-+ /* Print all the panic messages if possible. */
++ /* Print all the panic messages if possible. */
+ if (symfile_objfile != NULL)
+ {
+ printf ("panic messages:\n---\n");
+ snprintf (buf, sizeof buf,
-+ "/sbin/dmesg -N %s -M %s | \
-+ /usr/bin/awk '/^(panic:|Fatal trap) / { printing = 1 } \
-+ { if (printing) print $0 }'",
-+ symfile_objfile->name, filename);
-+ fflush(stdout);
++ "/sbin/dmesg -N %s -M %s | \
++ /usr/bin/awk '/^(panic:|Fatal trap) / { printing = 1 } \
++ { if (printing) print $0 }'",
++ symfile_objfile->name, filename);
++ fflush (stdout);
+ system (buf);
+ printf ("---\n");
+ }
+
+ if (!ontop)
+ {
-+ warning ("you won't be able to access this core file until you terminate\n\
-+your %s; do ``info files''", target_longname);
++ warning ("you won't be able to access this core file until you terminate\n"
++ "your %s; do ``info files''", target_longname);
+ return;
+ }
+
-+ /* we may need this later */
-+ cur_proc = (struct proc *)curProc ();
-+ /* Now, set up the frame cache, and print the top of stack */
-+ flush_cached_frames ();
-+ set_current_frame (create_new_frame (read_fp (), read_pc ()));
-+ select_frame (get_current_frame (), 0);
-+ print_stack_frame (selected_frame, selected_frame_level, 1);
++ /* Now, set up process context, and print the top of stack. */
++ (void)set_context (initial_pcb());
++ print_stack_frame (selected_frame, frame_relative_level(selected_frame), 1);
+}
+
+static void
-+kcore_detach (args, from_tty)
-+ char *args;
-+ int from_tty;
++kcore_detach (char *args, int from_tty)
+{
+ if (args)
+ error ("Too many arguments");
@@ -382,39 +334,70 @@
+ printf_filtered ("No kernel core file now.\n");
+}
+
-+/* Get the registers out of a core file. This is the machine-
-+ independent part. Fetch_core_registers is the machine-dependent
-+ part, typically implemented in the xm-file for each architecture. */
++#ifdef __alpha__
+
-+/* We just get all the registers, so we don't use regno. */
-+/* ARGSUSED */
-+static void
-+get_kcore_registers (regno)
-+ int regno;
++#include "alpha/tm-alpha.h"
++#include "alpha-tdep.h"
++
++#ifndef S0_REGNUM
++#define S0_REGNUM (ALPHA_T7_REGNUM+1)
++#endif
++
++fetch_kcore_registers (struct pcb *pcbp)
+{
-+ struct pcb *pcbaddr;
-+ struct thread *mainthread;
-+
-+ /* find the pcb for the current process */
-+ if (cur_proc == NULL)
-+ error ("get_kcore_registers no proc");
-+ if (kvread (&TAILQ_FIRST(&cur_proc->p_threads), &mainthread)) /* XXXKSE */
-+ error ("cannot read main thread for proc at %#x", cur_proc);
-+ if (kvread (&mainthread->td_pcb, &pcbaddr)) /* XXXKSE */
-+ error ("cannot read pcb pointer for proc at %#x", cur_proc);
-+ if (read_pcb (core_kd, (CORE_ADDR)pcbaddr) < 0)
-+ error ("cannot read pcb at %#x", pcbaddr);
++
++ /* First clear out any garbage. */
++ memset (registers, '\0', REGISTER_BYTES);
++
++ /* SP */
++ *(long *) &registers[REGISTER_BYTE (SP_REGNUM)] =
++ pcbp->pcb_hw.apcb_ksp;
++
++ /* S0 through S6 */
++ memcpy (&registers[REGISTER_BYTE (S0_REGNUM)],
++ &pcbp->pcb_context[0], 7 * sizeof (long));
++
++ /* PC */
++ *(long *) &registers[REGISTER_BYTE (PC_REGNUM)] =
++ pcbp->pcb_context[7];
++
++ registers_fetched ();
+}
+
-+static void
-+kcore_files_info (t)
-+ struct target_ops *t;
++
++CORE_ADDR
++fbsd_kern_frame_saved_pc (struct frame_info *fi)
+{
-+ printf ("\t`%s'\n", core_file);
++ struct minimal_symbol *sym;
++ CORE_ADDR this_saved_pc;
++
++ this_saved_pc = FRAME_SAVED_PC(fi);
++
++ sym = lookup_minimal_symbol_by_pc (this_saved_pc);
++
++ if (sym != NULL &&
++ (strcmp (SYMBOL_NAME (sym), "XentArith") == 0 ||
++ strcmp (SYMBOL_NAME (sym), "XentIF") == 0 ||
++ strcmp (SYMBOL_NAME (sym), "XentInt") == 0 ||
++ strcmp (SYMBOL_NAME (sym), "XentMM") == 0 ||
++ strcmp (SYMBOL_NAME (sym), "XentSys") == 0 ||
++ strcmp (SYMBOL_NAME (sym), "XentUna") == 0 ||
++ strcmp (SYMBOL_NAME (sym), "XentRestart") == 0))
++ {
++ return (read_memory_integer (fi->frame + 32 * 8, 8));
++ }
++ else
++ {
++ return (this_saved_pc);
++ }
+}
+
++#endif /* __alpha__ */
++
++#ifdef __i386__
++
+static CORE_ADDR
-+ksym_maxuseraddr()
++ksym_maxuseraddr (void)
+{
+ static CORE_ADDR maxuseraddr;
+ struct minimal_symbol *sym;
@@ -431,608 +414,256 @@
+ return maxuseraddr;
+}
+
-+static int
-+kcore_xfer_kmem (memaddr, myaddr, len, write, attrib, target)
-+ CORE_ADDR memaddr;
-+ char *myaddr;
-+ int len;
-+ int write;
-+ struct mem_attrib *attrib;
-+ struct target_ops *target;
-+{
-+ int ns;
-+ int nu;
+
-+ if (memaddr >= ksym_maxuseraddr())
-+ nu = 0;
-+ else
-+ {
-+ nu = xfer_umem (memaddr, myaddr, len, write);
-+ if (nu <= 0)
-+ return (0);
-+ if (nu == len)
-+ return (nu);
-+ memaddr += nu;
-+ if (memaddr != ksym_maxuseraddr())
-+ return (nu);
-+ myaddr += nu;
-+ len -= nu;
-+ }
-+
-+ ns = (write ? kvm_write : kvm_read) (core_kd, memaddr, myaddr, len);
-+ if (ns < 0)
-+ ns = 0;
-+
-+ return (nu + ns);
-+}
-+
-+static int
-+xfer_umem (memaddr, myaddr, len, write)
-+ CORE_ADDR memaddr;
-+ char *myaddr;
-+ int len;
-+ int write; /* ignored */
-+{
-+ int n;
-+ struct proc proc;
-+
-+ if (cur_proc == NULL || kvread (cur_proc, &proc))
-+ error ("cannot read proc at %#x", cur_proc);
-+ n = kvm_uread (core_kd, &proc, memaddr, myaddr, len) ;
++/* Symbol names of kernel entry points. Use special frames. */
++#define KSYM_TRAP "calltrap"
++#define KSYM_INTR "Xintr"
++#define KSYM_FASTINTR "Xfastintr"
++#define KSYM_OLDSYSCALL "Xlcall_syscall"
++#define KSYM_SYSCALL "Xint0x80_syscall"
+
-+ if (n < 0)
-+ return 0;
-+ return n;
-+}
++/* The following is FreeBSD-specific hackery to decode special frames
++ and elide the assembly-language stub. This could be made faster by
++ defining a frame_type field in the machine-dependent frame information,
++ but we don't think that's too important right now. */
++enum frametype { tf_normal, tf_trap, tf_interrupt, tf_syscall };
+
-+static CORE_ADDR
-+ksym_kernbase()
++CORE_ADDR
++fbsd_kern_frame_saved_pc (struct frame_info *fr)
+{
-+ static CORE_ADDR kernbase;
+ struct minimal_symbol *sym;
++ CORE_ADDR this_saved_pc;
++ enum frametype frametype;
+
-+ if (kernbase == 0)
++ this_saved_pc = read_memory_integer (fr->frame + 4, 4);
++ sym = lookup_minimal_symbol_by_pc (this_saved_pc);
++ frametype = tf_normal;
++ if (sym != NULL)
+ {
-+ sym = lookup_minimal_symbol ("kernbase", NULL, NULL);
-+ if (sym == NULL) {
-+ kernbase = KERNBASE;
-+ } else {
-+ kernbase = SYMBOL_VALUE_ADDRESS (sym);
-+ }
++ if (strcmp (SYMBOL_NAME (sym), KSYM_TRAP) == 0)
++ frametype = tf_trap;
++ else
++ if (strncmp (SYMBOL_NAME (sym), KSYM_INTR,
++ strlen (KSYM_INTR)) == 0 || strncmp (SYMBOL_NAME(sym),
++ KSYM_FASTINTR, strlen (KSYM_FASTINTR)) == 0)
++ frametype = tf_interrupt;
++ else
++ if (strcmp (SYMBOL_NAME (sym), KSYM_SYSCALL) == 0 ||
++ strcmp (SYMBOL_NAME (sym), KSYM_OLDSYSCALL) == 0)
++ frametype = tf_syscall;
+ }
-+ return kernbase;
-+}
+
-+#define KERNOFF (ksym_kernbase())
-+#define INKERNEL(x) ((x) >= KERNOFF)
++ switch (frametype)
++ {
++ default:
++ case tf_normal:
++ return (this_saved_pc);
++#define oEIP offsetof (struct trapframe, tf_eip)
+
-+static CORE_ADDR sbr;
-+static CORE_ADDR curpcb;
-+static int found_pcb;
-+static int devmem;
-+static int kfd;
-+static struct pcb pcb;
++ case tf_trap:
++ return (read_memory_integer (fr->frame + 8 + oEIP, 4));
+
-+static void
-+set_proc_cmd (arg, from_tty)
-+ char *arg;
-+ int from_tty;
-+{
-+ CORE_ADDR paddr;
-+ struct kinfo_proc *kp;
-+ int cnt = 0;
++ case tf_interrupt:
++ return (read_memory_integer (fr->frame + 12 + oEIP, 4));
+
-+ if (!arg)
-+ error_no_arg ("proc address for new current process");
-+ if (!kernel_debugging)
-+ error ("not debugging kernel");
-+
-+ paddr = (CORE_ADDR)parse_and_eval_address (arg);
-+ /* assume it's a proc pointer if it's in the kernel */
-+ if (paddr >= kernel_start) {
-+ if (set_proc_context(paddr))
-+ error("invalid proc address");
-+ } else {
-+ kp = kvm_getprocs(core_kd, KERN_PROC_PID, paddr, &cnt);
-+ if (!cnt)
-+ error("invalid pid");
-+ if (set_proc_context((CORE_ADDR)kp->ki_paddr))
-+ error("invalid proc address");
-+ }
++ case tf_syscall:
++ return (read_memory_integer (fr->frame + 8 + oEIP, 4));
++#undef oEIP
++ }
+}
+
+static void
-+set_cpu_cmd (arg, from_tty)
-+ char *arg;
-+ int from_tty;
++fetch_kcore_registers (struct pcb *pcb)
+{
-+ CORE_ADDR paddr;
-+ CORE_ADDR pcaddr;
-+ struct kinfo_proc *kp;
-+ int cpu, cfd;
++ int i;
++ int noreg;
+
-+ if (!arg)
-+ error_no_arg ("cpu number");
-+ if (!kernel_debugging)
-+ error ("not debugging kernel");
++ /* Get the register values out of the sys pcb and store them where
++ `read_register' will find them. */
++ /*
++ * XXX many registers aren't available.
++ * XXX for the non-core case, the registers are stale - they are for
++ * the last context switch to the debugger.
++ * XXX gcc's register numbers aren't all #defined in tm-i386.h.
++ */
++ noreg = 0;
++ for (i = 0; i < 3; ++i) /* eax,ecx,edx */
++ supply_register (i, (char *)&noreg);
+
-+ cfd = core_kd;
-+ cpu = (int)parse_and_eval_address (arg);
-+ if ((pcaddr = kvm_getpcpu (cfd, cpu)) == NULL)
-+ error ("cpu number out of range");
++ supply_register (3, (char *) &pcb->pcb_ebx);
++ supply_register (SP_REGNUM, (char *) &pcb->pcb_esp);
++ supply_register (FP_REGNUM, (char *) &pcb->pcb_ebp);
++ supply_register (6, (char *) &pcb->pcb_esi);
++ supply_register (7, (char *) &pcb->pcb_edi);
++ supply_register (PC_REGNUM, (char *) &pcb->pcb_eip);
+
-+ pcpu = pcaddr;
-+ curpcb = kvtophys(cfd, pcpu + PCPU_OFFSET (curpcb));
-+ physrd (cfd, curpcb, (char*)&curpcb, sizeof curpcb);
++ for (i = 9; i < 14; ++i) /* eflags, cs, ss, ds, es, fs */
++ supply_register (i, (char *) &noreg);
++ supply_register (15, (char *) &pcb->pcb_gs);
+
-+ if (!devmem)
-+ paddr = ksym_lookup ("dumppcb") - KERNOFF;
-+ else
-+ paddr = kvtophys (cfd, curpcb);
-+ read_pcb (cfd, paddr);
-+ printf ("initial pcb at %lx\n", (unsigned long)paddr);
++ /* XXX 80387 registers? */
++}
+
-+ if ((cur_proc = curProc()))
-+ target_fetch_registers (-1);
++#endif /* __i386__ */
+
-+ /* Now, set up the frame cache, and print the top of stack */
-+ flush_cached_frames ();
-+ set_current_frame (create_new_frame (read_fp (), read_pc ()));
-+ select_frame (get_current_frame (), 0);
-+ print_stack_frame (selected_frame, selected_frame_level, 1);
-+}
++#ifdef __sparc64__
+
-+/* substitutes for the stuff in libkvm which doesn't work */
-+/* most of this was taken from the old kgdb */
++/*
++#include "sparc/tm-sp64.h"
++*/
+
-+/* we don't need all this stuff, but the call should look the same */
++fetch_kcore_registers (struct pcb *pcbp)
++{
++}
+
-+static int
-+kvm_open (efile, cfile, sfile, perm, errout)
-+ const char *efile;
-+ char *cfile;
-+ char *sfile; /* makes this kvm_open more compatible to the one in libkvm */
-+ int perm;
-+ char *errout; /* makes this kvm_open more compatible to the one in libkvm */
++
++CORE_ADDR
++fbsd_kern_frame_saved_pc (struct frame_info *fi)
+{
-+ struct stat stb;
-+ int cfd;
-+ CORE_ADDR paddr;
++ return NULL;
++}
+
-+ if ((cfd = open (cfile, perm, 0)) < 0)
-+ return (cfd);
++#endif /* __sparc64__ */
+
-+ if ((pcpu = kvm_getpcpu (cfd, 0)) == NULL)
-+ return (-1);
++/* Get the registers out of a core file. This is the machine-
++ independent part. Fetch_core_registers is the machine-dependent
++ part, typically implemented in the xm-file for each architecture. */
+
-+ fstat (cfd, &stb);
-+ if ((stb.st_mode & S_IFMT) == S_IFCHR
-+ && stb.st_rdev == makedev (2, 0))
-+ {
-+ devmem = 1;
-+ kfd = open (_PATH_KMEM, perm, 0);
-+ }
++/* We just get all the registers, so we don't use regno. */
+
-+ physrd (cfd, ksym_lookup ("IdlePTD") - KERNOFF, (char*)&sbr, sizeof sbr);
-+ printf ("IdlePTD at phsyical address 0x%08lx\n", (unsigned long)sbr);
-+ curpcb = kvtophys(cfd, pcpu + PCPU_OFFSET (curpcb));
-+ physrd (cfd, curpcb, (char*)&curpcb, sizeof curpcb);
++/* ARGSUSED */
++static void
++get_kcore_registers (int regno)
++{
+
-+ found_pcb = 1; /* for vtophys */
-+ if (!devmem)
-+ paddr = ksym_lookup ("dumppcb") - KERNOFF;
-+ else
-+ paddr = kvtophys (cfd, curpcb);
-+ read_pcb (cfd, paddr);
-+ printf ("initial pcb at physical address 0x%08lx\n", (unsigned long)paddr);
++ /* XXX - Only read the pcb when set_context() is called.
++ When looking at a live kernel this may be a problem,
++ but the user can do another "proc" or "pcb" command to
++ grab a new copy of the pcb... */
+
-+ return (cfd);
++ /* Zero out register set then fill in the ones we know about. */
++ fetch_kcore_registers (&cur_pcb);
+}
+
-+static int
-+kvm_close (fd)
-+ int fd;
++static void
++kcore_files_info (t)
++ struct target_ops *t;
+{
-+ return (close (fd));
++ printf_filtered ("\t`%s'\n", core_file);
+}
++
++/* If mourn is being called in all the right places, this could be say
++ `gdb internal error' (since generic_mourn calls breakpoint_init_inferior). */
+
+static int
-+kvm_write (core_kd, memaddr, myaddr, len)
-+ int core_kd;
-+ CORE_ADDR memaddr;
-+ char *myaddr;
++ignore (CORE_ADDR addr, char *contents)
+{
-+ int cc;
-+
-+ if (devmem)
-+ {
-+ if (kfd > 0)
-+ {
-+ /*
-+ * Just like kvm_read, only we write.
-+ */
-+ errno = 0;
-+ if (lseek (kfd, (off_t)memaddr, 0) < 0
-+ && errno != 0)
-+ {
-+ error ("kvm_write:invalid address (%x)", memaddr);
-+ return (0);
-+ }
-+ cc = write (kfd, myaddr, len);
-+ if (cc < 0)
-+ {
-+ error ("kvm_write:write failed");
-+ return (0);
-+ }
-+ else if (cc < len)
-+ error ("kvm_write:short write");
-+ return (cc);
-+ }
-+ else
-+ return (0);
-+ }
-+ else
-+ {
-+ printf ("kvm_write not implemented for dead kernels\n");
-+ return (0);
-+ }
-+ /* NOTREACHED */
++ return 0;
+}
+
+static int
-+kvm_read (core_kd, memaddr, myaddr, len)
-+ int core_kd;
-+ CORE_ADDR memaddr;
-+ char *myaddr;
++xfer_kmem (CORE_ADDR memaddr, char *myaddr, int len, int write,
++ struct mem_attrib *attrib, struct target_ops *target)
+{
-+ return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
-+}
++ int n;
+
-+static int
-+kvm_uread (core_kd, p, memaddr, myaddr, len)
-+ int core_kd;
-+ register struct proc *p;
-+ CORE_ADDR memaddr;
-+ char *myaddr;
-+ int len;
-+{
-+ register char *cp;
-+ char procfile[MAXPATHLEN];
-+ ssize_t amount;
-+ int fd;
+
-+ if (devmem)
-+ {
-+ sprintf (procfile, "/proc/%d/mem", p->p_pid);
-+ fd = open (procfile, O_RDONLY, 0);
-+ if (fd < 0)
-+ {
-+ error ("cannot open %s", procfile);
-+ close (fd);
-+ return (0);
-+ }
++ if (!INKERNEL (memaddr))
++ return xfer_umem (memaddr, myaddr, len, write);
+
-+ cp = myaddr;
-+ while (len > 0)
-+ {
-+ errno = 0;
-+ if (lseek (fd, (off_t)memaddr, 0) == -1 && errno != 0)
-+ {
-+ error ("invalid address (%x) in %s", memaddr, procfile);
-+ break;
-+ }
-+ amount = read (fd, cp, len);
-+ if (amount < 0)
-+ {
-+ error ("error reading %s", procfile);
-+ break;
-+ }
-+ if (amount == 0)
-+ {
-+ error ("EOF reading %s", procfile);
-+ break;
-+ }
-+ cp += amount;
-+ memaddr += amount;
-+ len -= amount;
-+ }
++ if (core_kd == NULL)
++ return 0;
+
-+ close (fd);
-+ return ((ssize_t) (cp - myaddr));
-+ }
++ if (write)
++ n = kvm_write (core_kd, memaddr, myaddr, len);
+ else
-+ return (kernel_core_file_hook (core_kd, memaddr, myaddr, len));
++ n = kvm_read (core_kd, memaddr, myaddr, len) ;
++ if (n < 0) {
++ fprintf_unfiltered (gdb_stderr, "can not access 0x%x, %s\n",
++ memaddr, kvm_geterr (core_kd));
++ n = 0;
++ }
++
++ return n;
+}
+
-+static struct kinfo_proc kp;
+
-+/*
-+ * try to do what kvm_proclist in libkvm would do
-+ */
+static int
-+kvm_proclist (cfd, pid, p, cnt)
-+int cfd, pid, *cnt;
-+struct proc *p;
++xfer_umem (CORE_ADDR memaddr, char *myaddr, int len, int write /* ignored */)
+{
-+ struct proc lp;
-+
-+ for (; p != NULL; p = LIST_NEXT(&lp, p_list)) {
-+ if (!kvm_read(cfd, (CORE_ADDR)p, (char *)&lp, sizeof (lp)))
-+ return (0);
-+ if (lp.p_pid != pid)
-+ continue;
-+ kp.ki_paddr = p;
-+ *cnt = 1;
-+ return (1);
-+ }
-+ *cnt = 0;
-+ return (0);
-+}
++ int n = 0;
+
-+/*
-+ * try to do what kvm_deadprocs in libkvm would do
-+ */
-+static struct kinfo_proc *
-+kvm_deadprocs (cfd, pid, cnt)
-+int cfd, pid, *cnt;
-+{
-+ CORE_ADDR allproc, zombproc;
-+ struct proc *p;
-+
-+ allproc = ksym_lookup("allproc");
-+ if (kvm_read(cfd, allproc, (char *)&p, sizeof (p)) == 0)
-+ return (NULL);
-+ kvm_proclist (cfd, pid, p, cnt);
-+ if (!*cnt) {
-+ zombproc = ksym_lookup("zombproc");
-+ if (kvm_read(cfd, zombproc, (char *)&p, sizeof (p)) == 0)
-+ return (NULL);
-+ kvm_proclist (cfd, pid, p, cnt);
-+ }
-+ return (&kp);
-+}
-+
-+static CORE_ADDR
-+kvm_getpcpu (cfd, cpuid)
-+int cfd, cpuid;
-+{
-+ SLIST_HEAD(, pcpu) pcpu_head;
-+ struct pcpu lpc;
-+ struct pcpu *pc;
-+
-+ physrd (cfd, ksym_lookup ("cpuhead") - KERNOFF, (char*)&pcpu_head,
-+ sizeof pcpu_head);
-+ pc = SLIST_FIRST (&pcpu_head);
-+ for (; pc != NULL; pc = SLIST_NEXT (&lpc, pc_allcpu))
++ if (cur_proc == 0)
+ {
-+ kvm_read (cfd, (CORE_ADDR)pc, (char*)&lpc, sizeof lpc);
-+ if (lpc.pc_cpuid == cpuid)
-+ break;
++ error ("---Can't read userspace from dump, or kernel process---\n");
++ return 0;
+ }
+
-+ return ((CORE_ADDR)pc);
-+}
++ if (write)
++ error ("kvm_uwrite unimplemented\n");
++ else
++ n = kvm_uread (core_kd, cur_proc, memaddr, myaddr, len) ;
+
-+/*
-+ * try to do what kvm_getprocs in libkvm would do
-+ */
-+static struct kinfo_proc *
-+kvm_getprocs (cfd, op, proc, cnt)
-+int cfd, op, *cnt;
-+CORE_ADDR proc;
-+{
-+ int mib[4], size;
-+
-+ *cnt = 0;
-+ /* assume it's a pid */
-+ if (devmem) { /* "live" kernel, use sysctl */
-+ mib[0] = CTL_KERN;
-+ mib[1] = KERN_PROC;
-+ mib[2] = KERN_PROC_PID;
-+ mib[3] = (int)proc;
-+ size = sizeof (kp);
-+ if (sysctl (mib, 4, &kp, &size, NULL, 0) < 0) {
-+ perror("sysctl");
-+ *cnt = 0;
-+ return (NULL);
-+ }
-+ if (!size)
-+ *cnt = 0;
-+ else
-+ *cnt = 1;
-+ return (&kp);
-+ } else
-+ return (kvm_deadprocs (cfd, (int)proc, cnt));
-+}
++ if (n < 0)
++ return 0;
+
-+static int
-+physrd (cfd, addr, dat, len)
-+ int cfd;
-+ u_int addr;
-+ char *dat;
-+ int len;
-+{
-+ if (lseek (cfd, (off_t)addr, L_SET) == -1)
-+ return (-1);
-+ return (read (cfd, dat, len));
++ return n;
+}
+
-+static CORE_ADDR
-+kvtophys (fd, addr)
-+ int fd;
-+ CORE_ADDR addr;
++static void
++set_proc_cmd (char *arg, int from_tty)
+{
-+ CORE_ADDR v;
-+ unsigned int pte;
-+ static CORE_ADDR PTD = -1;
-+ CORE_ADDR current_ptd;
-+
-+ /*
-+ * We may no longer have a linear system page table...
-+ *
-+ * Here's the scoop. IdlePTD contains the physical address
-+ * of a page table directory that always maps the kernel.
-+ * IdlePTD is in memory that is mapped 1-to-1, so we can
-+ * find it easily given its 'virtual' address from ksym_lookup().
-+ * For hysterical reasons, the value of IdlePTD is stored in sbr.
-+ *
-+ * To look up a kernel address, we first convert it to a 1st-level
-+ * address and look it up in IdlePTD. This gives us the physical
-+ * address of a page table page; we extract the 2nd-level part of
-+ * VA and read the 2nd-level pte. Finally, we add the offset part
-+ * of the VA into the physical address from the pte and return it.
-+ *
-+ * User addresses are a little more complicated. If we don't have
-+ * a current PCB from read_pcb(), we use PTD, which is the (fixed)
-+ * virtual address of the current ptd. Since it's NOT in 1-to-1
-+ * kernel space, we must look it up using IdlePTD. If we do have
-+ * a pcb, we get the ptd from pcb_ptd.
-+ */
++ CORE_ADDR addr, pid_addr, first_td;
++ void *val;
++ struct kinfo_proc *kp;
++ int cnt;
++ pid_t pid;
+
-+ if (INKERNEL (addr))
-+ current_ptd = sbr;
-+ else if (found_pcb == 0)
-+ {
-+ if (PTD == -1)
-+ PTD = kvtophys (fd, ksym_lookup ("PTD"));
-+ current_ptd = PTD;
-+ }
-+ else
-+ current_ptd = pcb.pcb_cr3;
++ if (!arg)
++ error_no_arg ("proc address for the new context");
+
-+ /*
-+ * Read the first-level page table (ptd).
-+ */
-+ v = current_ptd + ( (unsigned)addr >> PDRSHIFT) * sizeof pte;
-+ if (physrd (fd, v, (char *)&pte, sizeof pte) < 0 || (pte&PG_V) == 0)
-+ return (~0);
++ if (core_kd == NULL)
++ error ("no kernel core file");
+
-+ if (pte & PG_PS)
++ addr = (CORE_ADDR) parse_and_eval_address (arg);
++
++ if (!INKERNEL (addr))
+ {
-+ /*
-+ * No second-level page table; ptd describes one 4MB page.
-+ * (We assume that the kernel wouldn't set PG_PS without enabling
-+ * it cr0, and that the kernel doesn't support 36-bit physical
-+ * addresses).
-+ */
-+#define PAGE4M_MASK (NBPDR - 1)
-+#define PG_FRAME4M (~PAGE4M_MASK)
-+ addr = (pte & PG_FRAME4M) + (addr & PAGE4M_MASK);
++ kp = kvm_getprocs (core_kd, KERN_PROC_PID, addr, &cnt);
++ if (!cnt)
++ error ("invalid pid");
++ addr = (CORE_ADDR)kp->ki_paddr;
++ cur_proc = kp;
+ }
+ else
+ {
-+ /*
-+ * Read the second-level page table.
-+ */
-+ v = (pte&PG_FRAME) + ((addr >> PAGE_SHIFT)&(NPTEPG-1)) * sizeof pte;
-+ if (physrd (fd, v, (char *) &pte, sizeof (pte)) < 0 || (pte&PG_V) == 0)
-+ return (~0);
-+
-+ addr = (pte & PG_FRAME) + (addr & PAGE_MASK);
-+ }
-+#if 0
-+ printf ("vtophys (%x) -> %x\n", oldaddr, addr);
-+#endif
-+ return (addr);
-+}
-+
-+static int
-+read_pcb (fd, uaddr)
-+ int fd;
-+ CORE_ADDR uaddr;
-+{
-+ int i;
-+ int noreg;
-+ CORE_ADDR nuaddr = uaddr;
-+
-+ /* need this for the `proc' command to work */
-+ if (INKERNEL(uaddr))
-+ nuaddr = kvtophys(fd, uaddr);
-+
-+ if (physrd (fd, nuaddr, (char *)&pcb, sizeof pcb) < 0)
-+ {
-+ error ("cannot read pcb at %x\n", uaddr);
-+ return (-1);
++ /* Update cur_proc. */
++ pid_addr = addr + offsetof (struct proc, p_pid);
++ if (kvread (pid_addr, &pid))
++ error ("cannot read pid ptr");
++ cur_proc = kvm_getprocs (core_kd, KERN_PROC_PID, pid, &cnt);
++ if (!cnt)
++ error("invalid pid");
+ }
+
-+ /*
-+ * get the register values out of the sys pcb and
-+ * store them where `read_register' will find them.
-+ */
-+ /*
-+ * XXX many registers aren't available.
-+ * XXX for the non-core case, the registers are stale - they are for
-+ * the last context switch to the debugger.
-+ * XXX gcc's register numbers aren't all #defined in tm-i386.h.
-+ */
-+ noreg = 0;
-+ for (i = 0; i < 3; ++i) /* eax,ecx,edx */
-+ supply_register (i, (char *)&noreg);
-+ supply_register (3, (char *)&pcb.pcb_ebx);
-+ supply_register (SP_REGNUM, (char *)&pcb.pcb_esp);
-+ supply_register (FP_REGNUM, (char *)&pcb.pcb_ebp);
-+ supply_register (6, (char *)&pcb.pcb_esi);
-+ supply_register (7, (char *)&pcb.pcb_edi);
-+ supply_register (PC_REGNUM, (char *)&pcb.pcb_eip);
-+ for (i = 9; i < 14; ++i) /* eflags, cs, ss, ds, es, fs */
-+ supply_register (i, (char *)&noreg);
-+ supply_register (15, (char *)&pcb.pcb_gs);
++ /* Find the first thread in the process. XXXKSE */
++ addr += offsetof (struct proc, p_threads.tqh_first);
++ if (kvread (addr, &first_td))
++ error ("cannot read thread ptr");
+
-+ /* XXX 80387 registers? */
-+}
-+
-+/*
-+ * read len bytes from kernel virtual address 'addr' into local
-+ * buffer 'buf'. Return numbert of bytes if read ok, 0 otherwise. On read
-+ * errors, portion of buffer not read is zeroed.
-+ */
-+
-+static int
-+kernel_core_file_hook (fd, addr, buf, len)
-+ int fd;
-+ CORE_ADDR addr;
-+ char *buf;
-+ int len;
-+{
-+ int i;
-+ CORE_ADDR paddr;
-+ register char *cp;
-+ int cc;
++ /* Read the PCB address in thread structure. */
++ addr = first_td + offsetof (struct thread, td_pcb);
++ if (kvread (addr, &val))
++ error("cannot read pcb ptr");
+
-+ cp = buf;
-+
-+ while (len > 0)
-+ {
-+ paddr = kvtophys (fd, addr);
-+ if (paddr == ~0)
-+ {
-+ memset (buf, '\000', len);
-+ break;
-+ }
-+ /* we can't read across a page boundary */
-+ i = min (len, PAGE_SIZE - (addr & PAGE_MASK));
-+ if ( (cc = physrd (fd, paddr, cp, i)) <= 0)
-+ {
-+ memset (cp, '\000', len);
-+ return (cp - buf);
-+ }
-+ cp += cc;
-+ addr += cc;
-+ len -= cc;
-+ }
-+ return (cp - buf);
++ /* Read the PCB address in proc structure. */
++ if (set_context ((CORE_ADDR) val))
++ error ("invalid proc address");
+}
+
-+static struct target_ops kcore_ops;
-+
-+#else
-+int kernel_debugging = 0;
-+#endif
-+
+void
-+_initialize_kcorelow()
++_initialize_kcorelow (void)
+{
-+#if __FreeBSD_version >= 500032 && defined(i386)
+ kcore_ops.to_shortname = "kcore";
+ kcore_ops.to_longname = "Kernel core dump file";
+ kcore_ops.to_doc =
@@ -1042,7 +673,7 @@
+ kcore_ops.to_attach = find_default_attach;
+ kcore_ops.to_detach = kcore_detach;
+ kcore_ops.to_fetch_registers = get_kcore_registers;
-+ kcore_ops.to_xfer_memory = kcore_xfer_kmem;
++ kcore_ops.to_xfer_memory = xfer_kmem;
+ kcore_ops.to_files_info = kcore_files_info;
+ kcore_ops.to_create_inferior = find_default_create_inferior;
+ kcore_ops.to_stratum = kcore_stratum;
@@ -1053,6 +684,4 @@
+
+ add_target (&kcore_ops);
+ add_com ("proc", class_obscure, set_proc_cmd, "Set current process context");
-+ add_com ("cpu", class_obscure, set_cpu_cmd, "Set current cpu");
-+#endif
+}