|
|
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: /*
27: * HISTORY
28: * $Log: db_sym.c,v $
1.1.1.2 ! root 29: * Revision 1.1.1.1 1993/03/21 09:46:27 cgd
! 30: * initial import of 386bsd-0.1 sources
! 31: *
1.1 root 32: * Revision 1.1 1992/03/25 21:45:27 pace
33: * Initial revision
34: *
35: * Revision 2.5 91/02/05 17:07:07 mrt
36: * Changed to new Mach copyright
37: * [91/01/31 16:19:17 mrt]
38: *
39: * Revision 2.4 90/10/25 14:44:05 rwd
40: * Changed db_printsym to print unsigned.
41: * [90/10/19 rpd]
42: *
43: * Revision 2.3 90/09/09 23:19:56 rpd
44: * Avoid totally incorrect guesses of symbol names for small values.
45: * [90/08/30 17:39:48 af]
46: *
47: * Revision 2.2 90/08/27 21:52:18 dbg
48: * Removed nlist.h. Fixed some type declarations.
49: * Qualifier character is ':'.
50: * [90/08/20 dbg]
51: * Modularized symtab info into a new db_symtab_t type.
52: * Modified db_add_symbol_table and others accordingly.
53: * Defined db_sym_t, a new (opaque) type used to represent
54: * symbols. This should support all sort of future symtable
55: * formats. Functions like db_qualify take a db_sym_t now.
56: * New db_symbol_values() function to explode the content
57: * of a db_sym_t.
58: * db_search_symbol() replaces db_find_sym_and_offset(), which is
59: * now a macro defined in our (new) header file. This new
60: * function accepts more restrictive searches, which are
61: * entirely delegated to the symtab-specific code.
62: * Accordingly, db_printsym() accepts a strategy parameter.
63: * New db_line_at_pc() function.
64: * Renamed misleading db_eqsym into db_eqname.
65: * [90/08/20 10:47:06 af]
66: *
67: * Created.
68: * [90/07/25 dbg]
69: *
70: * Revision 2.1 90/07/26 16:43:52 dbg
71: * Created.
72: *
73: */
74: /*
75: * Author: David B. Golub, Carnegie Mellon University
76: * Date: 7/90
77: */
78: #include "param.h"
79: #include "proc.h"
80: #include <machine/db_machdep.h>
81: #include <ddb/db_sym.h>
82:
83: /*
84: * We import from the symbol-table dependent routines:
85: */
86: extern db_sym_t X_db_lookup();
87: extern db_sym_t X_db_search_symbol();
88: extern boolean_t X_db_line_at_pc();
89: extern void X_db_symbol_values();
90:
91: /*
92: * Multiple symbol tables
93: */
94: #define MAXNOSYMTABS 3 /* mach, ux, emulator */
95:
96: db_symtab_t db_symtabs[MAXNOSYMTABS] = {{0,},};
97: int db_nsymtab = 0;
98:
99: db_symtab_t *db_last_symtab;
100:
101: db_sym_t db_lookup(); /* forward */
102:
103: /*
104: * Add symbol table, with given name, to list of symbol tables.
105: */
106: void
107: db_add_symbol_table(start, end, name, ref)
108: char *start;
109: char *end;
110: char *name;
111: char *ref;
112: {
113: if (db_nsymtab >= MAXNOSYMTABS) {
114: printf ("No slots left for %s symbol table", name);
115: panic ("db_sym.c: db_add_symbol_table");
116: }
117:
118: db_symtabs[db_nsymtab].start = start;
119: db_symtabs[db_nsymtab].end = end;
120: db_symtabs[db_nsymtab].name = name;
121: db_symtabs[db_nsymtab].private = ref;
122: db_nsymtab++;
123: }
124:
125: /*
126: * db_qualify("vm_map", "ux") returns "unix:vm_map".
127: *
128: * Note: return value points to static data whose content is
129: * overwritten by each call... but in practice this seems okay.
130: */
131: static char *
132: db_qualify(sym, symtabname)
133: db_sym_t sym;
134: register char *symtabname;
135: {
136: char *symname;
137: static char tmp[256];
138: register char *s;
139:
140: db_symbol_values(sym, &symname, 0);
141: s = tmp;
142: while (*s++ = *symtabname++) {
143: }
144: s[-1] = ':';
145: while (*s++ = *symname++) {
146: }
147: return tmp;
148: }
149:
150:
151: boolean_t
152: db_eqname(src, dst, c)
153: char *src;
154: char *dst;
155: char c;
156: {
157: if (!strcmp(src, dst))
158: return (TRUE);
159: if (src[0] == c)
160: return (!strcmp(src+1,dst));
161: return (FALSE);
162: }
163:
164: boolean_t
165: db_value_of_name(name, valuep)
166: char *name;
167: db_expr_t *valuep;
168: {
169: db_sym_t sym;
170:
171: sym = db_lookup(name);
172: if (sym == DB_SYM_NULL)
173: return (FALSE);
174: db_symbol_values(sym, &name, valuep);
175: return (TRUE);
176: }
177:
178:
179: /*
180: * Lookup a symbol.
181: * If the symbol has a qualifier (e.g., ux:vm_map),
182: * then only the specified symbol table will be searched;
183: * otherwise, all symbol tables will be searched.
184: */
185: db_sym_t
186: db_lookup(symstr)
187: char *symstr;
188: {
189: db_sym_t sp;
190: register int i;
191: int symtab_start = 0;
192: int symtab_end = db_nsymtab;
193: register char *cp;
194:
195: /*
196: * Look for, remove, and remember any symbol table specifier.
197: */
198: for (cp = symstr; *cp; cp++) {
199: if (*cp == ':') {
200: *cp = '\0';
201: for (i = 0; i < db_nsymtab; i++) {
202: if (! strcmp(symstr, db_symtabs[i].name)) {
203: symtab_start = i;
204: symtab_end = i + 1;
205: break;
206: }
207: }
208: *cp = ':';
209: if (i == db_nsymtab) {
210: db_error("invalid symbol table name");
211: }
212: symstr = cp+1;
213: }
214: }
215:
216: /*
217: * Look in the specified set of symbol tables.
218: * Return on first match.
219: */
220: for (i = symtab_start; i < symtab_end; i++) {
221: if (sp = X_db_lookup(&db_symtabs[i], symstr)) {
222: db_last_symtab = &db_symtabs[i];
223: return sp;
224: }
225: }
226: return 0;
227: }
228:
229: /*
230: * Does this symbol name appear in more than one symbol table?
231: * Used by db_symbol_values to decide whether to qualify a symbol.
232: */
233: boolean_t db_qualify_ambiguous_names = FALSE;
234:
235: boolean_t
236: db_symbol_is_ambiguous(sym)
237: db_sym_t sym;
238: {
239: char *sym_name;
240: register int i;
241: register
242: boolean_t found_once = FALSE;
243:
244: if (!db_qualify_ambiguous_names)
245: return FALSE;
246:
247: db_symbol_values(sym, &sym_name, 0);
248: for (i = 0; i < db_nsymtab; i++) {
249: if (X_db_lookup(&db_symtabs[i], sym_name)) {
250: if (found_once)
251: return TRUE;
252: found_once = TRUE;
253: }
254: }
255: return FALSE;
256: }
257:
258: /*
259: * Find the closest symbol to val, and return its name
260: * and the difference between val and the symbol found.
261: */
262: db_sym_t
263: db_search_symbol( val, strategy, offp)
264: register db_addr_t val;
265: db_strategy_t strategy;
266: db_expr_t *offp;
267: {
268: register
269: unsigned int diff;
270: unsigned int newdiff;
271: register int i;
272: db_sym_t ret = DB_SYM_NULL, sym;
273:
274: newdiff = diff = ~0;
275: db_last_symtab = 0;
276: for (i = 0; i < db_nsymtab; i++) {
277: sym = X_db_search_symbol(&db_symtabs[i], val, strategy, &newdiff);
278: if (newdiff < diff) {
279: db_last_symtab = &db_symtabs[i];
280: diff = newdiff;
281: ret = sym;
282: }
283: }
284: *offp = diff;
285: return ret;
286: }
287:
288: /*
289: * Return name and value of a symbol
290: */
291: void
292: db_symbol_values(sym, namep, valuep)
293: db_sym_t sym;
294: char **namep;
295: db_expr_t *valuep;
296: {
297: db_expr_t value;
298:
299: if (sym == DB_SYM_NULL) {
300: *namep = 0;
301: return;
302: }
303:
304: X_db_symbol_values(sym, namep, &value);
305:
306: if (db_symbol_is_ambiguous(sym))
307: *namep = db_qualify(sym, db_last_symtab->name);
308: if (valuep)
309: *valuep = value;
310: }
311:
312:
313: /*
314: * Print a the closest symbol to value
315: *
316: * After matching the symbol according to the given strategy
317: * we print it in the name+offset format, provided the symbol's
318: * value is close enough (eg smaller than db_maxoff).
319: * We also attempt to print [filename:linenum] when applicable
320: * (eg for procedure names).
321: *
322: * If we could not find a reasonable name+offset representation,
323: * then we just print the value in hex. Small values might get
324: * bogus symbol associations, e.g. 3 might get some absolute
325: * value like _INCLUDE_VERSION or something, therefore we do
326: * not accept symbols whose value is zero (and use plain hex).
327: */
328:
329: unsigned int db_maxoff = 0x10000000;
330:
331: void
332: db_printsym(off, strategy)
333: db_expr_t off;
334: db_strategy_t strategy;
335: {
336: db_expr_t d;
337: char *filename;
338: char *name;
339: db_expr_t value;
340: int linenum;
341: db_sym_t cursym;
342:
343: cursym = db_search_symbol(off, strategy, &d);
344: db_symbol_values(cursym, &name, &value);
345: if (name == 0 || d >= db_maxoff || value == 0) {
346: db_printf("%#n", off);
347: return;
348: }
349: db_printf("%s", name);
350: if (d)
351: db_printf("+%#r", d);
352: if (strategy == DB_STGY_PROC) {
353: if (db_line_at_pc(cursym, &filename, &linenum, off))
354: db_printf(" [%s:%d]", filename, linenum);
355: }
356: }
357:
358:
359: boolean_t
360: db_line_at_pc( sym, filename, linenum, pc)
361: {
362: return X_db_line_at_pc( db_last_symtab, sym, filename, linenum, pc);
363: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.