126424Ssam #ifndef lint
2*30965Sbostic static char sccsid[] = "@(#)sym.c 1.2 (Berkeley) 04/27/87";
326424Ssam #endif
426424Ssam
526424Ssam /*
626424Ssam * adb - symbol table routines
726424Ssam */
826424Ssam #include "defs.h"
926424Ssam #include <stab.h>
1026424Ssam
1126424Ssam /*
1226424Ssam * Lookup a symbol by name.
1326424Ssam */
1426424Ssam struct nlist *
lookup(symstr)1526424Ssam lookup(symstr)
1626424Ssam char *symstr;
1726424Ssam {
1826424Ssam register struct nlist *sp;
1926424Ssam
2026424Ssam cursym = 0;
2126424Ssam if (symtab)
2226424Ssam for (sp = symtab; sp < esymtab; sp++)
2326424Ssam /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
2426424Ssam if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_'))
2526424Ssam return(cursym = sp);
2626424Ssam return (0);
2726424Ssam }
2826424Ssam
2926424Ssam /*
3026424Ssam * Find the closest symbol to val, and return
3126424Ssam * the difference between val and the symbol found.
3226424Ssam * Leave a pointer to the symbol found as cursym.
3326424Ssam */
findsym(val,type)3426424Ssam findsym(val, type)
3526424Ssam register val;
3626424Ssam int type;
3726424Ssam {
3826424Ssam register diff;
3926424Ssam register struct nlist *sp;
4026424Ssam
4126424Ssam cursym = 0;
4226424Ssam diff = MAXINT;
4326424Ssam if (type == NSYM || symtab == 0)
4426424Ssam return (diff);
4526424Ssam for (sp = symtab; sp < esymtab; sp++) {
46*30965Sbostic if (sp->n_type & N_STAB || !(sp->n_type & N_EXT)
47*30965Sbostic || sp->n_type == (N_FN|N_EXT))
4826424Ssam continue;
4926424Ssam if (val - sp->n_value < diff && val >= sp->n_value) {
5026424Ssam diff = val - sp->n_value;
5126424Ssam cursym = sp;
5226424Ssam if (diff == 0)
5326424Ssam break;
5426424Ssam }
5526424Ssam }
5626424Ssam return (diff);
5726424Ssam }
5826424Ssam
5926424Ssam /*
6026424Ssam * Advance cursym to the next local variable.
6126424Ssam * Leave its value in localval as a side effect.
6226424Ssam * Return 0 at end of file.
6326424Ssam */
localsym(cframe)6426424Ssam localsym(cframe)
6526424Ssam ADDR cframe;
6626424Ssam {
6726424Ssam register int type;
6826424Ssam register struct nlist *sp;
6926424Ssam
7026424Ssam if (cursym)
7126424Ssam for (sp = cursym; ++sp < esymtab; ) {
7226424Ssam type = sp->n_type;
7326424Ssam if (sp->n_un.n_name[0] =='_' || type == N_FN)
7426424Ssam return (0);
7526424Ssam switch (type) {
7626424Ssam
7726424Ssam case N_TEXT:
7826424Ssam case N_TEXT|N_EXT:
7926424Ssam case N_DATA:
8026424Ssam case N_DATA|N_EXT:
8126424Ssam case N_BSS:
8226424Ssam case N_BSS|N_EXT:
8326424Ssam localval = sp->n_value;
8426424Ssam cursym = sp;
8526424Ssam return (1);
8626424Ssam
8726424Ssam case N_LSYM:
8826424Ssam localval = cframe - sp->n_value;
8926424Ssam cursym = sp;
9026424Ssam return (1);
9126424Ssam
9226424Ssam case N_PSYM:
9326424Ssam case N_ABS:
9426424Ssam localval = cframe + sp->n_value;
9526424Ssam cursym = sp;
9626424Ssam return (1);
9726424Ssam }
9826424Ssam }
9926424Ssam cursym = 0;
10026424Ssam return (0);
10126424Ssam }
10226424Ssam
10326424Ssam /*
10426424Ssam * Print value v and then the string s.
10526424Ssam * If v is not zero, then we look for a nearby symbol
10626424Ssam * and print name+offset if we find a symbol for which
10726424Ssam * offset is small enough.
10826424Ssam *
10926424Ssam * For values which are just into kernel address space
11026424Ssam * that they match exactly or that they be more than maxoff
11126424Ssam * bytes into kernel space.
11226424Ssam */
psymoff(v,type,s)11326424Ssam psymoff(v, type, s)
11426424Ssam register v;
11526424Ssam int type;
11626424Ssam char *s;
11726424Ssam {
11826424Ssam register w;
11926424Ssam
12026424Ssam if (v)
12126424Ssam w = findsym(v, type);
12226424Ssam if (v==0 || w >= maxoff)
12326424Ssam printf(LPRMODE, v);
12426424Ssam else {
12526424Ssam printf("%s", cursym->n_un.n_name);
12626424Ssam if (w)
12726424Ssam printf(OFFMODE, w);
12826424Ssam }
12926424Ssam printf(s);
13026424Ssam }
13126424Ssam
13226424Ssam /*
13326424Ssam * Print value v symbolically if it has a reasonable
13426424Ssam * interpretation as name+offset. If not, print nothing.
13526424Ssam * Used in printing out registers $r.
13626424Ssam */
valpr(v,idsp)13726424Ssam valpr(v, idsp)
13826424Ssam {
13926424Ssam register off_t d;
14026424Ssam
14126424Ssam d = findsym(v, idsp);
14226424Ssam if (d >= maxoff)
14326424Ssam return;
14426424Ssam printf("%s", cursym->n_un.n_name);
14526424Ssam if (d)
14626424Ssam printf(OFFMODE, d);
14726424Ssam }
148