xref: /csrg-svn/old/adb/common_source/sym.c (revision 47822)
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