1*30968Sbostic static char sccsid[] = "@(#)sym.c 4.3 04/27/87";
23767Sroot /*
33767Sroot * adb - symbol table routines
43767Sroot */
53767Sroot #include "defs.h"
63767Sroot #include <stab.h>
73767Sroot
83767Sroot /*
93767Sroot * Lookup a symbol by name.
103767Sroot */
113767Sroot struct nlist *
lookup(symstr)123767Sroot lookup(symstr)
133767Sroot char *symstr;
143767Sroot {
153767Sroot register struct nlist *sp;
163767Sroot
173767Sroot cursym = 0;
183767Sroot if (symtab)
193767Sroot for (sp = symtab; sp < esymtab; sp++)
203767Sroot /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
213767Sroot if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_'))
223767Sroot return(cursym = sp);
233767Sroot return (0);
243767Sroot }
253767Sroot
263767Sroot /*
273767Sroot * Find the closest symbol to val, and return
283767Sroot * the difference between val and the symbol found.
293767Sroot * Leave a pointer to the symbol found as cursym.
303767Sroot */
findsym(val,type)313767Sroot findsym(val, type)
323767Sroot long val;
333767Sroot int type;
343767Sroot {
353767Sroot long diff;
363767Sroot register struct nlist *sp;
373767Sroot
383767Sroot cursym = 0;
393767Sroot diff = MAXINT;
403767Sroot if (type == NSYM || symtab == 0)
413767Sroot return (diff);
423767Sroot for (sp = symtab; sp < esymtab; sp++) {
43*30968Sbostic if (sp->n_type & N_STAB || !(sp->n_type & N_EXT)
44*30968Sbostic || sp->n_type == (N_FN|N_EXT))
453767Sroot continue;
463767Sroot if (val - sp->n_value < diff && val >= sp->n_value) {
473767Sroot diff = val - sp->n_value;
483767Sroot cursym = sp;
493767Sroot if (diff == 0)
503767Sroot break;
513767Sroot }
523767Sroot }
533767Sroot return (diff);
543767Sroot }
553767Sroot
563767Sroot /*
573767Sroot * Advance cursym to the next local variable.
583767Sroot * Leave its value in localval as a side effect.
593767Sroot * Return 0 at end of file.
603767Sroot */
localsym(cframe,cargp)613767Sroot localsym(cframe, cargp)
623767Sroot ADDR cframe, cargp;
633767Sroot {
643767Sroot register int type;
653767Sroot register struct nlist *sp;
663767Sroot
673767Sroot if (cursym)
683767Sroot for (sp = cursym; ++sp < esymtab; ) {
693767Sroot if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN)
703767Sroot return (0);
713767Sroot type = sp->n_type;
723767Sroot switch (sp->n_type) {
733767Sroot
743767Sroot case N_TEXT:
753767Sroot case N_TEXT|N_EXT:
763767Sroot case N_DATA:
773767Sroot case N_DATA|N_EXT:
783767Sroot case N_BSS:
793767Sroot case N_BSS|N_EXT:
803767Sroot localval = sp->n_value;
813767Sroot cursym = sp;
823767Sroot return (1);
833767Sroot
843767Sroot case N_LSYM:
853767Sroot localval = cframe - sp->n_value;
863767Sroot cursym = sp;
873767Sroot return (1);
883767Sroot
893767Sroot case N_PSYM:
903767Sroot /* code below works since n_value > 0 */
913767Sroot case N_ABS:
923767Sroot if (sp->n_value < 0)
933767Sroot localval = cframe + sp->n_value;
943767Sroot else
953767Sroot localval = cargp + sp->n_value;
963767Sroot cursym = sp;
973767Sroot return (1);
983767Sroot }
993767Sroot }
1003767Sroot cursym = 0;
1013767Sroot return (0);
1023767Sroot }
1033767Sroot
1043767Sroot /*
1053767Sroot * Print value v and then the string s.
1063767Sroot * If v is not zero, then we look for a nearby symbol
1073767Sroot * and print name+offset if we find a symbol for which
1083767Sroot * offset is small enough.
1093767Sroot *
1103767Sroot * For values which are just into kernel address space
1113767Sroot * that they match exactly or that they be more than maxoff
1123767Sroot * bytes into kernel space.
1133767Sroot */
psymoff(v,type,s)1143767Sroot psymoff(v, type, s)
1153767Sroot long v;
1163767Sroot int type;
1173767Sroot char *s;
1183767Sroot {
1193767Sroot long w;
1203767Sroot
1213767Sroot if (v)
1223767Sroot w = findsym(v, type);
12318501Sedward if (v==0 || w >= maxoff || (INKERNEL(v) && KVTOPH(v) < maxoff && w))
1243767Sroot printf(LPRMODE, v);
1253767Sroot else {
1263767Sroot printf("%s", cursym->n_un.n_name);
1273767Sroot if (w)
1283767Sroot printf(OFFMODE, w);
1293767Sroot }
1303767Sroot printf(s);
1313767Sroot }
1323767Sroot
1333767Sroot /*
1343767Sroot * Print value v symbolically if it has a reasonable
1353767Sroot * interpretation as name+offset. If not, print nothing.
1363767Sroot * Used in printing out registers $r.
1373767Sroot */
valpr(v,idsp)1383767Sroot valpr(v, idsp)
1393767Sroot long v;
1403767Sroot {
1413767Sroot off_t d;
1423767Sroot
1433767Sroot d = findsym(v, idsp);
1443767Sroot if (d >= maxoff)
1453767Sroot return;
1463767Sroot printf("%s", cursym->n_un.n_name);
1473767Sroot if (d)
1483767Sroot printf(OFFMODE, d);
1493767Sroot }
150