[BACK]Return to ksyms.c CVS log [TXT][DIR] Up to [local] / sys / dev

Annotation of sys/dev/ksyms.c, Revision 1.1.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