1*18501Sedward static char sccsid[] = "@(#)sym.c 4.2 03/24/85"; 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 * 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 */ 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++) { 433767Sroot if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0) 443767Sroot continue; 453767Sroot if (val - sp->n_value < diff && val >= sp->n_value) { 463767Sroot diff = val - sp->n_value; 473767Sroot cursym = sp; 483767Sroot if (diff == 0) 493767Sroot break; 503767Sroot } 513767Sroot } 523767Sroot return (diff); 533767Sroot } 543767Sroot 553767Sroot /* 563767Sroot * Advance cursym to the next local variable. 573767Sroot * Leave its value in localval as a side effect. 583767Sroot * Return 0 at end of file. 593767Sroot */ 603767Sroot localsym(cframe, cargp) 613767Sroot ADDR cframe, cargp; 623767Sroot { 633767Sroot register int type; 643767Sroot register struct nlist *sp; 653767Sroot 663767Sroot if (cursym) 673767Sroot for (sp = cursym; ++sp < esymtab; ) { 683767Sroot if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN) 693767Sroot return (0); 703767Sroot type = sp->n_type; 713767Sroot switch (sp->n_type) { 723767Sroot 733767Sroot case N_TEXT: 743767Sroot case N_TEXT|N_EXT: 753767Sroot case N_DATA: 763767Sroot case N_DATA|N_EXT: 773767Sroot case N_BSS: 783767Sroot case N_BSS|N_EXT: 793767Sroot localval = sp->n_value; 803767Sroot cursym = sp; 813767Sroot return (1); 823767Sroot 833767Sroot case N_LSYM: 843767Sroot localval = cframe - sp->n_value; 853767Sroot cursym = sp; 863767Sroot return (1); 873767Sroot 883767Sroot case N_PSYM: 893767Sroot /* code below works since n_value > 0 */ 903767Sroot case N_ABS: 913767Sroot if (sp->n_value < 0) 923767Sroot localval = cframe + sp->n_value; 933767Sroot else 943767Sroot localval = cargp + sp->n_value; 953767Sroot cursym = sp; 963767Sroot return (1); 973767Sroot } 983767Sroot } 993767Sroot cursym = 0; 1003767Sroot return (0); 1013767Sroot } 1023767Sroot 1033767Sroot /* 1043767Sroot * Print value v and then the string s. 1053767Sroot * If v is not zero, then we look for a nearby symbol 1063767Sroot * and print name+offset if we find a symbol for which 1073767Sroot * offset is small enough. 1083767Sroot * 1093767Sroot * For values which are just into kernel address space 1103767Sroot * that they match exactly or that they be more than maxoff 1113767Sroot * bytes into kernel space. 1123767Sroot */ 1133767Sroot psymoff(v, type, s) 1143767Sroot long v; 1153767Sroot int type; 1163767Sroot char *s; 1173767Sroot { 1183767Sroot long w; 1193767Sroot 1203767Sroot if (v) 1213767Sroot w = findsym(v, type); 122*18501Sedward if (v==0 || w >= maxoff || (INKERNEL(v) && KVTOPH(v) < maxoff && w)) 1233767Sroot printf(LPRMODE, v); 1243767Sroot else { 1253767Sroot printf("%s", cursym->n_un.n_name); 1263767Sroot if (w) 1273767Sroot printf(OFFMODE, w); 1283767Sroot } 1293767Sroot printf(s); 1303767Sroot } 1313767Sroot 1323767Sroot /* 1333767Sroot * Print value v symbolically if it has a reasonable 1343767Sroot * interpretation as name+offset. If not, print nothing. 1353767Sroot * Used in printing out registers $r. 1363767Sroot */ 1373767Sroot valpr(v, idsp) 1383767Sroot long v; 1393767Sroot { 1403767Sroot off_t d; 1413767Sroot 1423767Sroot d = findsym(v, idsp); 1433767Sroot if (d >= maxoff) 1443767Sroot return; 1453767Sroot printf("%s", cursym->n_un.n_name); 1463767Sroot if (d) 1473767Sroot printf(OFFMODE, d); 1483767Sroot } 149