MFC r1.27:
[dragonfly.git] / sys / ddb / db_aout.c
blob0edec107f993176c577c3e7c64fc420846b27d1e
1 /*
2 * Mach Operating System
3 * Copyright (c) 1991,1990 Carnegie Mellon University
4 * All Rights Reserved.
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.
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.
16 * Carnegie Mellon requests users of this software to return to
18 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
19 * School of Computer Science
20 * Carnegie Mellon University
21 * Pittsburgh PA 15213-3890
23 * any improvements or extensions that they make and grant Carnegie the
24 * rights to redistribute these changes.
26 * $FreeBSD: src/sys/ddb/db_aout.c,v 1.27 1999/08/28 00:41:05 peter Exp $
27 * $DragonFly: src/sys/ddb/db_aout.c,v 1.8 2006/12/28 21:24:01 dillon Exp $
31 * Author: David B. Golub, Carnegie Mellon University
32 * Date: 7/90
35 * Symbol table routines for a.out format files.
38 #if !defined(__ELF__)
40 #include <sys/param.h>
41 #include <sys/systm.h>
43 #include <machine/bootinfo.h>
45 #include <ddb/ddb.h>
46 #include <ddb/db_sym.h>
48 #define _AOUT_INCLUDE_
49 #include <nlist.h>
50 #include <stab.h>
53 * An a.out symbol table as loaded into the kernel debugger:
55 * symtab -> size of symbol entries, in bytes
56 * sp -> first symbol entry
57 * ...
58 * ep -> last symbol entry + 1
59 * strtab == start of string table
60 * size of string table in bytes,
61 * including this word
62 * -> strings
65 static void X_db_sym_init (int *symtab, char *esymtab, char *name);
67 * Find pointers to the start and end of the symbol entries,
68 * given a pointer to the start of the symbol table.
70 #define db_get_aout_symtab(symtab, sp, ep) \
71 (sp = (struct nlist *)((symtab) + 1), \
72 ep = (struct nlist *)((char *)sp + *(symtab)))
75 * Parameters:
76 * symtab: pointer to start of symbol table
77 * esymtab: pointer to end of string table, for checking - rounded up to
78 * integer boundary
80 static void
81 X_db_sym_init(int *symtab, char *esymtab, char *name)
83 struct nlist *sym_start, *sym_end;
84 struct nlist *sp;
85 char * strtab;
86 int strlen;
88 if (*symtab < 4) {
89 kprintf ("DDB: no symbols\n");
90 return;
93 db_get_aout_symtab(symtab, sym_start, sym_end);
95 strtab = (char *)sym_end;
96 strlen = *(int *)strtab;
98 if (strtab + ((strlen + sizeof(int) - 1) & ~(sizeof(int)-1))
99 != esymtab)
101 db_printf("[ %s symbol table not valid ]\n", name);
102 return;
105 db_printf("[ preserving %#x bytes of %s symbol table ]\n",
106 esymtab - (char *)symtab, name);
108 for (sp = sym_start; sp < sym_end; sp++) {
109 int strx;
110 strx = sp->n_un.n_strx;
111 if (strx != 0) {
112 if (strx > strlen) {
113 db_printf("Bad string table index (%#x)\n", strx);
114 sp->n_un.n_name = 0;
115 continue;
117 sp->n_un.n_name = strtab + strx;
121 db_add_symbol_table((char *)sym_start, (char *)sym_end, name,
122 (char *)symtab);
125 c_db_sym_t
126 X_db_lookup(db_symtab_t *stab, const char *symstr)
128 struct nlist *sp, *ep;
130 sp = (struct nlist *)stab->start;
131 ep = (struct nlist *)stab->end;
133 for (; sp < ep; sp++) {
134 if (sp->n_un.n_name == 0)
135 continue;
136 if ((sp->n_type & N_STAB) == 0 &&
137 sp->n_un.n_name != 0 &&
138 db_eqname(sp->n_un.n_name, symstr, '_'))
140 return ((db_sym_t)sp);
143 return ((db_sym_t)0);
147 * Parameters:
148 * diffp: in/out
150 c_db_sym_t
151 X_db_search_symbol(db_symtab_t *symtab, db_addr_t off, db_strategy_t strategy,
152 db_expr_t *diffp)
154 unsigned int diff = *diffp;
155 struct nlist *symp = 0;
156 struct nlist *sp, *ep;
158 sp = (struct nlist *)symtab->start;
159 ep = (struct nlist *)symtab->end;
161 for (; sp < ep; sp++) {
162 if (sp->n_un.n_name == 0)
163 continue;
164 if ((sp->n_type & N_STAB) != 0 || (sp->n_type & N_TYPE) == N_FN)
165 continue;
166 if (off >= sp->n_value) {
167 if (off - sp->n_value < diff) {
168 diff = off - sp->n_value;
169 symp = sp;
170 if (diff == 0) {
171 if (strategy == DB_STGY_PROC &&
172 sp->n_type == (N_TEXT|N_EXT))
173 break;
174 if (strategy == DB_STGY_ANY &&
175 (sp->n_type & N_EXT))
176 break;
179 else if (off - sp->n_value == diff) {
180 if (symp == 0)
181 symp = sp;
182 else if ((symp->n_type & N_EXT) == 0 &&
183 (sp->n_type & N_EXT) != 0)
184 symp = sp; /* pick the external symbol */
188 if (symp == 0) {
189 *diffp = off;
191 else {
192 *diffp = diff;
194 return ((db_sym_t)symp);
198 * Return the name and value for a symbol.
200 void
201 X_db_symbol_values(db_symtab_t *symtab, c_db_sym_t sym, const char **namep,
202 db_expr_t *valuep)
204 const struct nlist *sp;
206 sp = (const struct nlist *)sym;
207 if (namep)
208 *namep = sp->n_un.n_name;
209 if (valuep)
210 *valuep = sp->n_value;
214 boolean_t
215 X_db_line_at_pc(db_symtab_t *symtab, c_db_sym_t cursym, char **filename,
216 int *linenum, db_expr_t off)
218 struct nlist *sp, *ep;
219 unsigned long sodiff = -1UL, lndiff = -1UL, ln = 0;
220 char *fname = NULL;
222 sp = (struct nlist *)symtab->start;
223 ep = (struct nlist *)symtab->end;
226 * XXX - this used to remove "gcc_compiled.", but that is obsolete. We
227 * now remove unwanted names using symorder.
229 #define NEWSRC(str) 0
231 for (; sp < ep; sp++) {
234 * Prevent bogus linenumbers in case module not compiled
235 * with debugging options
237 #if 0
238 if (sp->n_value <= off && (off - sp->n_value) <= sodiff &&
239 NEWSRC(sp->n_un.n_name)) {
240 #endif
241 if ((sp->n_type & N_TYPE) == N_FN || NEWSRC(sp->n_un.n_name)) {
242 sodiff = lndiff = -1UL;
243 ln = 0;
244 fname = NULL;
247 if (sp->n_type == N_SO && *sp->n_un.n_name != '/') {
248 if (sp->n_value <= off && (off - sp->n_value) < sodiff) {
249 sodiff = off - sp->n_value;
250 fname = sp->n_un.n_name;
252 continue;
255 if (sp->n_type != N_SLINE)
256 continue;
258 if (sp->n_value > off)
259 break;
261 if (off - sp->n_value < lndiff) {
262 lndiff = off - sp->n_value;
263 ln = sp->n_desc;
267 if (fname != NULL && ln != 0) {
268 *filename = fname;
269 *linenum = ln;
270 return TRUE;
273 return (FALSE);
276 boolean_t
277 X_db_sym_numargs(db_symtab_t *symtab, c_db_sym_t cursym, int *nargp,
278 char **argnamep)
280 struct nlist *sp, *ep;
281 u_long addr;
282 int maxnarg = *nargp, nargs = 0;
284 if (cursym == NULL)
285 return FALSE;
287 addr = ((const struct nlist *)cursym)->n_value;
288 sp = (struct nlist *)symtab->start;
289 ep = (struct nlist *)symtab->end;
291 for (; sp < ep; sp++) {
292 if (sp->n_type == N_FUN && sp->n_value == addr) {
293 while (++sp < ep && sp->n_type == N_PSYM) {
294 if (nargs >= maxnarg)
295 break;
296 nargs++;
297 *argnamep++ = sp->n_un.n_name?sp->n_un.n_name:"???";
299 /* XXX - remove trailers */
300 char *cp = *(argnamep-1);
301 while (*cp != '\0' && *cp != ':') cp++;
302 if (*cp == ':') *cp = '\0';
305 *nargp = nargs;
306 return TRUE;
309 return FALSE;
313 * Initialization routine for a.out files.
315 void
316 kdb_init(void)
318 #ifdef __i386__
319 if (bootinfo.bi_esymtab != bootinfo.bi_symtab)
320 X_db_sym_init((int *)bootinfo.bi_symtab,
321 (char *)((bootinfo.bi_esymtab + sizeof(int) - 1)
322 & ~(sizeof(int) - 1)),
323 "kernel");
324 #endif
327 #if 0
329 * Read symbol table from file.
330 * (should be somewhere else)
332 #include <boot_ufs/file_io.h>
333 #include <vm/vm_kern.h>
335 read_symtab_from_file(struct file *fp, char *symtab_name)
337 vm_size_t resid;
338 kern_return_t result;
339 vm_offset_t symoff;
340 vm_size_t symsize;
341 vm_offset_t stroff;
342 vm_size_t strsize;
343 vm_size_t table_size;
344 vm_offset_t symtab;
346 if (!get_symtab(fp, &symoff, &symsize)) {
347 boot_printf("[ error %d reading %s file header ]\n",
348 result, symtab_name);
349 return;
352 stroff = symoff + symsize;
353 result = read_file(fp, (vm_offset_t)stroff,
354 (vm_offset_t)&strsize, sizeof(strsize), &resid);
355 if (result || resid) {
356 boot_printf("[ no valid symbol table present for %s ]\n",
357 symtab_name);
358 return;
361 table_size = sizeof(int) + symsize + strsize;
362 table_size = (table_size + sizeof(int)-1) & ~(sizeof(int)-1);
364 symtab = kmem_alloc_wired(&kernel_map, table_size);
366 *(int *)symtab = symsize;
368 result = read_file(fp, symoff,
369 symtab + sizeof(int), symsize, &resid);
370 if (result || resid) {
371 boot_printf("[ error %d reading %s symbol table ]\n",
372 result, symtab_name);
373 return;
376 result = read_file(fp, stroff,
377 symtab + sizeof(int) + symsize, strsize, &resid);
378 if (result || resid) {
379 boot_printf("[ error %d reading %s string table ]\n",
380 result, symtab_name);
381 return;
384 X_db_sym_init((int *)symtab,
385 (char *)(symtab + table_size),
386 symtab_name);
389 #endif
390 #endif