summaryrefslogtreecommitdiffstats
path: root/usr.bin/gcore
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/gcore')
-rw-r--r--usr.bin/gcore/Makefile7
-rw-r--r--usr.bin/gcore/extern.h37
-rw-r--r--usr.bin/gcore/gcore.190
-rw-r--r--usr.bin/gcore/gcore.c313
-rw-r--r--usr.bin/gcore/md-nop.c53
-rw-r--r--usr.bin/gcore/md-sparc.c186
6 files changed, 686 insertions, 0 deletions
diff --git a/usr.bin/gcore/Makefile b/usr.bin/gcore/Makefile
new file mode 100644
index 0000000..c7bf6e0
--- /dev/null
+++ b/usr.bin/gcore/Makefile
@@ -0,0 +1,7 @@
+# @(#)Makefile 8.1 (Berkeley) 6/6/93
+
+PROG= gcore
+SRCS= gcore.c md-${MACHINE}.c
+LDADD= -lkvm
+
+.include <bsd.prog.mk>
diff --git a/usr.bin/gcore/extern.h b/usr.bin/gcore/extern.h
new file mode 100644
index 0000000..3dccafe
--- /dev/null
+++ b/usr.bin/gcore/extern.h
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)extern.h 8.1 (Berkeley) 6/6/93
+ */
+
+void err __P((int, const char *, ...));
+void md_core __P((kvm_t *, int, struct kinfo_proc *));
diff --git a/usr.bin/gcore/gcore.1 b/usr.bin/gcore/gcore.1
new file mode 100644
index 0000000..42fddbc
--- /dev/null
+++ b/usr.bin/gcore/gcore.1
@@ -0,0 +1,90 @@
+.\" Copyright (c) 1983, 1990, 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by the University of
+.\" California, Berkeley and its contributors.
+.\" 4. Neither the name of the University nor the names of its contributors
+.\" may be used to endorse or promote products derived from this software
+.\" without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" @(#)gcore.1 8.2 (Berkeley) 4/18/94
+.\"
+.Dd "April 18, 1994"
+.Dt GCORE 1
+.Os BSD 4.2
+.Sh NAME
+.Nm gcore
+.Nd get core images of running process
+.Sh SYNOPSIS
+.Nm gcore
+.Op Fl s
+.Op Fl c Ar core
+.Ar exec pid
+.Sh DESCRIPTION
+.Nm Gcore
+creates a core image of the specified process,
+suitable for use with
+.Xr gdb 1 .
+By default, the core is written to the file
+.Dq Pa core.<pid> .
+Both the executable image,
+.Ar exec ,
+and the process identifier,
+.Ar pid ,
+must be given on the command line.
+.Pp
+The options are:
+.Bl -tag -width indent
+.It Fl c
+Write the core file to the specified file instead of
+.Dq Pa core.<pid> .
+.It Fl s
+Stop the process while gathering the core image, and resume it
+when done. This guarantees that the resulting core dump will
+be in a consistent state. The process is resumed even if it was
+already stopped.
+The same effect can be achieved manually with
+.Xr kill 1 .
+.El
+.Sh FILES
+.Bl -tag -width /var/log/messages -compact
+.It Pa core.<pid>
+The core image.
+.EL
+.Dp
+.Sh HISTORY
+.Nm Gcore
+appeared in 4.2BSD.
+.Sh BUGS
+Context switches or paging activity that occur while
+.Nm gcore
+is running may cause the program to become confused.
+For best results, use -s to temporarily stop the target process.
+.Pp
+.Nm Gcore
+is not compatible with the original 4.2BSD version.
+In particular, 4.4BSD requires the
+.Ar exec
+argument.
diff --git a/usr.bin/gcore/gcore.c b/usr.bin/gcore/gcore.c
new file mode 100644
index 0000000..2ecca18
--- /dev/null
+++ b/usr.bin/gcore/gcore.c
@@ -0,0 +1,313 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char copyright[] =
+"@(#) Copyright (c) 1992, 1993\n\
+ The Regents of the University of California. All rights reserved.\n";
+#endif /* not lint */
+
+#ifndef lint
+static char sccsid[] = "@(#)gcore.c 8.2 (Berkeley) 9/23/93";
+#endif /* not lint */
+
+/*
+ * Originally written by Eric Cooper in Fall 1981.
+ * Inspired by a version 6 program by Len Levin, 1978.
+ * Several pieces of code lifted from Bill Joy's 4BSD ps.
+ * Most recently, hacked beyond recognition for 4.4BSD by Steven McCanne,
+ * Lawrence Berkeley Laboratory.
+ *
+ * Portions of this software were developed by the Computer Systems
+ * Engineering group at Lawrence Berkeley Laboratory under DARPA
+ * contract BG 91-66 and contributed to Berkeley.
+ */
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+
+#include <machine/vmparam.h>
+
+#include <a.out.h>
+#include <fcntl.h>
+#include <kvm.h>
+#include <limits.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "extern.h"
+
+void core __P((int, int, struct kinfo_proc *));
+void datadump __P((int, int, struct proc *, u_long, int));
+void usage __P((void));
+void userdump __P((int, struct proc *, u_long, int));
+
+kvm_t *kd;
+/* XXX undocumented routine, should be in kvm.h? */
+ssize_t kvm_uread __P((kvm_t *, struct proc *, u_long, char *, size_t));
+
+static int data_offset;
+
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ register struct proc *p;
+ struct kinfo_proc *ki;
+ struct exec exec;
+ int ch, cnt, efd, fd, pid, sflag, uid;
+ char *corefile, errbuf[_POSIX2_LINE_MAX], fname[MAXPATHLEN + 1];
+
+ sflag = 0;
+ corefile = NULL;
+ while ((ch = getopt(argc, argv, "c:s")) != EOF) {
+ switch (ch) {
+ case 'c':
+ corefile = optarg;
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+ argv += optind;
+ argc -= optind;
+
+ if (argc != 2)
+ usage();
+
+ kd = kvm_openfiles(0, 0, 0, O_RDONLY, errbuf);
+ if (kd == NULL)
+ err(1, "%s", errbuf);
+
+ uid = getuid();
+ pid = atoi(argv[1]);
+
+ ki = kvm_getprocs(kd, KERN_PROC_PID, pid, &cnt);
+ if (ki == NULL || cnt != 1)
+ err(1, "%d: not found", pid);
+
+ p = &ki->kp_proc;
+ if (ki->kp_eproc.e_pcred.p_ruid != uid && uid != 0)
+ err(1, "%d: not owner", pid);
+
+ if (p->p_stat == SZOMB)
+ err(1, "%d: zombie", pid);
+
+ if (p->p_flag & P_WEXIT)
+ err(0, "process exiting");
+ if (p->p_flag & P_SYSTEM) /* Swapper or pagedaemon. */
+ err(1, "%d: system process");
+
+ if (corefile == NULL) {
+ (void)snprintf(fname, sizeof(fname), "core.%d", pid);
+ corefile = fname;
+ }
+ fd = open(corefile, O_RDWR|O_CREAT|O_TRUNC, DEFFILEMODE);
+ if (fd < 0)
+ err(1, "%s: %s\n", corefile, strerror(errno));
+
+ efd = open(argv[0], O_RDONLY, 0);
+ if (efd < 0)
+ err(1, "%s: %s\n", argv[0], strerror(errno));
+
+ cnt = read(efd, &exec, sizeof(exec));
+ if (cnt != sizeof(exec))
+ err(1, "%s exec header: %s",
+ argv[0], cnt > 0 ? strerror(EIO) : strerror(errno));
+
+ data_offset = N_DATOFF(exec);
+
+ if (sflag && kill(pid, SIGSTOP) < 0)
+ err(0, "%d: stop signal: %s", pid, strerror(errno));
+
+ core(efd, fd, ki);
+
+ if (sflag && kill(pid, SIGCONT) < 0)
+ err(0, "%d: continue signal: %s", pid, strerror(errno));
+ (void)close(fd);
+
+ exit(0);
+}
+
+/*
+ * core --
+ * Build the core file.
+ */
+void
+core(efd, fd, ki)
+ int efd;
+ int fd;
+ struct kinfo_proc *ki;
+{
+ union {
+ struct user user;
+ char ubytes[ctob(UPAGES)];
+ } uarea;
+ struct proc *p = &ki->kp_proc;
+ int tsize = ki->kp_eproc.e_vm.vm_tsize;
+ int dsize = ki->kp_eproc.e_vm.vm_dsize;
+ int ssize = ki->kp_eproc.e_vm.vm_ssize;
+ int cnt;
+
+ /* Read in user struct */
+ cnt = kvm_read(kd, (u_long)p->p_addr, &uarea, sizeof(uarea));
+ if (cnt != sizeof(uarea))
+ err(1, "read user structure: %s",
+ cnt > 0 ? strerror(EIO) : strerror(errno));
+
+ /*
+ * Fill in the eproc vm parameters, since these are garbage unless
+ * the kernel is dumping core or something.
+ */
+ uarea.user.u_kproc = *ki;
+
+ /* Dump user area */
+ cnt = write(fd, &uarea, sizeof(uarea));
+ if (cnt != sizeof(uarea))
+ err(1, "write user structure: %s",
+ cnt > 0 ? strerror(EIO) : strerror(errno));
+
+ /* Dump data segment */
+ datadump(efd, fd, p, USRTEXT + ctob(tsize), dsize);
+
+ /* Dump stack segment */
+ userdump(fd, p, USRSTACK - ctob(ssize), ssize);
+
+ /* Dump machine dependent portions of the core. */
+ md_core(kd, fd, ki);
+}
+
+void
+datadump(efd, fd, p, addr, npage)
+ register int efd;
+ register int fd;
+ struct proc *p;
+ register u_long addr;
+ register int npage;
+{
+ register int cc, delta;
+ char buffer[NBPG];
+
+ delta = data_offset - addr;
+ while (--npage >= 0) {
+ cc = kvm_uread(kd, p, addr, buffer, NBPG);
+ if (cc != NBPG) {
+ /* Try to read the page from the executable. */
+ if (lseek(efd, (off_t)addr + delta, SEEK_SET) == -1)
+ err(1, "seek executable: %s", strerror(errno));
+ cc = read(efd, buffer, sizeof(buffer));
+ if (cc != sizeof(buffer))
+ if (cc < 0)
+ err(1, "read executable: %s",
+ strerror(errno));
+ else /* Assume untouched bss page. */
+ bzero(buffer, sizeof(buffer));
+ }
+ cc = write(fd, buffer, NBPG);
+ if (cc != NBPG)
+ err(1, "write data segment: %s",
+ cc > 0 ? strerror(EIO) : strerror(errno));
+ addr += NBPG;
+ }
+}
+
+void
+userdump(fd, p, addr, npage)
+ register int fd;
+ struct proc *p;
+ register u_long addr;
+ register int npage;
+{
+ register int cc;
+ char buffer[NBPG];
+
+ while (--npage >= 0) {
+ cc = kvm_uread(kd, p, addr, buffer, NBPG);
+ if (cc != NBPG)
+ /* Could be an untouched fill-with-zero page. */
+ bzero(buffer, NBPG);
+ cc = write(fd, buffer, NBPG);
+ if (cc != NBPG)
+ err(1, "write stack segment: %s",
+ cc > 0 ? strerror(EIO) : strerror(errno));
+ addr += NBPG;
+ }
+}
+
+void
+usage()
+{
+ (void)fprintf(stderr, "usage: gcore [-s] [-c core] executable pid\n");
+ exit(1);
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+err(int fatal, const char *fmt, ...)
+#else
+err(fatal, fmt, va_alist)
+ int fatal;
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ (void)fprintf(stderr, "gcore: ");
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ (void)fprintf(stderr, "\n");
+ exit(1);
+ /* NOTREACHED */
+}
diff --git a/usr.bin/gcore/md-nop.c b/usr.bin/gcore/md-nop.c
new file mode 100644
index 0000000..46e90c4
--- /dev/null
+++ b/usr.bin/gcore/md-nop.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)md-nop.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <stdio.h>
+#include <kvm.h>
+#include "extern.h"
+
+void
+md_core(kd, fd, ki)
+ kvm_t *kd;
+ int fd;
+ struct kinfo_proc *ki;
+{
+ /* Don't need to fix anything for this architecture. */
+ return;
+}
diff --git a/usr.bin/gcore/md-sparc.c b/usr.bin/gcore/md-sparc.c
new file mode 100644
index 0000000..794ceb1
--- /dev/null
+++ b/usr.bin/gcore/md-sparc.c
@@ -0,0 +1,186 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This software was developed by the Computer Systems Engineering group
+ * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
+ * contributed to Berkeley.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)md-sparc.c 8.1 (Berkeley) 6/6/93";
+#endif /* not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/stat.h>
+#include <sys/proc.h>
+#include <sys/user.h>
+#include <sys/sysctl.h>
+#include <machine/vmparam.h>
+
+#include <kvm.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include "extern.h"
+
+#ifndef offsetof
+#define offsetof(s, f) ((int)&((s *)0)->f)
+#endif
+
+static void
+shift_page(fd, off, ssize)
+ register int fd;
+ register off_t off;
+ register int ssize;
+{
+ char buffer[NBPG];
+
+ (void)lseek(fd, (off_t)-NBPG, SEEK_END);
+ for (; ssize > 0; ssize -= NBPG) {
+ (void)read(fd, buffer, NBPG);
+ (void)write(fd, buffer, NBPG);
+ (void)lseek(fd, (off_t)-2 * NBPG, SEEK_CUR);
+ }
+}
+
+/*
+ * Fix up the core image for the sparc. We need to flush any register
+ * windows that are cached in the pcb out to the user stack.
+ * Also, we need to get the trap frame and possible floating point state
+ * from the top of the kernel stack and store it in the pcb.
+ */
+void
+md_core(kd, fd, ki)
+ kvm_t *kd;
+ int fd;
+ struct kinfo_proc *ki;
+{
+ register struct rwindow *rw;
+ register int nsaved, cc, ssize;
+ register off_t off, s;
+ register u_long sp;
+ struct pcb pcb;
+ struct trapframe tf;
+
+ /*
+ * Before anything else read the trapframe. Synchronizing here
+ * is impossible if the process is running.
+ */
+ cc = kvm_read(kd, (u_long)ki->kp_proc.p_md.md_tf,
+ /* XXX */
+ (void *)&tf, sizeof(tf));
+ if (cc < 0)
+ err(1, "kvm_read: %s (reading kernel trapframe)",
+ kvm_geterr(kd));
+ if (cc != sizeof(tf))
+ err(1, "cannot read kernel trapframe");
+
+ /*
+ * Write out the real trap frame.
+ */
+ off = offsetof(struct user, u_md);
+ off += offsetof(struct md_coredump, md_tf);
+ if (lseek(fd, off, SEEK_SET) == -1)
+ err(1, "lseek: %s", strerror(errno));
+ (void)write(fd, &tf, sizeof(tf));
+
+ if (ki->kp_proc.p_md.md_fpstate != 0) {
+ /*
+ * If floating point state is present, write it out too.
+ * It comes right after the trapframe so we don't need to seek.
+ */
+ struct fpstate fs;
+ cc = kvm_read(kd, (u_long)ki->kp_proc.p_md.md_fpstate,
+ (void *)&fs, sizeof(fs));
+ if (cc < 0)
+ err(1, "kvm_read: %s (fpu state)", kvm_geterr(kd));
+ if (cc != sizeof(fs))
+ err(1, "cannot read fpu state");
+ (void)write(fd, (char *)&fs, sizeof(fs));
+ }
+ /*
+ * Read pcb.
+ */
+ if (lseek(fd, (off_t)offsetof(struct user, u_pcb), SEEK_SET) == -1)
+ err(1, "lseek: %s", strerror(errno));
+ cc = read(fd, (char *)&pcb, sizeof(pcb));
+ if (cc != sizeof(pcb)) {
+ if (cc < 0)
+ err(1, "read: %s", strerror(errno));
+ err(1, "couldn't read pcb from core file");
+ }
+
+ /*
+ * Write any unsaved windows to the appropriate stack locations.
+ */
+ nsaved = pcb.pcb_nsaved;
+ if (nsaved == 0)
+ return;
+
+ rw = &pcb.pcb_rw[0];
+ off = ctob(UPAGES + ki->kp_eproc.e_vm.vm_dsize);
+ ssize = ctob(ki->kp_eproc.e_vm.vm_ssize);
+ sp = tf.tf_out[6];
+ for (; --nsaved >= 0; ++rw) {
+ /*
+ * Copy register window into appropriate stack location.
+ */
+ s = ssize - (USRSTACK - sp);
+ if (s < 0) {
+ if (s < -NBPG)
+ err(1, "cannot copy pcb windows to stack");
+ /*
+ * It's possible to be missing the bottomost
+ * page because a stack page hasn't been allocated
+ * for the register save area. Shift over
+ * the stack segment by a page, and update
+ * the u-area to reflect the new stack size. YECH!
+ */
+ shift_page(fd, off, ssize);
+ ssize += NBPG;
+ s += NBPG;
+ ++ki->kp_eproc.e_vm.vm_ssize;
+ (void)lseek(fd,
+ (off_t)offsetof(struct user, u_kproc.kp_eproc.e_vm),
+ SEEK_SET);
+ (void)write(fd,
+ &ki->kp_eproc.e_vm, sizeof(ki->kp_eproc.e_vm));
+ }
+ if (lseek(fd, off + s, SEEK_SET) == -1)
+ err(1, "cannot copy pcb windows to stack");
+
+ (void)write(fd, rw, sizeof(*rw));
+ sp = rw->rw_in[6];
+ }
+}
OpenPOWER on IntegriCloud