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