diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 1998-08-24 05:26:51 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 1998-08-24 05:26:51 +0000 |
commit | 697c2bb43d8cf4e8dd706da625f5c5b250b4665d (patch) | |
tree | 0d592beb3eb7c0b9d6eeaa1189fa78139c1c6c64 | |
parent | 841002a2ec34dfdbd33b08b99bebc82a90259d2f (diff) |
/dev/ksyms; kernel symbols pseudo-device that masquerades as an a.out binary for ports that copy the symbol table to the end of kernel space (all that use DDB do this)
-rw-r--r-- | sys/conf/files | 9 | ||||
-rw-r--r-- | sys/dev/ksyms.c | 187 | ||||
-rw-r--r-- | sys/sys/conf.h | 10 |
3 files changed, 204 insertions, 2 deletions
diff --git a/sys/conf/files b/sys/conf/files index 8a483245d8b..b4b3c4f8036 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.80 1998/07/10 19:56:55 mickey Exp $ +# $OpenBSD: files,v 1.81 1998/08/24 05:26:50 millert Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -56,6 +56,10 @@ file dev/ic/isp.c isp device uha: scsi file dev/ic/uha.c uha +# National Semiconductor DP8390 Ethernet controller +device ed: ether, ifnet +file dev/ic/dp8390.c ed + # 3Com Etherlink-III Ethernet controller device ep: ether, ifnet file dev/ic/elink3.c ep @@ -109,6 +113,9 @@ pseudo-device strip: ifnet pseudo-device random pseudo-device enc: ifnet +pseudo-device ksyms +file dev/ksyms.c ksyms needs-flag + # XXX machine-independent SCSI files should live somewhere here, maybe # kernel sources diff --git a/sys/dev/ksyms.c b/sys/dev/ksyms.c new file mode 100644 index 00000000000..61792499b2a --- /dev/null +++ b/sys/dev/ksyms.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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. + */ + +/* + * kernel symbols special file (masquerades as a ZMAGIC a.out file) + * + * TODO: get boot loaders to put symbols on a page boundary so we + * can mmap them too (also requires minor change to db_aout.c). + */ + +#include <sys/param.h> +#include <sys/buf.h> +#include <sys/exec.h> +#include <sys/systm.h> +#include <sys/uio.h> +#include <sys/malloc.h> +#include <sys/fcntl.h> + +#include <machine/cpu.h> + +#include <vm/vm.h> + +extern char *esym; /* end of symbol table */ +extern long end; /* end of kernel */ + +static struct exec *k1; /* first page of /dev/ksyms */ +static caddr_t symtab = (caddr_t)(&end + 1); /* start of symbol table */ + +void ksymsattach __P((int)); +int ksymsopen __P((dev_t, int, int)); +int ksymsclose __P((dev_t, int, int)); +int ksymsread __P((dev_t, struct uio *, int)); + +/*ARGSUSED*/ +void +ksymsattach(num) + int num; +{ + + if (esym > (char *)&end) { + /* + * If we have a symbol table, fake up a struct exec. + * We only fill in the following non-zero entries: + * a_text - fake text sement (struct exec only) + * a_syms - size of symbol table + * + * We assume __LDPGSZ is a multiple of NBPG (it is) + */ + k1 = (struct exec *)malloc(__LDPGSZ, M_TEMP, M_WAITOK); + bzero(k1, __LDPGSZ); + N_SETMAGIC(*k1, ZMAGIC, MID_MACHINE, 0); + k1->a_text = __LDPGSZ; + k1->a_syms = end; + } + return; +} + +/*ARGSUSED*/ +int +ksymsopen(dev, flag, mode) + dev_t dev; + int flag, mode; +{ + + /* There are no non-zero minor devices */ + if (minor(dev) != 0) + return (ENXIO); + + /* This device is read-only */ + if ((flag & FWRITE)) + return (EPERM); + + /* Must have symbols at the end of the kernel to work */ + if (esym <= (char *)&end) + return (ENXIO); + + return (0); +} + +/*ARGSUSED*/ +int +ksymsclose(dev, flag, mode) + dev_t dev; + int flag, mode; +{ + + return (0); +} + +/*ARGSUSED*/ +int +ksymsread(dev, uio, flags) + dev_t dev; + struct uio *uio; + int flags; +{ + register vm_offset_t v; + register size_t c, len; + int error = 0; + +#define iov (uio->uio_iov) + while (uio->uio_resid > 0 && error == 0) { + /* Done with this iov? Fill the next one... */ + if (iov->iov_len == 0) { + uio->uio_iov++; + uio->uio_iovcnt--; + if (uio->uio_iovcnt < 0) + panic("ksymread"); + } + + /* Can't read past size of symbol table... */ + if (uio->uio_offset >= (vm_offset_t)(esym - symtab) + + k1->a_text) + break; + + if (uio->uio_offset < k1->a_text) { + /* + * If they asked for more that a_text, + * read the part of k1 first, then the + * part of symtab next time throug the loop. + */ + if (iov->iov_len + (size_t)uio->uio_offset > + k1->a_text) + len = k1->a_text; + else + len = iov->iov_len; + + /* Make offset relative to struct exec */ + v = uio->uio_offset + (vm_offset_t)k1; + c = min(len, MAXPHYS); + error = uiomove((caddr_t)v, c, uio); + } else { + /* Make offset relative to symtab */ + v = uio->uio_offset - k1->a_text + + (vm_offset_t)symtab; + c = min(iov->iov_len, MAXPHYS); + + /* Don't read past esym, truncate. */ + if (v + c > (vm_offset_t)esym) + c = (vm_offset_t)esym - v; + error = uiomove((caddr_t)v, c, uio); + } + } + return (error); +} + +/* XXX - can't do mmap until boot loaders make the symbol table page aligned */ +#if 0 +int +ksymsmmap(dev, off, prot) + dev_t dev; + int off, prot; +{ +#define ksyms_btop(x) ((vm_offset_t)(x) >> PGSHIFT + if ((unsigned)off >= (unsigned)(esym - symtab) + k1->a_text) + return (-1); + + if ((unsigned)off < k1->a_text) + return (ksyms_btop(off + (unsigned)k1)); + else + return (ksyms_btop(off + (unsigned)symtab - k1->a_text)); +} +#endif diff --git a/sys/sys/conf.h b/sys/sys/conf.h index ab0eec54ce9..c3d3d60bb0b 100644 --- a/sys/sys/conf.h +++ b/sys/sys/conf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.h,v 1.25 1998/04/26 21:03:18 provos Exp $ */ +/* $OpenBSD: conf.h,v 1.26 1998/08/24 05:26:49 millert Exp $ */ /* $NetBSD: conf.h,v 1.33 1996/05/03 20:03:32 christos Exp $ */ /*- @@ -188,6 +188,7 @@ extern struct cdevsw cdevsw[]; dev_init(c,n,write), dev_init(c,n,ioctl), (dev_type_stop((*))) enodev, \ 0, seltrue, (dev_type_mmap((*))) enodev, D_TAPE } +/* open, close, read, ioctl */ #define cdev_scanner_init(c,n) { \ dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ (dev_type_write((*))) enodev, dev_init(c,n,ioctl), \ @@ -332,6 +333,13 @@ extern struct cdevsw cdevsw[]; (dev_type_stop((*))) enodev, 0, (dev_type_select((*))) enodev, \ (dev_type_mmap((*))) enodev } +/* open, close, read */ +#define cdev_ksyms_init(c,n) { \ + dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ + (dev_type_write((*))) enodev, (dev_type_ioctl((*))) enodev, \ + (dev_type_stop((*))) enodev, 0, seltrue, \ + (dev_type_mmap((*))) enodev, 0 } + /* open, close, read, write, ioctl, select */ #define cdev_random_init(c,n) { \ dev_init(c,n,open), dev_init(c,n,close), dev_init(c,n,read), \ |