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