xref: /csrg-svn/old/adb/common_source/sym.c (revision 36559)
1*36559Sbostic #ifndef lint
2*36559Sbostic static char sccsid[] = "@(#)sym.c	5.1 (Berkeley) 01/16/89";
3*36559Sbostic #endif
4*36559Sbostic 
5*36559Sbostic /*
6*36559Sbostic  * adb - symbol table routines
7*36559Sbostic  */
8*36559Sbostic #include "defs.h"
9*36559Sbostic #include <stab.h>
10*36559Sbostic 
11*36559Sbostic #define	isstab(sp)	((sp)->n_type & N_STAB)
12*36559Sbostic 
13*36559Sbostic /*
14*36559Sbostic  * Lookup a symbol by name.
15*36559Sbostic  */
16*36559Sbostic struct nlist *
17*36559Sbostic lookup(symstr)
18*36559Sbostic 	register char *symstr;
19*36559Sbostic {
20*36559Sbostic 	register struct nlist *sp;
21*36559Sbostic 
22*36559Sbostic 	if (symtab)
23*36559Sbostic 		for (sp = symtab; sp < esymtab; sp++)
24*36559Sbostic 			if (!isstab(sp) && eqsym(sp->n_un.n_name, symstr, '_'))
25*36559Sbostic 				return (sp);
26*36559Sbostic 	return (0);
27*36559Sbostic }
28*36559Sbostic 
29*36559Sbostic /*
30*36559Sbostic  * Find the closest symbol to val, and return it and (through
31*36559Sbostic  * diffp) the difference between val and the symbol found.
32*36559Sbostic  */
33*36559Sbostic struct nlist *
34*36559Sbostic findsym(val, space, diffp)
35*36559Sbostic 	register addr_t val;
36*36559Sbostic 	int space;
37*36559Sbostic 	addr_t *diffp;
38*36559Sbostic {
39*36559Sbostic 	register struct nlist *sp;
40*36559Sbostic 	register addr_t diff;
41*36559Sbostic 	struct nlist *sym;
42*36559Sbostic 
43*36559Sbostic 	diff = ~(addr_t)0;
44*36559Sbostic 	sym = NULL;
45*36559Sbostic 	if (space != SP_NONE || symtab != NULL) {
46*36559Sbostic 		for (sp = symtab; sp < esymtab; sp++) {
47*36559Sbostic 			/* must be global */
48*36559Sbostic 			if (isstab(sp) || (sp->n_type & N_EXT) == 0)
49*36559Sbostic 				continue;
50*36559Sbostic 			/* and not a function */
51*36559Sbostic 			if (sp->n_type == (N_FN|N_EXT))
52*36559Sbostic 				continue;
53*36559Sbostic 			/* and have a greater address */
54*36559Sbostic 			if (val < sp->n_value)
55*36559Sbostic 				continue;
56*36559Sbostic 			/* and be closer than the last one */
57*36559Sbostic 			if (val - sp->n_value >= diff)
58*36559Sbostic 				continue;
59*36559Sbostic 			sym = sp;
60*36559Sbostic 			diff = val - sp->n_value;
61*36559Sbostic 			if (diff == 0)
62*36559Sbostic 				break;
63*36559Sbostic 		}
64*36559Sbostic 	}
65*36559Sbostic 	*diffp = diff;
66*36559Sbostic 	return (sym);
67*36559Sbostic }
68*36559Sbostic 
69*36559Sbostic /*
70*36559Sbostic  * Return the next local symbol after sym, or NULL at end of such locals.
71*36559Sbostic  */
72*36559Sbostic /* ARGSUSED */
73*36559Sbostic struct nlist *
74*36559Sbostic nextlocal(sym)
75*36559Sbostic 	struct nlist *sym;
76*36559Sbostic {
77*36559Sbostic 
78*36559Sbostic #ifdef busted
79*36559Sbostic 	/*
80*36559Sbostic 	 * none of this works at the moment, because the symbols are not in
81*36559Sbostic 	 * the desired order.
82*36559Sbostic 	 */
83*36559Sbostic 	if (sym == NULL)
84*36559Sbostic 		return (NULL);
85*36559Sbostic 	while (++sym < esymtab) {
86*36559Sbostic 		/*
87*36559Sbostic 		 * External and file name symbols terminate the
88*36559Sbostic 		 * list of local symbols.  Otherwise, if it is
89*36559Sbostic 		 * a .stabs parameter or local symbol, take it.
90*36559Sbostic 		 */
91*36559Sbostic 		if ((sym->n_type & N_EXT) || sym->n_type == N_FN)
92*36559Sbostic 			break;
93*36559Sbostic 		if (sym->n_type == N_LSYM || sym->n_type == N_PSYM)
94*36559Sbostic 			return (sym);
95*36559Sbostic 	}
96*36559Sbostic #endif
97*36559Sbostic 	return (NULL);
98*36559Sbostic }
99*36559Sbostic 
100*36559Sbostic /*
101*36559Sbostic  * Print value v (in format f) and then (as another format) s.
102*36559Sbostic  * If v is not zero, we look for a nearby symbol and print name+offset
103*36559Sbostic  * if we find a symbol whose offset is small enough (less than o).
104*36559Sbostic  */
105*36559Sbostic psymoff(f, v, space, o, s)
106*36559Sbostic 	char *f;
107*36559Sbostic 	addr_t v;
108*36559Sbostic 	int space;
109*36559Sbostic 	addr_t o;
110*36559Sbostic 	char *s;
111*36559Sbostic {
112*36559Sbostic 	struct nlist *sp;
113*36559Sbostic 	addr_t offset;
114*36559Sbostic 
115*36559Sbostic 	if (v && (sp = findsym(v, space, &offset)) != NULL && offset < o)
116*36559Sbostic 		adbprintf("%s%?+R", sp->n_un.n_name,
117*36559Sbostic 			offset != 0, (expr_t)offset);
118*36559Sbostic 	else
119*36559Sbostic 		adbprintf(f, (expr_t)v);
120*36559Sbostic 	adbprintf(s);
121*36559Sbostic }
122*36559Sbostic 
123*36559Sbostic /*
124*36559Sbostic  * Print value v symbolically if it has a reasonable
125*36559Sbostic  * interpretation as name+offset.  If not, print nothing.
126*36559Sbostic  * Used in printing out registers $r.
127*36559Sbostic  */
128*36559Sbostic valpr(v, space)
129*36559Sbostic 	addr_t v;
130*36559Sbostic 	int space;
131*36559Sbostic {
132*36559Sbostic 	struct nlist *sp;
133*36559Sbostic 	addr_t offset;
134*36559Sbostic 
135*36559Sbostic 	if (v && (sp = findsym(v, space, &offset)) != NULL && offset < maxoff)
136*36559Sbostic 		adbprintf("%s%?+R", sp->n_un.n_name,
137*36559Sbostic 			offset != 0, (expr_t)offset);
138*36559Sbostic }
139