Commit | Line | Data |
---|---|---|
05dfd780 | 1 | static char sccsid[] = "@(#)sym.c 4.3 %G%"; |
7222ebf4 BJ |
2 | /* |
3 | * adb - symbol table routines | |
4 | */ | |
5 | #include "defs.h" | |
6 | #include <stab.h> | |
7 | ||
8 | /* | |
9 | * Lookup a symbol by name. | |
10 | */ | |
11 | struct nlist * | |
12 | lookup(symstr) | |
13 | char *symstr; | |
14 | { | |
15 | register struct nlist *sp; | |
16 | ||
17 | cursym = 0; | |
18 | if (symtab) | |
19 | for (sp = symtab; sp < esymtab; sp++) | |
20 | /* SHOULD DO SOME OF EQSYM INLINE TO SAVE TIME */ | |
21 | if ((sp->n_type&N_STAB)==0 && eqsym(sp->n_un.n_name, symstr, '_')) | |
22 | return(cursym = sp); | |
23 | return (0); | |
24 | } | |
25 | ||
26 | /* | |
27 | * Find the closest symbol to val, and return | |
28 | * the difference between val and the symbol found. | |
29 | * Leave a pointer to the symbol found as cursym. | |
30 | */ | |
31 | findsym(val, type) | |
32 | long val; | |
33 | int type; | |
34 | { | |
35 | long diff; | |
36 | register struct nlist *sp; | |
37 | ||
38 | cursym = 0; | |
39 | diff = MAXINT; | |
40 | if (type == NSYM || symtab == 0) | |
41 | return (diff); | |
42 | for (sp = symtab; sp < esymtab; sp++) { | |
05dfd780 KB |
43 | if (sp->n_type & N_STAB || !(sp->n_type & N_EXT) |
44 | || sp->n_type == (N_FN|N_EXT)) | |
7222ebf4 BJ |
45 | continue; |
46 | if (val - sp->n_value < diff && val >= sp->n_value) { | |
47 | diff = val - sp->n_value; | |
48 | cursym = sp; | |
49 | if (diff == 0) | |
50 | break; | |
51 | } | |
52 | } | |
53 | return (diff); | |
54 | } | |
55 | ||
56 | /* | |
57 | * Advance cursym to the next local variable. | |
58 | * Leave its value in localval as a side effect. | |
59 | * Return 0 at end of file. | |
60 | */ | |
61 | localsym(cframe, cargp) | |
62 | ADDR cframe, cargp; | |
63 | { | |
64 | register int type; | |
65 | register struct nlist *sp; | |
66 | ||
67 | if (cursym) | |
68 | for (sp = cursym; ++sp < esymtab; ) { | |
69 | if (sp->n_un.n_name[0] =='_' || sp->n_type == N_FN) | |
70 | return (0); | |
71 | type = sp->n_type; | |
72 | switch (sp->n_type) { | |
73 | ||
74 | case N_TEXT: | |
75 | case N_TEXT|N_EXT: | |
76 | case N_DATA: | |
77 | case N_DATA|N_EXT: | |
78 | case N_BSS: | |
79 | case N_BSS|N_EXT: | |
80 | localval = sp->n_value; | |
81 | cursym = sp; | |
82 | return (1); | |
83 | ||
84 | case N_LSYM: | |
85 | localval = cframe - sp->n_value; | |
86 | cursym = sp; | |
87 | return (1); | |
88 | ||
89 | case N_PSYM: | |
90 | /* code below works since n_value > 0 */ | |
91 | case N_ABS: | |
92 | if (sp->n_value < 0) | |
93 | localval = cframe + sp->n_value; | |
94 | else | |
95 | localval = cargp + sp->n_value; | |
96 | cursym = sp; | |
97 | return (1); | |
98 | } | |
99 | } | |
100 | cursym = 0; | |
101 | return (0); | |
102 | } | |
103 | ||
104 | /* | |
105 | * Print value v and then the string s. | |
106 | * If v is not zero, then we look for a nearby symbol | |
107 | * and print name+offset if we find a symbol for which | |
108 | * offset is small enough. | |
109 | * | |
110 | * For values which are just into kernel address space | |
111 | * that they match exactly or that they be more than maxoff | |
112 | * bytes into kernel space. | |
113 | */ | |
114 | psymoff(v, type, s) | |
115 | long v; | |
116 | int type; | |
117 | char *s; | |
118 | { | |
119 | long w; | |
120 | ||
121 | if (v) | |
122 | w = findsym(v, type); | |
6a7922eb | 123 | if (v==0 || w >= maxoff || (INKERNEL(v) && KVTOPH(v) < maxoff && w)) |
7222ebf4 BJ |
124 | printf(LPRMODE, v); |
125 | else { | |
126 | printf("%s", cursym->n_un.n_name); | |
127 | if (w) | |
128 | printf(OFFMODE, w); | |
129 | } | |
130 | printf(s); | |
131 | } | |
132 | ||
133 | /* | |
134 | * Print value v symbolically if it has a reasonable | |
135 | * interpretation as name+offset. If not, print nothing. | |
136 | * Used in printing out registers $r. | |
137 | */ | |
138 | valpr(v, idsp) | |
139 | long v; | |
140 | { | |
141 | off_t d; | |
142 | ||
143 | d = findsym(v, idsp); | |
144 | if (d >= maxoff) | |
145 | return; | |
146 | printf("%s", cursym->n_un.n_name); | |
147 | if (d) | |
148 | printf(OFFMODE, d); | |
149 | } |