File: [local] / src / sys / dev / ksyms.c (download)
Revision 1.5, Fri Nov 26 16:41:17 1999 UTC (24 years, 6 months ago) by art
Branch: MAIN
CVS Tags: kame_19991208, SMP_BASE, OPENBSD_2_8_BASE, OPENBSD_2_8, OPENBSD_2_7_BASE, OPENBSD_2_7 Branch point for: SMP
Changes since 1.4: +1 -1 lines
Another comment change. (NBPG -> PAGE_SIZE).
|
/*
* 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 segment (struct exec only)
* a_syms - size of symbol table
*
* We assume __LDPGSZ is a multiple of PAGE_SIZE (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 vaddr_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 >= (vaddr_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 + (vaddr_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 + (vaddr_t)symtab;
c = min(iov->iov_len, MAXPHYS);
/* Don't read past esym, truncate. */
if (v + c > (vaddr_t)esym)
c = (vaddr_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) ((vaddr_t)(x) >> PGSHIFT
if (off < 0)
return (-1);
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