7b4ac7e1 |
1 | /* Symbol table lookup for the GNU debugger, GDB. |
2 | Copyright (C) 1986, 1987 Free Software Foundation, Inc. |
3 | |
4 | GDB is distributed in the hope that it will be useful, but WITHOUT ANY |
5 | WARRANTY. No author or distributor accepts responsibility to anyone |
6 | for the consequences of using it or for whether it serves any |
7 | particular purpose or works at all, unless he says so in writing. |
8 | Refer to the GDB General Public License for full details. |
9 | |
10 | Everyone is granted permission to copy, modify and redistribute GDB, |
11 | but only under the conditions described in the GDB General Public |
12 | License. A copy of this license is supposed to have been given to you |
13 | along with GDB so you can know your rights and responsibilities. It |
14 | should be in a file named COPYING. Among other things, the copyright |
15 | notice and this notice must be preserved on all copies. |
16 | |
17 | In other words, go ahead and share GDB, but don't try to stop |
18 | anyone else from sharing it farther. Help stamp out software hoarding! |
19 | */ |
20 | |
21 | #include "defs.h" |
22 | #include "initialize.h" |
23 | #include "symtab.h" |
24 | #include "param.h" |
25 | |
26 | #include <stdio.h> |
27 | #include <obstack.h> |
28 | |
29 | #ifdef mac_aux |
30 | #define REGCMP |
31 | #endif |
32 | |
33 | START_FILE |
34 | |
35 | /* Allocate an obstack to hold objects that should be freed |
36 | when we load a new symbol table. |
37 | This includes the symbols made by dbxread |
38 | and the types that are not permanent. */ |
39 | |
40 | struct obstack obstack1; |
41 | |
42 | struct obstack *symbol_obstack = &obstack1; |
43 | |
44 | /* These variables point to the objects |
45 | representing the predefined C data types. */ |
46 | |
47 | struct type *builtin_type_void; |
48 | struct type *builtin_type_char; |
49 | struct type *builtin_type_short; |
50 | struct type *builtin_type_int; |
51 | struct type *builtin_type_long; |
52 | struct type *builtin_type_unsigned_char; |
53 | struct type *builtin_type_unsigned_short; |
54 | struct type *builtin_type_unsigned_int; |
55 | struct type *builtin_type_unsigned_long; |
56 | struct type *builtin_type_float; |
57 | struct type *builtin_type_double; |
58 | |
59 | /* Lookup the symbol table of a source file named NAME. */ |
60 | |
61 | struct symtab * |
62 | lookup_symtab (name) |
63 | char *name; |
64 | { |
65 | register struct symtab *s; |
66 | register char *copy; |
67 | |
68 | for (s = symtab_list; s; s = s->next) |
69 | if (!strcmp (name, s->filename)) |
70 | return s; |
71 | |
72 | /* If name not found as specified, see if adding ".c" helps. */ |
73 | |
74 | copy = (char *) alloca (strlen (name) + 3); |
75 | strcpy (copy, name); |
76 | strcat (copy, ".c"); |
77 | for (s = symtab_list; s; s = s->next) |
78 | if (!strcmp (copy, s->filename)) |
79 | return s; |
80 | |
81 | return 0; |
82 | } |
83 | \f |
84 | /* Lookup a typedef or primitive type named NAME, |
85 | visible in lexical block BLOCK. |
86 | If NOERR is nonzero, return zero if NAME is not suitably defined. */ |
87 | |
88 | struct type * |
89 | lookup_typename (name, block, noerr) |
90 | char *name; |
91 | struct block *block; |
92 | int noerr; |
93 | { |
94 | register struct symbol *sym = lookup_symbol (name, block, VAR_NAMESPACE); |
95 | if (sym == 0 || SYMBOL_CLASS (sym) != LOC_TYPEDEF) |
96 | { |
97 | if (!strcmp (name, "int")) |
98 | return builtin_type_int; |
99 | if (!strcmp (name, "long")) |
100 | return builtin_type_long; |
101 | if (!strcmp (name, "short")) |
102 | return builtin_type_short; |
103 | if (!strcmp (name, "char")) |
104 | return builtin_type_char; |
105 | if (!strcmp (name, "float")) |
106 | return builtin_type_float; |
107 | if (!strcmp (name, "double")) |
108 | return builtin_type_double; |
109 | if (!strcmp (name, "void")) |
110 | return builtin_type_void; |
111 | |
112 | if (noerr) |
113 | return 0; |
114 | error ("No type named %s.", name); |
115 | } |
116 | return SYMBOL_TYPE (sym); |
117 | } |
118 | |
119 | struct type * |
120 | lookup_unsigned_typename (name) |
121 | char *name; |
122 | { |
123 | if (!strcmp (name, "int")) |
124 | return builtin_type_unsigned_int; |
125 | if (!strcmp (name, "long")) |
126 | return builtin_type_unsigned_long; |
127 | if (!strcmp (name, "short")) |
128 | return builtin_type_unsigned_short; |
129 | if (!strcmp (name, "char")) |
130 | return builtin_type_unsigned_char; |
131 | error ("No type named unsigned %s.", name); |
132 | } |
133 | |
134 | /* Lookup a structure type named "struct NAME", |
135 | visible in lexical block BLOCK. */ |
136 | |
137 | struct type * |
138 | lookup_struct (name, block) |
139 | char *name; |
140 | struct block *block; |
141 | { |
142 | register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE); |
143 | if (sym == 0) |
144 | error ("No struct type named %s.", name); |
145 | if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT) |
146 | error ("This context has union or enum %s, not a struct.", name); |
147 | return SYMBOL_TYPE (sym); |
148 | } |
149 | |
150 | /* Lookup a union type named "union NAME", |
151 | visible in lexical block BLOCK. */ |
152 | |
153 | struct type * |
154 | lookup_union (name, block) |
155 | char *name; |
156 | struct block *block; |
157 | { |
158 | register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE); |
159 | if (sym == 0) |
160 | error ("No union type named %s.", name); |
161 | if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_UNION) |
162 | error ("This context has struct or enum %s, not a union.", name); |
163 | return SYMBOL_TYPE (sym); |
164 | } |
165 | |
166 | /* Lookup an enum type named "enum NAME", |
167 | visible in lexical block BLOCK. */ |
168 | |
169 | struct type * |
170 | lookup_enum (name, block) |
171 | char *name; |
172 | struct block *block; |
173 | { |
174 | register struct symbol *sym = lookup_symbol (name, block, STRUCT_NAMESPACE); |
175 | if (sym == 0) |
176 | error ("No enum type named %s.", name); |
177 | if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_ENUM) |
178 | error ("This context has struct or union %s, not an enum.", name); |
179 | return SYMBOL_TYPE (sym); |
180 | } |
181 | |
182 | /* Given a type TYPE, return a type of pointers to that type. |
183 | May need to construct such a type if this is the first use. */ |
184 | |
185 | struct type * |
186 | lookup_pointer_type (type) |
187 | struct type *type; |
188 | { |
189 | register struct type *ptype = TYPE_POINTER_TYPE (type); |
190 | if (ptype) return ptype; |
191 | |
192 | /* This is the first time anyone wanted a pointer to a TYPE. */ |
193 | if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) |
194 | ptype = (struct type *) xmalloc (sizeof (struct type)); |
195 | else |
196 | ptype = (struct type *) obstack_alloc (symbol_obstack, |
197 | sizeof (struct type)); |
198 | |
199 | bzero (ptype, sizeof (struct type)); |
200 | TYPE_TARGET_TYPE (ptype) = type; |
201 | TYPE_POINTER_TYPE (type) = ptype; |
202 | /* New type is permanent if type pointed to is permanent. */ |
203 | if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) |
204 | TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM; |
205 | /* We assume the machine has only one representation for pointers! */ |
206 | TYPE_LENGTH (ptype) = sizeof (char *); |
207 | TYPE_CODE (ptype) = TYPE_CODE_PTR; |
208 | return ptype; |
209 | } |
210 | |
211 | /* Given a type TYPE, return a type of functions that return that type. |
212 | May need to construct such a type if this is the first use. */ |
213 | |
214 | struct type * |
215 | lookup_function_type (type) |
216 | struct type *type; |
217 | { |
218 | register struct type *ptype = TYPE_FUNCTION_TYPE (type); |
219 | if (ptype) return ptype; |
220 | |
221 | /* This is the first time anyone wanted a function returning a TYPE. */ |
222 | if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) |
223 | ptype = (struct type *) xmalloc (sizeof (struct type)); |
224 | else |
225 | ptype = (struct type *) obstack_alloc (symbol_obstack, |
226 | sizeof (struct type)); |
227 | |
228 | bzero (ptype, sizeof (struct type)); |
229 | TYPE_TARGET_TYPE (ptype) = type; |
230 | TYPE_FUNCTION_TYPE (type) = ptype; |
231 | /* New type is permanent if type returned is permanent. */ |
232 | if (TYPE_FLAGS (type) & TYPE_FLAG_PERM) |
233 | TYPE_FLAGS (ptype) |= TYPE_FLAG_PERM; |
234 | TYPE_LENGTH (ptype) = 1; |
235 | TYPE_CODE (ptype) = TYPE_CODE_FUNC; |
236 | TYPE_NFIELDS (ptype) = 0; |
237 | return ptype; |
238 | } |
239 | \f |
240 | /* Smash TYPE to be a type of pointers to TO_TYPE. |
241 | If TO_TYPE is not permanent and has no pointer-type yet, |
242 | record TYPE as its pointer-type. */ |
243 | |
244 | void |
245 | smash_to_pointer_type (type, to_type) |
246 | struct type *type, *to_type; |
247 | { |
248 | bzero (type, sizeof (struct type)); |
249 | TYPE_TARGET_TYPE (type) = to_type; |
250 | /* We assume the machine has only one representation for pointers! */ |
251 | TYPE_LENGTH (type) = sizeof (char *); |
252 | TYPE_CODE (type) = TYPE_CODE_PTR; |
253 | |
254 | if (TYPE_POINTER_TYPE (to_type) == 0 |
255 | && !(TYPE_FLAGS (type) & TYPE_FLAG_PERM)) |
256 | { |
257 | TYPE_POINTER_TYPE (to_type) = type; |
258 | } |
259 | } |
260 | |
261 | /* Smash TYPE to be a type of functions returning TO_TYPE. |
262 | If TO_TYPE is not permanent and has no function-type yet, |
263 | record TYPE as its function-type. */ |
264 | |
265 | void |
266 | smash_to_function_type (type, to_type) |
267 | struct type *type, *to_type; |
268 | { |
269 | bzero (type, sizeof (struct type)); |
270 | TYPE_TARGET_TYPE (type) = to_type; |
271 | TYPE_LENGTH (type) = 1; |
272 | TYPE_CODE (type) = TYPE_CODE_FUNC; |
273 | TYPE_NFIELDS (type) = 0; |
274 | |
275 | if (TYPE_FUNCTION_TYPE (to_type) == 0 |
276 | && !(TYPE_FLAGS (type) & TYPE_FLAG_PERM)) |
277 | { |
278 | TYPE_FUNCTION_TYPE (to_type) = type; |
279 | } |
280 | } |
281 | \f |
282 | static struct symbol *lookup_block_symbol (); |
283 | |
284 | /* Find the definition for a specified symbol name NAME |
285 | in namespace NAMESPACE, visible from lexical block BLOCK. |
286 | Returns the struct symbol pointer, or zero if no symbol is found. */ |
287 | |
288 | struct symbol * |
289 | lookup_symbol (name, block, namespace) |
290 | char *name; |
291 | register struct block *block; |
292 | enum namespace namespace; |
293 | { |
294 | register int i, n; |
295 | register struct symbol *sym; |
296 | register struct symtab *s; |
297 | struct blockvector *bv; |
298 | |
299 | /* Search specified block and its superiors. */ |
300 | |
301 | while (block != 0) |
302 | { |
303 | sym = lookup_block_symbol (block, name, namespace); |
304 | if (sym) return sym; |
305 | block = BLOCK_SUPERBLOCK (block); |
306 | } |
307 | |
308 | /* Now search all symtabs' global blocks. */ |
309 | |
310 | for (s = symtab_list; s; s = s->next) |
311 | { |
312 | bv = BLOCKVECTOR (s); |
313 | block = BLOCKVECTOR_BLOCK (bv, 0); |
314 | sym = lookup_block_symbol (block, name, namespace); |
315 | if (sym) return sym; |
316 | } |
317 | |
318 | /* Now search all symtabs' per-file blocks. |
319 | Not strictly correct, but more useful than an error. */ |
320 | |
321 | for (s = symtab_list; s; s = s->next) |
322 | { |
323 | bv = BLOCKVECTOR (s); |
324 | block = BLOCKVECTOR_BLOCK (bv, 1); |
325 | sym = lookup_block_symbol (block, name, namespace); |
326 | if (sym) return sym; |
327 | } |
328 | return 0; |
329 | } |
330 | |
331 | /* Look for a symbol in block BLOCK using binary search. */ |
332 | |
333 | static struct symbol * |
334 | lookup_block_symbol (block, name, namespace) |
335 | register struct block *block; |
336 | char *name; |
337 | enum namespace namespace; |
338 | { |
339 | register int bot, top, inc; |
340 | register struct symbol *sym; |
341 | |
342 | top = BLOCK_NSYMS (block); |
343 | bot = 0; |
344 | |
345 | /* First, advance BOT to not far before |
346 | the first symbol whose name is NAME. */ |
347 | |
348 | while (1) |
349 | { |
350 | inc = (top - bot + 1); |
351 | /* No need to keep binary searching for the last few bits worth. */ |
352 | if (inc < 7) |
353 | break; |
354 | inc >>= 1; |
355 | sym = BLOCK_SYM (block, bot + inc); |
356 | if (strcmp (SYMBOL_NAME (sym), name) < 0) |
357 | bot += inc; |
358 | else |
359 | top = bot + inc; |
360 | } |
361 | |
362 | /* Now scan forward until we run out of symbols, |
363 | find one whose name is greater than NAME, |
364 | or find one we want. |
365 | If there is more than one symbol with the right name and namespace, |
366 | we return the first one. dbxread.c is careful to make sure |
367 | that if one is a register then it comes first. */ |
368 | |
369 | top = BLOCK_NSYMS (block); |
370 | while (bot < top) |
371 | { |
372 | sym = BLOCK_SYM (block, bot); |
373 | inc = strcmp (SYMBOL_NAME (sym), name); |
374 | if (inc == 0 && SYMBOL_NAMESPACE (sym) == namespace) |
375 | return sym; |
376 | if (inc > 0) |
377 | return 0; |
378 | bot++; |
379 | } |
380 | return 0; |
381 | } |
382 | \f |
383 | /* Return the symbol for the function which contains a specified |
384 | lexical block, described by a struct block BL. */ |
385 | |
386 | struct symbol * |
387 | block_function (bl) |
388 | struct block *bl; |
389 | { |
390 | while (BLOCK_FUNCTION (bl) == 0 && BLOCK_SUPERBLOCK (bl) != 0) |
391 | bl = BLOCK_SUPERBLOCK (bl); |
392 | |
393 | return BLOCK_FUNCTION (bl); |
394 | } |
395 | |
396 | /* Subroutine of find_pc_line */ |
397 | |
398 | static struct symtab * |
399 | find_pc_symtab (pc) |
400 | register CORE_ADDR pc; |
401 | { |
402 | register struct block *b; |
403 | struct blockvector *bv; |
404 | register struct symtab *s; |
405 | |
406 | /* Search all symtabs for one whose file contains our pc */ |
407 | |
408 | for (s = symtab_list; s; s = s->next) |
409 | { |
410 | bv = BLOCKVECTOR (s); |
411 | b = BLOCKVECTOR_BLOCK (bv, 0); |
412 | if (BLOCK_START (b) <= pc |
413 | && BLOCK_END (b) > pc) |
414 | break; |
415 | } |
416 | |
417 | return s; |
418 | } |
419 | |
420 | /* Find the source file and line number for a given PC value. |
421 | Return a structure containing a symtab pointer, a line number, |
422 | and a pc range for the entire source line. |
423 | The value's .pc field is NOT the specified pc. |
424 | NOTCURRENT nonzero means, if specified pc is on a line boundary, |
425 | use the line that ends there. Otherwise, in that case, the line |
426 | that begins there is used. */ |
427 | |
428 | struct symtab_and_line |
429 | find_pc_line (pc, notcurrent) |
430 | CORE_ADDR pc; |
431 | int notcurrent; |
432 | { |
433 | struct symtab *s; |
434 | register struct linetable *l; |
435 | register int len; |
436 | register int i, item; |
437 | int line; |
438 | struct symtab_and_line value; |
439 | struct blockvector *bv; |
440 | |
441 | /* Info on best line seen so far, and where it starts, and its file. */ |
442 | |
443 | int best_line = 0; |
444 | CORE_ADDR best_pc = 0; |
445 | CORE_ADDR best_end = 0; |
446 | struct symtab *best_symtab = 0; |
447 | |
448 | /* Store here the first line number |
449 | of a file which contains the line at the smallest pc after PC. |
450 | If we don't find a line whose range contains PC, |
451 | we will use a line one less than this, |
452 | with a range from the start of that file to the first line's pc. */ |
453 | int alt_line = 0; |
454 | CORE_ADDR alt_pc = 0; |
455 | struct symtab *alt_symtab = 0; |
456 | |
457 | /* Info on best line seen in this file. */ |
458 | |
459 | int prev_line; |
460 | CORE_ADDR prev_pc; |
461 | |
462 | /* Info on first line of this file. */ |
463 | |
464 | int first_line; |
465 | CORE_ADDR first_pc; |
466 | |
467 | /* If this pc is not from the current frame, |
468 | it is the address of the end of a call instruction. |
469 | Quite likely that is the start of the following statement. |
470 | But what we want is the statement containing the instruction. |
471 | Fudge the pc to make sure we get that. */ |
472 | |
473 | if (notcurrent) pc -= 1; |
474 | |
475 | s = find_pc_symtab (pc); |
476 | if (s == 0) |
477 | { |
478 | value.symtab = 0; |
479 | value.line = 0; |
480 | value.pc = pc; |
481 | return value; |
482 | } |
483 | |
484 | bv = BLOCKVECTOR (s); |
485 | |
486 | /* Look at all the symtabs that share this blockvector. |
487 | They all have the same apriori range, that we found was right; |
488 | but they have different line tables. */ |
489 | |
490 | for (; s && BLOCKVECTOR (s) == bv; s = s->next) |
491 | { |
492 | /* Find the best line in this symtab. */ |
493 | l = LINETABLE (s); |
494 | len = l->nitems; |
495 | prev_line = -1; |
496 | first_line = -1; |
497 | for (i = 0; i < len; i++) |
498 | { |
499 | item = l->item[i]; |
500 | if (item < 0) |
501 | line = - item - 1; |
502 | else |
503 | { |
504 | line++; |
505 | if (first_line < 0) |
506 | { |
507 | first_line = line; |
508 | first_pc = item; |
509 | } |
510 | /* Return the last line that did not start after PC. */ |
511 | if (pc >= item) |
512 | { |
513 | prev_line = line; |
514 | prev_pc = item; |
515 | } |
516 | else |
517 | break; |
518 | } |
519 | } |
520 | |
521 | /* Is this file's best line closer than the best in the other files? |
522 | If so, record this file, and its best line, as best so far. */ |
523 | if (prev_line >= 0 && prev_pc > best_pc) |
524 | { |
525 | best_pc = prev_pc; |
526 | best_line = prev_line; |
527 | best_symtab = s; |
528 | if (i < len) |
529 | best_end = item; |
530 | else |
531 | best_end = 0; |
532 | } |
533 | /* Is this file's first line closer than the first lines of other files? |
534 | If so, record this file, and its first line, as best alternate. */ |
535 | if (first_line >= 0 && first_pc > pc |
536 | && (alt_pc == 0 || first_pc < alt_pc)) |
537 | { |
538 | alt_pc = first_pc; |
539 | alt_line = first_line; |
540 | alt_symtab = s; |
541 | } |
542 | } |
543 | if (best_symtab == 0) |
544 | { |
545 | value.symtab = alt_symtab; |
546 | value.line = alt_line - 1; |
547 | value.pc = BLOCK_END (BLOCKVECTOR_BLOCK (bv, 0)); |
548 | value.end = alt_pc; |
549 | } |
550 | else |
551 | { |
552 | value.symtab = best_symtab; |
553 | value.line = best_line; |
554 | value.pc = best_pc; |
555 | value.end = (best_end ? best_end |
556 | : (alt_pc ? alt_pc |
557 | : BLOCK_END (BLOCKVECTOR_BLOCK (bv, 0)))); |
558 | } |
559 | return value; |
560 | } |
561 | |
562 | /* Find the range of pc values in a line. |
563 | Store the starting pc of the line into *STARTPTR |
564 | and the ending pc (start of next line) into *ENDPTR. |
565 | Returns 1 to indicate success. |
566 | Returns 0 if could not find the specified line. */ |
567 | |
568 | int |
569 | find_line_pc_range (symtab, thisline, startptr, endptr) |
570 | struct symtab *symtab; |
571 | int thisline; |
572 | CORE_ADDR *startptr, *endptr; |
573 | { |
574 | register struct linetable *l; |
575 | register int i, line, item; |
576 | int len; |
577 | register CORE_ADDR prev_pc; |
578 | CORE_ADDR last_pc; |
579 | |
580 | if (symtab == 0) |
581 | return 0; |
582 | |
583 | l = LINETABLE (symtab); |
584 | len = l->nitems; |
585 | prev_pc = -1; |
586 | for (i = 0; i < len; i++) |
587 | { |
588 | item = l->item[i]; |
589 | if (item < 0) |
590 | line = - item - 1; |
591 | else |
592 | { |
593 | line++; |
594 | /* As soon as we find a line following the specified one |
595 | we know the end pc and can return. */ |
596 | if (line > thisline) |
597 | { |
598 | /* If we have not seen an entry for the specified line, |
599 | assume that means the specified line has zero bytes. */ |
600 | *startptr = prev_pc == -1 ? item : prev_pc; |
601 | *endptr = item; |
602 | return 1; |
603 | } |
604 | /* If we see an entry for the specified line, |
605 | it gives the beginning. */ |
606 | if (line == thisline) |
607 | prev_pc = item; |
608 | last_pc = item; |
609 | } |
610 | } |
611 | if (prev_pc != -1) |
612 | { |
613 | /* If we found the specified line but no later line, it's file's last. |
614 | Its range is from line's pc to file's end pc. */ |
615 | *startptr = last_pc; |
616 | *endptr = BLOCK_END (BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), 0)); |
617 | return 1; |
618 | } |
619 | |
620 | return 0; |
621 | } |
622 | |
623 | /* Find the PC value for a given source file and line number. |
624 | Returns zero for invalid line number. |
625 | The source file is specified with a struct symtab. */ |
626 | |
627 | CORE_ADDR |
628 | find_line_pc (symtab, line) |
629 | struct symtab *symtab; |
630 | int line; |
631 | { |
632 | register struct linetable *l; |
633 | register int len; |
634 | register int i; |
635 | register int item; |
636 | register int nextline = -1; |
637 | |
638 | if (line <= 0) |
639 | return 0; |
640 | |
641 | l = LINETABLE (symtab); |
642 | len = l->nitems; |
643 | for (i = 0; i < len; i++) |
644 | { |
645 | item = l->item[i]; |
646 | if (item < 0) |
647 | nextline = - item - 1; |
648 | else |
649 | { |
650 | nextline++; |
651 | if (line <= nextline) |
652 | return item; |
653 | } |
654 | } |
655 | return 0; |
656 | } |
657 | |
658 | int |
659 | find_pc_line_pc_range (pc, startptr, endptr) |
660 | CORE_ADDR pc; |
661 | CORE_ADDR *startptr, *endptr; |
662 | { |
663 | struct symtab_and_line sal; |
664 | sal = find_pc_line (pc, 0); |
665 | *startptr = sal.pc; |
666 | *endptr = sal.end; |
667 | return sal.symtab != 0; |
668 | } |
669 | \f |
670 | /* Parse a string that specifies a line number. |
671 | Pass the address of a char * variable; that variable will be |
672 | advanced over the characters actually parsed. |
673 | |
674 | The string can be: |
675 | |
676 | LINENUM -- that line number in current file. PC returned is 0. |
677 | FILE:LINENUM -- that line in that file. PC returned is 0. |
678 | FUNCTION -- line number of openbrace of that function. |
679 | PC returned is the start of the function. |
680 | FILE:FUNCTION -- likewise, but prefer functions in that file. |
681 | *EXPR -- line in which address EXPR appears. |
682 | |
683 | FUNCTION may be an undebuggable function found in misc_function_vector. |
684 | |
685 | If the argument FUNFIRSTLINE is nonzero, we want the first line |
686 | of real code inside a function when a function is specified. |
687 | |
688 | DEFAULT_SYMTAB specifies the file to use if none is specified. |
689 | It defaults to current_source_symtab. |
690 | DEFAULT_LINE specifies the line number to use for relative |
691 | line numbers (that start with signs). Defaults to current_source_line. |
692 | |
693 | Note that it is possible to return zero for the symtab |
694 | if no file is validly specified. Callers must check that. |
695 | Also, the line number returned may be invalid. */ |
696 | |
697 | struct symtab_and_line |
698 | decode_line_1 (argptr, funfirstline, default_symtab, default_line) |
699 | char **argptr; |
700 | int funfirstline; |
701 | struct symtab *default_symtab; |
702 | int default_line; |
703 | { |
704 | struct symtab_and_line value; |
705 | register char *p, *p1; |
706 | register struct symtab *s; |
707 | register struct symbol *sym; |
708 | register CORE_ADDR pc; |
709 | register int i; |
710 | char *copy; |
711 | |
712 | /* Defaults have defaults. */ |
713 | |
714 | if (default_symtab == 0) |
715 | { |
716 | default_symtab = current_source_symtab; |
717 | default_line = current_source_line; |
718 | } |
719 | |
720 | /* See if arg is *PC */ |
721 | |
722 | if (**argptr == '*') |
723 | { |
724 | (*argptr)++; |
725 | pc = parse_and_eval_address_1 (argptr); |
726 | value = find_pc_line (pc, 0); |
727 | value.pc = pc; |
728 | return value; |
729 | } |
730 | |
731 | /* Maybe arg is FILE : LINENUM or FILE : FUNCTION */ |
732 | |
733 | s = 0; |
734 | |
735 | for (p = *argptr; *p; p++) |
736 | { |
737 | if (p[0] == ':' || p[0] == ' ' || p[0] == '\t') |
738 | break; |
739 | } |
740 | while (p[0] == ' ' || p[0] == '\t') p++; |
741 | |
742 | if (p[0] == ':') |
743 | { |
744 | /* Extract the file name. */ |
745 | p1 = p; |
746 | while (p != *argptr && p[-1] == ' ') --p; |
747 | copy = (char *) alloca (p - *argptr + 1); |
748 | bcopy (*argptr, copy, p - *argptr); |
749 | copy[p - *argptr] = 0; |
750 | |
751 | /* Find that file's data. */ |
752 | s = lookup_symtab (copy); |
753 | if (s == 0) |
754 | { |
755 | if (symtab_list == 0) |
756 | error ("No symbol table is loaded. Use the \"symbol-file\" command."); |
757 | error ("No source file named %s.", copy); |
758 | } |
759 | |
760 | /* Discard the file name from the arg. */ |
761 | p = p1 + 1; |
762 | while (*p == ' ' || *p == '\t') p++; |
763 | *argptr = p; |
764 | } |
765 | |
766 | /* S is specified file's symtab, or 0 if no file specified. |
767 | arg no longer contains the file name. */ |
768 | |
769 | /* Check whether arg is all digits (and sign) */ |
770 | |
771 | p = *argptr; |
772 | if (*p == '-' || *p == '+') p++; |
773 | while (*p >= '0' && *p <= '9') |
774 | p++; |
775 | |
776 | if (p != *argptr && (*p == 0 || *p == ' ' || *p == '\t' || *p == ',')) |
777 | { |
778 | /* We found a token consisting of all digits -- at least one digit. */ |
779 | enum sign {none, plus, minus} sign = none; |
780 | |
781 | if (**argptr == '+') |
782 | sign = plus, (*argptr)++; |
783 | else if (**argptr == '-') |
784 | sign = minus, (*argptr)++; |
785 | value.line = atoi (*argptr); |
786 | switch (sign) |
787 | { |
788 | case plus: |
789 | if (p == *argptr) |
790 | value.line = 5; |
791 | if (s == 0) |
792 | value.line = default_line + value.line; |
793 | break; |
794 | case minus: |
795 | if (p == *argptr) |
796 | value.line = 15; |
797 | if (s == 0) |
798 | value.line = default_line - value.line; |
799 | else |
800 | value.line = 1; |
801 | break; |
802 | } |
803 | |
804 | while (*p == ' ' || *p == '\t') p++; |
805 | *argptr = p; |
806 | if (s == 0) |
807 | s = default_symtab; |
808 | value.symtab = s; |
809 | value.pc = 0; |
810 | return value; |
811 | } |
812 | |
813 | /* Arg token is not digits => try it as a function name |
814 | Find the next token (everything up to end or next whitespace). */ |
815 | p = *argptr; |
816 | while (*p && *p != ' ' && *p != '\t' && *p != ',') p++; |
817 | copy = (char *) alloca (p - *argptr + 1); |
818 | bcopy (*argptr, copy, p - *argptr); |
819 | copy[p - *argptr] = 0; |
820 | while (*p == ' ' || *p == '\t') p++; |
821 | *argptr = p; |
822 | |
823 | /* Look up that token as a function. |
824 | If file specified, use that file's per-file block to start with. */ |
825 | |
826 | sym = lookup_symbol (copy, s ? BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), 1) : 0, |
827 | VAR_NAMESPACE); |
828 | |
829 | if (sym && SYMBOL_CLASS (sym) == LOC_BLOCK) |
830 | { |
831 | /* Arg is the name of a function */ |
832 | pc = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)) + FUNCTION_START_OFFSET; |
833 | if (funfirstline) |
834 | SKIP_PROLOGUE (pc); |
835 | value = find_pc_line (pc, 0); |
836 | value.pc = (value.end && value.pc != pc) ? value.end : pc; |
837 | return value; |
838 | } |
839 | |
840 | if (sym) |
841 | error ("%s is not a function.", copy); |
842 | |
843 | for (i = 0; i < misc_function_count; i++) |
844 | if (!strcmp (misc_function_vector[i].name, copy)) |
845 | { |
846 | value.symtab = 0; |
847 | value.line = 0; |
848 | value.pc = misc_function_vector[i].address + FUNCTION_START_OFFSET; |
849 | if (funfirstline) |
850 | SKIP_PROLOGUE (value.pc); |
851 | return value; |
852 | } |
853 | |
854 | if (symtab_list == 0) |
855 | error ("No symbol table is loaded. Use the \"symbol-file\" command."); |
856 | error ("Function %s not defined.", copy); |
857 | } |
858 | |
859 | struct symtab_and_line |
860 | decode_line_spec (string, funfirstline) |
861 | char *string; |
862 | int funfirstline; |
863 | { |
864 | struct symtab_and_line sal; |
865 | if (string == 0) |
866 | error ("Empty line specification."); |
867 | sal = decode_line_1 (&string, funfirstline, |
868 | current_source_symtab, current_source_line); |
869 | if (*string) |
870 | error ("Junk at end of line specification: %s", string); |
871 | return sal; |
872 | } |
873 | \f |
874 | static void |
875 | sources_info () |
876 | { |
877 | register struct symtab *s; |
878 | register int column = 0; |
879 | |
880 | if (symtab_list == 0) |
881 | { |
882 | printf ("No symbol table is loaded.\n"); |
883 | return; |
884 | } |
885 | printf ("Source files for which symbol table is known:\n"); |
886 | for (s = symtab_list; s; s = s->next) |
887 | { |
888 | if (column != 0 && column + strlen (s->filename) >= 70) |
889 | { |
890 | printf ("\n"); |
891 | column = 0; |
892 | } |
893 | else if (column != 0) |
894 | { |
895 | printf (" "); |
896 | column++; |
897 | } |
898 | printf ("%s", s->filename); |
899 | column += strlen (s->filename); |
900 | if (s->next) |
901 | { |
902 | printf (","); |
903 | column++; |
904 | } |
905 | } |
906 | printf ("\n"); |
907 | } |
908 | |
909 | /* List all symbols (if REGEXP is 0) or all symbols matching REGEXP. |
910 | If CLASS is zero, list all symbols except functions and type names. |
911 | If CLASS is 1, list only functions. |
912 | If CLASS is 2, list only type names. */ |
913 | |
914 | #define MORE \ |
915 | { print_count++; \ |
916 | if (print_count >= 21) \ |
917 | { printf ("--Type Return to print more--"); \ |
918 | print_count = 0; \ |
919 | fflush (stdout); \ |
920 | read_line (); } } |
921 | |
922 | static void |
923 | list_symbols (regexp, class) |
924 | char *regexp; |
925 | int class; |
926 | { |
927 | register struct symtab *s; |
928 | register struct blockvector *bv; |
929 | struct blockvector *prev_bv = 0; |
930 | register struct block *b; |
931 | register int i, j; |
932 | register struct symbol *sym; |
933 | char *val = 0; |
934 | int found_in_file; |
935 | static char *classnames[] |
936 | = {"variable", "function", "type"}; |
937 | int print_count = 0; |
938 | #ifdef REGCMP |
939 | extern char *regcmp(), *regex(), *loc1; |
940 | #endif |
941 | |
942 | if (regexp) { |
943 | #ifdef REGCMP |
944 | val = regcmp(regexp, (char *)0); |
945 | if (val == 0) |
946 | error ("Invalid regexp: %s", regexp); |
947 | #else |
948 | if (val = (char *) re_comp (regexp)) |
949 | error ("Invalid regexp: %s", val); |
950 | #endif |
951 | } |
952 | |
953 | printf (regexp |
954 | ? "All %ss matching regular expression \"%s\":\n" |
955 | : "All defined %ss:\n", |
956 | classnames[class], |
957 | regexp); |
958 | |
959 | for (s = symtab_list; s; s = s->next) |
960 | { |
961 | found_in_file = 0; |
962 | bv = BLOCKVECTOR (s); |
963 | /* Often many files share a blockvector. |
964 | Scan each blockvector only once so that |
965 | we don't get every symbol many times. |
966 | It happens that the first symtab in the list |
967 | for any given blockvector is the main file. */ |
968 | if (bv != prev_bv) |
969 | for (i = 0; i < 2; i++) |
970 | { |
971 | b = BLOCKVECTOR_BLOCK (bv, i); |
972 | for (j = 0; j < BLOCK_NSYMS (b); j++) |
973 | { |
974 | QUIT; |
975 | sym = BLOCK_SYM (b, j); |
976 | if (regexp) { |
977 | #ifdef REGCMP |
978 | if (!regex(val, SYMBOL_NAME (sym))) |
979 | continue; |
980 | #else |
981 | if (!re_exec (SYMBOL_NAME (sym))) |
982 | continue; |
983 | #endif |
984 | } |
985 | if ((class == 0 && SYMBOL_CLASS (sym) != LOC_TYPEDEF |
986 | && SYMBOL_CLASS (sym) != LOC_BLOCK) |
987 | || (class == 1 && SYMBOL_CLASS (sym) == LOC_BLOCK) |
988 | || (class == 2 && SYMBOL_CLASS (sym) == LOC_TYPEDEF)) |
989 | { |
990 | if (!found_in_file) |
991 | { |
992 | printf ("\nFile %s:\n", s->filename); |
993 | print_count += 2; |
994 | } |
995 | found_in_file = 1; |
996 | MORE; |
997 | if (class != 2 && i == 1) |
998 | printf ("static "); |
999 | if (class == 2 |
1000 | && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE) |
1001 | printf ("typedef "); |
1002 | |
1003 | type_print (SYMBOL_TYPE (sym), |
1004 | (SYMBOL_CLASS (sym) == LOC_TYPEDEF |
1005 | ? "" : SYMBOL_NAME (sym)), |
1006 | stdout, 0); |
1007 | if (class == 2 |
1008 | && SYMBOL_NAMESPACE (sym) != STRUCT_NAMESPACE |
1009 | && (TYPE_NAME ((SYMBOL_TYPE (sym))) == 0 |
1010 | || 0 != strcmp (TYPE_NAME ((SYMBOL_TYPE (sym))), |
1011 | SYMBOL_NAME (sym)))) |
1012 | printf (" %s", SYMBOL_NAME (sym)); |
1013 | printf (";\n"); |
1014 | } |
1015 | } |
1016 | } |
1017 | prev_bv = bv; |
1018 | } |
1019 | #ifdef REGCMP |
1020 | if (val) |
1021 | (void)free(val); |
1022 | #endif |
1023 | } |
1024 | |
1025 | static void |
1026 | variables_info (regexp) |
1027 | char *regexp; |
1028 | { |
1029 | list_symbols (regexp, 0); |
1030 | } |
1031 | |
1032 | static void |
1033 | functions_info (regexp) |
1034 | char *regexp; |
1035 | { |
1036 | list_symbols (regexp, 1); |
1037 | } |
1038 | |
1039 | static void |
1040 | types_info (regexp) |
1041 | char *regexp; |
1042 | { |
1043 | list_symbols (regexp, 2); |
1044 | } |
1045 | \f |
1046 | /* Initialize the standard C scalar types. */ |
1047 | |
1048 | static |
1049 | struct type * |
1050 | init_type (code, length, uns, name) |
1051 | enum type_code code; |
1052 | int length, uns; |
1053 | char *name; |
1054 | { |
1055 | register struct type *type; |
1056 | |
1057 | type = (struct type *) xmalloc (sizeof (struct type)); |
1058 | bzero (type, sizeof *type); |
1059 | TYPE_CODE (type) = code; |
1060 | TYPE_LENGTH (type) = length; |
1061 | TYPE_FLAGS (type) = uns ? TYPE_FLAG_UNSIGNED : 0; |
1062 | TYPE_FLAGS (type) |= TYPE_FLAG_PERM; |
1063 | TYPE_NFIELDS (type) = 0; |
1064 | TYPE_NAME (type) = name; |
1065 | |
1066 | return type; |
1067 | } |
1068 | |
1069 | static |
1070 | initialize () |
1071 | { |
1072 | add_info ("variables", variables_info, |
1073 | "All global and static variable names, or those matching REGEXP."); |
1074 | add_info ("functions", functions_info, |
1075 | "All function names, or those matching REGEXP."); |
1076 | add_info ("types", types_info, |
1077 | "All types names, or those matching REGEXP."); |
1078 | add_info ("sources", sources_info, |
1079 | "Source files in the program."); |
1080 | |
1081 | obstack_init (symbol_obstack); |
1082 | |
1083 | builtin_type_void = init_type (TYPE_CODE_VOID, 0, 0, "void"); |
1084 | |
1085 | builtin_type_float = init_type (TYPE_CODE_FLT, sizeof (float), 0, "float"); |
1086 | builtin_type_double = init_type (TYPE_CODE_FLT, sizeof (double), 0, "double"); |
1087 | |
1088 | builtin_type_char = init_type (TYPE_CODE_INT, sizeof (char), 0, "char"); |
1089 | builtin_type_short = init_type (TYPE_CODE_INT, sizeof (short), 0, "short"); |
1090 | builtin_type_long = init_type (TYPE_CODE_INT, sizeof (long), 0, "long"); |
1091 | builtin_type_int = init_type (TYPE_CODE_INT, sizeof (int), 0, "int"); |
1092 | |
1093 | builtin_type_unsigned_char = init_type (TYPE_CODE_INT, sizeof (char), 1, "unsigned char"); |
1094 | builtin_type_unsigned_short = init_type (TYPE_CODE_INT, sizeof (short), 1, "unsigned short"); |
1095 | builtin_type_unsigned_long = init_type (TYPE_CODE_INT, sizeof (long), 1, "unsigned long"); |
1096 | builtin_type_unsigned_int = init_type (TYPE_CODE_INT, sizeof (int), 1, "unsigned int"); |
1097 | } |
1098 | |
1099 | END_FILE |