This source file includes following definitions.
- db_aout_sym_init
- db_aout_lookup
- db_aout_search_symbol
- db_aout_symbol_values
- db_aout_line_at_pc
- db_aout_sym_numargs
- db_aout_forall
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/systm.h>
33 #include <sys/proc.h>
34
35 #include <machine/db_machdep.h>
36
37 #include <ddb/db_sym.h>
38 #include <ddb/db_output.h>
39 #include <ddb/db_extern.h>
40
41 #ifdef DB_AOUT_SYMBOLS
42
43 #include <ddb/db_aout.h>
44
45 boolean_t db_aout_sym_init(int, void *, void *, const char *);
46 db_sym_t db_aout_lookup(db_symtab_t *, char *);
47 db_sym_t db_aout_search_symbol(db_symtab_t *, db_addr_t,
48 db_strategy_t, db_expr_t *);
49 void db_aout_symbol_values(db_symtab_t *, db_sym_t,
50 char **, db_expr_t *);
51 boolean_t db_aout_line_at_pc(db_symtab_t *, db_sym_t,
52 char **, int *, db_expr_t);
53 boolean_t db_aout_sym_numargs(db_symtab_t *, db_sym_t, int *,
54 char **);
55 void db_aout_forall(db_symtab_t *,
56 db_forall_func_t db_forall_func, void *);
57
58 db_symformat_t db_symformat_aout = {
59 "a.out",
60 db_aout_sym_init,
61 db_aout_lookup,
62 db_aout_search_symbol,
63 db_aout_symbol_values,
64 db_aout_line_at_pc,
65 db_aout_sym_numargs,
66 db_aout_forall
67 };
68
69
70
71
72
73
74
75
76
77
78
79
80
81 static char *strtab;
82 static int slen;
83
84 #define X_db_getname(t, s) (s->n_un.n_strx ? t->end + s->n_un.n_strx : NULL)
85
86
87
88
89
90
91
92
93
94 boolean_t
95 db_aout_sym_init(int symsize, void *vsymtab, void *vesymtab, const char *name)
96 {
97 struct nlist *sym_start, *sym_end;
98 struct nlist *sp;
99 int bad = 0;
100 char *estrtab;
101
102
103
104
105
106 symsize = *(long *)vsymtab;
107 vsymtab = (void *)((long *)vsymtab + 1);
108
109
110 if (ALIGNED_POINTER(vsymtab, long) == 0) {
111 printf("[ %s symbol table has bad start address %p ]\n",
112 name, vsymtab);
113 return (FALSE);
114 }
115
116
117
118
119
120 sym_start = (struct nlist *)vsymtab;
121 sym_end = (struct nlist *)((char *)sym_start + symsize);
122
123 strtab = (char *)sym_end;
124 if (ALIGNED_POINTER(strtab, int) == 0) {
125 printf("[ %s symbol table has bad string table address %p ]\n",
126 name, strtab);
127 return (FALSE);
128 }
129 slen = *(int *)strtab;
130
131 estrtab = strtab + slen;
132
133 #define round_to_size(x) \
134 (((vaddr_t)(x) + sizeof(vsize_t) - 1) & ~(sizeof(vsize_t) - 1))
135
136 if (round_to_size(estrtab) != round_to_size(vesymtab)) {
137 printf("[ %s a.out symbol table not valid ]\n", name);
138 return (FALSE);
139 }
140 #undef round_to_size
141
142 for (sp = sym_start; sp < sym_end; sp++) {
143 int strx;
144 strx = sp->n_un.n_strx;
145 if (strx != 0) {
146 if (strx > slen) {
147 printf("[ %s has bad a.out string table index "
148 "(0x%x) ]\n",
149 name, strx);
150 bad = 1;
151 continue;
152 }
153 }
154 }
155
156 if (bad)
157 return (FALSE);
158
159 if (db_add_symbol_table((char *)sym_start, (char *)sym_end, name,
160 NULL) != -1) {
161 printf("[ using %ld bytes of %s a.out symbol table ]\n",
162 (long)vesymtab - (long)vsymtab, name);
163 return (TRUE);
164 }
165
166 return (FALSE);
167 }
168
169 db_sym_t
170 db_aout_lookup(db_symtab_t *stab, char *symstr)
171 {
172 struct nlist *sp, *ep;
173 char *n_name;
174
175 sp = (struct nlist *)stab->start;
176 ep = (struct nlist *)stab->end;
177
178 for (; sp < ep; sp++) {
179 if ((n_name = X_db_getname(stab, sp)) == 0)
180 continue;
181 if ((sp->n_type & N_STAB) == 0 &&
182 db_eqname(n_name, symstr, '_'))
183 return ((db_sym_t)sp);
184 }
185 return ((db_sym_t)0);
186 }
187
188 db_sym_t
189 db_aout_search_symbol(db_symtab_t *symtab, db_addr_t off,
190 db_strategy_t strategy, db_expr_t *diffp)
191 {
192 unsigned int diff = *diffp;
193 struct nlist *symp = 0;
194 struct nlist *sp, *ep;
195
196 sp = (struct nlist *)symtab->start;
197 ep = (struct nlist *)symtab->end;
198
199 for (; sp < ep; sp++) {
200 if ((sp->n_type & N_STAB) != 0 ||
201 (sp->n_type & N_TYPE) == N_FN)
202 continue;
203 if (X_db_getname(symtab, sp) == 0)
204 continue;
205 if (off >= sp->n_value) {
206 if (off - sp->n_value < diff) {
207 diff = off - sp->n_value;
208 symp = sp;
209 if (diff == 0 && ((strategy == DB_STGY_PROC &&
210 sp->n_type == (N_TEXT|N_EXT)) ||
211 (strategy == DB_STGY_ANY &&
212 (sp->n_type & N_EXT))))
213 break;
214 } else if (off - sp->n_value == diff) {
215 if (symp == 0)
216 symp = sp;
217 else if ((symp->n_type & N_EXT) == 0 &&
218 (sp->n_type & N_EXT) != 0)
219 symp = sp;
220 }
221 }
222 }
223 if (symp == 0) {
224 *diffp = off;
225 } else {
226 *diffp = diff;
227 }
228 return ((db_sym_t)symp);
229 }
230
231
232
233
234 void
235 db_aout_symbol_values(db_symtab_t *symtab, db_sym_t sym, char **namep,
236 db_expr_t *valuep)
237 {
238 struct nlist *sp;
239
240 sp = (struct nlist *)sym;
241 if (namep)
242 *namep = X_db_getname(symtab, sp);
243 if (valuep)
244 *valuep = sp->n_value;
245 }
246
247
248 boolean_t
249 db_aout_line_at_pc(db_symtab_t *symtab, db_sym_t cursym, char **filename,
250 int *linenum, db_expr_t off)
251 {
252 struct nlist *sp, *ep;
253 unsigned long sodiff = -1UL, lndiff = -1UL, ln = 0;
254 char *fname = NULL;
255
256 sp = (struct nlist *)symtab->start;
257 ep = (struct nlist *)symtab->end;
258
259
260 #define NEWSRC(str) ((str) != NULL && \
261 (str)[0] == 'g' && strcmp((str), "gcc_compiled.") == 0)
262
263 for (; sp < ep; sp++) {
264
265
266
267
268
269 #if 0
270 if (sp->n_value <= off && (off - sp->n_value) <= sodiff &&
271 NEWSRC(X_db_getname(symtab, sp))) {
272 #endif
273 if ((sp->n_type & N_TYPE) == N_FN ||
274 NEWSRC(X_db_getname(symtab, sp))) {
275 sodiff = lndiff = -1UL;
276 ln = 0;
277 fname = NULL;
278 }
279
280 if (sp->n_type == N_SO) {
281 if (sp->n_value <= off &&
282 (off - sp->n_value) < sodiff) {
283 sodiff = off - sp->n_value;
284 fname = X_db_getname(symtab, sp);
285 }
286 continue;
287 }
288
289 if (sp->n_type != N_SLINE)
290 continue;
291
292 if (sp->n_value > off)
293 break;
294
295 if (off - sp->n_value < lndiff) {
296 lndiff = off - sp->n_value;
297 ln = sp->n_desc;
298 }
299 }
300
301 if (fname != NULL && ln != 0) {
302 *filename = fname;
303 *linenum = ln;
304 return (TRUE);
305 }
306
307 return (FALSE);
308 }
309
310 boolean_t
311 db_aout_sym_numargs(db_symtab_t *symtab, db_sym_t cursym, int *nargp,
312 char **argnamep)
313 {
314 struct nlist *sp, *ep;
315 u_long addr;
316 int maxnarg = *nargp, nargs = 0;
317 char *n_name;
318
319 if (cursym == NULL)
320 return (FALSE);
321
322 addr = ((struct nlist *)cursym)->n_value;
323 sp = (struct nlist *)symtab->start;
324 ep = (struct nlist *)symtab->end;
325
326 for (; sp < ep; sp++) {
327 if (sp->n_type == N_FUN && sp->n_value == addr) {
328 while (++sp < ep && sp->n_type == N_PSYM) {
329 if (nargs >= maxnarg)
330 break;
331 nargs++;
332 n_name = X_db_getname(symtab, sp);
333 *argnamep++ = n_name ? n_name : "???";
334 {
335
336 char *cp = *(argnamep - 1);
337
338 while (*cp != '\0' && *cp != ':')
339 cp++;
340 if (*cp == ':') *cp = '\0';
341 }
342 }
343 *nargp = nargs;
344 return (TRUE);
345 }
346 }
347 return (FALSE);
348 }
349
350 void
351 db_aout_forall(db_symtab_t *stab, db_forall_func_t db_forall_func, void *arg)
352 {
353 static char suffix[2];
354 struct nlist *sp, *ep;
355
356 sp = (struct nlist *)stab->start;
357 ep = (struct nlist *)stab->end;
358
359 for (; sp < ep; sp++) {
360 if (X_db_getname(stab, sp) == 0)
361 continue;
362 if ((sp->n_type & N_STAB) == 0) {
363 suffix[1] = '\0';
364 switch(sp->n_type & N_TYPE) {
365 case N_ABS:
366 suffix[0] = '@';
367 break;
368 case N_TEXT:
369 suffix[0] = '*';
370 break;
371 case N_DATA:
372 suffix[0] = '+';
373 break;
374 case N_BSS:
375 suffix[0] = '-';
376 break;
377 case N_FN:
378 suffix[0] = '/';
379 break;
380 default:
381 suffix[0] = '\0';
382 }
383 (*db_forall_func)(stab, (db_sym_t)sp,
384 X_db_getname(stab, sp), suffix, '_', arg);
385 }
386 }
387 return;
388 }
389
390
391 #endif