130296Ssam /*
230296Ssam * Copyright (c) 1986 Regents of the University of California.
330296Ssam * All rights reserved. The Berkeley software License Agreement
430296Ssam * specifies the terms and conditions for redistribution.
530296Ssam *
6*41343Ssklower * @(#)kdb_sym.c 7.3 (Berkeley) 05/03/90
730296Ssam */
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 */
kdbsetsym(sym,esym,strtab,strsize)18*41343Ssklower kdbsetsym(sym, esym, strtab, strsize)
1930296Ssam char *sym, *esym, *strtab;
2030112Ssam {
2130112Ssam register struct nlist *sp;
2230112Ssam
23*41343Ssklower kdbsymtab = (struct nlist *)sym, kdbesymtab = (struct nlist *)esym;
24*41343Ssklower for (sp = kdbsymtab; sp < kdbesymtab; sp++)
2530112Ssam if (sp->n_un.n_strx) {
2630112Ssam if (sp->n_un.n_strx > strsize) {
27*41343Ssklower kdbprintf("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 *
kdblookup(symstr)40*41343Ssklower kdblookup(symstr)
4130112Ssam char *symstr;
4230112Ssam {
4330112Ssam register struct nlist *sp;
4430112Ssam
45*41343Ssklower kdbcursym = 0;
46*41343Ssklower if (kdbsymtab)
47*41343Ssklower for (sp = kdbsymtab; sp < kdbesymtab; sp++)
4830112Ssam /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */
49*41343Ssklower if ((sp->n_type&N_STAB)==0 && kdbeqsym(sp->n_un.n_name, symstr, '_'))
50*41343Ssklower return(kdbcursym = 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 */
kdbfindsym(val,type)59*41343Ssklower kdbfindsym(val, type)
6030296Ssam register long val;
6130112Ssam int type;
6230112Ssam {
6330112Ssam register diff;
6430112Ssam register struct nlist *sp;
6530112Ssam
66*41343Ssklower kdbcursym = 0;
6730112Ssam diff = MAXINT;
68*41343Ssklower if (type == NSYM || kdbsymtab == 0)
6930112Ssam return (diff);
70*41343Ssklower for (sp = kdbsymtab; sp < kdbesymtab; 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;
75*41343Ssklower kdbcursym = 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 */
kdblocalsym(cframe)88*41343Ssklower kdblocalsym(cframe)
8930296Ssam long cframe;
9030112Ssam {
9130112Ssam register int type;
9230112Ssam register struct nlist *sp;
9330112Ssam
94*41343Ssklower if (kdbcursym)
95*41343Ssklower for (sp = kdbcursym; ++sp < kdbesymtab; ) {
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:
107*41343Ssklower kdblocalval = sp->n_value;
108*41343Ssklower kdbcursym = sp;
10930112Ssam return (1);
11030112Ssam
11130112Ssam case N_LSYM:
112*41343Ssklower kdblocalval = cframe - sp->n_value;
113*41343Ssklower kdbcursym = sp;
11430112Ssam return (1);
11530112Ssam
11630112Ssam case N_PSYM:
11730112Ssam case N_ABS:
118*41343Ssklower kdblocalval = cframe + sp->n_value;
119*41343Ssklower kdbcursym = sp;
12030112Ssam return (1);
12130112Ssam }
12230112Ssam }
123*41343Ssklower kdbcursym = 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 */
kdbpsymoff(v,type,s)137*41343Ssklower kdbpsymoff(v, type, s)
13830296Ssam register long v;
13930112Ssam int type;
14030112Ssam char *s;
14130112Ssam {
14230112Ssam register w;
14330112Ssam
14430112Ssam if (v)
145*41343Ssklower w = kdbfindsym(v, type);
146*41343Ssklower if (v==0 || w >= kdbmaxoff)
147*41343Ssklower kdbprintf(LPRMODE, v);
14830112Ssam else {
149*41343Ssklower kdbprintf("%s", kdbcursym->n_un.n_name);
15030112Ssam if (w)
151*41343Ssklower kdbprintf(OFFMODE, w);
15230112Ssam }
153*41343Ssklower kdbprintf(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 */
kdbvalpr(v,idsp)161*41343Ssklower kdbvalpr(v, idsp)
16230296Ssam long v;
16330112Ssam {
16430112Ssam register off_t d;
16530112Ssam
166*41343Ssklower d = kdbfindsym(v, idsp);
167*41343Ssklower if (d >= kdbmaxoff)
16830112Ssam return;
169*41343Ssklower kdbprintf("%s", kdbcursym->n_un.n_name);
17030112Ssam if (d)
171*41343Ssklower kdbprintf(OFFMODE, d);
17230112Ssam }
173