Annotation of sys/dev/ksyms.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ksyms.c,v 1.17 2006/07/12 18:09:24 martin Exp $ */
! 2: /*
! 3: * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
! 4: * Copyright (c) 2001 Artur Grabowski <art@openbsd.org>
! 5: * All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: *
! 16: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
! 17: * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
! 18: * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
! 19: * THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! 20: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! 21: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
! 22: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
! 23: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
! 24: * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
! 25: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 26: */
! 27:
! 28: #include <sys/param.h>
! 29: #include <sys/buf.h>
! 30: #include <sys/exec.h>
! 31: #include <sys/systm.h>
! 32: #include <sys/uio.h>
! 33: #include <sys/malloc.h>
! 34: #include <sys/fcntl.h>
! 35: #include <sys/conf.h>
! 36:
! 37: #include <uvm/uvm_extern.h>
! 38:
! 39: #ifdef _NLIST_DO_ELF
! 40: #include <sys/exec_elf.h>
! 41: #endif
! 42:
! 43: #include <machine/cpu.h>
! 44:
! 45: extern char *esym; /* end of symbol table */
! 46: #if defined(__sparc64__) || defined(__mips__)
! 47: extern char *ssym; /* end of kernel */
! 48: #else
! 49: extern long end; /* end of kernel */
! 50: #endif
! 51:
! 52: static caddr_t ksym_head;
! 53: static caddr_t ksym_syms;
! 54: static size_t ksym_head_size;
! 55: static size_t ksym_syms_size;
! 56:
! 57: void ksymsattach(int);
! 58:
! 59: /*
! 60: * We assume __LDPGSZ is a multiple of PAGE_SIZE (it is)
! 61: */
! 62:
! 63: /*ARGSUSED*/
! 64: void
! 65: ksymsattach(num)
! 66: int num;
! 67: {
! 68:
! 69: #if defined(__sparc64__) || defined(__mips__)
! 70: if (esym <= ssym) {
! 71: printf("/dev/ksyms: Symbol table not valid.\n");
! 72: return;
! 73: }
! 74: #else
! 75: if (esym <= (char *)&end) {
! 76: printf("/dev/ksyms: Symbol table not valid.\n");
! 77: return;
! 78: }
! 79: #endif
! 80:
! 81: #ifdef _NLIST_DO_ELF
! 82: do {
! 83: #if defined(__sparc64__) || defined(__mips__)
! 84: caddr_t symtab = ssym;
! 85: #else
! 86: caddr_t symtab = (caddr_t)&end;
! 87: #endif
! 88: Elf_Ehdr *elf;
! 89: Elf_Shdr *shdr;
! 90: int i;
! 91:
! 92: elf = (Elf_Ehdr *)symtab;
! 93: if (memcmp(elf->e_ident, ELFMAG, SELFMAG) != 0 ||
! 94: elf->e_ident[EI_CLASS] != ELFCLASS ||
! 95: elf->e_machine != ELF_TARG_MACH)
! 96: break;
! 97:
! 98: shdr = (Elf_Shdr *)&symtab[elf->e_shoff];
! 99: for (i = 0; i < elf->e_shnum; i++) {
! 100: if (shdr[i].sh_type == SHT_SYMTAB) {
! 101: break;
! 102: }
! 103: }
! 104:
! 105: /*
! 106: * No symbol table found.
! 107: */
! 108: if (i == elf->e_shnum)
! 109: break;
! 110:
! 111: /*
! 112: * No additional header.
! 113: */
! 114: ksym_head_size = 0;
! 115: ksym_syms = symtab;
! 116: ksym_syms_size = (size_t)(esym - symtab);
! 117:
! 118: return;
! 119: } while (0);
! 120: #endif
! 121:
! 122: #ifdef _NLIST_DO_AOUT
! 123: {
! 124: /*
! 125: * a.out header.
! 126: * Fake up a struct exec.
! 127: * We only fill in the following non-zero entries:
! 128: * a_text - fake text segment (struct exec only)
! 129: * a_syms - size of symbol table
! 130: */
! 131: caddr_t symtab = (char *)(&end + 1);
! 132: struct exec *k1;
! 133:
! 134: ksym_head_size = __LDPGSZ;
! 135: ksym_head = malloc(ksym_head_size, M_DEVBUF, M_NOWAIT);
! 136: if (ksym_head == NULL) {
! 137: printf("failed to allocate memory for /dev/ksyms\n");
! 138: return;
! 139: }
! 140: bzero(ksym_head, ksym_head_size);
! 141:
! 142: k1 = (struct exec *)ksym_head;
! 143:
! 144: N_SETMAGIC(*k1, ZMAGIC, MID_MACHINE, 0);
! 145: k1->a_text = __LDPGSZ;
! 146: k1->a_syms = end;
! 147:
! 148: ksym_syms = symtab;
! 149: ksym_syms_size = (size_t)(esym - symtab);
! 150: }
! 151: #endif
! 152: }
! 153:
! 154: /*ARGSUSED*/
! 155: int
! 156: ksymsopen(dev, flag, mode, p)
! 157: dev_t dev;
! 158: int flag, mode;
! 159: struct proc *p;
! 160: {
! 161:
! 162: /* There are no non-zero minor devices */
! 163: if (minor(dev) != 0)
! 164: return (ENXIO);
! 165:
! 166: /* This device is read-only */
! 167: if ((flag & FWRITE))
! 168: return (EPERM);
! 169:
! 170: /* ksym_syms must be initialized */
! 171: if (ksym_syms == NULL)
! 172: return (ENXIO);
! 173:
! 174: return (0);
! 175: }
! 176:
! 177: /*ARGSUSED*/
! 178: int
! 179: ksymsclose(dev, flag, mode, p)
! 180: dev_t dev;
! 181: int flag, mode;
! 182: struct proc *p;
! 183: {
! 184:
! 185: return (0);
! 186: }
! 187:
! 188: /*ARGSUSED*/
! 189: int
! 190: ksymsread(dev, uio, flags)
! 191: dev_t dev;
! 192: struct uio *uio;
! 193: int flags;
! 194: {
! 195: int error;
! 196: size_t len;
! 197: caddr_t v;
! 198: size_t off;
! 199:
! 200: while (uio->uio_resid > 0) {
! 201: if (uio->uio_offset >= ksym_head_size + ksym_syms_size)
! 202: break;
! 203:
! 204: if (uio->uio_offset < ksym_head_size) {
! 205: v = ksym_head + uio->uio_offset;
! 206: len = ksym_head_size - uio->uio_offset;
! 207: } else {
! 208: off = uio->uio_offset - ksym_head_size;
! 209: v = ksym_syms + off;
! 210: len = ksym_syms_size - off;
! 211: }
! 212:
! 213: if (len > uio->uio_resid)
! 214: len = uio->uio_resid;
! 215:
! 216: if ((error = uiomove(v, len, uio)) != 0)
! 217: return (error);
! 218: }
! 219:
! 220: return (0);
! 221: }
! 222:
! 223: /* XXX - not yet */
! 224: #if 0
! 225: paddr_t
! 226: ksymsmmap(dev, off, prot)
! 227: dev_t dev;
! 228: off_t off;
! 229: int prot;
! 230: {
! 231: vaddr_t va;
! 232: paddr_t pa;
! 233:
! 234: if (off < 0)
! 235: return (-1);
! 236: if (off >= ksym_head_size + ksym_syms_size)
! 237: return (-1);
! 238:
! 239: if ((vaddr_t)off < ksym_head_size) {
! 240: va = (vaddr_t)ksym_head + off;
! 241: } else {
! 242: va = (vaddr_t)ksym_syms + off;
! 243: }
! 244:
! 245: if (pmap_extract(pmap_kernel, va, &pa) == FALSE)
! 246: panic("ksymsmmap: unmapped page");
! 247:
! 248: return atop(pa);
! 249: }
! 250: #endif
CVSweb