+# $OpenBSD: Makefile,v 1.2 1996/03/19 23:14:49 niklas Exp $
+# $NetBSD: Makefile,v 1.18 1996/03/16 10:23:29 leo Exp $
# from: @(#)Makefile 5.25.1.1 (Berkeley) 5/7/91
-# $Id: Makefile,v 1.1.1.1 1995/10/18 08:41:16 deraadt Exp $
-SUBDIR= csu libarch libc libcompat libcrypt libcurses libedit libkvm libl \
+SUBDIR= csu libarch libc libcompat libcrypt libcurses libedit libl \
libm libpcap libresolv librpcsvc libskey libtelnet libterm libutil liby
+# XXX Temporarely until all ports are able to use libkvm (leo)
+.if (${MACHINE} == "atari")
+SUBDIR+= libkvm
+.else
+SUBDIR+= libkvm.old
+.endif
+
.include <bsd.subdir.mk>
-# $Id: Makefile,v 1.1.1.1 1995/10/18 08:41:19 deraadt Exp $
+# $OpenBSD: Makefile,v 1.2 1996/03/19 23:14:51 niklas Exp $
+# $NetBSD: Makefile,v 1.8 1996/02/21 02:43:52 jtk Exp $
-.if exists(${.CURDIR}/${MACHINE})
-.PATH: ${.CURDIR}/${MACHINE}
-.include "${.CURDIR}/${MACHINE}/Makefile.inc"
-AINC+= -I${.CURDIR}/${MACHINE}
+.if exists(${MACHINE})
+SUBDIR+= ${MACHINE}
.endif
-.if exists(${.CURDIR}/${MACHINE_ARCH}) && (${MACHINE} != ${MACHINE_ARCH})
-.PATH: ${.CURDIR}/${MACHINE_ARCH}
-.include "${.CURDIR}/${MACHINE_ARCH}/Makefile.inc"
-AINC+= -I${.CURDIR}/${MACHINE_ARCH}
-.endif
-
-OBJS+= ${ASM}
-POBJS+= ${ASM:.o=.po}
-CLEANFILES+= ${ASM} ${POBJS}
-
-
-.if exists(${.CURDIR}/${MACHINE}) || exists(${.CURDIR}/${MACHINE_ARCH})
-# then there's a lib for this machine/machine architecture
-LIB= ${MACHINE}
-.include <bsd.lib.mk>
-.else
-# there's NOT, so get the targets right
-all:
-clean:
-cleandir:
-depend:
-install:
-lint:
-obj:
-.endif
+.include <bsd.subdir.mk>
--- /dev/null
+# $OpenBSD: Makefile.inc,v 1.1 1996/03/19 23:14:52 niklas Exp $
+# $NetBSD: Makefile.inc,v 1.1 1996/02/21 02:43:57 jtk Exp $
+#
+# This Makefile includes boiler-plate stuff included by each subdir's Makefile.
+
+.if exists(${.CURDIR}/../${MACHINE_ARCH}) && (${MACHINE} != ${MACHINE_ARCH})
+.PATH: ${.CURDIR}/../${MACHINE_ARCH}
+.include "${.CURDIR}/../${MACHINE_ARCH}/Makefile.inc"
+AINC+= -I${.CURDIR}/../${MACHINE_ARCH}
+.endif
+
+OBJS+= ${ASM}
+POBJS+= ${ASM:.o=.po}
+CLEANFILES+= ${ASM} ${POBJS}
+
+LIB= ${MACHINE}
--- /dev/null
+# $OpenBSD: Makefile,v 1.1 1996/03/19 23:14:54 niklas Exp $
+# $NetBSD: Makefile,v 1.1 1996/02/21 02:45:40 jtk Exp $
+
+#.PATH: ${LIBC}/i386
+
+SRCS+= alpha_mmclock_gettime.c alpha_mmclock_init.c gettimeofday.c
+
+.include <bsd.lib.mk>
+++ /dev/null
-# Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp
-
-#.PATH: ${LIBC}/i386
-
-SRCS+= alpha_mmclock_gettime.c alpha_mmclock_init.c gettimeofday.c
--- /dev/null
+# $OpenBSD: Makefile,v 1.1 1996/03/19 23:14:56 niklas Exp $
+# $NetBSD: Makefile,v 1.1 1996/02/21 02:45:47 jtk Exp $
+
+.PATH: ${LIBC}/i386
+
+SRCS+= i386_get_ldt.c i386_set_ldt.c \
+ i386_iopl.c i386_get_ioperm.c i386_set_ioperm.c \
+ i386_vm86.c
+
+MAN+= i386_get_ldt.2 \
+ i386_iopl.2 i386_get_ioperm.2 \
+ i386_vm86.2
+
+MLINKS+=i386_get_ldt.2 i386_set_ldt.2 \
+ i386_get_ioperm.2 i386_set_ioperm.2
+
+.include <bsd.lib.mk>
+
+++ /dev/null
-# Makefile.inc,v 1.1 1993/09/03 19:04:23 jtc Exp
-
-.PATH: ${LIBC}/i386
-
-SRCS+= i386_get_ldt.c i386_set_ldt.c \
- i386_iopl.c i386_get_ioperm.c i386_set_ioperm.c
-
-MAN+= i386_get_ldt.2 \
- i386_iopl.2 i386_get_ioperm.2
-
-MLINKS+=i386_get_ldt.2 i386_set_ldt.2 \
- i386_get_ioperm.2 i386_set_ioperm.2
-.\" Copyright (c) 1980, 1991 Regents of the University of California.
+.\" $OpenBSD: i386_get_ioperm.2,v 1.3 1996/03/19 23:14:58 niklas Exp $
+.\" $NetBSD: i386_get_ioperm.2,v 1.3 1996/02/27 22:57:17 jtc Exp $
+.\"
+.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by John T. Kohl and Charles M. Hannum.
+.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 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.
+.\" This product includes software developed by the NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
.\"
-.\" from: @(#)fork.2 6.5 (Berkeley) 3/10/91
-.\" $NetBSD: i386_get_ioperm.2,v 1.2 1996/01/05 14:56:42 pk Exp $
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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.
.\"
.Dd October 14, 1995
.Dt I386_GET_IOPERM 2
-/* $NetBSD: i386_get_ioperm.c,v 1.1 1995/10/15 02:29:10 mycroft Exp $ */
+/* $OpenBSD: i386_get_ioperm.c,v 1.2 1996/03/19 23:14:59 niklas Exp $ */
+/* $NetBSD: i386_get_ioperm.c,v 1.2 1996/02/27 22:57:22 jtc Exp $ */
-/*
- * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
- *
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by John T. Kohl and Charles M. Hannum.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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 Charles M. Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 AUTHOR ``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 AUTHOR 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.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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.
*/
#include <sys/cdefs.h>
-.\" Copyright (c) 1980, 1991 Regents of the University of California.
+.\" $OpenBSD: i386_iopl.2,v 1.3 1996/03/19 23:14:59 niklas Exp $
+.\" $NetBSD: i386_iopl.2,v 1.3 1996/02/27 22:57:25 jtc Exp $
+.\"
+.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by John T. Kohl and Charles M. Hannum.
+.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 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.
+.\" This product includes software developed by the NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation nor the names of its
+.\" contributors may be used to endorse or promote products derived
+.\" from this software without specific prior written permission.
.\"
-.\" from: @(#)fork.2 6.5 (Berkeley) 3/10/91
-.\" $NetBSD: i386_iopl.2,v 1.2 1996/01/05 14:56:45 pk Exp $
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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.
.\"
.Dd October 14, 1995
.Dt I386_IOPL 2
-/* $NetBSD: i386_iopl.c,v 1.1 1995/10/15 02:29:12 mycroft Exp $ */
+/* $OpenBSD: i386_iopl.c,v 1.2 1996/03/19 23:15:00 niklas Exp $ */
+/* $NetBSD: i386_iopl.c,v 1.2 1996/02/27 22:57:29 jtc Exp $ */
-/*
- * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
- *
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by John T. Kohl and Charles M. Hannum.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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 Charles M. Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 AUTHOR ``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 AUTHOR 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.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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.
*/
#include <sys/cdefs.h>
-/* $NetBSD: i386_set_ioperm.c,v 1.1 1995/10/15 02:29:13 mycroft Exp $ */
+/* $OpenBSD: i386_set_ioperm.c,v 1.2 1996/03/19 23:15:01 niklas Exp $ */
+/* $NetBSD: i386_set_ioperm.c,v 1.2 1996/02/27 22:57:31 jtc Exp $ */
-/*
- * Copyright (c) 1995 Charles M. Hannum. All rights reserved.
- *
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by John T. Kohl and Charles M. Hannum.
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 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 Charles M. Hannum.
- * 4. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 AUTHOR ``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 AUTHOR 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.
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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.
*/
#include <sys/cdefs.h>
--- /dev/null
+.\" $OpenBSD: i386_vm86.2,v 1.1 1996/03/19 23:15:02 niklas Exp $
+.\" $NetBSD: i386_vm86.2,v 1.1 1996/02/21 00:21:52 jtk Exp $
+.\"
+.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by John Kohl.
+.\"
+.\" 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 NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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.
+.\"
+.\" from: @(#)fork.2 6.5 (Berkeley) 3/10/91
+.\"
+.Dd February 20, 1996
+.Dt I386_VM86 2
+.Os NetBSD
+.Sh NAME
+.Nm i386_vm86
+.Nd set virtual 8086 processor registers and mode
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <signal.h>
+.Fd #include <machine/segments.h>
+.Fd #include <machine/sysarch.h>
+.Fd #include <machine/vm86.h>
+.Ft int
+.Fn i386_vm86 "struct vm86_struct *vmcp"
+.Sh DESCRIPTION
+.Fn i386_vm86
+will set the process into virtual 8086 mode using the registers and
+selectors specified by the context pointed to by
+.Ar vmcp .
+The processor registers are set from
+.Ar vmcp->substr.regs ,
+and the emulated processor type from
+.Ar vmcp->substr.ss_cpu_type .
+.Pp
+The kernel keeps a pointer to the context, and uses the tables stored at
+.Ar vmcp->int_byuser
+and
+.Ar vmcp->int21_byuser
+for fast virtual interrupt handling. If the
+.Ar n th
+bit is clear in the first of
+these arrays, then the kernel may directly emulate the real-mode x86 INT
+.Ar n
+instruction handling. If the
+.Ar n
+th bit is set, then the process is
+delivered a signal when an INT instruction is executed.
+.Pp
+Since MS-DOS puts many DOS functions onto interrupt 21, it is handled
+specially: the
+.Ar k
+th bit in the
+.Ar vmcp->int21_byuser
+array is checked when INT
+.Ar 21
+is requested and the
+.Ar ah
+register is
+.Ar k .
+.Sh RETURN VALUES
+This routine does not normally return: 32-bit mode will be restored by
+the delivery of a signal to the process. In case of an error in setting
+the VM86 mode, a value of -1 is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Fn i386_vm86
+will fail if:
+.Bl -tag -width [EINVAL]
+.It Bq Er EFAULT
+The state at
+.Ar vmcp
+was not readable to the user process.
+.Sh REFERENCES
+i386 Microprocessor Programmer's Reference Manual, Intel
--- /dev/null
+/* $OpenBSD: i386_vm86.c,v 1.1 1996/03/19 23:15:03 niklas Exp $ */
+/* $NetBSD: i386_vm86.c,v 1.1 1996/02/21 00:21:56 jtk Exp $ */
+
+/*-
+ * Copyright (c) 1996 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by John Kohl.
+ *
+ * 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 NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <machine/signal.h>
+#include <machine/segments.h>
+#include <machine/sysarch.h>
+#include <machine/vm86.h>
+
+int
+i386_vm86(vmcp)
+ register struct vm86_struct *vmcp;
+{
+
+ return sysarch(I386_VM86, (char *)vmcp);
+}
+
--- /dev/null
+major=0
+minor=2
+++ /dev/null
-major=0
-minor=1
+/* $OpenBSD: _setjmp.S,v 1.2 1996/03/19 23:15:05 niklas Exp $ */
+
/*
+ *
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* SUCH DAMAGE.
*
* from: Header: _setjmp.s,v 1.1 91/07/06 16:45:53 torek Exp
- * $Id: _setjmp.S,v 1.1.1.1 1995/10/18 08:41:40 deraadt Exp $
*/
#if defined(LIBC_SCCS) && !defined(lint)
#include "DEFS.h"
ENTRY(_setjmp)
- std %sp, [%o0+0] /* caller's stack pointer and return pc */
- st %fp, [%o0+8] /* store caller's frame pointer */
+ st %sp, [%o0+0] /* store caller's stack pointer */
+ st %o7, [%o0+4] /* ... return pc */
+ st %fp, [%o0+8] /* ... and frame pointer */
retl
clr %o0 ! return 0
bl,a 1b ! if below,
restore ! pop frame and loop
be,a 2f ! if there,
- ldd [%g1+0], %o2 ! fetch return %sp and pc, and get out
+ ld [%g1+0], %o2 ! fetch return %sp
Lbotch:
call _longjmperror ! otherwise, went too far; bomb out
mov %o2, %sp ! it is OK, put it in place
b,a Lbotch
3:
+ ld [%g1+4], %o3 ! fetch pc
jmp %o3 + 8 ! success, return %g6
mov %g6, %o0
+.\" $OpenBSD: getdtablesize.3,v 1.2 1996/03/19 23:15:06 niklas Exp $
+.\"
.\" Copyright (c) 1983, 1991 The Regents of the University of California.
.\" All rights reserved.
.\"
.\" SUCH DAMAGE.
.\"
.\" from: @(#)getdtablesize.2 6.5 (Berkeley) 3/10/91
-.\" $Id: getdtablesize.3,v 1.1.1.1 1995/10/18 08:41:46 deraadt Exp $
.\"
.Dd March 10, 1991
.Dt GETDTABLESIZE 3
.Sh SEE ALSO
.Xr close 2 ,
.Xr dup 2 ,
+.Xr getrlimit 2 ,
.Xr open 2 ,
-.Xr select 2
+.Xr select 2 ,
+.Xr sysconf 3
.Sh HISTORY
The
.Fn getdtablesize
-/* $NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp $ */
+/* $OpenBSD: inet_network.c,v 1.2 1996/03/19 23:15:08 niklas Exp $ */
+/* $NetBSD: inet_network.c,v 1.5 1996/02/17 15:35:41 hpeyerl Exp $ */
/*
* Copyright (c) 1983, 1993
#if 0
static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
#else
-static char rcsid[] = "$NetBSD: inet_network.c,v 1.4 1995/02/25 06:20:45 cgd Exp $";
+static char rcsid[] = "$OpenBSD: inet_network.c,v 1.2 1996/03/19 23:15:08 niklas Exp $";
+static char rcsid[] = "$NetBSD: inet_network.c,v 1.5 1996/02/17 15:35:41 hpeyerl Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
break;
}
if (*cp == '.') {
- if (pp >= parts + 4)
+ if (pp >= parts + 3)
return (INADDR_NONE);
*pp++ = val, cp++;
goto again;
return (INADDR_NONE);
*pp++ = val;
n = pp - parts;
- if (n > 4)
- return (INADDR_NONE);
for (val = 0, i = 0; i < n; i++) {
val <<= 8;
val |= parts[i] & 0xff;
-/* $NetBSD: xdr_float.c,v 1.9 1995/06/05 11:48:26 pk Exp $ */
+/* $OpenBSD: xdr_float.c,v 1.2 1996/03/19 23:15:09 niklas Exp $ */
+/* $NetBSD: xdr_float.c,v 1.10 1996/02/16 21:14:03 mark Exp $ */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
#if defined(LIBC_SCCS) && !defined(lint)
/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/
/*static char *sccsid = "from: @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC";*/
-static char *rcsid = "$NetBSD: xdr_float.c,v 1.9 1995/06/05 11:48:26 pk Exp $";
+static char *rcsid = "$OpenBSD: xdr_float.c,v 1.2 1996/03/19 23:15:09 niklas Exp $";
+static char *rcsid = "$NetBSD: xdr_float.c,v 1.10 1996/02/16 21:14:03 mark Exp $";
#endif
/*
*/
#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
- defined(__mips__) || defined(__ns32k__) || defined(__alpha__)
+ defined(__mips__) || defined(__ns32k__) || defined(__alpha__) || \
+ defined(__arm32__)
#include <machine/endian.h>
#define IEEEFP
#endif
+/* $OpenBSD: strtod.c,v 1.2 1996/03/19 23:15:11 niklas Exp $ */
+/* $NetBSD: strtod.c,v 1.21 1996/02/16 21:19:29 mark Exp $ */
+
/****************************************************************
*
* The author of this software is David M. Gay.
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char *rcsid = "$Id: strtod.c,v 1.1.1.1 1995/10/18 08:42:19 deraadt Exp $";
+static char *rcsid = "$OpenBSD: strtod.c,v 1.2 1996/03/19 23:15:11 niklas Exp $";
#endif /* LIBC_SCCS and not lint */
#if defined(__m68k__) || defined(__sparc__) || defined(__i386__) || \
#endif
#endif
+#ifdef __arm32__
+/*
+ * Although the CPU is little endian the FP has different
+ * byte and word endianness. The byte order is still little endian
+ * but the word order is big endian.
+ */
+#define IEEE_BIG_ENDIAN
+#endif
+
#ifdef vax
#define VAX
#endif
* An alternative that might be better on some machines is
* #define Storeinc(a,b,c) (*a++ = b << 16 | c & 0xffff)
*/
-#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX)
+#if defined(IEEE_LITTLE_ENDIAN) + defined(VAX) + defined(__arm32__)
#define Storeinc(a,b,c) (((unsigned short *)a)[1] = (unsigned short)b, \
((unsigned short *)a)[0] = (unsigned short)c, a++)
#else
+.\" $OpenBSD: system.3,v 1.3 1996/03/19 23:15:12 niklas Exp $
+.\" $NetBSD: system.3,v 1.7 1996/02/16 22:30:46 jtc Exp $
+.\"
.\" Copyright (c) 1990, 1991 The Regents of the University of California.
.\" All rights reserved.
.\"
.\" SUCH DAMAGE.
.\"
.\" from: @(#)system.3 6.5 (Berkeley) 6/29/91
-.\" $Id: system.3,v 1.2 1995/11/01 16:43:27 deraadt Exp $
.\"
.Dd June 29, 1991
.Dt SYSTEM 3
.Sh SEE ALSO
.Xr sh 1 ,
.Xr execve 2 ,
-.Xr popen 3 ,
-.Xr waitpid 3 ,
+.Xr waitpid 2 ,
+.Xr popen 3
.Sh STANDARDS
The
.Fn system
+.\" $OpenBSD: strftime.3,v 1.2 1996/03/19 23:15:14 niklas Exp $
+.\"
.\" Copyright (c) 1989, 1991 The Regents of the University of California.
.\" All rights reserved.
.\"
.\" SUCH DAMAGE.
.\"
.\" from: @(#)strftime.3 5.12 (Berkeley) 6/29/91
-.\" $Id: strftime.3,v 1.1.1.1 1995/10/18 08:42:22 deraadt Exp $
.\"
.Dd June 29, 1991
.Dt STRFTIME 3
is replaced by the weekday (Sunday as the first day of the week)
as a decimal number (0-6).
.It Cm \&%X
-is replaced by the locale's appropriate date representation.
-.It Cm \&%x
is replaced by the locale's appropriate time representation.
+.It Cm \&%x
+is replaced by the locale's appropriate date representation.
.It Cm \&%Y
is replaced by the year with century as a decimal number.
.It Cm \&%y
-.\" $NetBSD: listen.2,v 1.6 1995/02/27 12:34:05 cgd Exp $
+.\" $OpenBSD: listen.2,v 1.2 1996/03/19 23:15:16 niklas Exp $
+.\" $NetBSD: listen.2,v 1.7 1996/02/16 20:38:45 phil Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.Sh BUGS
The
.Fa backlog
-is currently limited (silently) to 5.
+is currently limited (silently) to 128.
.Sh HISTORY
The
.Fn listen
-.\" $OpenBSD: mount.2,v 1.4 1996/03/09 02:42:59 niklas Exp $
-.\" $NetBSD: mount.2,v 1.11 1996/02/08 18:33:58 mycroft Exp $
+.\" $OpenBSD: mount.2,v 1.5 1996/03/19 23:15:17 niklas Exp $
+.\" $NetBSD: mount.2,v 1.12 1996/02/29 23:47:48 jtc Exp $
.\"
.\" Copyright (c) 1980, 1989, 1993
.\" The Regents of the University of California. All rights reserved.
Do not honor setuid or setgid bits on files when executing them.
.It Dv MNT_NODEV
Do not interpret special files on the file system.
+.It Dv MNT_UNION
+Union with underlying filesystem instead of obscuring it.
.It Dv MNT_SYNCHRONOUS
All I/O to the file system should be done synchronously.
.El
.Dv MOUNT_FFS
.Bd -literal -offset indent -compact
struct ufs_args {
- char *fspec; /* Block special file to mount */
- int exflags; /* export related flags */
- uid_t exroot; /* mapping for root uid */
+ char *fspec; /* block special file to mount */
+ struct export_args export; /* network export information */
};
.Ed
.Pp
.Dv MOUNT_NFS
.Bd -literal -offset indent -compact
struct nfs_args {
- struct sockaddr_in *addr; /* file server address */
- nfsv2fh_t *fh; /* File handle to be mounted */
- int flags; /* flags */
- int wsize; /* write size in bytes */
- int rsize; /* read size in bytes */
- int timeo; /* initial timeout 0.1 secs */
- int retrans; /* times to retry send */
- char *hostname; /* server's name */
+ int version; /* args structure version */
+ struct sockaddr *addr; /* file server address */
+ int addrlen; /* length of address */
+ int sotype; /* Socket type */
+ int proto; /* and Protocol */
+ u_char *fh; /* File handle to be mounted */
+ int fhsize; /* Size, in bytes, of fh */
+ int flags; /* flags */
+ int wsize; /* write size in bytes */
+ int rsize; /* read size in bytes */
+ int readdirsize; /* readdir size in bytes */
+ int timeo; /* initial timeout in .1 secs */
+ int retrans; /* times to retry send */
+ int maxgrouplist; /* Max. size of group list */
+ int readahead; /* # of blocks to readahead */
+ int leaseterm; /* Term (sec) of lease */
+ int deadthresh; /* Retrans threshold */
+ char *hostname; /* server's name */
};
.Ed
.Pp
.Dv MOUNT_MFS
.Bd -literal -offset indent -compact
struct mfs_args {
- char *name; /* name of backing process */
- caddr_t base; /* base address of the file system */
- u_long size; /* size of the file system */
+ char *fspec; /* name to export for statfs */
+ struct export_args export; /* if we can export an MFS */
+ caddr_t base; /* base of file system in mem */
+ u_long size; /* size of file system */
};
.Ed
.Pp
-.\" $NetBSD: ptrace.2,v 1.2 1995/02/27 12:35:37 cgd Exp $
+.\" $OpenBSD: ptrace.2,v 1.2 1996/03/19 23:15:18 niklas Exp $
+.\" $NetBSD: ptrace.2,v 1.3 1996/02/23 01:39:41 jtc Exp $
.\"
.\" This file is in the public domain.
.Dd November 7, 1994
.Dv PT_READ_I
reads from the instruction space and
.Dv PT_READ_D
-reads from the data space. In the current NetBSD implementation, these
+reads from the data space. In the current OpenBSD implementation, these
two requests are completely identical. The
.Fa addr
argument specifies the address (in the traced process' virtual address
except that they write rather than read. The
.Fa data
argument supplies the value to be written.
-.It Dv PT_READ_U
-This request reads an
-.Li int
-from the traced process' user structure. The
-.Fa addr
-argument specifies the location of the int relative to the base of the
-user structure; it will usually be an integer value cast to
-.Li caddr_t
-either explicitly or via the presence of a prototype for
-.Eo \&
-.Fn ptrace
-.Ec .
-Unlike
-.Dv PT_READ_I
-and
-.Dv PT_READ_D ,
-.Fa addr
-must be aligned on an
-.Li int
-boundary. The value read is returned as the return value from
-.Eo \&
-.Fn ptrace
-.Ec .
-.It Dv PT_WRITE_U
-This request writes an
-.Li int
-into the traced process' user structure.
-.Fa addr
-specifies the offset, just as for
-.Dv PT_READ_U ,
-and
-.Fa data
-specifies the value to be written, just as for
-.Dv PT_WRITE_I
-and
-.Dv PT_WRITE_D .
+.\" .It Dv PT_READ_U
+.\" This request reads an
+.\" .Li int
+.\" from the traced process' user structure. The
+.\" .Fa addr
+.\" argument specifies the location of the int relative to the base of the
+.\" user structure; it will usually be an integer value cast to
+.\" .Li caddr_t
+.\" either explicitly or via the presence of a prototype for
+.\" .Eo \&
+.\" .Fn ptrace
+.\" .Ec .
+.\" Unlike
+.\" .Dv PT_READ_I
+.\" and
+.\" .Dv PT_READ_D ,
+.\" .Fa addr
+.\" must be aligned on an
+.\" .Li int
+.\" boundary. The value read is returned as the return value from
+.\" .Eo \&
+.\" .Fn ptrace
+.\" .Ec .
+.\" .It Dv PT_WRITE_U
+.\" This request writes an
+.\" .Li int
+.\" into the traced process' user structure.
+.\" .Fa addr
+.\" specifies the offset, just as for
+.\" .Dv PT_READ_U ,
+.\" and
+.\" .Fa data
+.\" specifies the value to be written, just as for
+.\" .Dv PT_WRITE_I
+.\" and
+.\" .Dv PT_WRITE_D .
.It Dv PT_CONTINUE
The traced process continues execution.
.Fa addr
.Aq Pa machine/reg.h )
pointed to by
.Fa addr .
-.It Dv PT_SYSCALL
-This request is like
-.Dv PT_CONTINUE
-except that the process will stop next time it executes any system
-call. Information about the system call can be examined with
-.Dv PT_READ_U
-and potentially modified with
-.Dv PT_WRITE_U
-through the
-.Li u_kproc.kp_proc.p_md
-element of the user structure (see below). If the process is continued
-with another
-.Dv PT_SYSCALL
-request, it will stop again on exit from the syscall, at which point
-the return values can be examined and potentially changed. The
-.Li u_kproc.kp_proc.p_md
-element is of type
-.Dq Li "struct mdproc" ,
-which should be declared by including
-.Aq Pa sys/param.h ,
-.Aq Pa sys/user.h ,
-and
-.Aq Pa machine/proc.h ,
-and contains the following fields (among others):
-.Bl -item -compact -offset indent
-.It
-.Li syscall_num
-.It
-.Li syscall_nargs
-.It
-.Li syscall_args[8]
-.It
-.Li syscall_err
-.It
-.Li syscall_rv[2]
-.El
-When a process stops on entry to a syscall,
-.Li syscall_num
-holds the number of the syscall,
-.Li syscall_nargs
-holds the number of arguments it expects, and
-.Li syscall_args
-holds the arguments themselves. (Only the first
-.Li syscall_nargs
-elements of
-.Li syscall_args
-are guaranteed to be useful.) When a process stops on exit from a
-syscall,
-.Li syscall_num
-is
-.Eo \&
-.Li -1
-.Ec ,
-.Li syscall_err
-holds the error number
-.Po
-see
-.Xr errno 2
-.Pc ,
-or 0 if no error occurred, and
-.Li syscall_rv
-holds the return values. (If the syscall returns only one value, only
-.Li syscall_rv[0]
-is useful.) The tracing process can modify any of these with
-.Dv PT_WRITE_U ;
-only some modifications are useful.
-.Pp
-On entry to a syscall,
-.Li syscall_num
-can be changed, and the syscall actually performed will correspond to
-the new number (it is the responsibility of the tracing process to fill
-in
-.Li syscall_args
-appropriately for the new call, but there is no need to modify
-.Eo \&
-.Li syscall_nargs
-.Ec ).
-If the new syscall number is 0, no syscall is actually performed;
-instead,
-.Li syscall_err
-and
-.Li syscall_rv
-are passed back to the traced process directly (and therefore should be
-filled in). If the syscall number is otherwise out of range, a dummy
-syscall which simply produces an
-.Er ENOSYS
-error is effectively performed.
-.Pp
-On exit from a syscall, only
-.Li syscall_err
-and
-.Li syscall_rv
-can usefully be changed; they are set to the values returned by the
-syscall and will be passed back to the traced process by the normal
-syscall return mechanism.
+.\" .It Dv PT_SYSCALL
+.\" This request is like
+.\" .Dv PT_CONTINUE
+.\" except that the process will stop next time it executes any system
+.\" call. Information about the system call can be examined with
+.\" .Dv PT_READ_U
+.\" and potentially modified with
+.\" .Dv PT_WRITE_U
+.\" through the
+.\" .Li u_kproc.kp_proc.p_md
+.\" element of the user structure (see below). If the process is continued
+.\" with another
+.\" .Dv PT_SYSCALL
+.\" request, it will stop again on exit from the syscall, at which point
+.\" the return values can be examined and potentially changed. The
+.\" .Li u_kproc.kp_proc.p_md
+.\" element is of type
+.\" .Dq Li "struct mdproc" ,
+.\" which should be declared by including
+.\" .Aq Pa sys/param.h ,
+.\" .Aq Pa sys/user.h ,
+.\" and
+.\" .Aq Pa machine/proc.h ,
+.\" and contains the following fields (among others):
+.\" .Bl -item -compact -offset indent
+.\" .It
+.\" .Li syscall_num
+.\" .It
+.\" .Li syscall_nargs
+.\" .It
+.\" .Li syscall_args[8]
+.\" .It
+.\" .Li syscall_err
+.\" .It
+.\" .Li syscall_rv[2]
+.\" .El
+.\" When a process stops on entry to a syscall,
+.\" .Li syscall_num
+.\" holds the number of the syscall,
+.\" .Li syscall_nargs
+.\" holds the number of arguments it expects, and
+.\" .Li syscall_args
+.\" holds the arguments themselves. (Only the first
+.\" .Li syscall_nargs
+.\" elements of
+.\" .Li syscall_args
+.\" are guaranteed to be useful.) When a process stops on exit from a
+.\" syscall,
+.\" .Li syscall_num
+.\" is
+.\" .Eo \&
+.\" .Li -1
+.\" .Ec ,
+.\" .Li syscall_err
+.\" holds the error number
+.\" .Po
+.\" see
+.\" .Xr errno 2
+.\" .Pc ,
+.\" or 0 if no error occurred, and
+.\" .Li syscall_rv
+.\" holds the return values. (If the syscall returns only one value, only
+.\" .Li syscall_rv[0]
+.\" is useful.) The tracing process can modify any of these with
+.\" .Dv PT_WRITE_U ;
+.\" only some modifications are useful.
+.\" .Pp
+.\" On entry to a syscall,
+.\" .Li syscall_num
+.\" can be changed, and the syscall actually performed will correspond to
+.\" the new number (it is the responsibility of the tracing process to fill
+.\" in
+.\" .Li syscall_args
+.\" appropriately for the new call, but there is no need to modify
+.\" .Eo \&
+.\" .Li syscall_nargs
+.\" .Ec ).
+.\" If the new syscall number is 0, no syscall is actually performed;
+.\" instead,
+.\" .Li syscall_err
+.\" and
+.\" .Li syscall_rv
+.\" are passed back to the traced process directly (and therefore should be
+.\" filled in). If the syscall number is otherwise out of range, a dummy
+.\" syscall which simply produces an
+.\" .Er ENOSYS
+.\" error is effectively performed.
+.\" .Pp
+.\" On exit from a syscall, only
+.\" .Li syscall_err
+.\" and
+.\" .Li syscall_rv
+.\" can usefully be changed; they are set to the values returned by the
+.\" syscall and will be passed back to the traced process by the normal
+.\" syscall return mechanism.
.El
.Sh ERRORS
Some requests can cause
The
.Fa request
was not one of the legal requests.
-.It
-The
-.Fa addr
-to
-.Dv PT_READ_U
-or
-.Dv PT_WRITE_U
-was not
-.Li int Ns \&-aligned.
+.\" .It
+.\" The
+.\" .Fa addr
+.\" to
+.\" .Dv PT_READ_U
+.\" or
+.\" .Dv PT_WRITE_U
+.\" was not
+.\" .Li int Ns \&-aligned.
.It
The signal number (in
.Fa data )
to
.Dv PT_CONTINUE
-or
-.Dv PT_SYSCALL
+.\" or
+.\" .Dv PT_SYSCALL
was neither 0 nor a legal signal number.
.It
.Dv PT_GETREGS ,
should be able to sidestep this.
.Pp
Single-stepping is not available.
-.Pp
-When using
-.Dv PT_SYSCALL ,
-there is no easy way to tell whether the traced process stopped because
-it made a syscall or because a signal was sent at a moment that it just
-happened to have valid-looking garbage in its
-.Dq Li "struct mdproc" .
+.\" .Pp
+.\" When using
+.\" .Dv PT_SYSCALL ,
+.\" there is no easy way to tell whether the traced process stopped because
+.\" it made a syscall or because a signal was sent at a moment that it just
+.\" happened to have valid-looking garbage in its
+.\" .Dq Li "struct mdproc" .
-.\" $NetBSD: ypclnt.3,v 1.4 1995/09/12 19:33:03 thorpej Exp $
+.\" $OpenBSD: ypclnt.3,v 1.2 1996/03/19 23:15:20 niklas Exp $
+.\" $NetBSD: ypclnt.3,v 1.5 1996/02/28 00:57:22 thorpej Exp $
.\"
-.\" Copyright (c) 1994 Jason R. Thorpe
+.\" Copyright (c) 1996 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Jason R. Thorpe.
+.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 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 Jason Thorpe.
-.\" 4. Neither the name of the author nor the names of its contributors
-.\" may be used to endorse or promote products derived from this software
-.\" without specific prior written permission.
+.\" This product includes software developed by the NetBSD
+.\" Foundation, Inc. and its contributors.
+.\" 4. Neither the name of The NetBSD Foundation 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 AUTHOR ``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 AUTHOR 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.
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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.
.\"
.Dd October 26, 1994
.Dt YPCLNT 3
--- /dev/null
+# from: @(#)Makefile 8.1 (Berkeley) 6/4/93
+# $OpenBSD: Makefile,v 1.1 1996/03/19 23:15:26 niklas Exp $
+
+LIB= kvm
+CFLAGS+=-DLIBC_SCCS
+
+# Try most specific name first.
+.if exists(kvm_${MACHINE}.c)
+SRCS= kvm_${MACHINE}.c
+.else
+# Less specific name (i.e. m68k)
+CFLAGS+=-D${MACHINE}
+SRCS= kvm_${MACHINE_ARCH}.c
+.endif
+
+SRCS+= kvm.c kvm_file.c kvm_getloadavg.c kvm_proc.c
+
+MAN= kvm.3 kvm_geterr.3 kvm_getfiles.3 kvm_getloadavg.3 kvm_getprocs.3 \
+ kvm_nlist.3 kvm_open.3 kvm_read.3
+
+MLINKS+=kvm_getprocs.3 kvm_getargv.3 kvm_getprocs.3 kvm_getenvv.3
+MLINKS+=kvm_open.3 kvm_openfiles.3 kvm_open.3 kvm_close.3
+MLINKS+=kvm_read.3 kvm_write.3
+
+.include <bsd.lib.mk>
--- /dev/null
+.\" $OpenBSD: kvm.3,v 1.1 1996/03/19 23:15:27 niklas Exp $
+.\"
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software 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.
+.\"
+.\" @(#)kvm.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt KVM 3
+.Os
+.Sh NAME
+.Nm kvm
+.Nd kernel memory interface
+.Sh DESCRIPTION
+The
+.Xr kvm 3
+library provides a uniform interface for accessing kernel virtual memory
+images, including live systems and crashdumps.
+Access to live systems is via
+/dev/mem
+while crashdumps can be examined via the core file generated by
+.Xr savecore 8 .
+The interface behaves identically in both cases.
+Memory can be read and written, kernel symbol addresses can be
+looked up efficiently, and information about user processes can
+be gathered.
+.Pp
+.Fn kvm_open
+is first called to obtain a descriptor for all subsequent calls.
+.Sh COMPATIBILITY
+The kvm interface was first introduced in SunOS. A considerable
+number of programs have been developed that use this interface,
+making backward compatibility highly desirable.
+In most respects, the Sun kvm interface is consistent and clean.
+Accordingly, the generic portion of the interface (i.e.,
+.Fn kvm_open ,
+.Fn kvm_close ,
+.Fn kvm_read ,
+.Fn kvm_write ,
+and
+.Fn kvm_nlist )
+has been incorporated into the BSD interface. Indeed, many kvm
+applications (i.e., debuggers and statistical monitors) use only
+this subset of the interface.
+.Pp
+The process interface was not kept. This is not a portability
+issue since any code that manipulates processes is inherently
+machine dependent.
+.Pp
+Finally, the Sun kvm error reporting semantics are poorly defined.
+The library can be configured either to print errors to stderr automatically,
+or to print no error messages at all.
+In the latter case, the nature of the error cannot be determined.
+To overcome this, the BSD interface includes a
+routine,
+.Xr kvm_geterr 3 ,
+to return (not print out) the error message
+corresponding to the most recent error condition on the
+given descriptor.
+.Sh SEE ALSO
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getloadavg 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
--- /dev/null
+/* $OpenBSD: kvm.c,v 1.1 1996/03/19 23:15:28 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm.c 8.2 (Berkeley) 2/13/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/swap_pager.h>
+
+#include <machine/vmparam.h>
+
+#include <ctype.h>
+#include <db.h>
+#include <fcntl.h>
+#include <kvm.h>
+#include <limits.h>
+#include <nlist.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "kvm_private.h"
+
+static int kvm_dbopen __P((kvm_t *, const char *));
+static kvm_t *_kvm_open __P((kvm_t *, const char *, const char *,
+ const char *, int, char *));
+
+char *
+kvm_geterr(kd)
+ kvm_t *kd;
+{
+ return (kd->errbuf);
+}
+
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+/*
+ * Report an error using printf style arguments. "program" is kd->program
+ * on hard errors, and 0 on soft errors, so that under sun error emulation,
+ * only hard errors are printed out (otherwise, programs like gdb will
+ * generate tons of error messages when trying to access bogus pointers).
+ */
+void
+#if __STDC__
+_kvm_err(kvm_t *kd, const char *program, const char *fmt, ...)
+#else
+_kvm_err(kd, program, fmt, va_alist)
+ kvm_t *kd;
+ char *program, *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+
+#ifdef __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ if (program != NULL) {
+ (void)fprintf(stderr, "%s: ", program);
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fputc('\n', stderr);
+ } else
+ (void)vsnprintf(kd->errbuf,
+ sizeof(kd->errbuf), (char *)fmt, ap);
+
+ va_end(ap);
+}
+
+void
+#if __STDC__
+_kvm_syserr(kvm_t *kd, const char *program, const char *fmt, ...)
+#else
+_kvm_syserr(kd, program, fmt, va_alist)
+ kvm_t *kd;
+ char *program, *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+ register int n;
+
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+ if (program != NULL) {
+ (void)fprintf(stderr, "%s: ", program);
+ (void)vfprintf(stderr, fmt, ap);
+ (void)fprintf(stderr, ": %s\n", strerror(errno));
+ } else {
+ register char *cp = kd->errbuf;
+
+ (void)vsnprintf(cp, sizeof(kd->errbuf), (char *)fmt, ap);
+ n = strlen(cp);
+ (void)snprintf(&cp[n], sizeof(kd->errbuf) - n, ": %s",
+ strerror(errno));
+ }
+ va_end(ap);
+}
+
+void *
+_kvm_malloc(kd, n)
+ register kvm_t *kd;
+ register size_t n;
+{
+ void *p;
+
+ if ((p = malloc(n)) == NULL)
+ _kvm_err(kd, kd->program, strerror(errno));
+ return (p);
+}
+
+static kvm_t *
+_kvm_open(kd, uf, mf, sf, flag, errout)
+ register kvm_t *kd;
+ const char *uf;
+ const char *mf;
+ const char *sf;
+ int flag;
+ char *errout;
+{
+ struct stat st;
+
+ kd->db = 0;
+ kd->pmfd = -1;
+ kd->vmfd = -1;
+ kd->swfd = -1;
+ kd->nlfd = -1;
+ kd->procbase = 0;
+ kd->nbpg = getpagesize();
+ kd->swapspc = 0;
+ kd->argspc = 0;
+ kd->argbuf = 0;
+ kd->argv = 0;
+ kd->vmst = 0;
+ kd->vm_page_buckets = 0;
+
+ if (uf == 0)
+ uf = _PATH_UNIX;
+ else if (strlen(uf) >= MAXPATHLEN) {
+ _kvm_err(kd, kd->program, "exec file name too long");
+ goto failed;
+ }
+ if (flag & ~O_RDWR) {
+ _kvm_err(kd, kd->program, "bad flags arg");
+ goto failed;
+ }
+ if (mf == 0)
+ mf = _PATH_MEM;
+ if (sf == 0)
+ sf = _PATH_DRUM;
+
+ if ((kd->pmfd = open(mf, flag, 0)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", mf);
+ goto failed;
+ }
+ if (fstat(kd->pmfd, &st) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", mf);
+ goto failed;
+ }
+ if (S_ISCHR(st.st_mode)) {
+ /*
+ * If this is a character special device, then check that
+ * it's /dev/mem. If so, open kmem too. (Maybe we should
+ * make it work for either /dev/mem or /dev/kmem -- in either
+ * case you're working with a live kernel.)
+ */
+ if (strcmp(mf, _PATH_MEM) != 0) { /* XXX */
+ _kvm_err(kd, kd->program,
+ "%s: not physical memory device", mf);
+ goto failed;
+ }
+ if ((kd->vmfd = open(_PATH_KMEM, flag)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", _PATH_KMEM);
+ goto failed;
+ }
+ if ((kd->swfd = open(sf, flag, 0)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", sf);
+ goto failed;
+ }
+ /*
+ * Open kvm nlist database. We go ahead and do this
+ * here so that we don't have to hold on to the vmunix
+ * path name. Since a kvm application will surely do
+ * a kvm_nlist(), this probably won't be a wasted effort.
+ * If the database cannot be opened, open the namelist
+ * argument so we revert to slow nlist() calls.
+ */
+ if (kvm_dbopen(kd, uf) < 0 &&
+ (kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", uf);
+ goto failed;
+ }
+ } else {
+ /*
+ * This is a crash dump.
+ * Initalize the virtual address translation machinery,
+ * but first setup the namelist fd.
+ */
+ if ((kd->nlfd = open(uf, O_RDONLY, 0)) < 0) {
+ _kvm_syserr(kd, kd->program, "%s", uf);
+ goto failed;
+ }
+ if (_kvm_initvtop(kd) < 0)
+ goto failed;
+ }
+ return (kd);
+failed:
+ /*
+ * Copy out the error if doing sane error semantics.
+ */
+ if (errout != 0)
+ strcpy(errout, kd->errbuf);
+ (void)kvm_close(kd);
+ return (0);
+}
+
+kvm_t *
+kvm_openfiles(uf, mf, sf, flag, errout)
+ const char *uf;
+ const char *mf;
+ const char *sf;
+ int flag;
+ char *errout;
+{
+ register kvm_t *kd;
+
+ if ((kd = malloc(sizeof(*kd))) == NULL) {
+ (void)strcpy(errout, strerror(errno));
+ return (0);
+ }
+ kd->program = 0;
+ return (_kvm_open(kd, uf, mf, sf, flag, errout));
+}
+
+kvm_t *
+kvm_open(uf, mf, sf, flag, program)
+ const char *uf;
+ const char *mf;
+ const char *sf;
+ int flag;
+ const char *program;
+{
+ register kvm_t *kd;
+
+ if ((kd = malloc(sizeof(*kd))) == NULL && program != NULL) {
+ (void)fprintf(stderr, "%s: %s\n", strerror(errno));
+ return (0);
+ }
+ kd->program = program;
+ return (_kvm_open(kd, uf, mf, sf, flag, NULL));
+}
+
+int
+kvm_close(kd)
+ kvm_t *kd;
+{
+ register int error = 0;
+
+ if (kd->pmfd >= 0)
+ error |= close(kd->pmfd);
+ if (kd->vmfd >= 0)
+ error |= close(kd->vmfd);
+ if (kd->nlfd >= 0)
+ error |= close(kd->nlfd);
+ if (kd->swfd >= 0)
+ error |= close(kd->swfd);
+ if (kd->db != 0)
+ error |= (kd->db->close)(kd->db);
+ if (kd->vmst)
+ _kvm_freevtop(kd);
+ if (kd->procbase != 0)
+ free((void *)kd->procbase);
+ if (kd->swapspc != 0)
+ free((void *)kd->swapspc);
+ if (kd->argspc != 0)
+ free((void *)kd->argspc);
+ if (kd->argbuf != 0)
+ free((void *)kd->argbuf);
+ if (kd->argv != 0)
+ free((void *)kd->argv);
+ free((void *)kd);
+
+ return (0);
+}
+
+/*
+ * Set up state necessary to do queries on the kernel namelist
+ * data base. If the data base is out-of-data/incompatible with
+ * given executable, set up things so we revert to standard nlist call.
+ * Only called for live kernels. Return 0 on success, -1 on failure.
+ */
+static int
+kvm_dbopen(kd, uf)
+ kvm_t *kd;
+ const char *uf;
+{
+ char *cp;
+ DBT rec;
+ int dbversionlen;
+ struct nlist nitem;
+ char dbversion[_POSIX2_LINE_MAX];
+ char kversion[_POSIX2_LINE_MAX];
+ char dbname[MAXPATHLEN];
+
+ if ((cp = rindex(uf, '/')) != 0)
+ uf = cp + 1;
+
+ (void)snprintf(dbname, sizeof(dbname), "%skvm_%s.db", _PATH_VARDB, uf);
+ kd->db = dbopen(dbname, O_RDONLY, 0, DB_HASH, NULL);
+ if (kd->db == 0)
+ return (-1);
+ /*
+ * read version out of database
+ */
+ rec.data = VRS_KEY;
+ rec.size = sizeof(VRS_KEY) - 1;
+ if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
+ goto close;
+ if (rec.data == 0 || rec.size > sizeof(dbversion))
+ goto close;
+
+ bcopy(rec.data, dbversion, rec.size);
+ dbversionlen = rec.size;
+ /*
+ * Read version string from kernel memory.
+ * Since we are dealing with a live kernel, we can call kvm_read()
+ * at this point.
+ */
+ rec.data = VRS_SYM;
+ rec.size = sizeof(VRS_SYM) - 1;
+ if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
+ goto close;
+ if (rec.data == 0 || rec.size != sizeof(struct nlist))
+ goto close;
+ bcopy((char *)rec.data, (char *)&nitem, sizeof(nitem));
+ if (kvm_read(kd, (u_long)nitem.n_value, kversion, dbversionlen) !=
+ dbversionlen)
+ goto close;
+ /*
+ * If they match, we win - otherwise clear out kd->db so
+ * we revert to slow nlist().
+ */
+ if (bcmp(dbversion, kversion, dbversionlen) == 0)
+ return (0);
+close:
+ (void)(kd->db->close)(kd->db);
+ kd->db = 0;
+
+ return (-1);
+}
+
+int
+kvm_nlist(kd, nl)
+ kvm_t *kd;
+ struct nlist *nl;
+{
+ register struct nlist *p;
+ register int nvalid;
+
+ /*
+ * If we can't use the data base, revert to the
+ * slow library call.
+ */
+ if (kd->db == 0)
+ return (__fdnlist(kd->nlfd, nl));
+
+ /*
+ * We can use the kvm data base. Go through each nlist entry
+ * and look it up with a db query.
+ */
+ nvalid = 0;
+ for (p = nl; p->n_name && p->n_name[0]; ++p) {
+ register int len;
+ DBT rec;
+
+ if ((len = strlen(p->n_name)) > 4096) {
+ /* sanity */
+ _kvm_err(kd, kd->program, "symbol too large");
+ return (-1);
+ }
+ rec.data = p->n_name;
+ rec.size = len;
+ if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
+ continue;
+ if (rec.data == 0 || rec.size != sizeof(struct nlist))
+ continue;
+ ++nvalid;
+ /*
+ * Avoid alignment issues.
+ */
+ bcopy((char *)&((struct nlist *)rec.data)->n_type,
+ (char *)&p->n_type,
+ sizeof(p->n_type));
+ bcopy((char *)&((struct nlist *)rec.data)->n_value,
+ (char *)&p->n_value,
+ sizeof(p->n_value));
+ }
+ /*
+ * Return the number of entries that weren't found.
+ */
+ return ((p - nl) - nvalid);
+}
+
+ssize_t
+kvm_read(kd, kva, buf, len)
+ kvm_t *kd;
+ register u_long kva;
+ register void *buf;
+ register size_t len;
+{
+ register int cc;
+ register void *cp;
+
+ if (ISALIVE(kd)) {
+ /*
+ * We're using /dev/kmem. Just read straight from the
+ * device and let the active kernel do the address translation.
+ */
+ errno = 0;
+ if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) {
+ _kvm_err(kd, 0, "invalid address (%x)", kva);
+ return (0);
+ }
+ cc = read(kd->vmfd, buf, len);
+ if (cc < 0) {
+ _kvm_syserr(kd, 0, "kvm_read");
+ return (0);
+ } else if (cc < len)
+ _kvm_err(kd, kd->program, "short read");
+ return (cc);
+ } else {
+ cp = buf;
+ while (len > 0) {
+ u_long pa;
+
+ cc = _kvm_kvatop(kd, kva, &pa);
+ if (cc == 0)
+ return (0);
+ if (cc > len)
+ cc = len;
+ errno = 0;
+ if (lseek(kd->pmfd, (off_t)pa, 0) == -1 && errno != 0) {
+ _kvm_syserr(kd, 0, _PATH_MEM);
+ break;
+ }
+ cc = read(kd->pmfd, cp, cc);
+ if (cc < 0) {
+ _kvm_syserr(kd, kd->program, "kvm_read");
+ break;
+ }
+ /*
+ * If kvm_kvatop returns a bogus value or our core
+ * file is truncated, we might wind up seeking beyond
+ * the end of the core file in which case the read will
+ * return 0 (EOF).
+ */
+ if (cc == 0)
+ break;
+ cp = (char *)cp + cc;
+ kva += cc;
+ len -= cc;
+ }
+ return ((char *)cp - (char *)buf);
+ }
+ /* NOTREACHED */
+}
+
+ssize_t
+kvm_write(kd, kva, buf, len)
+ kvm_t *kd;
+ register u_long kva;
+ register const void *buf;
+ register size_t len;
+{
+ register int cc;
+
+ if (ISALIVE(kd)) {
+ /*
+ * Just like kvm_read, only we write.
+ */
+ errno = 0;
+ if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) {
+ _kvm_err(kd, 0, "invalid address (%x)", kva);
+ return (0);
+ }
+ cc = write(kd->vmfd, buf, len);
+ if (cc < 0) {
+ _kvm_syserr(kd, 0, "kvm_write");
+ return (0);
+ } else if (cc < len)
+ _kvm_err(kd, kd->program, "short write");
+ return (cc);
+ } else {
+ _kvm_err(kd, kd->program,
+ "kvm_write not implemented for dead kernels");
+ return (0);
+ }
+ /* NOTREACHED */
+}
--- /dev/null
+/* $OpenBSD: kvm_alpha.c,v 1.1 1996/03/19 23:15:28 niklas Exp $ */
+/* $NetBSD: kvm_alpha.c,v 1.1.1.1 1996/03/16 10:05:25 leo Exp $ */
+
+/*
+ * Copyright (c) 1994, 1995 Carnegie-Mellon University.
+ * All rights reserved.
+ *
+ * Author: Chris G. Demetriou
+ *
+ * Permission to use, copy, modify and distribute this software and
+ * its documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
+ * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie the
+ * rights to redistribute these changes.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+
+ return (0);
+}
+
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+
+ /* don't forget k0seg translations! */
+
+ return (0);
+}
--- /dev/null
+/* $OpenBSD: kvm_arm32.c,v 1.1 1996/03/19 23:15:29 niklas Exp $ */
+/* $NetBSD: kvm_arm32.c,v 1.1.1.1 1996/03/16 10:05:25 leo Exp $ */
+
+/*
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ *
+ * $OpenBSD: kvm_arm32.c,v 1.1 1996/03/19 23:15:29 niklas Exp $
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93"; */
+static char *rcsid = "$OpenBSD: kvm_arm32.c,v 1.1 1996/03/19 23:15:29 niklas Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * arm32 machine dependent routines for kvm.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#include <machine/pte.h>
+
+#ifndef btop
+#define btop(x) (((unsigned)(x)) >> PGSHIFT) /* XXX */
+#define ptob(x) ((caddr_t)((x) << PGSHIFT)) /* XXX */
+#endif
+
+struct vmstate {
+ pd_entry_t **IdlePTD;
+ pd_entry_t *PTD;
+};
+
+#define KREAD(kd, addr, p)\
+ (kvm_read(kd, addr, (char *)(p), sizeof(*(p))) != sizeof(*(p)))
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ _kvm_err(kd, 0, "unsupported");
+ return;
+ if (kd->vmst->PTD != 0)
+ free(kd->vmst->PTD);
+
+ if (kd->vmst != 0)
+ free(kd->vmst);
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ struct vmstate *vm;
+ struct nlist nlist[2];
+
+ _kvm_err(kd, 0, "unsupported");
+ return (0);
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+ kd->vmst = vm;
+
+ nlist[0].n_name = "_IdlePTD";
+ nlist[1].n_name = 0;
+
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist");
+ return (-1);
+ }
+ vm->IdlePTD = 0;
+ vm->PTD = 0;
+ if (KREAD(kd, (u_long)nlist[0].n_value, &vm->IdlePTD)) {
+ _kvm_err(kd, kd->program, "cannot read IdlePTD");
+ return (-1);
+ }
+ vm->PTD = (pd_entry_t *)_kvm_malloc(kd, NBPG);
+ if ((kvm_read(kd, (u_long)vm->IdlePTD, &vm->PTD, NBPG)) != NBPG) {
+ _kvm_err(kd, kd->program, "cannot read PTD");
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Translate a kernel virtual address to a physical address.
+ */
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ struct vmstate *vm;
+ u_long offset;
+
+ _kvm_err(kd, 0, "unsupported");
+ return (0);
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
+ return(0);
+ }
+ vm = kd->vmst;
+ offset = va & PGOFSET;
+
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
+
+/*
+ * Translate a user virtual address to a physical address.
+ */
+int
+_kvm_uvatop(kd, p, va, pa)
+ kvm_t *kd;
+ const struct proc *p;
+ u_long va;
+ u_long *pa;
+{
+ struct vmspace vms;
+ pd_entry_t pde, *pdeloc;
+ pt_entry_t pte, *pteloc;
+ u_long kva, offset;
+
+ _kvm_err(kd, 0, "unsupported");
+ return (0);
+
+ if (va >= KERNBASE)
+ goto invalid;
+
+ /* XXX - should be passed a `kinfo_proc *' here */
+ if (kvm_read(kd, (u_long)p->p_vmspace, (char *)&vms, sizeof(vms)) !=
+ sizeof(vms))
+ goto invalid;
+
+ pdeloc = vms.vm_pmap.pm_pdir + (va >> PDSHIFT);
+ if (kvm_read(kd, (u_long)pdeloc, (char *)&pde, sizeof(pde)) !=
+ sizeof(pde))
+ goto invalid;
+ if (pde == 0)
+ goto invalid;
+
+ pteloc = (pt_entry_t *)(pde & PG_FRAME) + btop(va & PT_MASK);
+ if (lseek(kd->pmfd, (off_t)(u_long)pteloc, 0) != (off_t)(u_long)pteloc)
+ goto invalid;
+ if (read(kd->pmfd, (char *)&pte, sizeof(pte)) != sizeof(pte))
+ goto invalid;
+ if (pte == 0)
+ goto invalid;
+
+ offset = va & PGOFSET;
+ *pa = (pte & PG_FRAME) + offset;
+ return (NBPG - offset);
+
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
--- /dev/null
+/* $OpenBSD: kvm_file.c,v 1.1 1996/03/19 23:15:30 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1989, 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_file.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * File list interface for kvm. pstat, fstat and netstat are
+ * users of this code, so we've factored it out into a separate module.
+ * Thus, we keep this grunge out of the other kvm applications (i.e.,
+ * most other applications are interested only in open/close/read/nlist).
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/exec.h>
+#define _KERNEL
+#include <sys/file.h>
+#undef _KERNEL
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/swap_pager.h>
+
+#include <sys/sysctl.h>
+
+#include <limits.h>
+#include <ndbm.h>
+#include <paths.h>
+
+#include "kvm_private.h"
+
+#define KREAD(kd, addr, obj) \
+ (kvm_read(kd, addr, obj, sizeof(*obj)) != sizeof(*obj))
+
+/*
+ * Get file structures.
+ */
+static
+kvm_deadfiles(kd, op, arg, filehead_o, nfiles)
+ kvm_t *kd;
+ int op, arg, nfiles;
+ long filehead_o;
+{
+ int buflen = kd->arglen, needed = buflen, error, n = 0;
+ struct file *fp, file;
+ struct filelist filehead;
+ register char *where = kd->argspc;
+ char *start = where;
+
+ /*
+ * first copyout filehead
+ */
+ if (buflen > sizeof (filehead)) {
+ if (KREAD(kd, filehead_o, &filehead)) {
+ _kvm_err(kd, kd->program, "can't read filehead");
+ return (0);
+ }
+ buflen -= sizeof (filehead);
+ where += sizeof (filehead);
+ *(struct filelist *)kd->argspc = filehead;
+ }
+ /*
+ * followed by an array of file structures
+ */
+ for (fp = filehead.lh_first; fp != 0; fp = fp->f_list.le_next) {
+ if (buflen > sizeof (struct file)) {
+ if (KREAD(kd, (long)fp, ((struct file *)where))) {
+ _kvm_err(kd, kd->program, "can't read kfp");
+ return (0);
+ }
+ buflen -= sizeof (struct file);
+ fp = (struct file *)where;
+ where += sizeof (struct file);
+ n++;
+ }
+ }
+ if (n != nfiles) {
+ _kvm_err(kd, kd->program, "inconsistant nfiles");
+ return (0);
+ }
+ return (nfiles);
+}
+
+char *
+kvm_getfiles(kd, op, arg, cnt)
+ kvm_t *kd;
+ int op, arg;
+ int *cnt;
+{
+ size_t size;
+ int mib[2], st, nfiles;
+ struct file *fp, *fplim;
+ struct filelist filehead;
+
+ if (ISALIVE(kd)) {
+ size = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_FILE;
+ st = sysctl(mib, 2, NULL, &size, NULL, 0);
+ if (st == -1) {
+ _kvm_syserr(kd, kd->program, "kvm_getprocs");
+ return (0);
+ }
+ if (kd->argspc == 0)
+ kd->argspc = (char *)_kvm_malloc(kd, size);
+ else if (kd->arglen < size)
+ kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size);
+ if (kd->argspc == 0)
+ return (0);
+ kd->arglen = size;
+ st = sysctl(mib, 2, kd->argspc, &size, NULL, 0);
+ if (st == -1 || size < sizeof(filehead)) {
+ _kvm_syserr(kd, kd->program, "kvm_getfiles");
+ return (0);
+ }
+ filehead = *(struct filelist *)kd->argspc;
+ fp = (struct file *)(kd->argspc + sizeof (filehead));
+ fplim = (struct file *)(kd->argspc + size);
+ for (nfiles = 0; filehead.lh_first && (fp < fplim);
+ nfiles++, fp++)
+ filehead.lh_first = fp->f_list.le_next;
+ } else {
+ struct nlist nl[3], *p;
+
+ nl[0].n_name = "_filehead";
+ nl[1].n_name = "_nfiles";
+ nl[2].n_name = 0;
+
+ if (kvm_nlist(kd, nl) != 0) {
+ for (p = nl; p->n_type != 0; ++p)
+ ;
+ _kvm_err(kd, kd->program,
+ "%s: no such symbol", p->n_name);
+ return (0);
+ }
+ if (KREAD(kd, nl[0].n_value, &nfiles)) {
+ _kvm_err(kd, kd->program, "can't read nfiles");
+ return (0);
+ }
+ size = sizeof(filehead) + (nfiles + 10) * sizeof(struct file);
+ if (kd->argspc == 0)
+ kd->argspc = (char *)_kvm_malloc(kd, size);
+ else if (kd->arglen < size)
+ kd->argspc = (char *)_kvm_realloc(kd, kd->argspc, size);
+ if (kd->argspc == 0)
+ return (0);
+ kd->arglen = size;
+ nfiles = kvm_deadfiles(kd, op, arg, nl[1].n_value, nfiles);
+ if (nfiles == 0)
+ return (0);
+ }
+ *cnt = nfiles;
+ return (kd->argspc);
+}
--- /dev/null
+.\" $OpenBSD: kvm_geterr.3,v 1.1 1996/03/19 23:15:31 niklas Exp $
+.\"
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software 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.
+.\"
+.\" @(#)kvm_geterr.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt KVM_GETERR 3
+.Os
+.Sh NAME
+.Nm kvm_geterr
+.Nd get error message on kvm descriptor
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.br
+.Ft char *
+.Fn kvm_geterr "kvm_t *kd"
+.Sh DESCRIPTION
+This function returns a string describing the most recent error condition
+on the descriptor
+.Fa kd .
+The results are undefined if the most recent
+.Xr kvm 3
+library call did not produce an error.
+The string returned is stored in memory owned by
+.Xr kvm 3
+so the message should be copied out and saved elsewhere if necessary.
+.Sh BUGS
+This routine cannot be used to access error conditions due to a failed
+.Fn kvm_openfiles
+call, since failure is indicated by returning a
+.Dv NULL
+descriptor.
+Therefore, errors on open are output to the special error buffer
+passed to
+.Fn kvm_openfiles .
+This option is not available to
+.Fn kvm_open .
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
--- /dev/null
+.\" $OpenBSD: kvm_getfiles.3,v 1.1 1996/03/19 23:15:32 niklas Exp $
+.\"
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software 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.
+.\"
+.\" @(#)kvm_getfiles.3 8.2 (Berkeley) 4/19/94
+.\"
+.Dd April 19, 1994
+.Dt KVM_GETFILES 3
+.Os
+.Sh NAME
+.Nm kvm_getfiles
+.Nd survey open files
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Fd #include <sys/kinfo.h>
+.Fd #define _KERNEL
+.Fd #include <sys/file.h>
+.Fd #undef _KERNEL
+.\" .Fa kvm_t *kd
+.br
+.Ft char *
+.Fn kvm_getfiles "kvm_t *kd" "int op" "int arg" "int *cnt"
+.Sh DESCRIPTION
+.Fn kvm_getfiles
+returns a (sub-)set of the open files in the kernel indicated by
+.Fa kd.
+The
+.Fa op
+and
+.Fa arg
+arguments constitute a predicate which limits the set of files
+returned. No predicates are currently defined.
+.Pp
+The number of processes found is returned in the reference parameter
+.Fa cnt .
+The files are returned as a contiguous array of file structures,
+preceded by the address of the first file entry in the kernel.
+This memory is owned by kvm and is not guaranteed to be persistent across
+subsequent kvm library calls. Data should be copied out if it needs to be
+saved.
+.Sh RETURN VALUES
+.Fn kvm_getfiles
+will return NULL on failure.
+.Pp
+.Sh BUGS
+This routine does not belong in the kvm interface.
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_geterr 3
--- /dev/null
+.\" $OpenBSD: kvm_getloadavg.3,v 1.1 1996/03/19 23:15:32 niklas Exp $
+.\"
+.\" 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.
+.\"
+.\" @(#)kvm_getloadavg.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt KVM_GETLOADAVG 3
+.Os
+.Sh NAME
+.Nm kvm_getloadavg
+.Nd get error message on kvm descriptor
+.Sh SYNOPSIS
+.Fd #include <sys/resource.h>
+.Fd #include <kvm.h>
+.br
+.Ft int
+.Fn kvm_getloadavg "kvm_t *kd" "double loadavg[]" "int nelem"
+.Sh DESCRIPTION
+The
+.Fn kvm_getloadavg
+function returns the number of processes in the system run queue
+of the kernel indicated by
+.Fa kd ,
+averaged over various periods of time.
+Up to
+.Fa nelem
+samples are retrieved and assigned to successive elements of
+.Fa loadavg Ns Bq .
+The system imposes a maximum of 3 samples, representing averages
+over the last 1, 5, and 15 minutes, respectively.
+.Sh DIAGNOSTICS
+If the load average was unobtainable, \-1 is returned; otherwise,
+the number of samples actually retrieved is returned.
+.Sh SEE ALSO
+.Xr uptime 1 ,
+.Xr kvm 3 ,
+.Xr getloadavg 3
--- /dev/null
+/* $OpenBSD: kvm_getloadavg.c,v 1.1 1996/03/19 23:15:33 niklas Exp $ */
+
+/*-
+ * Copyright (c) 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_getloadavg.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <vm/vm_param.h>
+
+#include <db.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include "kvm_private.h"
+
+static struct nlist nl[] = {
+ { "_averunnable" },
+#define X_AVERUNNABLE 0
+ { "_fscale" },
+#define X_FSCALE 1
+ { "" },
+};
+
+/*
+ * kvm_getloadavg() -- Get system load averages, from live or dead kernels.
+ *
+ * Put `nelem' samples into `loadavg' array.
+ * Return number of samples retrieved, or -1 on error.
+ */
+int
+kvm_getloadavg(kd, loadavg, nelem)
+ kvm_t *kd;
+ double loadavg[];
+ int nelem;
+{
+ struct loadavg loadinfo;
+ struct nlist *p;
+ int fscale, i;
+
+ if (ISALIVE(kd))
+ return (getloadavg(loadavg, nelem));
+
+ if (kvm_nlist(kd, nl) != 0) {
+ for (p = nl; p->n_type != 0; ++p);
+ _kvm_err(kd, kd->program,
+ "%s: no such symbol", p->n_name);
+ return (-1);
+ }
+
+#define KREAD(kd, addr, obj) \
+ (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
+ if (KREAD(kd, nl[X_AVERUNNABLE].n_value, &loadinfo)) {
+ _kvm_err(kd, kd->program, "can't read averunnable");
+ return (-1);
+ }
+
+ /*
+ * Old kernels have fscale separately; if not found assume
+ * running new format.
+ */
+ if (!KREAD(kd, nl[X_FSCALE].n_value, &fscale))
+ loadinfo.fscale = fscale;
+
+ nelem = MIN(nelem, sizeof(loadinfo.ldavg) / sizeof(fixpt_t));
+ for (i = 0; i < nelem; i++)
+ loadavg[i] = (double) loadinfo.ldavg[i] / loadinfo.fscale;
+ return (nelem);
+}
--- /dev/null
+.\" $OpenBSD: kvm_getprocs.3,v 1.1 1996/03/19 23:15:34 niklas Exp $
+.\"
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software 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.
+.\"
+.\" @(#)kvm_getprocs.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt KVM_GETPROCS 3
+.Os
+.Sh NAME
+.Nm kvm_getprocs ,
+.Nm kvm_getargv ,
+.Nm kvm_getenvv
+.Nd access user process state
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Fd #include <sys/kinfo.h>
+.Fd #include <sys/kinfo_proc.h>
+.\" .Fa kvm_t *kd
+.br
+.Ft struct kinfo_proc *
+.Fn kvm_getprocs "kvm_t *kd" "int op" "int arg" "int *cnt"
+.Ft char **
+.Fn kvm_getargv "kvm_t *kd" "const struct kinfo_proc *p" "int nchr"
+.Ft char **
+.Fn kvm_getenvv "kvm_t *kd" "const struct kinfo_proc *p" "int nchr"
+.Sh DESCRIPTION
+.Fn kvm_getprocs
+returns a (sub-)set of active processes in the kernel indicated by
+.Fa kd.
+The
+.Fa op
+and
+.Fa arg
+arguments constitute a predicate which limits the set of processes
+returned. The value of
+.Fa op
+describes the filtering predicate as follows:
+.Pp
+.Bl -tag -width 20n -offset indent -compact
+.It Sy KINFO_PROC_ALL
+all processes
+.It Sy KINFO_PROC_PID
+processes with process id
+.Fa arg
+.It Sy KINFO_PROC_PGRP
+processes with process group
+.Fa arg
+.It Sy KINFO_PROC_SESSION
+processes with session
+.Fa arg
+.It Sy KINFO_PROC_TTY
+processes with tty
+.Fa arg
+.It Sy KINFO_PROC_UID
+processes with effective user id
+.Fa arg
+.It Sy KINFO_PROC_RUID
+processes with real user id
+.Fa arg
+.El
+.Pp
+The number of processes found is returned in the reference parameter
+.Fa cnt .
+The processes are returned as a contiguous array of kinfo_proc structures.
+This memory is locally allocated, and subsequent calls to
+.Fn kvm_getprocs
+and
+.Fn kvm_close
+will overwrite this storage.
+.Pp
+.Fn kvm_getargv
+returns a null-terminated argument vector that corresponds to the
+command line arguments passed to process indicated by
+.Fa p .
+Most likely, these arguments correspond to the values passed to
+.Xr exec 3
+on process creation. This information is, however,
+deliberately under control of the process itself.
+Note that the original command name can be found, unaltered,
+in the p_comm field of the process structure returned by
+.Fn kvm_getprocs .
+.Pp
+The
+.Fa nchr
+argument indicates the maximum number of characters, including null bytes,
+to use in building the strings. If this amount is exceeded, the string
+causing the overflow is truncated and the partial result is returned.
+This is handy for programs like
+.Xr ps 1
+and
+.Xr w 1
+that print only a one line summary of a command and should not copy
+out large amounts of text only to ignore it.
+If
+.Fa nchr
+is zero, no limit is imposed and all argument strings are returned in
+their entirety.
+.Pp
+The memory allocated to the argv pointers and string storage
+is owned by the kvm library. Subsequent
+.Fn kvm_getprocs
+and
+.Xr kvm_close 3
+calls will clobber this storage.
+.Pp
+The
+.Fn kvm_getenvv
+function is similar to
+.Fn kvm_getargv
+but returns the vector of environment strings. This data is
+also alterable by the process.
+.Sh RETURN VALUES
+.Fn kvm_getprocs ,
+.Fn kvm_getargv ,
+and
+.Fn kvm_getenvv ,
+all return
+.Dv NULL
+on failure.
+.Pp
+.Sh BUGS
+These routines do not belong in the kvm interface.
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
--- /dev/null
+/* $OpenBSD: kvm_i386.c,v 1.1 1996/03/19 23:15:34 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93"; */
+static char *rcsid = "$OpenBSD: kvm_i386.c,v 1.1 1996/03/19 23:15:34 niklas Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * i386 machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#include <machine/pte.h>
+
+#ifndef btop
+#define btop(x) (((unsigned)(x)) >> PGSHIFT) /* XXX */
+#define ptob(x) ((caddr_t)((x) << PGSHIFT)) /* XXX */
+#endif
+
+struct vmstate {
+ pd_entry_t *PTD;
+};
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ if (kd->vmst != 0) {
+ if (kd->vmst->PTD != 0)
+ free(kd->vmst->PTD);
+
+ free(kd->vmst);
+ }
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ struct vmstate *vm;
+ struct nlist nlist[2];
+ u_long pa;
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+ kd->vmst = vm;
+
+ nlist[0].n_name = "_PTDpaddr";
+ nlist[1].n_name = 0;
+
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist");
+ return (-1);
+ }
+
+ vm->PTD = 0;
+
+ if (lseek(kd->pmfd, (off_t)(nlist[0].n_value - KERNBASE), 0) == -1 &&
+ errno != 0) {
+ _kvm_syserr(kd, kd->program, "kvm_lseek");
+ goto invalid;
+ }
+ if (read(kd->pmfd, &pa, sizeof pa) != sizeof pa) {
+ _kvm_syserr(kd, kd->program, "kvm_read");
+ goto invalid;
+ }
+
+ vm->PTD = (pd_entry_t *)_kvm_malloc(kd, NBPG);
+
+ if (lseek(kd->pmfd, (off_t)pa, 0) == -1 && errno != 0) {
+ _kvm_syserr(kd, kd->program, "kvm_lseek");
+ goto invalid;
+ }
+ if (read(kd->pmfd, vm->PTD, NBPG) != NBPG) {
+ _kvm_syserr(kd, kd->program, "kvm_read");
+ goto invalid;
+ }
+
+ return (0);
+
+invalid:
+ if (vm->PTD != 0)
+ free(vm->PTD);
+ return (-1);
+}
+
+/*
+ * Translate a kernel virtual address to a physical address.
+ */
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ struct vmstate *vm;
+ u_long offset;
+ u_long pte_pa;
+ pt_entry_t pte;
+
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
+ return(0);
+ }
+
+ vm = kd->vmst;
+ offset = va & PGOFSET;
+
+ /*
+ * If we are initializing (kernel page table descriptor pointer
+ * not yet set) * then return pa == va to avoid infinite recursion.
+ */
+ if (vm->PTD == 0) {
+ *pa = va;
+ return (NBPG - offset);
+ }
+ if ((vm->PTD[pdei(va)] & PG_V) == 0)
+ goto invalid;
+
+ pte_pa = (vm->PTD[pdei(va)] & PG_FRAME) +
+ (ptei(va) * sizeof(pt_entry_t));
+ /* XXX READ PHYSICAL XXX */
+ {
+ if (lseek(kd->pmfd, (off_t)pte_pa, 0) == -1 && errno != 0) {
+ _kvm_syserr(kd, kd->program, "kvm_lseek");
+ goto invalid;
+ }
+ if (read(kd->pmfd, &pte, sizeof pte) != sizeof pte) {
+ _kvm_syserr(kd, kd->program, "kvm_read");
+ goto invalid;
+ }
+ }
+
+ *pa = (pte & PG_FRAME) + offset;
+ return (NBPG - offset);
+
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
--- /dev/null
+/* $OpenBSD: kvm_m68k.c,v 1.1 1996/03/19 23:15:35 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/* from: static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93"; */
+static char *rcsid = "$OpenBSD: kvm_m68k.c,v 1.1 1996/03/19 23:15:35 niklas Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * m68k machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#include <machine/pte.h>
+
+#ifndef btop
+#define btop(x) (((unsigned)(x)) >> PGSHIFT) /* XXX */
+#define ptob(x) ((caddr_t)((x) << PGSHIFT)) /* XXX */
+#endif
+
+struct vmstate {
+ u_long lowram;
+ int mmutype;
+ st_entry_t *Sysseg;
+};
+
+#define KREAD(kd, addr, p)\
+ (kvm_read(kd, addr, (char *)(p), sizeof(*(p))) != sizeof(*(p)))
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ if (kd->vmst != 0)
+ free(kd->vmst);
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ struct vmstate *vm;
+ struct nlist nlist[4];
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+ kd->vmst = vm;
+
+ nlist[0].n_name = "_lowram";
+ nlist[1].n_name = "_mmutype";
+ nlist[2].n_name = "_Sysseg";
+ nlist[3].n_name = 0;
+
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist");
+ return (-1);
+ }
+ vm->Sysseg = 0;
+ if (KREAD(kd, (u_long)nlist[0].n_value, &vm->lowram)) {
+ _kvm_err(kd, kd->program, "cannot read lowram");
+ return (-1);
+ }
+ if (KREAD(kd, (u_long)nlist[1].n_value, &vm->mmutype)) {
+ _kvm_err(kd, kd->program, "cannot read mmutype");
+ return (-1);
+ }
+ if (KREAD(kd, (u_long)nlist[2].n_value, &vm->Sysseg)) {
+ _kvm_err(kd, kd->program, "cannot read segment table");
+ return (-1);
+ }
+ return (0);
+}
+
+static int
+_kvm_vatop(kd, sta, va, pa)
+ kvm_t *kd;
+ st_entry_t *sta;
+ u_long va;
+ u_long *pa;
+{
+ register struct vmstate *vm;
+ register u_long lowram;
+ register u_long addr;
+ int p, ste, pte;
+ int offset;
+
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
+ return((off_t)0);
+ }
+ vm = kd->vmst;
+ offset = va & PGOFSET;
+ /*
+ * If we are initializing (kernel segment table pointer not yet set)
+ * then return pa == va to avoid infinite recursion.
+ */
+ if (vm->Sysseg == 0) {
+ *pa = va;
+ return (NBPG - offset);
+ }
+ lowram = vm->lowram;
+ if (vm->mmutype == -2) {
+ st_entry_t *sta2;
+
+ addr = (u_long)&sta[va >> SG4_SHIFT1];
+ /*
+ * Can't use KREAD to read kernel segment table entries.
+ * Fortunately it is 1-to-1 mapped so we don't have to.
+ */
+ if (sta == vm->Sysseg) {
+ if (lseek(kd->pmfd, (off_t)addr, 0) == -1 ||
+ read(kd->pmfd, (char *)&ste, sizeof(ste)) < 0)
+ goto invalid;
+ } else if (KREAD(kd, addr, &ste))
+ goto invalid;
+ if ((ste & SG_V) == 0) {
+ _kvm_err(kd, 0, "invalid level 1 descriptor (%x)",
+ ste);
+ return((off_t)0);
+ }
+ sta2 = (st_entry_t *)(ste & SG4_ADDR1);
+ addr = (u_long)&sta2[(va & SG4_MASK2) >> SG4_SHIFT2];
+ /*
+ * Address from level 1 STE is a physical address,
+ * so don't use kvm_read.
+ */
+ if (lseek(kd->pmfd, (off_t)(addr - lowram), 0) == -1 ||
+ read(kd->pmfd, (char *)&ste, sizeof(ste)) < 0)
+ goto invalid;
+ if ((ste & SG_V) == 0) {
+ _kvm_err(kd, 0, "invalid level 2 descriptor (%x)",
+ ste);
+ return((off_t)0);
+ }
+ sta2 = (st_entry_t *)(ste & SG4_ADDR2);
+ addr = (u_long)&sta2[(va & SG4_MASK3) >> SG4_SHIFT3];
+ } else {
+ addr = (u_long)&sta[va >> SEGSHIFT];
+ /*
+ * Can't use KREAD to read kernel segment table entries.
+ * Fortunately it is 1-to-1 mapped so we don't have to.
+ */
+ if (sta == vm->Sysseg) {
+ if (lseek(kd->pmfd, (off_t)addr, 0) == -1 ||
+ read(kd->pmfd, (char *)&ste, sizeof(ste)) < 0)
+ goto invalid;
+ } else if (KREAD(kd, addr, &ste))
+ goto invalid;
+ if ((ste & SG_V) == 0) {
+ _kvm_err(kd, 0, "invalid segment (%x)", ste);
+ return((off_t)0);
+ }
+ p = btop(va & SG_PMASK);
+ addr = (ste & SG_FRAME) + (p * sizeof(pt_entry_t));
+ }
+ /*
+ * Address from STE is a physical address so don't use kvm_read.
+ */
+ if (lseek(kd->pmfd, (off_t)(addr - lowram), 0) == -1 ||
+ read(kd->pmfd, (char *)&pte, sizeof(pte)) < 0)
+ goto invalid;
+ addr = pte & PG_FRAME;
+ if (pte == PG_NV) {
+ _kvm_err(kd, 0, "page not valid");
+ return (0);
+ }
+ *pa = addr - lowram + offset;
+
+ return (NBPG - offset);
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
+
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ return (_kvm_vatop(kd, (u_long)kd->vmst->Sysseg, va, pa));
+}
--- /dev/null
+/* $OpenBSD: kvm_mips.c,v 1.1 1996/03/19 23:15:36 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software developed by the Computer Systems
+ * Engineering group at Lawrence Berkeley Laboratory under DARPA contract
+ * BG 91-66 and contributed to Berkeley. Modified for MIPS by Ralph Campbell.
+ *
+ * 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_mips.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+/*
+ * MIPS machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#include <machine/machConst.h>
+#include <machine/pte.h>
+#include <machine/pmap.h>
+
+struct vmstate {
+ pt_entry_t *Sysmap;
+ u_int Sysmapsize;
+};
+
+#define KREAD(kd, addr, p)\
+ (kvm_read(kd, addr, (char *)(p), sizeof(*(p))) != sizeof(*(p)))
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ if (kd->vmst != 0)
+ free(kd->vmst);
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ struct vmstate *vm;
+ struct nlist nlist[3];
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+ kd->vmst = vm;
+
+ nlist[0].n_name = "Sysmap";
+ nlist[1].n_name = "Sysmapsize";
+ nlist[2].n_name = 0;
+
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist");
+ return (-1);
+ }
+ if (KREAD(kd, (u_long)nlist[0].n_value, &vm->Sysmap)) {
+ _kvm_err(kd, kd->program, "cannot read Sysmap");
+ return (-1);
+ }
+ if (KREAD(kd, (u_long)nlist[1].n_value, &vm->Sysmapsize)) {
+ _kvm_err(kd, kd->program, "cannot read mmutype");
+ return (-1);
+ }
+ return (0);
+}
+
+/*
+ * Translate a kernel virtual address to a physical address.
+ */
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ register struct vmstate *vm;
+ u_long pte, addr, offset;
+
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
+ return((off_t)0);
+ }
+ vm = kd->vmst;
+ offset = va & PGOFSET;
+ /*
+ * If we are initializing (kernel segment table pointer not yet set)
+ * then return pa == va to avoid infinite recursion.
+ */
+ if (vm->Sysmap == 0) {
+ *pa = va;
+ return (NBPG - offset);
+ }
+ if (va < KERNBASE ||
+ va >= VM_MIN_KERNEL_ADDRESS + vm->Sysmapsize * NBPG)
+ goto invalid;
+ if (va < VM_MIN_KERNEL_ADDRESS) {
+ *pa = MACH_CACHED_TO_PHYS(va);
+ return (NBPG - offset);
+ }
+ addr = (u_long)(vm->Sysmap + ((va - VM_MIN_KERNEL_ADDRESS) >> PGSHIFT));
+ /*
+ * Can't use KREAD to read kernel segment table entries.
+ * Fortunately it is 1-to-1 mapped so we don't have to.
+ */
+ if (lseek(kd->pmfd, (off_t)addr, 0) < 0 ||
+ read(kd->pmfd, (char *)&pte, sizeof(pte)) < 0)
+ goto invalid;
+ if (!(pte & PG_V))
+ goto invalid;
+ *pa = (pte & PG_FRAME) | offset;
+ return (NBPG - offset);
+
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
--- /dev/null
+.\" $OpenBSD: kvm_nlist.3,v 1.1 1996/03/19 23:15:37 niklas Exp $
+.\"
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software 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.
+.\"
+.\" @(#)kvm_nlist.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt KVM_NLIST 3
+.Os
+.Sh NAME
+.Nm kvm_nlist
+.Nd retrieve symbol table names from a kernel image
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Fd #include <nlist.h>
+.Ft int
+.Fn kvm_nlist "kvm_t *kd" "struct nlist *nl"
+.Sh DESCRIPTION
+.Fn kvm_nlist
+retrieves the symbol table entries indicated by the name list argument
+.Fa \&nl .
+This argument points to an array of nlist structures, terminated by
+an entry whose n_name field is
+.Dv NULL
+(see
+.Xr nlist 3 ) .
+Each symbol is looked up using the n_name field, and if found, the
+corresponding n_type and n_value fields are filled in. These fields are set
+to 0 if the symbol is not found.
+.Pp
+The program
+.Xr kvm_mkdb 8
+builds a database from the running kernel's namelist.
+If the database matches the opened kernel,
+.Fn kvm_nlist
+uses it to speed lookups.
+.Sh RETURN VALUES
+The
+.Fn kvm_nlist
+function returns the number of invalid entries found.
+If the kernel symbol table was unreadable, -1 is returned.
+.Sh FILES
+.Bl -tag -width /var/db/kvm_netbsd.db -compact
+.It Pa /var/db/kvm_netbsd.db
+.El
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3 ,
+.Xr kvm_mkdb 8
--- /dev/null
+/* $OpenBSD: kvm_ns32k.c,v 1.1 1996/03/19 23:15:38 niklas Exp $ */
+/* $NetBSD: kvm_ns32k.c,v 1.1.1.1 1996/03/16 10:05:24 leo Exp $ */
+
+/*-
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ */
+
+/* from: "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93"; */
+
+/*
+ * ns32k machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module.
+ *
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#include <machine/pte.h>
+
+#ifndef btop
+#define btop(x) (((unsigned)(x)) >> PGSHIFT) /* XXX */
+#define ptob(x) ((caddr_t)((x) << PGSHIFT)) /* XXX */
+#endif
+
+struct vmstate {
+ pd_entry_t **PTDpaddr;
+ pd_entry_t *PTD;
+};
+
+#define KREAD(kd, addr, p)\
+ (kvm_read(kd, addr, (char *)(p), sizeof(*(p))) != sizeof(*(p)))
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ if (kd->vmst != 0) {
+ if (kd->vmst->PTD != 0)
+ free(kd->vmst->PTD);
+
+ free(kd->vmst);
+ }
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ struct vmstate *vm;
+ struct nlist nlist[2];
+ pt_entry_t *tmpPTD;
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+ kd->vmst = vm;
+
+ nlist[0].n_name = "_PTDpaddr";
+ nlist[1].n_name = 0;
+
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "bad namelist");
+ return (-1);
+ }
+
+ vm->PTDpaddr = 0;
+ vm->PTD = 0;
+ if (KREAD(kd, (u_long)nlist[0].n_value - KERNBASE, &vm->PTDpaddr)) {
+ _kvm_err(kd, kd->program, "cannot read PTDpaddr");
+ return (-1);
+ }
+
+ tmpPTD = (pd_entry_t *)_kvm_malloc(kd, NBPG);
+ if ((kvm_read(kd, (u_long)vm->PTDpaddr, tmpPTD, NBPG)) != NBPG) {
+ free(tmpPTD);
+ _kvm_err(kd, kd->program, "cannot read PTD");
+ return (-1);
+ }
+ vm->PTD = tmpPTD;
+ return (0);
+}
+
+/*
+ * Translate a kernel virtual address to a physical address.
+ */
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ struct vmstate *vm;
+ u_long offset;
+ u_long pte_pa;
+ pt_entry_t pte;
+
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, 0, "vatop called in live kernel!");
+ return(0);
+ }
+
+ vm = kd->vmst;
+ offset = va & PGOFSET;
+
+ /*
+ * If we are initializing (kernel page table descriptor pointer
+ * not yet set) * then return pa == va to avoid infinite recursion.
+ */
+ if (vm->PTD == 0) {
+ *pa = va;
+ return (NBPG - offset);
+ }
+ if ((vm->PTD[pdei(va)] & PG_V) == 0)
+ goto invalid;
+
+ pte_pa = (vm->PTD[pdei(va)] & PG_FRAME) +
+ (ptei(va) * sizeof(pt_entry_t));
+ /* XXX READ PHYSICAL XXX */
+ {
+ if (lseek(kd->pmfd, (off_t)pte_pa, 0) == -1 && errno != 0) {
+ _kvm_syserr(kd, 0, "kvm_lseek");
+ goto invalid;
+ }
+ if (read(kd->pmfd, &pte, sizeof pte) != sizeof pte) {
+ _kvm_syserr(kd, kd->program, "kvm_read");
+ goto invalid;
+ }
+ }
+
+ *pa = (pte & PG_FRAME) + offset;
+ return (NBPG - offset);
+
+invalid:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
--- /dev/null
+.\" $OpenBSD: kvm_open.3,v 1.1 1996/03/19 23:15:38 niklas Exp $
+.\"
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software 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.
+.\"
+.\" @(#)kvm_open.3 8.3 (Berkeley) 4/19/94
+.\"
+.Dd April 19, 1994
+.Dt KVM_OPEN 3
+.Os
+.Sh NAME
+.Nm kvm_open ,
+.Nm kvm_openfiles ,
+.Nm kvm_close
+.Nd initialize kernel virtual memory access
+.Sh SYNOPSIS
+.Fd #include <fcntl.h>
+.Fd #include <kvm.h>
+.br
+.Ft kvm_t *
+.Fn kvm_open "const char *execfile" "const char *corefile" "char *swapfile" "int flags" "const char *errstr"
+.Ft kvm_t *
+.Fn kvm_openfiles "const char *execfile" "const char *corefile" "char *swapfile" "int flags" "char *errbuf"
+.Ft int
+.Fn kvm_close "kvm_t *kd"
+.Sh DESCRIPTION
+The functions
+.Fn kvm_open
+and
+.Fn kvm_openfiles
+return a descriptor used to access kernel virtual memory
+via the
+.Xr kvm 3
+library routines. Both active kernels and crash dumps are accessible
+through this interface.
+.Pp
+.Fa execfile
+is the executable image of the kernel being examined.
+This file must contain a symbol table.
+If this argument is
+.Dv NULL ,
+the currently running system is assumed,
+which is indicated by
+.Dv _PATH_UNIX
+in <paths.h>.
+.Pp
+.Fa corefile
+is the kernel memory device file. It can be either /dev/mem
+or a crash dump core generated by
+.Xr savecore 8 .
+If
+.Fa corefile
+is
+.Dv NULL ,
+the default indicated by
+.Dv _PATH_MEM
+from <paths.h> is used.
+.Pp
+.Fa swapfile
+should indicate the swap device. If
+.Dv NULL ,
+.Dv _PATH_DRUM
+from <paths.h> is used.
+.Pp
+The
+.Fa flags
+argument indicates read/write access as in
+.Xr open 2
+and applies only to the core file.
+Only
+.Dv O_RDONLY ,
+.Dv O_WRONLY ,
+and
+.Dv O_RDWR
+are permitted.
+.Pp
+There are two open routines which differ only with respect to
+the error mechanism.
+One provides backward compatibility with the SunOS kvm library, while the
+other provides an improved error reporting framework.
+.Pp
+The
+.Fn kvm_open
+function is the Sun kvm compatible open call. Here, the
+.Fa errstr
+argument indicates how errors should be handled. If it is
+.Dv NULL ,
+no errors are reported and the application cannot know the
+specific nature of the failed kvm call.
+If it is not
+.Dv NULL ,
+errors are printed to stderr with
+.Fa errstr
+prepended to the message, as in
+.Xr perror 3 .
+Normally, the name of the program is used here.
+The string is assumed to persist at least until the corresponding
+.Fn kvm_close
+call.
+.Pp
+The
+.Fn kvm_openfiles
+function provides BSD style error reporting.
+Here, error messages are not printed out by the library.
+Instead, the application obtains the error message
+corresponding to the most recent kvm library call using
+.Fn kvm_geterr
+(see
+.Xr kvm_geterr 3 ).
+The results are undefined if the most recent kvm call did not produce
+an error.
+Since
+.Fn kvm_geterr
+requires a kvm descriptor, but the open routines return
+.Dv NULL
+on failure,
+.Fn kvm_geterr
+cannot be used to get the error message if open fails.
+Thus,
+.Fn kvm_openfiles
+will place any error message in the
+.Fa errbuf
+argument. This buffer should be _POSIX2_LINE_MAX characters large (from
+<limits.h>).
+.Sh RETURN VALUES
+The
+.Fn kvm_open
+and
+.Fn kvm_openfiles
+functions both return a descriptor to be used
+in all subsequent kvm library calls.
+The library is fully re-entrant.
+On failure,
+.Dv NULL
+is returned, in which case
+.Fn kvm_openfiles
+writes the error message into
+.Fa errbuf .
+.Pp
+The
+.Fn kvm_close
+function returns 0 on success and -1 on failure.
+.Sh BUGS
+There should not be two open calls. The ill-defined error semantics
+of the Sun library and the desire to have a backward-compatible library
+for BSD left little choice.
+.Sh SEE ALSO
+.Xr open 2 ,
+.Xr kvm 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_read 3 ,
+.Xr kvm_write 3
--- /dev/null
+/* $OpenBSD: kvm_private.h,v 1.1 1996/03/19 23:15:39 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ *
+ * @(#)kvm_private.h 8.1 (Berkeley) 6/4/93
+ */
+
+struct __kvm {
+ /*
+ * a string to be prepended to error messages
+ * provided for compatibility with sun's interface
+ * if this value is null, errors are saved in errbuf[]
+ */
+ const char *program;
+ char *errp; /* XXX this can probably go away */
+ char errbuf[_POSIX2_LINE_MAX];
+ DB *db;
+#define ISALIVE(kd) ((kd)->vmfd >= 0)
+ int pmfd; /* physical memory file (or crashdump) */
+ int vmfd; /* virtual memory file (-1 if crashdump) */
+ int swfd; /* swap file (e.g., /dev/drum) */
+ int nlfd; /* namelist file (e.g., /vmunix) */
+ struct kinfo_proc *procbase;
+ int nbpg; /* page size */
+ char *swapspc; /* (dynamic) storage for swapped pages */
+ char *argspc, *argbuf; /* (dynamic) storage for argv strings */
+ int arglen; /* length of the above */
+ char **argv; /* (dynamic) storage for argv pointers */
+ int argc; /* length of above (not actual # present) */
+ /*
+ * Kernel virtual address translation state. This only gets filled
+ * in for dead kernels; otherwise, the running kernel (i.e. kmem)
+ * will do the translations for us. It could be big, so we
+ * only allocate it if necessary.
+ */
+ struct vmstate *vmst;
+ /*
+ * These kernel variables are used for looking up user addresses,
+ * and are cached for efficiency.
+ */
+ struct pglist *vm_page_buckets;
+ int vm_page_hash_mask;
+};
+
+/*
+ * Functions used internally by kvm, but across kvm modules.
+ */
+void _kvm_err __P((kvm_t *kd, const char *program, const char *fmt, ...));
+void _kvm_freeprocs __P((kvm_t *kd));
+void _kvm_freevtop __P((kvm_t *));
+int _kvm_initvtop __P((kvm_t *));
+int _kvm_kvatop __P((kvm_t *, u_long, u_long *));
+void *_kvm_malloc __P((kvm_t *kd, size_t));
+void *_kvm_realloc __P((kvm_t *kd, void *, size_t));
+void _kvm_syserr
+ __P((kvm_t *kd, const char *program, const char *fmt, ...));
--- /dev/null
+/* $OpenBSD: kvm_proc.c,v 1.1 1996/03/19 23:15:40 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1994, 1995 Charles M. Hannum. All rights reserved.
+ * Copyright (c) 1989, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_proc.c 8.3 (Berkeley) 9/23/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Proc traversal interface for kvm. ps and w are (probably) the exclusive
+ * users of this code, so we've factored it out into a separate module.
+ * Thus, we keep this grunge out of the other kvm applications (i.e.,
+ * most other applications are interested only in open/close/read/nlist).
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/exec.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/tty.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <vm/swap_pager.h>
+
+#include <sys/sysctl.h>
+
+#include <limits.h>
+#include <db.h>
+#include <paths.h>
+
+#include "kvm_private.h"
+
+#define KREAD(kd, addr, obj) \
+ (kvm_read(kd, addr, (char *)(obj), sizeof(*obj)) != sizeof(*obj))
+
+int _kvm_readfromcore __P((kvm_t *, u_long, u_long));
+int _kvm_readfrompager __P((kvm_t *, struct vm_object *, u_long));
+ssize_t kvm_uread __P((kvm_t *, const struct proc *, u_long, char *,
+ size_t));
+
+static char **kvm_argv __P((kvm_t *, const struct proc *, u_long, int,
+ int));
+static int kvm_deadprocs __P((kvm_t *, int, int, u_long, u_long, int));
+static char **kvm_doargv __P((kvm_t *, const struct kinfo_proc *, int,
+ void (*)(struct ps_strings *, u_long *, int *)));
+static int kvm_proclist __P((kvm_t *, int, int, struct proc *,
+ struct kinfo_proc *, int));
+static int proc_verify __P((kvm_t *, u_long, const struct proc *));
+static void ps_str_a __P((struct ps_strings *, u_long *, int *));
+static void ps_str_e __P((struct ps_strings *, u_long *, int *));
+
+char *
+_kvm_uread(kd, p, va, cnt)
+ kvm_t *kd;
+ const struct proc *p;
+ u_long va;
+ u_long *cnt;
+{
+ register u_long addr, head;
+ register u_long offset;
+ struct vm_map_entry vme;
+ struct vm_object vmo;
+ int rv;
+
+ if (kd->swapspc == 0) {
+ kd->swapspc = (char *)_kvm_malloc(kd, kd->nbpg);
+ if (kd->swapspc == 0)
+ return (0);
+ }
+
+ /*
+ * Look through the address map for the memory object
+ * that corresponds to the given virtual address.
+ * The header just has the entire valid range.
+ */
+ head = (u_long)&p->p_vmspace->vm_map.header;
+ addr = head;
+ while (1) {
+ if (KREAD(kd, addr, &vme))
+ return (0);
+
+ if (va >= vme.start && va < vme.end &&
+ vme.object.vm_object != 0)
+ break;
+
+ addr = (u_long)vme.next;
+ if (addr == head)
+ return (0);
+ }
+
+ /*
+ * We found the right object -- follow shadow links.
+ */
+ offset = va - vme.start + vme.offset;
+ addr = (u_long)vme.object.vm_object;
+
+ while (1) {
+ /* Try reading the page from core first. */
+ if ((rv = _kvm_readfromcore(kd, addr, offset)))
+ break;
+
+ if (KREAD(kd, addr, &vmo))
+ return (0);
+
+ /* If there is a pager here, see if it has the page. */
+ if (vmo.pager != 0 &&
+ (rv = _kvm_readfrompager(kd, &vmo, offset)))
+ break;
+
+ /* Move down the shadow chain. */
+ addr = (u_long)vmo.shadow;
+ if (addr == 0)
+ return (0);
+ offset += vmo.shadow_offset;
+ }
+
+ if (rv == -1)
+ return (0);
+
+ /* Found the page. */
+ offset %= kd->nbpg;
+ *cnt = kd->nbpg - offset;
+ return (&kd->swapspc[offset]);
+}
+
+#define vm_page_hash(kd, object, offset) \
+ (((u_long)object + (u_long)(offset / kd->nbpg)) & kd->vm_page_hash_mask)
+
+int
+_kvm_coreinit(kd)
+ kvm_t *kd;
+{
+ struct nlist nlist[3];
+
+ nlist[0].n_name = "_vm_page_buckets";
+ nlist[1].n_name = "_vm_page_hash_mask";
+ nlist[2].n_name = 0;
+ if (kvm_nlist(kd, nlist) != 0)
+ return (-1);
+
+ if (KREAD(kd, nlist[0].n_value, &kd->vm_page_buckets) ||
+ KREAD(kd, nlist[1].n_value, &kd->vm_page_hash_mask))
+ return (-1);
+
+ return (0);
+}
+
+int
+_kvm_readfromcore(kd, object, offset)
+ kvm_t *kd;
+ u_long object, offset;
+{
+ u_long addr;
+ struct pglist bucket;
+ struct vm_page mem;
+ off_t seekpoint;
+
+ if (kd->vm_page_buckets == 0 &&
+ _kvm_coreinit(kd))
+ return (-1);
+
+ addr = (u_long)&kd->vm_page_buckets[vm_page_hash(kd, object, offset)];
+ if (KREAD(kd, addr, &bucket))
+ return (-1);
+
+ addr = (u_long)bucket.tqh_first;
+ offset &= ~(kd->nbpg -1);
+ while (1) {
+ if (addr == 0)
+ return (0);
+
+ if (KREAD(kd, addr, &mem))
+ return (-1);
+
+ if ((u_long)mem.object == object &&
+ (u_long)mem.offset == offset)
+ break;
+
+ addr = (u_long)mem.hashq.tqe_next;
+ }
+
+ seekpoint = mem.phys_addr;
+
+ if (lseek(kd->pmfd, seekpoint, 0) == -1)
+ return (-1);
+ if (read(kd->pmfd, kd->swapspc, kd->nbpg) != kd->nbpg)
+ return (-1);
+
+ return (1);
+}
+
+int
+_kvm_readfrompager(kd, vmop, offset)
+ kvm_t *kd;
+ struct vm_object *vmop;
+ u_long offset;
+{
+ u_long addr;
+ struct pager_struct pager;
+ struct swpager swap;
+ int ix;
+ struct swblock swb;
+ off_t seekpoint;
+
+ /* Read in the pager info and make sure it's a swap device. */
+ addr = (u_long)vmop->pager;
+ if (KREAD(kd, addr, &pager) || pager.pg_type != PG_SWAP)
+ return (-1);
+
+ /* Read in the swap_pager private data. */
+ addr = (u_long)pager.pg_data;
+ if (KREAD(kd, addr, &swap))
+ return (-1);
+
+ /*
+ * Calculate the paging offset, and make sure it's within the
+ * bounds of the pager.
+ */
+ offset += vmop->paging_offset;
+ ix = offset / dbtob(swap.sw_bsize);
+#if 0
+ if (swap.sw_blocks == 0 || ix >= swap.sw_nblocks)
+ return (-1);
+#else
+ if (swap.sw_blocks == 0 || ix >= swap.sw_nblocks) {
+ int i;
+ printf("BUG BUG BUG BUG:\n");
+ printf("object %x offset %x pgoffset %x pager %x swpager %x\n",
+ vmop, offset - vmop->paging_offset, vmop->paging_offset,
+ vmop->pager, pager.pg_data);
+ printf("osize %x bsize %x blocks %x nblocks %x\n",
+ swap.sw_osize, swap.sw_bsize, swap.sw_blocks,
+ swap.sw_nblocks);
+ for (ix = 0; ix < swap.sw_nblocks; ix++) {
+ addr = (u_long)&swap.sw_blocks[ix];
+ if (KREAD(kd, addr, &swb))
+ return (0);
+ printf("sw_blocks[%d]: block %x mask %x\n", ix,
+ swb.swb_block, swb.swb_mask);
+ }
+ return (-1);
+ }
+#endif
+
+ /* Read in the swap records. */
+ addr = (u_long)&swap.sw_blocks[ix];
+ if (KREAD(kd, addr, &swb))
+ return (-1);
+
+ /* Calculate offset within pager. */
+ offset %= dbtob(swap.sw_bsize);
+
+ /* Check that the page is actually present. */
+ if ((swb.swb_mask & (1 << (offset / kd->nbpg))) == 0)
+ return (0);
+
+ if (!ISALIVE(kd))
+ return (-1);
+
+ /* Calculate the physical address and read the page. */
+ seekpoint = dbtob(swb.swb_block) + (offset & ~(kd->nbpg -1));
+
+ if (lseek(kd->swfd, seekpoint, 0) == -1)
+ return (-1);
+ if (read(kd->swfd, kd->swapspc, kd->nbpg) != kd->nbpg)
+ return (-1);
+
+ return (1);
+}
+
+/*
+ * Read proc's from memory file into buffer bp, which has space to hold
+ * at most maxcnt procs.
+ */
+static int
+kvm_proclist(kd, what, arg, p, bp, maxcnt)
+ kvm_t *kd;
+ int what, arg;
+ struct proc *p;
+ struct kinfo_proc *bp;
+ int maxcnt;
+{
+ register int cnt = 0;
+ struct eproc eproc;
+ struct pgrp pgrp;
+ struct session sess;
+ struct tty tty;
+ struct proc proc;
+
+ for (; cnt < maxcnt && p != NULL; p = proc.p_list.le_next) {
+ if (KREAD(kd, (u_long)p, &proc)) {
+ _kvm_err(kd, kd->program, "can't read proc at %x", p);
+ return (-1);
+ }
+ if (KREAD(kd, (u_long)proc.p_cred, &eproc.e_pcred) == 0)
+ KREAD(kd, (u_long)eproc.e_pcred.pc_ucred,
+ &eproc.e_ucred);
+
+ switch(what) {
+
+ case KERN_PROC_PID:
+ if (proc.p_pid != (pid_t)arg)
+ continue;
+ break;
+
+ case KERN_PROC_UID:
+ if (eproc.e_ucred.cr_uid != (uid_t)arg)
+ continue;
+ break;
+
+ case KERN_PROC_RUID:
+ if (eproc.e_pcred.p_ruid != (uid_t)arg)
+ continue;
+ break;
+ }
+ /*
+ * We're going to add another proc to the set. If this
+ * will overflow the buffer, assume the reason is because
+ * nprocs (or the proc list) is corrupt and declare an error.
+ */
+ if (cnt >= maxcnt) {
+ _kvm_err(kd, kd->program, "nprocs corrupt");
+ return (-1);
+ }
+ /*
+ * gather eproc
+ */
+ eproc.e_paddr = p;
+ if (KREAD(kd, (u_long)proc.p_pgrp, &pgrp)) {
+ _kvm_err(kd, kd->program, "can't read pgrp at %x",
+ proc.p_pgrp);
+ return (-1);
+ }
+ eproc.e_sess = pgrp.pg_session;
+ eproc.e_pgid = pgrp.pg_id;
+ eproc.e_jobc = pgrp.pg_jobc;
+ if (KREAD(kd, (u_long)pgrp.pg_session, &sess)) {
+ _kvm_err(kd, kd->program, "can't read session at %x",
+ pgrp.pg_session);
+ return (-1);
+ }
+ if ((proc.p_flag & P_CONTROLT) && sess.s_ttyp != NULL) {
+ if (KREAD(kd, (u_long)sess.s_ttyp, &tty)) {
+ _kvm_err(kd, kd->program,
+ "can't read tty at %x", sess.s_ttyp);
+ return (-1);
+ }
+ eproc.e_tdev = tty.t_dev;
+ eproc.e_tsess = tty.t_session;
+ if (tty.t_pgrp != NULL) {
+ if (KREAD(kd, (u_long)tty.t_pgrp, &pgrp)) {
+ _kvm_err(kd, kd->program,
+ "can't read tpgrp at &x",
+ tty.t_pgrp);
+ return (-1);
+ }
+ eproc.e_tpgid = pgrp.pg_id;
+ } else
+ eproc.e_tpgid = -1;
+ } else
+ eproc.e_tdev = NODEV;
+ eproc.e_flag = sess.s_ttyvp ? EPROC_CTTY : 0;
+ if (sess.s_leader == p)
+ eproc.e_flag |= EPROC_SLEADER;
+ if (proc.p_wmesg)
+ (void)kvm_read(kd, (u_long)proc.p_wmesg,
+ eproc.e_wmesg, WMESGLEN);
+
+ (void)kvm_read(kd, (u_long)proc.p_vmspace,
+ (char *)&eproc.e_vm, sizeof(eproc.e_vm));
+
+ eproc.e_xsize = eproc.e_xrssize = 0;
+ eproc.e_xccount = eproc.e_xswrss = 0;
+
+ switch (what) {
+
+ case KERN_PROC_PGRP:
+ if (eproc.e_pgid != (pid_t)arg)
+ continue;
+ break;
+
+ case KERN_PROC_TTY:
+ if ((proc.p_flag & P_CONTROLT) == 0 ||
+ eproc.e_tdev != (dev_t)arg)
+ continue;
+ break;
+ }
+ bcopy(&proc, &bp->kp_proc, sizeof(proc));
+ bcopy(&eproc, &bp->kp_eproc, sizeof(eproc));
+ ++bp;
+ ++cnt;
+ }
+ return (cnt);
+}
+
+/*
+ * Build proc info array by reading in proc list from a crash dump.
+ * Return number of procs read. maxcnt is the max we will read.
+ */
+static int
+kvm_deadprocs(kd, what, arg, a_allproc, a_zombproc, maxcnt)
+ kvm_t *kd;
+ int what, arg;
+ u_long a_allproc;
+ u_long a_zombproc;
+ int maxcnt;
+{
+ register struct kinfo_proc *bp = kd->procbase;
+ register int acnt, zcnt;
+ struct proc *p;
+
+ if (KREAD(kd, a_allproc, &p)) {
+ _kvm_err(kd, kd->program, "cannot read allproc");
+ return (-1);
+ }
+ acnt = kvm_proclist(kd, what, arg, p, bp, maxcnt);
+ if (acnt < 0)
+ return (acnt);
+
+ if (KREAD(kd, a_zombproc, &p)) {
+ _kvm_err(kd, kd->program, "cannot read zombproc");
+ return (-1);
+ }
+ zcnt = kvm_proclist(kd, what, arg, p, bp + acnt, maxcnt - acnt);
+ if (zcnt < 0)
+ zcnt = 0;
+
+ return (acnt + zcnt);
+}
+
+struct kinfo_proc *
+kvm_getprocs(kd, op, arg, cnt)
+ kvm_t *kd;
+ int op, arg;
+ int *cnt;
+{
+ size_t size;
+ int mib[4], st, nprocs;
+
+ if (kd->procbase != 0) {
+ free((void *)kd->procbase);
+ /*
+ * Clear this pointer in case this call fails. Otherwise,
+ * kvm_close() will free it again.
+ */
+ kd->procbase = 0;
+ }
+ if (ISALIVE(kd)) {
+ size = 0;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = op;
+ mib[3] = arg;
+ st = sysctl(mib, 4, NULL, &size, NULL, 0);
+ if (st == -1) {
+ _kvm_syserr(kd, kd->program, "kvm_getprocs");
+ return (0);
+ }
+ kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size);
+ if (kd->procbase == 0)
+ return (0);
+ st = sysctl(mib, 4, kd->procbase, &size, NULL, 0);
+ if (st == -1) {
+ _kvm_syserr(kd, kd->program, "kvm_getprocs");
+ return (0);
+ }
+ if (size % sizeof(struct kinfo_proc) != 0) {
+ _kvm_err(kd, kd->program,
+ "proc size mismatch (%d total, %d chunks)",
+ size, sizeof(struct kinfo_proc));
+ return (0);
+ }
+ nprocs = size / sizeof(struct kinfo_proc);
+ } else {
+ struct nlist nl[4], *p;
+
+ nl[0].n_name = "_nprocs";
+ nl[1].n_name = "_allproc";
+ nl[2].n_name = "_zombproc";
+ nl[3].n_name = 0;
+
+ if (kvm_nlist(kd, nl) != 0) {
+ for (p = nl; p->n_type != 0; ++p)
+ ;
+ _kvm_err(kd, kd->program,
+ "%s: no such symbol", p->n_name);
+ return (0);
+ }
+ if (KREAD(kd, nl[0].n_value, &nprocs)) {
+ _kvm_err(kd, kd->program, "can't read nprocs");
+ return (0);
+ }
+ size = nprocs * sizeof(struct kinfo_proc);
+ kd->procbase = (struct kinfo_proc *)_kvm_malloc(kd, size);
+ if (kd->procbase == 0)
+ return (0);
+
+ nprocs = kvm_deadprocs(kd, op, arg, nl[1].n_value,
+ nl[2].n_value, nprocs);
+#ifdef notdef
+ size = nprocs * sizeof(struct kinfo_proc);
+ (void)realloc(kd->procbase, size);
+#endif
+ }
+ *cnt = nprocs;
+ return (kd->procbase);
+}
+
+void
+_kvm_freeprocs(kd)
+ kvm_t *kd;
+{
+ if (kd->procbase) {
+ free(kd->procbase);
+ kd->procbase = 0;
+ }
+}
+
+void *
+_kvm_realloc(kd, p, n)
+ kvm_t *kd;
+ void *p;
+ size_t n;
+{
+ void *np = (void *)realloc(p, n);
+
+ if (np == 0)
+ _kvm_err(kd, kd->program, "out of memory");
+ return (np);
+}
+
+#ifndef MAX
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+#endif
+
+/*
+ * Read in an argument vector from the user address space of process p.
+ * addr if the user-space base address of narg null-terminated contiguous
+ * strings. This is used to read in both the command arguments and
+ * environment strings. Read at most maxcnt characters of strings.
+ */
+static char **
+kvm_argv(kd, p, addr, narg, maxcnt)
+ kvm_t *kd;
+ const struct proc *p;
+ register u_long addr;
+ register int narg;
+ register int maxcnt;
+{
+ register char *np, *cp, *ep, *ap;
+ register u_long oaddr = -1;
+ register int len, cc;
+ register char **argv;
+
+ /*
+ * Check that there aren't an unreasonable number of agruments,
+ * and that the address is in user space.
+ */
+ if (narg > ARG_MAX || addr < VM_MIN_ADDRESS || addr >= VM_MAXUSER_ADDRESS)
+ return (0);
+
+ if (kd->argv == 0) {
+ /*
+ * Try to avoid reallocs.
+ */
+ kd->argc = MAX(narg + 1, 32);
+ kd->argv = (char **)_kvm_malloc(kd, kd->argc *
+ sizeof(*kd->argv));
+ if (kd->argv == 0)
+ return (0);
+ } else if (narg + 1 > kd->argc) {
+ kd->argc = MAX(2 * kd->argc, narg + 1);
+ kd->argv = (char **)_kvm_realloc(kd, kd->argv, kd->argc *
+ sizeof(*kd->argv));
+ if (kd->argv == 0)
+ return (0);
+ }
+ if (kd->argspc == 0) {
+ kd->argspc = (char *)_kvm_malloc(kd, kd->nbpg);
+ if (kd->argspc == 0)
+ return (0);
+ kd->arglen = kd->nbpg;
+ }
+ if (kd->argbuf == 0) {
+ kd->argbuf = (char *)_kvm_malloc(kd, kd->nbpg);
+ if (kd->argbuf == 0)
+ return (0);
+ }
+ cc = sizeof(char *) * narg;
+ if (kvm_uread(kd, p, addr, (char *)kd->argv, cc) != cc)
+ return (0);
+ ap = np = kd->argspc;
+ argv = kd->argv;
+ len = 0;
+ /*
+ * Loop over pages, filling in the argument vector.
+ */
+ while (argv < kd->argv + narg && *argv != 0) {
+ addr = (u_long)*argv & ~(kd->nbpg - 1);
+ if (addr != oaddr) {
+ if (kvm_uread(kd, p, addr, kd->argbuf, kd->nbpg) !=
+ kd->nbpg)
+ return (0);
+ oaddr = addr;
+ }
+ addr = (u_long)*argv & (kd->nbpg - 1);
+ cp = kd->argbuf + addr;
+ cc = kd->nbpg - addr;
+ if (maxcnt > 0 && cc > maxcnt - len)
+ cc = maxcnt - len;;
+ ep = memchr(cp, '\0', cc);
+ if (ep != 0)
+ cc = ep - cp + 1;
+ if (len + cc > kd->arglen) {
+ register int off;
+ register char **pp;
+ register char *op = kd->argspc;
+
+ kd->arglen *= 2;
+ kd->argspc = (char *)_kvm_realloc(kd, kd->argspc,
+ kd->arglen);
+ if (kd->argspc == 0)
+ return (0);
+ /*
+ * Adjust argv pointers in case realloc moved
+ * the string space.
+ */
+ off = kd->argspc - op;
+ for (pp = kd->argv; pp < argv; pp++)
+ *pp += off;
+ ap += off;
+ np += off;
+ }
+ memcpy(np, cp, cc);
+ np += cc;
+ len += cc;
+ if (ep != 0) {
+ *argv++ = ap;
+ ap = np;
+ } else
+ *argv += cc;
+ if (maxcnt > 0 && len >= maxcnt) {
+ /*
+ * We're stopping prematurely. Terminate the
+ * current string.
+ */
+ if (ep == 0) {
+ *np = '\0';
+ *argv++ = ap;
+ }
+ break;
+ }
+ }
+ /* Make sure argv is terminated. */
+ *argv = 0;
+ return (kd->argv);
+}
+
+static void
+ps_str_a(p, addr, n)
+ struct ps_strings *p;
+ u_long *addr;
+ int *n;
+{
+ *addr = (u_long)p->ps_argvstr;
+ *n = p->ps_nargvstr;
+}
+
+static void
+ps_str_e(p, addr, n)
+ struct ps_strings *p;
+ u_long *addr;
+ int *n;
+{
+ *addr = (u_long)p->ps_envstr;
+ *n = p->ps_nenvstr;
+}
+
+/*
+ * Determine if the proc indicated by p is still active.
+ * This test is not 100% foolproof in theory, but chances of
+ * being wrong are very low.
+ */
+static int
+proc_verify(kd, kernp, p)
+ kvm_t *kd;
+ u_long kernp;
+ const struct proc *p;
+{
+ struct proc kernproc;
+
+ /*
+ * Just read in the whole proc. It's not that big relative
+ * to the cost of the read system call.
+ */
+ if (kvm_read(kd, kernp, (char *)&kernproc, sizeof(kernproc)) !=
+ sizeof(kernproc))
+ return (0);
+ return (p->p_pid == kernproc.p_pid &&
+ (kernproc.p_stat != SZOMB || p->p_stat == SZOMB));
+}
+
+static char **
+kvm_doargv(kd, kp, nchr, info)
+ kvm_t *kd;
+ const struct kinfo_proc *kp;
+ int nchr;
+ void (*info)(struct ps_strings *, u_long *, int *);
+{
+ register const struct proc *p = &kp->kp_proc;
+ register char **ap;
+ u_long addr;
+ int cnt;
+ struct ps_strings arginfo;
+
+ /*
+ * Pointers are stored at the top of the user stack.
+ */
+ if (p->p_stat == SZOMB ||
+ kvm_uread(kd, p, USRSTACK - sizeof(arginfo), (char *)&arginfo,
+ sizeof(arginfo)) != sizeof(arginfo))
+ return (0);
+
+ (*info)(&arginfo, &addr, &cnt);
+ if (cnt == 0)
+ return (0);
+ ap = kvm_argv(kd, p, addr, cnt, nchr);
+ /*
+ * For live kernels, make sure this process didn't go away.
+ */
+ if (ap != 0 && ISALIVE(kd) &&
+ !proc_verify(kd, (u_long)kp->kp_eproc.e_paddr, p))
+ ap = 0;
+ return (ap);
+}
+
+/*
+ * Get the command args. This code is now machine independent.
+ */
+char **
+kvm_getargv(kd, kp, nchr)
+ kvm_t *kd;
+ const struct kinfo_proc *kp;
+ int nchr;
+{
+ return (kvm_doargv(kd, kp, nchr, ps_str_a));
+}
+
+char **
+kvm_getenvv(kd, kp, nchr)
+ kvm_t *kd;
+ const struct kinfo_proc *kp;
+ int nchr;
+{
+ return (kvm_doargv(kd, kp, nchr, ps_str_e));
+}
+
+/*
+ * Read from user space. The user context is given by p.
+ */
+ssize_t
+kvm_uread(kd, p, uva, buf, len)
+ kvm_t *kd;
+ register const struct proc *p;
+ register u_long uva;
+ register char *buf;
+ register size_t len;
+{
+ register char *cp;
+
+ cp = buf;
+ while (len > 0) {
+ register int cc;
+ register char *dp;
+ u_long cnt;
+
+ dp = _kvm_uread(kd, p, uva, &cnt);
+ if (dp == 0) {
+ _kvm_err(kd, 0, "invalid address (%x)", uva);
+ return (0);
+ }
+ cc = MIN(cnt, len);
+ bcopy(dp, cp, cc);
+
+ cp += cc;
+ uva += cc;
+ len -= cc;
+ }
+ return (ssize_t)(cp - buf);
+}
--- /dev/null
+.\" $OpenBSD: kvm_read.3,v 1.1 1996/03/19 23:15:41 niklas Exp $
+.\"
+.\" Copyright (c) 1992, 1993
+.\" The Regents of the University of California. All rights reserved.
+.\"
+.\" This code is derived from software 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.
+.\"
+.\" @(#)kvm_read.3 8.1 (Berkeley) 6/4/93
+.\"
+.Dd June 4, 1993
+.Dt KVM_READ 3
+.Os
+.Sh NAME
+.Nm kvm_read ,
+.Nm kvm_write
+.Nd read or write kernel virtual memory
+.Sh SYNOPSIS
+.Fd #include <kvm.h>
+.Ft ssize_t
+.Fn kvm_read "kvm_t *kd" "u_long addr" "void *buf" "size_t nbytes"
+.Ft ssize_t
+.Fn kvm_write "kvm_t *kd" "u_long addr" "const void *buf" "size_t nbytes"
+.Sh DESCRIPTION
+The
+.Fn kvm_read
+and
+.Fn kvm_write
+functions are used to read and write kernel virtual memory (or a crash
+dump file). See
+.Fn kvm_open 3
+or
+.Fn kvm_openfiles 3
+for information regarding opening kernel virtual memory and crash dumps.
+.Pp
+The
+.Fn kvm_read
+function transfers
+.Fa nbytes
+bytes of data from
+the kernel space address
+.Fa addr
+to
+.Fa buf .
+Conversely,
+.Fn kvm_write
+transfers data from
+.Fa buf
+to
+.Fa addr .
+Unlike their SunOS counterparts, these functions cannot be used to
+read or write process address spaces.
+.Sh RETURN VALUES
+Upon success, the number of bytes actually transferred is returned.
+Otherwise, -1 is returned.
+.Sh SEE ALSO
+.Xr kvm 3 ,
+.Xr kvm_close 3 ,
+.Xr kvm_getargv 3 ,
+.Xr kvm_getenvv 3 ,
+.Xr kvm_geterr 3 ,
+.Xr kvm_getprocs 3 ,
+.Xr kvm_nlist 3 ,
+.Xr kvm_open 3 ,
+.Xr kvm_openfiles 3
--- /dev/null
+/* $OpenBSD: kvm_sparc.c,v 1.1 1996/03/19 23:15:41 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)kvm_sparc.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Sparc machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <sys/sysctl.h>
+#include <sys/device.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+#include <machine/autoconf.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+#define MA_SIZE 32 /* XXX */
+struct vmstate {
+ struct {
+ int x_seginval;
+ int x_npmemarr;
+ struct memarr x_pmemarr[MA_SIZE];
+ struct segmap x_segmap_store[NKREG*NSEGRG];
+ } x;
+#define seginval x.x_seginval
+#define npmemarr x.x_npmemarr
+#define pmemarr x.x_pmemarr
+#define segmap_store x.x_segmap_store
+ int *pte;
+};
+#define NPMEG(vm) ((vm)->seginval+1)
+
+static int cputyp = -1;
+
+static int pgshift, nptesg;
+
+#define VA_VPG(va) (cputyp==CPU_SUN4C ? VA_SUN4C_VPG(va) : VA_SUN4_VPG(va))
+
+static void
+_kvm_mustinit(kd)
+ kvm_t *kd;
+{
+ if (cputyp != -1)
+ return;
+ for (pgshift = 12; (1 << pgshift) != kd->nbpg; pgshift++)
+ ;
+ nptesg = NBPSG / kd->nbpg;
+
+#if 1
+ if (cputyp == -1) {
+ if (kd->nbpg == 8192)
+ cputyp = CPU_SUN4;
+ else
+ cputyp = CPU_SUN4C;
+ }
+#endif
+}
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ if (kd->vmst != 0) {
+ if (kd->vmst->pte != 0)
+ free(kd->vmst->pte);
+ free(kd->vmst);
+ kd->vmst = 0;
+ }
+}
+
+/*
+ * Prepare for translation of kernel virtual addresses into offsets
+ * into crash dump files. We use the MMU specific goop written at the
+ * and of crash dump by pmap_dumpmmu().
+ * (note: sun4/sun4c 2-level MMU specific)
+ */
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ register int i;
+ register int off;
+ register struct vmstate *vm;
+ struct stat st;
+ struct nlist nlist[5];
+
+ _kvm_mustinit(kd);
+
+ if ((vm = kd->vmst) == 0) {
+ kd->vmst = vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+ }
+
+ if (fstat(kd->pmfd, &st) < 0)
+ return (-1);
+ /*
+ * Read segment table.
+ */
+
+ off = st.st_size - roundup(sizeof(vm->x), kd->nbpg);
+ errno = 0;
+ if (lseek(kd->pmfd, (off_t)off, 0) == -1 && errno != 0 ||
+ read(kd->pmfd, (char *)&vm->x, sizeof(vm->x)) < 0) {
+ _kvm_err(kd, kd->program, "cannot read segment map");
+ return (-1);
+ }
+
+ vm->pte = (int *)_kvm_malloc(kd, NPMEG(vm) * nptesg * sizeof(int));
+ if (vm->pte == 0) {
+ free(kd->vmst);
+ kd->vmst = 0;
+ return (-1);
+ }
+
+ /*
+ * Read PMEGs.
+ */
+ off = st.st_size - roundup(sizeof(vm->x), kd->nbpg) -
+ roundup(NPMEG(vm) * nptesg * sizeof(int), kd->nbpg);
+
+ errno = 0;
+ if (lseek(kd->pmfd, (off_t)off, 0) == -1 && errno != 0 ||
+ read(kd->pmfd, (char *)vm->pte, NPMEG(vm) * nptesg * sizeof(int)) < 0) {
+ _kvm_err(kd, kd->program, "cannot read PMEG table");
+ return (-1);
+ }
+
+ return (0);
+}
+
+#define VA_OFF(va) (va & (kd->nbpg - 1))
+
+/*
+ * Translate a kernel virtual address to a physical address using the
+ * mapping information in kd->vm. Returns the result in pa, and returns
+ * the number of bytes that are contiguously available from this
+ * physical address. This routine is used only for crashdumps.
+ */
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ register int vr, vs, pte, off, nmem;
+ register struct vmstate *vm = kd->vmst;
+ struct regmap *rp;
+ struct segmap *sp;
+ struct memarr *mp;
+
+ _kvm_mustinit(kd);
+
+ if (va < KERNBASE)
+ goto err;
+
+ vr = VA_VREG(va);
+ vs = VA_VSEG(va);
+
+ sp = &vm->segmap_store[(vr-NUREG)*NSEGRG + vs];
+ if (sp->sg_npte == 0)
+ goto err;
+ if (sp->sg_pmeg == vm->seginval)
+ goto err;
+ pte = vm->pte[sp->sg_pmeg * nptesg + VA_VPG(va)];
+ if ((pte & PG_V) != 0) {
+ register long p, dumpoff = 0;
+
+ off = VA_OFF(va);
+ p = (pte & PG_PFNUM) << pgshift;
+ /* Translate (sparse) pfnum to (packed) dump offset */
+ for (mp = vm->pmemarr, nmem = vm->npmemarr; --nmem >= 0; mp++) {
+ if (mp->addr <= p && p < mp->addr + mp->len)
+ break;
+ dumpoff += mp->len;
+ }
+ if (nmem < 0)
+ goto err;
+ *pa = (dumpoff + p - mp->addr) | off;
+ return (kd->nbpg - off);
+ }
+err:
+ _kvm_err(kd, 0, "invalid address (%x)", va);
+ return (0);
+}
+
+#if 0
+static int
+getcputyp()
+{
+ int mib[2];
+ size_t size;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_CLASS;
+ size = sizeof cputyp;
+ if (sysctl(mib, 2, &cputyp, &size, NULL, 0) == -1)
+ return (-1);
+}
+#endif
--- /dev/null
+/* $OpenBSD: kvm_sun3.c,v 1.1 1996/03/19 23:15:42 niklas Exp $ */
+
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ */
+
+/*
+ * Sun3 machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module. Furthermore, I hope it
+ * gets here soon, because this basically is an error stub! (sorry)
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+struct vmstate {
+ u_long end;
+};
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ if (kd->vmst != 0)
+ free(kd->vmst);
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ register int i;
+ register int off;
+ register struct vmstate *vm;
+ struct stat st;
+ struct nlist nlist[2];
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+
+ kd->vmst = vm;
+
+ if (fstat(kd->pmfd, &st) < 0)
+ return (-1);
+
+ /* Get end of kernel address */
+ nlist[0].n_name = "_end";
+ nlist[1].n_name = 0;
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "pmap_stod: no such symbol");
+ return (-1);
+ }
+ vm->end = (u_long)nlist[0].n_value;
+
+ return (0);
+}
+
+#define VA_OFF(va) (va & (NBPG - 1))
+
+/*
+ * Translate a kernel virtual address to a physical address using the
+ * mapping information in kd->vm. Returns the result in pa, and returns
+ * the number of bytes that are contiguously available from this
+ * physical address. This routine is used only for crashdumps.
+ */
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ register int end;
+
+ if (va < KERNBASE) {
+ _kvm_err(kd, 0, "invalid address (%x<%x)", va, KERNBASE);
+ return (0);
+ }
+
+ end = kd->vmst->end;
+ if (va >= end) {
+ _kvm_err(kd, 0, "invalid address (%x>=%x)", va, end);
+ return (0);
+ }
+
+ *pa = (va - KERNBASE);
+ return (end - va);
+}
--- /dev/null
+/* $OpenBSD: kvm_vax.c,v 1.1 1996/03/19 23:15:43 niklas Exp $ */
+/* $NetBSD: kvm_vax.c,v 1.1.1.1 1996/03/16 10:05:24 leo Exp $ */
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software 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.
+ */
+
+/*
+ * VAX machine dependent routines for kvm. Hopefully, the forthcoming
+ * vm code will one day obsolete this module. Furthermore, I hope it
+ * gets here soon, because this basically is an error stub! (sorry)
+ * This code may not work anyway.
+ */
+
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <nlist.h>
+#include <kvm.h>
+
+#include <vm/vm.h>
+#include <vm/vm_param.h>
+
+#include <limits.h>
+#include <db.h>
+
+#include "kvm_private.h"
+
+struct vmstate {
+ u_long end;
+};
+
+void
+_kvm_freevtop(kd)
+ kvm_t *kd;
+{
+ if (kd->vmst != 0)
+ free(kd->vmst);
+}
+
+int
+_kvm_initvtop(kd)
+ kvm_t *kd;
+{
+ register int i;
+ register int off;
+ register struct vmstate *vm;
+ struct stat st;
+ struct nlist nlist[2];
+
+ vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
+ if (vm == 0)
+ return (-1);
+
+ kd->vmst = vm;
+
+ if (fstat(kd->pmfd, &st) < 0)
+ return (-1);
+
+ /* Get end of kernel address */
+ nlist[0].n_name = "_end";
+ nlist[1].n_name = 0;
+ if (kvm_nlist(kd, nlist) != 0) {
+ _kvm_err(kd, kd->program, "pmap_stod: no such symbol");
+ return (-1);
+ }
+ vm->end = (u_long)nlist[0].n_value;
+
+ return (0);
+}
+
+#define VA_OFF(va) (va & (NBPG - 1))
+
+/*
+ * Translate a kernel virtual address to a physical address using the
+ * mapping information in kd->vm. Returns the result in pa, and returns
+ * the number of bytes that are contiguously available from this
+ * physical address. This routine is used only for crashdumps.
+ */
+int
+_kvm_kvatop(kd, va, pa)
+ kvm_t *kd;
+ u_long va;
+ u_long *pa;
+{
+ register int end;
+
+ if (va < KERNBASE) {
+ _kvm_err(kd, 0, "invalid address (%x<%x)", va, KERNBASE);
+ return (0);
+ }
+
+ end = kd->vmst->end;
+ if (va >= end) {
+ _kvm_err(kd, 0, "invalid address (%x>=%x)", va, end);
+ return (0);
+ }
+
+ *pa = (va - KERNBASE);
+ return (end - va);
+}
--- /dev/null
+major=4
+minor=0
+/* $OpenBSD: kvm.c,v 1.2 1996/03/19 23:15:22 niklas Exp $ */
+
/*-
* Copyright (c) 1989, 1992, 1993
* The Regents of the University of California. All rights reserved.
#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <sys/core.h>
+#include <sys/exec_aout.h>
+#include <sys/kcore.h>
+
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/swap_pager.h>
#include <machine/vmparam.h>
+#include <machine/kcore.h>
#include <ctype.h>
#include <db.h>
#include "kvm_private.h"
static int kvm_dbopen __P((kvm_t *, const char *));
+static int _kvm_get_header __P((kvm_t *));
static kvm_t *_kvm_open __P((kvm_t *, const char *, const char *,
const char *, int, char *));
+static int clear_gap __P((kvm_t *, FILE *, int));
+static off_t Lseek __P((kvm_t *, int, off_t, int));
+static ssize_t Read __P(( kvm_t *, int, void *, size_t));
char *
kvm_geterr(kd)
return (p);
}
+/*
+ * Wrappers for Lseek/Read system calls. They check for errors and
+ * call _kvm_syserr() if appropriate.
+ */
+static off_t
+Lseek(kd, fd, offset, whence)
+ kvm_t *kd;
+ int fd, whence;
+ off_t offset;
+{
+ off_t off;
+
+ errno = 0;
+ if ((off = lseek(fd, offset, whence)) == -1 && errno != 0) {
+ _kvm_syserr(kd, kd->program, "Lseek");
+ return (-1);
+ }
+ return (off);
+}
+
+static ssize_t
+Read(kd, fd, buf, nbytes)
+ kvm_t *kd;
+ int fd;
+ void *buf;
+ size_t nbytes;
+{
+ ssize_t rv;
+
+ errno = 0;
+
+ if ((rv = read(fd, buf, nbytes)) != nbytes && errno != 0)
+ _kvm_syserr(kd, kd->program, "Read");
+ return (rv);
+}
+
static kvm_t *
_kvm_open(kd, uf, mf, sf, flag, errout)
register kvm_t *kd;
kd->argv = 0;
kd->vmst = 0;
kd->vm_page_buckets = 0;
+ kd->kcore_hdr = 0;
+ kd->cpu_hdr = 0;
+ kd->dump_off = 0;
if (uf == 0)
uf = _PATH_UNIX;
_kvm_syserr(kd, kd->program, "%s", uf);
goto failed;
}
- if (_kvm_initvtop(kd) < 0)
- goto failed;
+
+ /*
+ * If there is no valid core header, fail silently here.
+ * The address translations however will fail without
+ * header. Things can be made to run by calling
+ * kvm_dump_mkheader() before doing any translation.
+ */
+ if (_kvm_get_header(kd) == 0) {
+ if (_kvm_initvtop(kd) < 0)
+ goto failed;
+ }
}
return (kd);
failed:
return (0);
}
+static int
+_kvm_get_header(kd)
+kvm_t *kd;
+{
+ cpu_kcore_hdr_t ckhdr;
+ kcore_hdr_t khdr;
+ kcore_seg_t seghdr;
+ off_t offset;
+
+ if (Lseek(kd, kd->pmfd, (off_t)0, SEEK_SET) == -1)
+ return (-1);
+
+ if (Read(kd, kd->pmfd, &khdr, sizeof(khdr)) != sizeof(khdr))
+ return (-1);
+ offset = khdr.c_hdrsize;
+
+ /*
+ * Currently, we only support dump-files made by the current
+ * architecture...
+ */
+ if ((CORE_GETMAGIC(khdr) != KCORE_MAGIC)
+ || ((CORE_GETMID(khdr) != MID_MACHINE)))
+ return (-1);
+
+ /*
+ * Currently, we only support exactly 2 segments: cpu-segment
+ * and data-segment in exactly that order.
+ */
+ if (khdr.c_nseg != 2)
+ return (-1);
+
+ /*
+ * Read the next segment header: cpu segment
+ */
+ if (Lseek(kd, kd->pmfd, (off_t)offset, SEEK_SET) == -1)
+ return (-1);
+ if (Read(kd, kd->pmfd, &seghdr, sizeof(seghdr)) != sizeof(seghdr))
+ return (-1);
+ if (CORE_GETMAGIC(seghdr) != KCORESEG_MAGIC
+ || CORE_GETFLAG(seghdr) != CORE_CPU)
+ return (-1);
+ offset += khdr.c_seghdrsize;
+ if (Lseek(kd, kd->pmfd, (off_t)offset, SEEK_SET) == -1)
+ return (-1);
+ if (Read(kd, kd->pmfd, &ckhdr, sizeof(ckhdr)) != sizeof(ckhdr))
+ return (-1);
+ offset += seghdr.c_size;
+
+ /*
+ * Read the next segment header: data segment
+ */
+ if (Lseek(kd, kd->pmfd, (off_t)offset, SEEK_SET) == -1)
+ return (-1);
+ if (Read(kd, kd->pmfd, &seghdr, sizeof(seghdr)) != sizeof(seghdr))
+ return (-1);
+ offset += khdr.c_seghdrsize;
+
+ if (CORE_GETMAGIC(seghdr) != KCORESEG_MAGIC
+ || CORE_GETFLAG(seghdr) != CORE_DATA)
+ return (-1);
+
+ kd->kcore_hdr = (kcore_hdr_t *)_kvm_malloc(kd, sizeof(*kd->kcore_hdr));
+ if (kd->kcore_hdr == NULL)
+ return (-1);
+ kd->cpu_hdr = (cpu_kcore_hdr_t *)_kvm_malloc(kd, sizeof(*kd->cpu_hdr));
+ if (kd->cpu_hdr == NULL) {
+ free((void *)kd->kcore_hdr);
+ kd->kcore_hdr = NULL;
+ return (-1);
+ }
+
+ *kd->kcore_hdr = khdr;
+ *kd->cpu_hdr = ckhdr;
+ kd->dump_off = offset;
+ return (0);
+}
+
+/*
+ * Translate a physical address to a file-offset in the crash-dump.
+ */
+off_t
+_kvm_pa2off(kd, pa)
+ kvm_t *kd;
+ u_long pa;
+{
+ off_t off;
+ phys_ram_seg_t *rsp;
+
+ off = 0;
+ for (rsp = kd->cpu_hdr->ram_segs; rsp->size; rsp++) {
+ if (pa >= rsp->start && pa < rsp->start + rsp->size) {
+ pa -= rsp->start;
+ break;
+ }
+ off += rsp->size;
+ }
+ return(pa + off + kd->dump_off);
+}
+
+int
+kvm_dump_mkheader(kd_live, kd_dump, dump_off)
+kvm_t *kd_live, *kd_dump;
+off_t dump_off;
+{
+ kcore_hdr_t kch;
+ kcore_seg_t kseg;
+ cpu_kcore_hdr_t ckhdr;
+ int hdr_size;
+
+ hdr_size = 0;
+ if (kd_dump->kcore_hdr != NULL) {
+ _kvm_err(kd_dump, kd_dump->program, "already has a dump header");
+ return (-1);
+ }
+ if (!ISALIVE(kd_live) || ISALIVE(kd_dump)) {
+ _kvm_err(kd_live, kd_live->program, "wrong arguments");
+ return (-1);
+ }
+
+ /*
+ * Check for new format crash dump
+ */
+ if (Lseek(kd_dump, kd_dump->pmfd, dump_off, SEEK_SET) == -1)
+ return (-1);
+ if (Read(kd_dump, kd_dump->pmfd, &kseg, sizeof(kseg)) != sizeof(kseg))
+ return (-1);
+ if ((CORE_GETMAGIC(kseg) == KCORE_MAGIC)
+ && ((CORE_GETMID(kseg) == MID_MACHINE))) {
+ hdr_size += ALIGN(sizeof(kcore_seg_t));
+ if (Lseek(kd_dump, kd_dump->pmfd, dump_off+hdr_size, SEEK_SET)
+ == -1)
+ return (-1);
+ if (Read(kd_dump, kd_dump->pmfd, &ckhdr, sizeof(ckhdr))
+ != sizeof(ckhdr))
+ return (-1);
+ hdr_size += kseg.c_size;
+ if (Lseek(kd_dump, kd_dump->pmfd, dump_off+hdr_size, SEEK_SET)
+ == -1)
+ return (-1);
+ kd_dump->cpu_hdr = (cpu_kcore_hdr_t *)
+ _kvm_malloc(kd_dump, sizeof(cpu_kcore_hdr_t));
+ *kd_dump->cpu_hdr = ckhdr;
+ }
+
+ /*
+ * Create a kcore_hdr.
+ */
+ kd_dump->kcore_hdr = (kcore_hdr_t *)
+ _kvm_malloc(kd_dump, sizeof(kcore_hdr_t));
+ if (kd_dump->kcore_hdr == NULL) {
+ if (kd_dump->cpu_hdr != NULL) {
+ free((void *)kd_dump->cpu_hdr);
+ kd_dump->cpu_hdr = NULL;
+ }
+ return (-1);
+ }
+
+ kd_dump->kcore_hdr->c_hdrsize = ALIGN(sizeof(kcore_hdr_t));
+ kd_dump->kcore_hdr->c_seghdrsize = ALIGN(sizeof(kcore_seg_t));
+ kd_dump->kcore_hdr->c_nseg = 2;
+ CORE_SETMAGIC(*(kd_dump->kcore_hdr), KCORE_MAGIC, MID_MACHINE,0);
+
+ /*
+ * If there is no cpu_hdr at this point, we probably have an
+ * old format crash dump.....bail out
+ */
+ if (kd_dump->cpu_hdr == NULL) {
+ free((void *)kd_dump->kcore_hdr);
+ kd_dump->kcore_hdr = NULL;
+ _kvm_err(kd_dump, kd_dump->program, "invalid dump");
+ }
+
+ kd_dump->dump_off = dump_off + hdr_size;
+
+ /*
+ * Now that we have a valid header, enable translations.
+ */
+ _kvm_initvtop(kd_dump);
+
+ return(hdr_size);
+}
+
+static int
+clear_gap(kd, fp, size)
+kvm_t *kd;
+FILE *fp;
+int size;
+{
+ if (size <= 0) /* XXX - < 0 should never happen */
+ return (0);
+ while (size-- > 0) {
+ if (fputc(0, fp) == EOF) {
+ _kvm_syserr(kd, kd->program, "clear_gap");
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+/*
+ * Write the dump header info to 'fp'. Note that we can't use fseek(3) here
+ * because 'fp' might be a file pointer obtained by zopen().
+ */
+int
+kvm_dump_wrtheader(kd, fp, dumpsize)
+kvm_t *kd;
+FILE *fp;
+int dumpsize;
+{
+ kcore_seg_t seghdr;
+ long offset;
+ int gap;
+
+ if (kd->kcore_hdr == NULL || kd->cpu_hdr == NULL) {
+ _kvm_err(kd, kd->program, "no valid dump header(s)");
+ return (-1);
+ }
+
+ /*
+ * Write the generic header
+ */
+ offset = 0;
+ if (fwrite((void*)kd->kcore_hdr, sizeof(kcore_hdr_t), 1, fp) <= 0) {
+ _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
+ return (-1);
+ }
+ offset += kd->kcore_hdr->c_hdrsize;
+ gap = kd->kcore_hdr->c_hdrsize - sizeof(kcore_hdr_t);
+ if (clear_gap(kd, fp, gap) == -1)
+ return (-1);
+
+ /*
+ * Write the cpu header
+ */
+ CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_CPU);
+ seghdr.c_size = ALIGN(sizeof(cpu_kcore_hdr_t));
+ if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) {
+ _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
+ return (-1);
+ }
+ offset += kd->kcore_hdr->c_seghdrsize;
+ gap = kd->kcore_hdr->c_seghdrsize - sizeof(seghdr);
+ if (clear_gap(kd, fp, gap) == -1)
+ return (-1);
+
+ if (fwrite((void*)kd->cpu_hdr, sizeof(cpu_kcore_hdr_t), 1, fp) <= 0) {
+ _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
+ return (-1);
+ }
+ offset += seghdr.c_size;
+ gap = seghdr.c_size - sizeof(cpu_kcore_hdr_t);
+ if (clear_gap(kd, fp, gap) == -1)
+ return (-1);
+
+ /*
+ * Write the actual dump data segment header
+ */
+ CORE_SETMAGIC(seghdr, KCORESEG_MAGIC, 0, CORE_DATA);
+ seghdr.c_size = dumpsize;
+ if (fwrite((void*)&seghdr, sizeof(seghdr), 1, fp) <= 0) {
+ _kvm_syserr(kd, kd->program, "kvm_dump_wrtheader");
+ return (-1);
+ }
+ offset += kd->kcore_hdr->c_seghdrsize;
+ gap = kd->kcore_hdr->c_seghdrsize - sizeof(seghdr);
+ if (clear_gap(kd, fp, gap) == -1)
+ return (-1);
+
+ return (offset);
+}
+
kvm_t *
kvm_openfiles(uf, mf, sf, flag, errout)
const char *uf;
error |= (kd->db->close)(kd->db);
if (kd->vmst)
_kvm_freevtop(kd);
+ if (kd->cpu_hdr != NULL)
+ free((void *)kd->cpu_hdr);
+ if (kd->kcore_hdr != NULL)
+ free((void *)kd->kcore_hdr);
if (kd->procbase != 0)
free((void *)kd->procbase);
if (kd->swapspc != 0)
}
rec.data = p->n_name;
rec.size = len;
+
+ /*
+ * Make sure that n_value = 0 when the symbol isn't found
+ */
+ p->n_value = 0;
+
if ((kd->db->get)(kd->db, (DBT *)&rec, (DBT *)&rec, 0))
continue;
if (rec.data == 0 || rec.size != sizeof(struct nlist))
return ((p - nl) - nvalid);
}
+int kvm_dump_inval(kd)
+kvm_t *kd;
+{
+ struct nlist nlist[2];
+ u_long pa;
+
+ if (ISALIVE(kd)) {
+ _kvm_err(kd, kd->program, "clearing dump on live kernel");
+ return (-1);
+ }
+ nlist[0].n_name = "_dumpmag";
+ nlist[1].n_name = NULL;
+
+ if (kvm_nlist(kd, nlist) == -1) {
+ _kvm_err(kd, 0, "bad namelist");
+ return (-1);
+ }
+ if (_kvm_kvatop(kd, (u_long)nlist[0].n_value, &pa) == 0)
+ return (-1);
+
+ errno = 0;
+ if (lseek(kd->pmfd, _kvm_pa2off(kd, pa), SEEK_SET) == -1
+ && errno != 0) {
+ _kvm_err(kd, 0, "cannot invalidate dump - lseek");
+ return (-1);
+ }
+ pa = 0;
+ if (write(kd->pmfd, &pa, sizeof(pa)) != sizeof(pa)) {
+ _kvm_err(kd, 0, "cannot invalidate dump - write");
+ return (-1);
+ }
+ return (0);
+}
+
ssize_t
kvm_read(kd, kva, buf, len)
kvm_t *kd;
* device and let the active kernel do the address translation.
*/
errno = 0;
- if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) {
+ if (lseek(kd->vmfd, (off_t)kva, SEEK_SET) == -1
+ && errno != 0) {
_kvm_err(kd, 0, "invalid address (%x)", kva);
return (0);
}
_kvm_err(kd, kd->program, "short read");
return (cc);
} else {
+ if ((kd->kcore_hdr == NULL) || (kd->cpu_hdr == NULL)) {
+ _kvm_err(kd, kd->program, "no valid dump header");
+ return (0);
+ }
cp = buf;
while (len > 0) {
- u_long pa;
+ u_long pa;
+ off_t foff;
cc = _kvm_kvatop(kd, kva, &pa);
if (cc == 0)
return (0);
if (cc > len)
cc = len;
+ foff = _kvm_pa2off(kd, pa);
errno = 0;
- if (lseek(kd->pmfd, (off_t)pa, 0) == -1 && errno != 0) {
+ if (lseek(kd->pmfd, foff, SEEK_SET) == -1
+ && errno != 0) {
_kvm_syserr(kd, 0, _PATH_MEM);
break;
}
* Just like kvm_read, only we write.
*/
errno = 0;
- if (lseek(kd->vmfd, (off_t)kva, 0) == -1 && errno != 0) {
+ if (lseek(kd->vmfd, (off_t)kva, SEEK_SET) == -1
+ && errno != 0) {
_kvm_err(kd, 0, "invalid address (%x)", kva);
return (0);
}
+/* $OpenBSD: kvm_i386.c,v 1.2 1996/03/19 23:15:23 niklas Exp $ */
+
/*-
* Copyright (c) 1989, 1992, 1993
* The Regents of the University of California. All rights reserved.
#if defined(LIBC_SCCS) && !defined(lint)
/* from: static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93"; */
-static char *rcsid = "$Id: kvm_i386.c,v 1.1.1.1 1995/10/18 08:42:44 deraadt Exp $";
+static char *rcsid = "$OpenBSD: kvm_i386.c,v 1.2 1996/03/19 23:15:23 niklas Exp $";
#endif /* LIBC_SCCS and not lint */
/*
#endif
struct vmstate {
- pd_entry_t **PTDpaddr;
pd_entry_t *PTD;
};
-#define KREAD(kd, addr, p)\
- (kvm_read(kd, addr, (char *)(p), sizeof(*(p))) != sizeof(*(p)))
-
void
_kvm_freevtop(kd)
kvm_t *kd;
{
struct vmstate *vm;
struct nlist nlist[2];
- pt_entry_t *tmpPTD;
+ u_long pa;
vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
if (vm == 0)
return (-1);
}
- vm->PTDpaddr = 0;
vm->PTD = 0;
- if (KREAD(kd, (u_long)nlist[0].n_value - KERNBASE, &vm->PTDpaddr)) {
- _kvm_err(kd, kd->program, "cannot read PTDpaddr");
- return (-1);
+
+ if (lseek(kd->pmfd, (off_t)(nlist[0].n_value - KERNBASE), 0) == -1 &&
+ errno != 0) {
+ _kvm_syserr(kd, kd->program, "kvm_lseek");
+ goto invalid;
+ }
+ if (read(kd->pmfd, &pa, sizeof pa) != sizeof pa) {
+ _kvm_syserr(kd, kd->program, "kvm_read");
+ goto invalid;
}
- tmpPTD = (pd_entry_t *)_kvm_malloc(kd, NBPG);
- if ((kvm_read(kd, (u_long)vm->PTDpaddr, tmpPTD, NBPG)) != NBPG) {
- free(tmpPTD);
- _kvm_err(kd, kd->program, "cannot read PTD");
- return (-1);
+ vm->PTD = (pd_entry_t *)_kvm_malloc(kd, NBPG);
+
+ if (lseek(kd->pmfd, (off_t)pa, 0) == -1 && errno != 0) {
+ _kvm_syserr(kd, kd->program, "kvm_lseek");
+ goto invalid;
+ }
+ if (read(kd->pmfd, vm->PTD, NBPG) != NBPG) {
+ _kvm_syserr(kd, kd->program, "kvm_read");
+ goto invalid;
}
- vm->PTD = tmpPTD;
+
return (0);
+
+invalid:
+ if (vm->PTD != 0)
+ free(vm->PTD);
+ return (-1);
}
/*
/* XXX READ PHYSICAL XXX */
{
if (lseek(kd->pmfd, (off_t)pte_pa, 0) == -1 && errno != 0) {
- _kvm_syserr(kd, 0, "kvm_lseek");
+ _kvm_syserr(kd, kd->program, "kvm_lseek");
goto invalid;
}
if (read(kd->pmfd, &pte, sizeof pte) != sizeof pte) {
+/* $OpenBSD: kvm_m68k.c,v 1.2 1996/03/19 23:15:24 niklas Exp $ */
+
/*-
* Copyright (c) 1989, 1992, 1993
* The Regents of the University of California. All rights reserved.
#if defined(LIBC_SCCS) && !defined(lint)
/* from: static char sccsid[] = "@(#)kvm_hp300.c 8.1 (Berkeley) 6/4/93"; */
-static char *rcsid = "$Id: kvm_m68k.c,v 1.1.1.1 1995/10/18 08:42:44 deraadt Exp $";
+static char *rcsid = "$OpenBSD: kvm_m68k.c,v 1.2 1996/03/19 23:15:24 niklas Exp $";
#endif /* LIBC_SCCS and not lint */
/*
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/stat.h>
+
+#include <sys/core.h>
+#include <sys/exec_aout.h>
+#include <sys/kcore.h>
+
#include <unistd.h>
+#include <limits.h>
#include <nlist.h>
#include <kvm.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
-#include <limits.h>
#include <db.h>
#include "kvm_private.h"
#include <machine/pte.h>
+#include <machine/kcore.h>
#ifndef btop
#define btop(x) (((unsigned)(x)) >> PGSHIFT) /* XXX */
#define ptob(x) ((caddr_t)((x) << PGSHIFT)) /* XXX */
#endif
-struct vmstate {
- u_long lowram;
- int mmutype;
- st_entry_t *Sysseg;
-};
-
#define KREAD(kd, addr, p)\
(kvm_read(kd, addr, (char *)(p), sizeof(*(p))) != sizeof(*(p)))
_kvm_initvtop(kd)
kvm_t *kd;
{
- struct vmstate *vm;
- struct nlist nlist[4];
-
- vm = (struct vmstate *)_kvm_malloc(kd, sizeof(*vm));
- if (vm == 0)
- return (-1);
- kd->vmst = vm;
-
- nlist[0].n_name = "_lowram";
- nlist[1].n_name = "_mmutype";
- nlist[2].n_name = "_Sysseg";
- nlist[3].n_name = 0;
-
- if (kvm_nlist(kd, nlist) != 0) {
- _kvm_err(kd, kd->program, "bad namelist");
- return (-1);
- }
- vm->Sysseg = 0;
- if (KREAD(kd, (u_long)nlist[0].n_value, &vm->lowram)) {
- _kvm_err(kd, kd->program, "cannot read lowram");
- return (-1);
- }
- if (KREAD(kd, (u_long)nlist[1].n_value, &vm->mmutype)) {
- _kvm_err(kd, kd->program, "cannot read mmutype");
- return (-1);
- }
- if (KREAD(kd, (u_long)nlist[2].n_value, &vm->Sysseg)) {
- _kvm_err(kd, kd->program, "cannot read segment table");
- return (-1);
- }
return (0);
}
u_long va;
u_long *pa;
{
- register struct vmstate *vm;
- register u_long lowram;
+ register cpu_kcore_hdr_t *cpu_kh;
register u_long addr;
int p, ste, pte;
int offset;
_kvm_err(kd, 0, "vatop called in live kernel!");
return((off_t)0);
}
- vm = kd->vmst;
offset = va & PGOFSET;
+ cpu_kh = kd->cpu_hdr;
/*
* If we are initializing (kernel segment table pointer not yet set)
* then return pa == va to avoid infinite recursion.
*/
- if (vm->Sysseg == 0) {
- *pa = va;
+ if (cpu_kh->sysseg_pa == 0) {
+ *pa = va + cpu_kh->kernel_pa;
return (NBPG - offset);
}
- lowram = vm->lowram;
- if (vm->mmutype == -2) {
+ if (cpu_kh->mmutype == -2) {
st_entry_t *sta2;
addr = (u_long)&sta[va >> SG4_SHIFT1];
* Can't use KREAD to read kernel segment table entries.
* Fortunately it is 1-to-1 mapped so we don't have to.
*/
- if (sta == vm->Sysseg) {
- if (lseek(kd->pmfd, (off_t)addr, 0) == -1 ||
+ if (sta == cpu_kh->sysseg_pa) {
+ if (lseek(kd->pmfd, _kvm_pa2off(kd, addr), 0) == -1 ||
read(kd->pmfd, (char *)&ste, sizeof(ste)) < 0)
goto invalid;
} else if (KREAD(kd, addr, &ste))
* Address from level 1 STE is a physical address,
* so don't use kvm_read.
*/
- if (lseek(kd->pmfd, (off_t)(addr - lowram), 0) == -1 ||
+ if (lseek(kd->pmfd, _kvm_pa2off(kd, addr), 0) == -1 ||
read(kd->pmfd, (char *)&ste, sizeof(ste)) < 0)
goto invalid;
if ((ste & SG_V) == 0) {
* Can't use KREAD to read kernel segment table entries.
* Fortunately it is 1-to-1 mapped so we don't have to.
*/
- if (sta == vm->Sysseg) {
- if (lseek(kd->pmfd, (off_t)addr, 0) == -1 ||
+ if (sta == cpu_kh->sysseg_pa) {
+ if (lseek(kd->pmfd, _kvm_pa2off(kd, addr), 0) == -1 ||
read(kd->pmfd, (char *)&ste, sizeof(ste)) < 0)
goto invalid;
} else if (KREAD(kd, addr, &ste))
/*
* Address from STE is a physical address so don't use kvm_read.
*/
- if (lseek(kd->pmfd, (off_t)(addr - lowram), 0) == -1 ||
+ if (lseek(kd->pmfd, _kvm_pa2off(kd, addr), 0) == -1 ||
read(kd->pmfd, (char *)&pte, sizeof(pte)) < 0)
goto invalid;
addr = pte & PG_FRAME;
_kvm_err(kd, 0, "page not valid");
return (0);
}
- *pa = addr - lowram + offset;
+ *pa = addr + offset;
return (NBPG - offset);
invalid:
u_long va;
u_long *pa;
{
- return (_kvm_vatop(kd, (u_long)kd->vmst->Sysseg, va, pa));
+ return (_kvm_vatop(kd, (u_long)kd->cpu_hdr->sysseg_pa, va, pa));
}
+/* $OpenBSD: kvm_private.h,v 1.2 1996/03/19 23:15:25 niklas Exp $ */
+
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
int arglen; /* length of the above */
char **argv; /* (dynamic) storage for argv pointers */
int argc; /* length of above (not actual # present) */
+
+ /*
+ * Header structures for kernel dumps. Only gets filled in for
+ * dead kernels.
+ */
+ struct kcore_hdr *kcore_hdr;
+ struct cpu_kcore_hdr *cpu_hdr;
+ off_t dump_off; /* Where the actual dump starts */
+
/*
* Kernel virtual address translation state. This only gets filled
* in for dead kernels; otherwise, the running kernel (i.e. kmem)
* will do the translations for us. It could be big, so we
* only allocate it if necessary.
*/
- struct vmstate *vmst;
+ struct vmstate *vmst; /* XXX: should become obsoleted */
/*
* These kernel variables are used for looking up user addresses,
* and are cached for efficiency.
* Functions used internally by kvm, but across kvm modules.
*/
void _kvm_err __P((kvm_t *kd, const char *program, const char *fmt, ...));
+int _kvm_dump_mkheader __P((kvm_t *kd_live, kvm_t *kd_dump));
void _kvm_freeprocs __P((kvm_t *kd));
void _kvm_freevtop __P((kvm_t *));
int _kvm_initvtop __P((kvm_t *));
int _kvm_kvatop __P((kvm_t *, u_long, u_long *));
void *_kvm_malloc __P((kvm_t *kd, size_t));
+off_t _kvm_pa2off __P((kvm_t *, u_long));
void *_kvm_realloc __P((kvm_t *kd, void *, size_t));
void _kvm_syserr
__P((kvm_t *kd, const char *program, const char *fmt, ...));
# from: @(#)Makefile 8.2 (Berkeley) 12/15/93
-# $Id: Makefile,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $
+# $OpenBSD: Makefile,v 1.2 1996/03/19 23:15:46 niklas Exp $
+# $NetBSD: Makefile,v 1.6 1996/02/24 01:15:15 jtk Exp $
LIB= telnet
SRCS= auth.c encrypt.c genget.c getent.c misc.c
* SUCH DAMAGE.
*
* from: @(#)auth-proto.h 8.1 (Berkeley) 6/4/93
- * $Id: auth-proto.h,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $
+ * $OpenBSD: auth-proto.h,v 1.2 1996/03/19 23:15:47 niklas Exp $
+ * $NetBSD: auth-proto.h,v 1.5 1996/02/24 01:15:16 jtk Exp $
*/
/*
+/* $OpenBSD: auth.c,v 1.2 1996/03/19 23:15:48 niklas Exp $ */
+
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*/
#ifndef lint
-/* from: static char sccsid[] = "@(#)auth.c 8.1 (Berkeley) 6/4/93"; */
-static char *rcsid = "$Id: auth.c,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $";
+/* from: static char sccsid[] = "@(#)auth.c 8.3 (Berkeley) 5/30/95" */
+/* from: static char *rcsid = "$NetBSD: auth.c,v 1.5 1996/02/24 01:15:17 jtk Exp $"; */
+static char *rcsid = "$OpenBSD: auth.c,v 1.2 1996/03/19 23:15:48 niklas Exp $";
#endif /* not lint */
/*
Name,
ap->type, ap->way);
}
+ else if (auth_debug_mode)
+ printf(">>>%s: Init failed: auth type %d %d\r\n",
+ Name, ap->type, ap->way);
++ap;
}
}
{
register int x;
- if (strcasecmp(type, AUTHTYPE_NAME(0))) {
+ if (!strcasecmp(type, AUTHTYPE_NAME(0))) {
*maskp = -1;
return(1);
}
char *type;
int on;
{
- int mask = -1;
+ int i, mask = -1;
Authenticator *ap;
if (!strcasecmp(type, "?") || !strcasecmp(type, "help")) {
- printf("auth %s 'type'\n", on ? "enable" : "disable");
+ printf("auth %s 'type'\n", on ? "enable" : "disable");
printf("Where 'type' is one of:\n");
printf("\t%s\n", AUTHTYPE_NAME(0));
- for (ap = authenticators; ap->type; ap++)
+ mask = 0;
+ for (ap = authenticators; ap->type; ap++) {
+ if ((mask & (i = typemask(ap->type))) != 0)
+ continue;
+ mask |= i;
printf("\t%s\n", AUTHTYPE_NAME(ap->type));
+ }
return(0);
}
printf("%s: invalid authentication type\n", type);
return(0);
}
- mask = getauthmask(type, &mask);
if (on)
i_wont_support &= ~mask;
else
auth_status()
{
Authenticator *ap;
+ int i, mask;
if (i_wont_support == -1)
printf("Authentication disabled\n");
else
printf("Authentication enabled\n");
- for (ap = authenticators; ap->type; ap++)
+ mask = 0;
+ for (ap = authenticators; ap->type; ap++) {
+ if ((mask & (i = typemask(ap->type))) != 0)
+ continue;
+ mask |= i;
printf("%s: %s\n", AUTHTYPE_NAME(ap->type),
(i_wont_support & typemask(ap->type)) ?
"disabled" : "enabled");
+ }
return(1);
}
auth_send_cnt = cnt > sizeof(_auth_send_data)
? sizeof(_auth_send_data)
: cnt;
- bcopy((void *)data, (void *)_auth_send_data, auth_send_cnt);
+ memmove((void *)_auth_send_data, (void *)data, auth_send_cnt);
auth_send_data = _auth_send_data;
} else {
/*
* We requested strong authentication, however no mechanisms worked.
* Therefore, exit on client end.
*/
- printf("Unable to securely authenticate user ... exit\n");
+ printf("Unable to securely authenticate user ... exit\n");
exit(0);
#endif /* KANNAN */
}
Name, cnt, sizeof(savename)-1);
return;
}
- bcopy((void *)data, (void *)savename, cnt);
+ memmove((void *)savename, (void *)data, cnt);
savename[cnt] = '\0'; /* Null terminate */
if (auth_debug_mode)
printf(">>>%s: Got NAME [%s]\r\n", Name, savename);
* SUCH DAMAGE.
*
* from: @(#)auth.h 8.1 (Berkeley) 6/4/93
- * $Id: auth.h,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $
+ * $OpenBSD: auth.h,v 1.2 1996/03/19 23:15:49 niklas Exp $
+ * $NetBSD: auth.h,v 1.5 1996/02/24 01:15:18 jtk Exp $
*/
/*
*/
#ifndef lint
-/* from: static char sccsid[] = "@(#)encrypt.c 8.1 (Berkeley) 6/4/93"; */
-static char *rcsid = "$Id: encrypt.c,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $";
+/* from: static char sccsid[] = "@(#)encrypt.c 8.2 (Berkeley) 5/30/95"; */
+/* from: static char rcsid[] = "$NetBSD: encrypt.c,v 1.4 1996/02/24 01:15:19 jtk Exp $"; */
+static char rcsid[] = "$OpenBSD: encrypt.c,v 1.2 1996/03/19 23:15:50 niklas Exp $";
#endif /* not lint */
/*
* SUCH DAMAGE.
*
* from: @(#)encrypt.h 8.1 (Berkeley) 6/4/93
- * $Id: encrypt.h,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $
+ * $OpenBSD: encrypt.h,v 1.2 1996/03/19 23:15:51 niklas Exp $
+ * $NetBSD: encrypt.h,v 1.4 1996/02/24 01:15:20 jtk Exp $
*/
/*
+/* $OpenBSD: genget.c,v 1.2 1996/03/19 23:15:52 niklas Exp $ */
+
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*/
#ifndef lint
-/* from: static char sccsid[] = "@(#)genget.c 8.1 (Berkeley) 6/4/93"; */
-static char *rcsid = "$Id: genget.c,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $";
+/* from: static char sccsid[] = "@(#)genget.c 8.2 (Berkeley) 5/30/95"; */
+/* from: static char *rcsid = "$NetBSD: genget.c,v 1.5 1996/02/24 01:15:21 jtk Exp $"; */
+static char *rcsid = "$OpenBSD: genget.c,v 1.2 1996/03/19 23:15:52 niklas Exp $";
#endif /* not lint */
+
#include <ctype.h>
#include "misc-proto.h"
isprefix(s1, s2)
register char *s1, *s2;
{
+ register int n = 0;
char *os1;
register char c1, c2;
- if (*s1 == '\0')
- return(-1);
- os1 = s1;
+ if (*s1 == '\0')
+ return(-1);
+ os1 = s1;
c1 = *s1;
c2 = *s2;
- while (LOWER(c1) == LOWER(c2)) {
+ while (LOWER(c1) == LOWER(c2)) {
if (c1 == '\0')
break;
- c1 = *++s1;
- c2 = *++s2;
- }
- return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1)));
+ c1 = *++s1;
+ c2 = *++s2;
+ }
+ return(*s1 ? 0 : (*s2 ? (s1 - os1) : (os1 - s1)));
}
static char *ambiguous; /* special return value for command routines */
*/
#ifndef lint
-/* from: static char sccsid[] = "@(#)getent.c 8.1 (Berkeley) 6/4/93"; */
-static char *rcsid = "$Id: getent.c,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $";
+/* from: static char sccsid[] = "@(#)getent.c 8.2 (Berkeley) 12/15/93"; */
+/* from: static char *rcsid = "$NetBSD: getent.c,v 1.5 1996/02/24 01:15:22 jtk Exp $"; */
+static char *rcsid = "$OpenBSD: getent.c,v 1.2 1996/03/19 23:15:53 niklas Exp $";
#endif /* not lint */
#include <stdlib.h>
* SUCH DAMAGE.
*
* from: @(#)misc-proto.h 8.1 (Berkeley) 6/4/93
- * $Id: misc-proto.h,v 1.1.1.1 1995/10/18 08:43:11 deraadt Exp $
+ * $OpenBSD: misc-proto.h,v 1.2 1996/03/19 23:15:54 niklas Exp $
+ * $NetBSD: misc-proto.h,v 1.5 1996/02/24 01:15:23 jtk Exp $
*/
/*
#ifndef lint
/* from: static char sccsid[] = "@(#)misc.c 8.1 (Berkeley) 6/4/93"; */
-static char *rcsid = "$Id: misc.c,v 1.1.1.1 1995/10/18 08:43:12 deraadt Exp $";
+/* from: static char rcsid[] = "$NetBSD: misc.c,v 1.5 1996/02/24 01:15:25 jtk Exp $"; */
+static char rcsid[] = "$OpenBSD: misc.c,v 1.2 1996/03/19 23:15:55 niklas Exp $";
#endif /* not lint */
#include <stdio.h>
* SUCH DAMAGE.
*
* from: @(#)misc.h 8.1 (Berkeley) 6/4/93
- * $Id: misc.h,v 1.1.1.1 1995/10/18 08:43:12 deraadt Exp $
+ * $OpenBSD: misc.h,v 1.2 1996/03/19 23:15:56 niklas Exp $
+ * $NetBSD: misc.h,v 1.4 1996/02/24 01:15:27 jtk Exp $
*/
extern char *UserNameRequested;