]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/ddb/db_aout.c
This is the Linux generic soundcard driver, version 1.0c. Supports
[FreeBSD/FreeBSD.git] / sys / ddb / db_aout.c
1 /* 
2  * Mach Operating System
3  * Copyright (c) 1991,1990 Carnegie Mellon University
4  * All Rights Reserved.
5  * 
6  * Permission to use, copy, modify and distribute this software and its
7  * documentation is hereby granted, provided that both the copyright
8  * notice and this permission notice appear in all copies of the
9  * software, derivative works or modified versions, and any portions
10  * thereof, and that both notices appear in supporting documentation.
11  * 
12  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS 
13  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15  * 
16  * Carnegie Mellon requests users of this software to return to
17  * 
18  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
19  *  School of Computer Science
20  *  Carnegie Mellon University
21  *  Pittsburgh PA 15213-3890
22  * 
23  * any improvements or extensions that they make and grant Carnegie the
24  * rights to redistribute these changes.
25  *
26  *      $Id$
27  */
28
29 /*
30  *      Author: David B. Golub, Carnegie Mellon University
31  *      Date:   7/90
32  */
33 /*
34  * Symbol table routines for a.out format files.
35  */
36
37 #include "param.h"
38 #include "proc.h"
39 #include <machine/db_machdep.h>         /* data types */
40 #include <ddb/db_sym.h>
41
42 #ifndef DB_NO_AOUT
43
44 #define _AOUT_INCLUDE_
45 #include "nlist.h"
46
47 /*
48  * An a.out symbol table as loaded into the kernel debugger:
49  *
50  * symtab       -> size of symbol entries, in bytes
51  * sp           -> first symbol entry
52  *                 ...
53  * ep           -> last symbol entry + 1
54  * strtab       == start of string table
55  *                 size of string table in bytes,
56  *                 including this word
57  *              -> strings
58  */
59
60 /*
61  * Find pointers to the start and end of the symbol entries,
62  * given a pointer to the start of the symbol table.
63  */
64 #define db_get_aout_symtab(symtab, sp, ep) \
65         (sp = (struct nlist *)((symtab) + 1), \
66          ep = (struct nlist *)((char *)sp + *(symtab)))
67
68 #ifndef SYMTAB_SPACE
69 #define SYMTAB_SPACE 63000
70 #endif  /*SYMTAB_SPACE*/
71
72 int db_symtabsize = SYMTAB_SPACE;
73 char db_symtab[SYMTAB_SPACE] = { 1 };
74
75 X_db_sym_init(symtab, esymtab, name)
76         int *   symtab;         /* pointer to start of symbol table */
77         char *  esymtab;        /* pointer to end of string table,
78                                    for checking - rounded up to integer
79                                    boundary */
80         char *  name;
81 {
82         register struct nlist   *sym_start, *sym_end;
83         register struct nlist   *sp;
84         register char * strtab;
85         register int    strlen;
86
87         if (*symtab < 4) {
88                 printf ("DDB: no symbols\n");
89                 return;
90         }
91
92         db_get_aout_symtab(symtab, sym_start, sym_end);
93
94         strtab = (char *)sym_end;
95         strlen = *(int *)strtab;
96
97 #if 0
98         if (strtab + ((strlen + sizeof(int) - 1) & ~(sizeof(int)-1))
99             != esymtab)
100         {
101             db_printf("[ %s symbol table not valid ]\n", name);
102             return;
103         }
104
105         db_printf("[ preserving %#x bytes of %s symbol table ]\n",
106                 esymtab - (char *)symtab, name);
107 #endif
108
109         for (sp = sym_start; sp < sym_end; sp++) {
110             register int strx;
111             strx = sp->n_un.n_strx;
112             if (strx != 0) {
113                 if (strx > strlen) {
114                     db_printf("Bad string table index (%#x)\n", strx);
115                     sp->n_un.n_name = 0;
116                     continue;
117                 }
118                 sp->n_un.n_name = strtab + strx;
119             }
120         }
121
122         db_add_symbol_table(sym_start, sym_end, name, (char *)symtab);
123 }
124
125 db_sym_t
126 X_db_lookup(stab, symstr)
127         db_symtab_t     *stab;
128         char *          symstr;
129 {
130         register struct nlist *sp, *ep;
131
132         sp = (struct nlist *)stab->start;
133         ep = (struct nlist *)stab->end;
134
135         for (; sp < ep; sp++) {
136             if (sp->n_un.n_name == 0)
137                 continue;
138             if ((sp->n_type & N_STAB) == 0 &&
139                 sp->n_un.n_name != 0 &&
140                 db_eqname(sp->n_un.n_name, symstr, '_'))
141             {
142                 return ((db_sym_t)sp);
143             }
144         }
145         return ((db_sym_t)0);
146 }
147
148 db_sym_t
149 X_db_search_symbol(symtab, off, strategy, diffp)
150         db_symtab_t *   symtab;
151         register
152         db_addr_t       off;
153         db_strategy_t   strategy;
154         db_expr_t       *diffp;         /* in/out */
155 {
156         register unsigned int   diff = *diffp;
157         register struct nlist   *symp = 0;
158         register struct nlist   *sp, *ep;
159
160         sp = (struct nlist *)symtab->start;
161         ep = (struct nlist *)symtab->end;
162
163         for (; sp < ep; sp++) {
164             if (sp->n_un.n_name == 0)
165                 continue;
166             if ((sp->n_type & N_STAB) != 0)
167                 continue;
168             if (off >= sp->n_value) {
169                 if (off - sp->n_value < diff) {
170                     diff = off - sp->n_value;
171                     symp = sp;
172                     if (diff == 0)
173                         break;
174                 }
175                 else if (off - sp->n_value == diff) {
176                     if (symp == 0)
177                         symp = sp;
178                     else if ((symp->n_type & N_EXT) == 0 &&
179                                 (sp->n_type & N_EXT) != 0)
180                         symp = sp;      /* pick the external symbol */
181                 }
182             }
183         }
184         if (symp == 0) {
185             *diffp = off;
186         }
187         else {
188             *diffp = diff;
189         }
190         return ((db_sym_t)symp);
191 }
192
193 /*
194  * Return the name and value for a symbol.
195  */
196 void
197 X_db_symbol_values(sym, namep, valuep)
198         db_sym_t        sym;
199         char            **namep;
200         db_expr_t       *valuep;
201 {
202         register struct nlist *sp;
203
204         sp = (struct nlist *)sym;
205         if (namep)
206             *namep = sp->n_un.n_name;
207         if (valuep)
208             *valuep = sp->n_value;
209 }
210
211 boolean_t
212 X_db_line_at_pc()
213 {
214         return (FALSE);
215 }
216
217 /*
218  * Initialization routine for a.out files.
219  */
220 kdb_init()
221 {
222 #if 0
223         extern char     *esym;
224         extern int      end;
225
226         if (esym > (char *)&end) {
227             X_db_sym_init((int *)&end, esym, "mach");
228         }
229 #endif
230
231         X_db_sym_init (db_symtab, 0, "mach");
232 }
233
234 #if 0
235 /*
236  * Read symbol table from file.
237  * (should be somewhere else)
238  */
239 #include <boot_ufs/file_io.h>
240 #include <vm/vm_kern.h>
241
242 read_symtab_from_file(fp, symtab_name)
243         struct file     *fp;
244         char *          symtab_name;
245 {
246         vm_size_t       resid;
247         kern_return_t   result;
248         vm_offset_t     symoff;
249         vm_size_t       symsize;
250         vm_offset_t     stroff;
251         vm_size_t       strsize;
252         vm_size_t       table_size;
253         vm_offset_t     symtab;
254
255         if (!get_symtab(fp, &symoff, &symsize)) {
256             boot_printf("[ error %d reading %s file header ]\n",
257                         result, symtab_name);
258             return;
259         }
260
261         stroff = symoff + symsize;
262         result = read_file(fp, (vm_offset_t)stroff,
263                         (vm_offset_t)&strsize, sizeof(strsize), &resid);
264         if (result || resid) {
265             boot_printf("[ no valid symbol table present for %s ]\n",
266                 symtab_name);
267                 return;
268         }
269
270         table_size = sizeof(int) + symsize + strsize;
271         table_size = (table_size + sizeof(int)-1) & ~(sizeof(int)-1);
272
273         symtab = kmem_alloc_wired(kernel_map, table_size);
274
275         *(int *)symtab = symsize;
276
277         result = read_file(fp, symoff,
278                         symtab + sizeof(int), symsize, &resid);
279         if (result || resid) {
280             boot_printf("[ error %d reading %s symbol table ]\n",
281                         result, symtab_name);
282             return;
283         }
284
285         result = read_file(fp, stroff,
286                         symtab + sizeof(int) + symsize, strsize, &resid);
287         if (result || resid) {
288             boot_printf("[ error %d reading %s string table ]\n",
289                         result, symtab_name);
290             return;
291         }
292
293         X_db_sym_init((int *)symtab,
294                         (char *)(symtab + table_size),
295                         symtab_name);
296         
297 }
298 #endif
299
300 #endif  /* DB_NO_AOUT */