|
|
1.1 root 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 [email protected]
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: /*
1.1.1.3 ! root 27: * db_aout.c,v 1.3 1993/05/20 03:39:06 cgd Exp
! 28: *
1.1 root 29: * HISTORY
1.1.1.3 ! root 30: * db_aout.c,v
! 31: * Revision 1.3 1993/05/20 03:39:06 cgd
! 32: * add explicit rcs id
! 33: *
! 34: * Revision 1.2 1993/05/07 09:13:53 cgd
! 35: * make SYMTAB_SPACE user-definable, as an "option"
! 36: *
! 37: * Revision 1.1.1.1 1993/03/21 09:46:26 cgd
1.1.1.2 root 38: * initial import of 386bsd-0.1 sources
39: *
1.1 root 40: * Revision 1.1 1992/03/25 21:44:55 pace
41: * Initial revision
42: *
43: * Revision 2.3 91/02/05 17:05:55 mrt
44: * Changed to new Mach copyright
45: * [91/01/31 16:16:44 mrt]
46: *
47: * Revision 2.2 90/08/27 21:48:35 dbg
48: * Created.
49: * [90/08/17 dbg]
50: *
51: */
52: /*
53: * Author: David B. Golub, Carnegie Mellon University
54: * Date: 7/90
55: */
56: /*
57: * Symbol table routines for a.out format files.
58: */
59:
1.1.1.3 ! root 60: #include "types.h"
1.1 root 61: #include "param.h"
1.1.1.3 ! root 62: #include "systm.h"
1.1 root 63: #include "proc.h"
64: #include <machine/db_machdep.h> /* data types */
65: #include <ddb/db_sym.h>
66:
67: #ifndef DB_NO_AOUT
68:
69: #define _AOUT_INCLUDE_
70: #include "nlist.h"
1.1.1.3 ! root 71: #include "stab.h"
1.1 root 72:
73: /*
74: * An a.out symbol table as loaded into the kernel debugger:
75: *
76: * symtab -> size of symbol entries, in bytes
77: * sp -> first symbol entry
78: * ...
79: * ep -> last symbol entry + 1
80: * strtab == start of string table
81: * size of string table in bytes,
82: * including this word
83: * -> strings
84: */
85:
86: /*
87: * Find pointers to the start and end of the symbol entries,
88: * given a pointer to the start of the symbol table.
89: */
90: #define db_get_aout_symtab(symtab, sp, ep) \
91: (sp = (struct nlist *)((symtab) + 1), \
92: ep = (struct nlist *)((char *)sp + *(symtab)))
93:
1.1.1.3 ! root 94: #ifndef SYMTAB_SPACE
1.1 root 95: #define SYMTAB_SPACE 63000
1.1.1.3 ! root 96: #endif
1.1 root 97: int db_symtabsize = SYMTAB_SPACE;
98: char db_symtab[SYMTAB_SPACE] = { 1 };
99:
100: X_db_sym_init(symtab, esymtab, name)
101: int * symtab; /* pointer to start of symbol table */
102: char * esymtab; /* pointer to end of string table,
103: for checking - rounded up to integer
104: boundary */
105: char * name;
106: {
107: register struct nlist *sym_start, *sym_end;
108: register struct nlist *sp;
109: register char * strtab;
110: register int strlen;
111:
112: if (*symtab < 4) {
113: printf ("DDB: no symbols\n");
114: return;
115: }
116:
117: db_get_aout_symtab(symtab, sym_start, sym_end);
118:
119: strtab = (char *)sym_end;
120: strlen = *(int *)strtab;
121:
122: #if 0
123: if (strtab + ((strlen + sizeof(int) - 1) & ~(sizeof(int)-1))
124: != esymtab)
125: {
126: db_printf("[ %s symbol table not valid ]\n", name);
127: return;
128: }
129:
130: db_printf("[ preserving %#x bytes of %s symbol table ]\n",
131: esymtab - (char *)symtab, name);
132: #endif
133:
134: for (sp = sym_start; sp < sym_end; sp++) {
135: register int strx;
136: strx = sp->n_un.n_strx;
137: if (strx != 0) {
138: if (strx > strlen) {
139: db_printf("Bad string table index (%#x)\n", strx);
140: sp->n_un.n_name = 0;
141: continue;
142: }
143: sp->n_un.n_name = strtab + strx;
144: }
145: }
146:
147: db_add_symbol_table(sym_start, sym_end, name, (char *)symtab);
148: }
149:
150: db_sym_t
151: X_db_lookup(stab, symstr)
152: db_symtab_t *stab;
153: char * symstr;
154: {
155: register struct nlist *sp, *ep;
156:
157: sp = (struct nlist *)stab->start;
158: ep = (struct nlist *)stab->end;
159:
160: for (; sp < ep; sp++) {
161: if (sp->n_un.n_name == 0)
162: continue;
163: if ((sp->n_type & N_STAB) == 0 &&
164: sp->n_un.n_name != 0 &&
165: db_eqname(sp->n_un.n_name, symstr, '_'))
166: {
167: return ((db_sym_t)sp);
168: }
169: }
170: return ((db_sym_t)0);
171: }
172:
173: db_sym_t
174: X_db_search_symbol(symtab, off, strategy, diffp)
175: db_symtab_t * symtab;
176: register
177: db_addr_t off;
178: db_strategy_t strategy;
179: db_expr_t *diffp; /* in/out */
180: {
181: register unsigned int diff = *diffp;
182: register struct nlist *symp = 0;
183: register struct nlist *sp, *ep;
184:
185: sp = (struct nlist *)symtab->start;
186: ep = (struct nlist *)symtab->end;
187:
188: for (; sp < ep; sp++) {
189: if (sp->n_un.n_name == 0)
190: continue;
1.1.1.3 ! root 191: if ((sp->n_type & N_STAB) != 0 || (sp->n_type & N_TYPE) == N_FN)
1.1 root 192: continue;
193: if (off >= sp->n_value) {
194: if (off - sp->n_value < diff) {
195: diff = off - sp->n_value;
196: symp = sp;
1.1.1.3 ! root 197: if (diff == 0 &&
! 198: (strategy == DB_STGY_PROC &&
! 199: sp->n_type == (N_TEXT|N_EXT) ||
! 200: strategy == DB_STGY_ANY &&
! 201: (sp->n_type & N_EXT)))
1.1 root 202: break;
203: }
204: else if (off - sp->n_value == diff) {
205: if (symp == 0)
206: symp = sp;
207: else if ((symp->n_type & N_EXT) == 0 &&
208: (sp->n_type & N_EXT) != 0)
209: symp = sp; /* pick the external symbol */
210: }
211: }
212: }
213: if (symp == 0) {
214: *diffp = off;
215: }
216: else {
217: *diffp = diff;
218: }
219: return ((db_sym_t)symp);
220: }
221:
222: /*
223: * Return the name and value for a symbol.
224: */
225: void
226: X_db_symbol_values(sym, namep, valuep)
227: db_sym_t sym;
228: char **namep;
229: db_expr_t *valuep;
230: {
231: register struct nlist *sp;
232:
233: sp = (struct nlist *)sym;
234: if (namep)
235: *namep = sp->n_un.n_name;
236: if (valuep)
237: *valuep = sp->n_value;
238: }
239:
1.1.1.3 ! root 240:
1.1 root 241: boolean_t
1.1.1.3 ! root 242: X_db_line_at_pc(symtab, cursym, filename, linenum, off)
! 243: db_symtab_t * symtab;
! 244: db_sym_t cursym;
! 245: char **filename;
! 246: int *linenum;
! 247: db_expr_t off;
1.1 root 248: {
1.1.1.3 ! root 249: register struct nlist *sp, *ep;
! 250: register struct nlist *sym = (struct nlist *)cursym;
! 251: unsigned long sodiff = -1UL, lndiff = -1UL, ln = 0;
! 252: char *fname = NULL;
! 253:
! 254: sp = (struct nlist *)symtab->start;
! 255: ep = (struct nlist *)symtab->end;
! 256:
! 257: /* XXX - gcc specific */
! 258: #define NEWSRC(str) ((str) != NULL && \
! 259: (str)[0] == 'g' && strcmp((str), "gcc_compiled.") == 0)
! 260:
! 261: for (; sp < ep; sp++) {
! 262:
! 263: /*
! 264: * Prevent bogus linenumbers in case module not compiled
! 265: * with debugging options
! 266: */
! 267: #if 0
! 268: if (sp->n_value <= off && (off - sp->n_value) <= sodiff &&
! 269: NEWSRC(sp->n_un.n_name)) {
! 270: #endif
! 271: if ((sp->n_type & N_TYPE) == N_FN || NEWSRC(sp->n_un.n_name)) {
! 272: sodiff = lndiff = -1UL;
! 273: ln = 0;
! 274: fname = NULL;
! 275: }
! 276:
! 277: if (sp->n_type == N_SO) {
! 278: if (sp->n_value <= off && (off - sp->n_value) < sodiff) {
! 279: sodiff = off - sp->n_value;
! 280: fname = sp->n_un.n_name;
! 281: }
! 282: continue;
! 283: }
! 284:
! 285: if (sp->n_type != N_SLINE)
! 286: continue;
! 287:
! 288: if (sp->n_value > off)
! 289: break;
! 290:
! 291: if (off - sp->n_value < lndiff) {
! 292: lndiff = off - sp->n_value;
! 293: ln = sp->n_desc;
! 294: }
! 295: }
! 296:
! 297: if (fname != NULL && ln != 0) {
! 298: *filename = fname;
! 299: *linenum = ln;
! 300: return TRUE;
! 301: }
! 302:
1.1 root 303: return (FALSE);
304: }
305:
1.1.1.3 ! root 306: boolean_t
! 307: X_db_sym_numargs(symtab, cursym, nargp, argnamep)
! 308: db_symtab_t * symtab;
! 309: db_sym_t cursym;
! 310: int *nargp;
! 311: char **argnamep;
! 312: {
! 313: register struct nlist *sp, *ep;
! 314: u_long addr;
! 315: int maxnarg = *nargp, nargs = 0;
! 316:
! 317: if (cursym == NULL)
! 318: return FALSE;
! 319:
! 320: addr = ((struct nlist *)cursym)->n_value;
! 321: sp = (struct nlist *)symtab->start;
! 322: ep = (struct nlist *)symtab->end;
! 323:
! 324: for (; sp < ep; sp++) {
! 325: if (sp->n_type == N_FUN && sp->n_value == addr) {
! 326: while (++sp < ep && sp->n_type == N_PSYM) {
! 327: if (nargs >= maxnarg)
! 328: break;
! 329: nargs++;
! 330: *argnamep++ = sp->n_un.n_name?sp->n_un.n_name:"???";
! 331: {
! 332: /* XXX - remove trailers */
! 333: char *cp = *(argnamep-1);
! 334: while (*cp != '\0' && *cp != ':') cp++;
! 335: if (*cp == ':') *cp = '\0';
! 336: }
! 337: }
! 338: *nargp = nargs;
! 339: return TRUE;
! 340: }
! 341: }
! 342: return FALSE;
! 343: }
! 344:
1.1 root 345: /*
346: * Initialization routine for a.out files.
347: */
348: kdb_init()
349: {
350: #if 0
351: extern char *esym;
352: extern int end;
353:
354: if (esym > (char *)&end) {
1.1.1.3 ! root 355: X_db_sym_init((int *)&end, esym, "netbsd");
1.1 root 356: }
357: #endif
358:
1.1.1.3 ! root 359: X_db_sym_init (db_symtab, 0, "netbsd");
1.1 root 360: }
361:
362: #if 0
363: /*
364: * Read symbol table from file.
365: * (should be somewhere else)
366: */
367: #include <boot_ufs/file_io.h>
368: #include <vm/vm_kern.h>
369:
370: read_symtab_from_file(fp, symtab_name)
371: struct file *fp;
372: char * symtab_name;
373: {
374: vm_size_t resid;
375: kern_return_t result;
376: vm_offset_t symoff;
377: vm_size_t symsize;
378: vm_offset_t stroff;
379: vm_size_t strsize;
380: vm_size_t table_size;
381: vm_offset_t symtab;
382:
383: if (!get_symtab(fp, &symoff, &symsize)) {
384: boot_printf("[ error %d reading %s file header ]\n",
385: result, symtab_name);
386: return;
387: }
388:
389: stroff = symoff + symsize;
390: result = read_file(fp, (vm_offset_t)stroff,
391: (vm_offset_t)&strsize, sizeof(strsize), &resid);
392: if (result || resid) {
393: boot_printf("[ no valid symbol table present for %s ]\n",
394: symtab_name);
395: return;
396: }
397:
398: table_size = sizeof(int) + symsize + strsize;
399: table_size = (table_size + sizeof(int)-1) & ~(sizeof(int)-1);
400:
401: symtab = kmem_alloc_wired(kernel_map, table_size);
402:
403: *(int *)symtab = symsize;
404:
405: result = read_file(fp, symoff,
406: symtab + sizeof(int), symsize, &resid);
407: if (result || resid) {
408: boot_printf("[ error %d reading %s symbol table ]\n",
409: result, symtab_name);
410: return;
411: }
412:
413: result = read_file(fp, stroff,
414: symtab + sizeof(int) + symsize, strsize, &resid);
415: if (result || resid) {
416: boot_printf("[ error %d reading %s string table ]\n",
417: result, symtab_name);
418: return;
419: }
420:
421: X_db_sym_init((int *)symtab,
422: (char *)(symtab + table_size),
423: symtab_name);
424:
425: }
426: #endif
427:
428: #endif /* DB_NO_AOUT */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.