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