1*30296Ssam /* 2*30296Ssam * Copyright (c) 1986 Regents of the University of California. 3*30296Ssam * All rights reserved. The Berkeley software License Agreement 4*30296Ssam * specifies the terms and conditions for redistribution. 5*30296Ssam * 6*30296Ssam * @(#)kdb_sym.c 7.2 (Berkeley) 12/15/86 7*30296Ssam */ 830112Ssam 930112Ssam /* 1030112Ssam * adb - symbol table routines 1130112Ssam */ 1230112Ssam #include "../kdb/defs.h" 1330112Ssam #include <stab.h> 1430112Ssam 1530112Ssam /* 1630112Ssam * Initialize the symbol table. 1730112Ssam */ 1830112Ssam setsym(sym, esym, strtab, strsize) 19*30296Ssam char *sym, *esym, *strtab; 2030112Ssam { 2130112Ssam register struct nlist *sp; 2230112Ssam 23*30296Ssam symtab = (struct nlist *)sym, esymtab = (struct nlist *)esym; 2430112Ssam for (sp = symtab; sp < esymtab; sp++) 2530112Ssam if (sp->n_un.n_strx) { 2630112Ssam if (sp->n_un.n_strx > strsize) { 2730112Ssam printf("setsym: Bad string table index (%d)\n", 2830112Ssam sp->n_un.n_strx); 2930112Ssam sp->n_un.n_strx = 0; /* XXX */ 3030112Ssam continue; 3130112Ssam } 3230112Ssam sp->n_un.n_name = strtab + sp->n_un.n_strx; 3330112Ssam } 3430112Ssam } 3530112Ssam 3630112Ssam /* 3730112Ssam * Lookup a symbol by name. 3830112Ssam */ 3930112Ssam struct nlist * 4030112Ssam lookup(symstr) 4130112Ssam char *symstr; 4230112Ssam { 4330112Ssam register struct nlist *sp; 4430112Ssam 4530112Ssam cursym = 0; 4630112Ssam if (symtab) 4730112Ssam for (sp = symtab; sp < esymtab; sp++) 4830112Ssam /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */ 4930112Ssam if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_')) 5030112Ssam return(cursym = sp); 5130112Ssam return (0); 5230112Ssam } 5330112Ssam 5430112Ssam /* 5530112Ssam * Find the closest symbol to val, and return 5630112Ssam * the difference between val and the symbol found. 5730112Ssam * Leave a pointer to the symbol found as cursym. 5830112Ssam */ 5930112Ssam findsym(val, type) 60*30296Ssam register long val; 6130112Ssam int type; 6230112Ssam { 6330112Ssam register diff; 6430112Ssam register struct nlist *sp; 6530112Ssam 6630112Ssam cursym = 0; 6730112Ssam diff = MAXINT; 6830112Ssam if (type == NSYM || symtab == 0) 6930112Ssam return (diff); 7030112Ssam for (sp = symtab; sp < esymtab; sp++) { 7130112Ssam if (sp->n_type&N_STAB || (sp->n_type&N_EXT)==0) 7230112Ssam continue; 7330112Ssam if (val - sp->n_value < diff && val >= sp->n_value) { 7430112Ssam diff = val - sp->n_value; 7530112Ssam cursym = sp; 7630112Ssam if (diff == 0) 7730112Ssam break; 7830112Ssam } 7930112Ssam } 8030112Ssam return (diff); 8130112Ssam } 8230112Ssam 8330112Ssam /* 8430112Ssam * Advance cursym to the next local variable. 8530112Ssam * Leave its value in localval as a side effect. 8630112Ssam * Return 0 at end of file. 8730112Ssam */ 8830112Ssam localsym(cframe) 89*30296Ssam long cframe; 9030112Ssam { 9130112Ssam register int type; 9230112Ssam register struct nlist *sp; 9330112Ssam 9430112Ssam if (cursym) 9530112Ssam for (sp = cursym; ++sp < esymtab; ) { 9630112Ssam type = sp->n_type; 9730112Ssam if (sp->n_un.n_name[0] =='_' || type == N_FN) 9830112Ssam return (0); 9930112Ssam switch (type) { 10030112Ssam 10130112Ssam case N_TEXT: 10230112Ssam case N_TEXT|N_EXT: 10330112Ssam case N_DATA: 10430112Ssam case N_DATA|N_EXT: 10530112Ssam case N_BSS: 10630112Ssam case N_BSS|N_EXT: 10730112Ssam localval = sp->n_value; 10830112Ssam cursym = sp; 10930112Ssam return (1); 11030112Ssam 11130112Ssam case N_LSYM: 11230112Ssam localval = cframe - sp->n_value; 11330112Ssam cursym = sp; 11430112Ssam return (1); 11530112Ssam 11630112Ssam case N_PSYM: 11730112Ssam case N_ABS: 11830112Ssam localval = cframe + sp->n_value; 11930112Ssam cursym = sp; 12030112Ssam return (1); 12130112Ssam } 12230112Ssam } 12330112Ssam cursym = 0; 12430112Ssam return (0); 12530112Ssam } 12630112Ssam 12730112Ssam /* 12830112Ssam * Print value v and then the string s. 12930112Ssam * If v is not zero, then we look for a nearby symbol 13030112Ssam * and print name+offset if we find a symbol for which 13130112Ssam * offset is small enough. 13230112Ssam * 13330112Ssam * For values which are just into kernel address space 13430112Ssam * that they match exactly or that they be more than maxoff 13530112Ssam * bytes into kernel space. 13630112Ssam */ 13730112Ssam psymoff(v, type, s) 138*30296Ssam register long v; 13930112Ssam int type; 14030112Ssam char *s; 14130112Ssam { 14230112Ssam register w; 14330112Ssam 14430112Ssam if (v) 14530112Ssam w = findsym(v, type); 14630112Ssam if (v==0 || w >= maxoff) 14730112Ssam printf(LPRMODE, v); 14830112Ssam else { 14930112Ssam printf("%s", cursym->n_un.n_name); 15030112Ssam if (w) 15130112Ssam printf(OFFMODE, w); 15230112Ssam } 15330112Ssam printf(s); 15430112Ssam } 15530112Ssam 15630112Ssam /* 15730112Ssam * Print value v symbolically if it has a reasonable 15830112Ssam * interpretation as name+offset. If not, print nothing. 15930112Ssam * Used in printing out registers $r. 16030112Ssam */ 16130112Ssam valpr(v, idsp) 162*30296Ssam long v; 16330112Ssam { 16430112Ssam register off_t d; 16530112Ssam 16630112Ssam d = findsym(v, idsp); 16730112Ssam if (d >= maxoff) 16830112Ssam return; 16930112Ssam printf("%s", cursym->n_un.n_name); 17030112Ssam if (d) 17130112Ssam printf(OFFMODE, d); 17230112Ssam } 173