1*47822Sbostic /*-
2*47822Sbostic * Copyright (c) 1991 The Regents of the University of California.
3*47822Sbostic * All rights reserved.
4*47822Sbostic *
5*47822Sbostic * %sccs.include.proprietary.c%
6*47822Sbostic */
7*47822Sbostic
836559Sbostic #ifndef lint
9*47822Sbostic static char sccsid[] = "@(#)sym.c 5.3 (Berkeley) 04/04/91";
10*47822Sbostic #endif /* not lint */
1136559Sbostic
1236559Sbostic /*
1336559Sbostic * adb - symbol table routines
1436559Sbostic */
1536559Sbostic #include "defs.h"
1636559Sbostic #include <stab.h>
1736559Sbostic
1836559Sbostic #define isstab(sp) ((sp)->n_type & N_STAB)
1936559Sbostic
2036559Sbostic /*
2136559Sbostic * Lookup a symbol by name.
2236559Sbostic */
2336559Sbostic struct nlist *
lookup(symstr)2436559Sbostic lookup(symstr)
2536559Sbostic register char *symstr;
2636559Sbostic {
2736559Sbostic register struct nlist *sp;
2836559Sbostic
2936559Sbostic if (symtab)
3036559Sbostic for (sp = symtab; sp < esymtab; sp++)
3136559Sbostic if (!isstab(sp) && eqsym(sp->n_un.n_name, symstr, '_'))
3236559Sbostic return (sp);
3336559Sbostic return (0);
3436559Sbostic }
3536559Sbostic
3636559Sbostic /*
3736559Sbostic * Find the closest symbol to val, and return it and (through
3836559Sbostic * diffp) the difference between val and the symbol found.
3936559Sbostic */
4036559Sbostic struct nlist *
findsym(val,space,diffp)4136559Sbostic findsym(val, space, diffp)
4236559Sbostic register addr_t val;
4336559Sbostic int space;
4436559Sbostic addr_t *diffp;
4536559Sbostic {
4636559Sbostic register struct nlist *sp;
4736559Sbostic register addr_t diff;
4836559Sbostic struct nlist *sym;
4936559Sbostic
5036559Sbostic diff = ~(addr_t)0;
5136559Sbostic sym = NULL;
5237338Storek if (space != SP_NONE && symtab != NULL) {
5336559Sbostic for (sp = symtab; sp < esymtab; sp++) {
5436559Sbostic /* must be global */
5536559Sbostic if (isstab(sp) || (sp->n_type & N_EXT) == 0)
5636559Sbostic continue;
5736559Sbostic /* and not a function */
5836559Sbostic if (sp->n_type == (N_FN|N_EXT))
5936559Sbostic continue;
6036559Sbostic /* and have a greater address */
6136559Sbostic if (val < sp->n_value)
6236559Sbostic continue;
6336559Sbostic /* and be closer than the last one */
6436559Sbostic if (val - sp->n_value >= diff)
6536559Sbostic continue;
6636559Sbostic sym = sp;
6736559Sbostic diff = val - sp->n_value;
6836559Sbostic if (diff == 0)
6936559Sbostic break;
7036559Sbostic }
7136559Sbostic }
7236559Sbostic *diffp = diff;
7336559Sbostic return (sym);
7436559Sbostic }
7536559Sbostic
7636559Sbostic /*
7736559Sbostic * Return the next local symbol after sym, or NULL at end of such locals.
7836559Sbostic */
7936559Sbostic /* ARGSUSED */
8036559Sbostic struct nlist *
nextlocal(sym)8136559Sbostic nextlocal(sym)
8236559Sbostic struct nlist *sym;
8336559Sbostic {
8436559Sbostic
8536559Sbostic #ifdef busted
8636559Sbostic /*
8736559Sbostic * none of this works at the moment, because the symbols are not in
8836559Sbostic * the desired order.
8936559Sbostic */
9036559Sbostic if (sym == NULL)
9136559Sbostic return (NULL);
9236559Sbostic while (++sym < esymtab) {
9336559Sbostic /*
9436559Sbostic * External and file name symbols terminate the
9536559Sbostic * list of local symbols. Otherwise, if it is
9636559Sbostic * a .stabs parameter or local symbol, take it.
9736559Sbostic */
9836559Sbostic if ((sym->n_type & N_EXT) || sym->n_type == N_FN)
9936559Sbostic break;
10036559Sbostic if (sym->n_type == N_LSYM || sym->n_type == N_PSYM)
10136559Sbostic return (sym);
10236559Sbostic }
10336559Sbostic #endif
10436559Sbostic return (NULL);
10536559Sbostic }
10636559Sbostic
10736559Sbostic /*
10836559Sbostic * Print value v (in format f) and then (as another format) s.
10936559Sbostic * If v is not zero, we look for a nearby symbol and print name+offset
11036559Sbostic * if we find a symbol whose offset is small enough (less than o).
11136559Sbostic */
psymoff(f,v,space,o,s)11236559Sbostic psymoff(f, v, space, o, s)
11336559Sbostic char *f;
11436559Sbostic addr_t v;
11536559Sbostic int space;
11636559Sbostic addr_t o;
11736559Sbostic char *s;
11836559Sbostic {
11936559Sbostic struct nlist *sp;
12036559Sbostic addr_t offset;
12136559Sbostic
12236559Sbostic if (v && (sp = findsym(v, space, &offset)) != NULL && offset < o)
12336559Sbostic adbprintf("%s%?+R", sp->n_un.n_name,
12436559Sbostic offset != 0, (expr_t)offset);
12536559Sbostic else
12636559Sbostic adbprintf(f, (expr_t)v);
12736559Sbostic adbprintf(s);
12836559Sbostic }
12936559Sbostic
13036559Sbostic /*
13136559Sbostic * Print value v symbolically if it has a reasonable
13236559Sbostic * interpretation as name+offset. If not, print nothing.
13336559Sbostic * Used in printing out registers $r.
13436559Sbostic */
valpr(v,space)13536559Sbostic valpr(v, space)
13636559Sbostic addr_t v;
13736559Sbostic int space;
13836559Sbostic {
13936559Sbostic struct nlist *sp;
14036559Sbostic addr_t offset;
14136559Sbostic
14236559Sbostic if (v && (sp = findsym(v, space, &offset)) != NULL && offset < maxoff)
14336559Sbostic adbprintf("%s%?+R", sp->n_un.n_name,
14436559Sbostic offset != 0, (expr_t)offset);
14536559Sbostic }
146