* mipsread.c (parse_partial_symbols, psymtab_to_symtab_1):
[binutils-gdb.git] / gdb / symmisc.c
1 /* Do various things to symbol tables (other than lookup), for GDB.
2 Copyright 1986, 1987, 1989, 1991, 1992, 1993 Free Software Foundation, Inc.
3
4 This file is part of GDB.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "gdbtypes.h"
23 #include "bfd.h"
24 #include "symfile.h"
25 #include "objfiles.h"
26 #include "breakpoint.h"
27 #include "command.h"
28 #include "obstack.h"
29 #include "language.h"
30
31 #include <string.h>
32
33 #ifndef DEV_TTY
34 #define DEV_TTY "/dev/tty"
35 #endif
36
37 /* Unfortunately for debugging, stderr is usually a macro. This is painful
38 when calling functions that take FILE *'s from the debugger.
39 So we make a variable which has the same value and which is accessible when
40 debugging GDB with itself. Because stdin et al need not be constants,
41 we initialize them in the _initialize_symmisc function at the bottom
42 of the file. */
43 FILE *std_in;
44 FILE *std_out;
45 FILE *std_err;
46
47 /* Prototypes for local functions */
48
49 static void
50 dump_symtab PARAMS ((struct objfile *, struct symtab *, FILE *));
51
52 static void
53 dump_psymtab PARAMS ((struct objfile *, struct partial_symtab *, FILE *));
54
55 static void
56 dump_msymbols PARAMS ((struct objfile *, FILE *));
57
58 static void
59 dump_objfile PARAMS ((struct objfile *));
60
61 static int
62 block_depth PARAMS ((struct block *));
63
64 static void
65 print_partial_symbol PARAMS ((struct partial_symbol *, int, char *, FILE *));
66
67 static void
68 print_symbol PARAMS ((struct symbol *, int, FILE *));
69
70 static void
71 free_symtab_block PARAMS ((struct objfile *, struct block *));
72
73 \f
74 /* Free a struct block <- B and all the symbols defined in that block. */
75
76 static void
77 free_symtab_block (objfile, b)
78 struct objfile *objfile;
79 struct block *b;
80 {
81 register int i, n;
82 n = BLOCK_NSYMS (b);
83 for (i = 0; i < n; i++)
84 {
85 mfree (objfile -> md, SYMBOL_NAME (BLOCK_SYM (b, i)));
86 mfree (objfile -> md, (PTR) BLOCK_SYM (b, i));
87 }
88 mfree (objfile -> md, (PTR) b);
89 }
90
91 /* Free all the storage associated with the struct symtab <- S.
92 Note that some symtabs have contents malloc'ed structure by structure,
93 while some have contents that all live inside one big block of memory,
94 and some share the contents of another symbol table and so you should
95 not free the contents on their behalf (except sometimes the linetable,
96 which maybe per symtab even when the rest is not).
97 It is s->free_code that says which alternative to use. */
98
99 void
100 free_symtab (s)
101 register struct symtab *s;
102 {
103 register int i, n;
104 register struct blockvector *bv;
105
106 switch (s->free_code)
107 {
108 case free_nothing:
109 /* All the contents are part of a big block of memory (an obstack),
110 and some other symtab is in charge of freeing that block.
111 Therefore, do nothing. */
112 break;
113
114 case free_contents:
115 /* Here all the contents were malloc'ed structure by structure
116 and must be freed that way. */
117 /* First free the blocks (and their symbols. */
118 bv = BLOCKVECTOR (s);
119 n = BLOCKVECTOR_NBLOCKS (bv);
120 for (i = 0; i < n; i++)
121 free_symtab_block (s -> objfile, BLOCKVECTOR_BLOCK (bv, i));
122 /* Free the blockvector itself. */
123 mfree (s -> objfile -> md, (PTR) bv);
124 /* Also free the linetable. */
125
126 case free_linetable:
127 /* Everything will be freed either by our `free_ptr'
128 or by some other symtab, except for our linetable.
129 Free that now. */
130 if (LINETABLE (s))
131 mfree (s -> objfile -> md, (PTR) LINETABLE (s));
132 break;
133 }
134
135 /* If there is a single block of memory to free, free it. */
136 if (s -> free_ptr != NULL)
137 mfree (s -> objfile -> md, s -> free_ptr);
138
139 /* Free source-related stuff */
140 if (s -> line_charpos != NULL)
141 mfree (s -> objfile -> md, (PTR) s -> line_charpos);
142 if (s -> fullname != NULL)
143 mfree (s -> objfile -> md, s -> fullname);
144 mfree (s -> objfile -> md, (PTR) s);
145 }
146
147 #if MAINTENANCE_CMDS
148
149 static void
150 dump_objfile (objfile)
151 struct objfile *objfile;
152 {
153 struct symtab *symtab;
154 struct partial_symtab *psymtab;
155
156 printf_filtered ("\nObject file %s: ", objfile -> name);
157 printf_filtered ("Objfile at %x, bfd at %x, %d minsyms\n\n",
158 objfile, objfile -> obfd, objfile->minimal_symbol_count);
159
160 if (objfile -> psymtabs)
161 {
162 printf_filtered ("Psymtabs:\n");
163 for (psymtab = objfile -> psymtabs;
164 psymtab != NULL;
165 psymtab = psymtab -> next)
166 {
167 printf_filtered ("%s at %x, ", psymtab -> filename, psymtab);
168 if (psymtab -> objfile != objfile)
169 {
170 printf_filtered ("NOT ON CHAIN! ");
171 }
172 wrap_here (" ");
173 }
174 printf_filtered ("\n\n");
175 }
176
177 if (objfile -> symtabs)
178 {
179 printf_filtered ("Symtabs:\n");
180 for (symtab = objfile -> symtabs;
181 symtab != NULL;
182 symtab = symtab->next)
183 {
184 printf_filtered ("%s at %x, ", symtab -> filename, symtab);
185 if (symtab -> objfile != objfile)
186 {
187 printf_filtered ("NOT ON CHAIN! ");
188 }
189 wrap_here (" ");
190 }
191 printf_filtered ("\n\n");
192 }
193 }
194
195 /* Print minimal symbols from this objfile. */
196
197 static void
198 dump_msymbols (objfile, outfile)
199 struct objfile *objfile;
200 FILE *outfile;
201 {
202 struct minimal_symbol *msymbol;
203 int index;
204 char ms_type;
205
206 fprintf_filtered (outfile, "\nObject file %s:\n\n", objfile -> name);
207 if (objfile -> minimal_symbol_count == 0)
208 {
209 fprintf_filtered (outfile, "No minimal symbols found.\n");
210 return;
211 }
212 for (index = 0, msymbol = objfile -> msymbols;
213 SYMBOL_NAME (msymbol) != NULL; msymbol++, index++)
214 {
215 switch (msymbol -> type)
216 {
217 case mst_unknown:
218 ms_type = 'u';
219 break;
220 case mst_text:
221 ms_type = 'T';
222 break;
223 case mst_data:
224 ms_type = 'D';
225 break;
226 case mst_bss:
227 ms_type = 'B';
228 break;
229 case mst_abs:
230 ms_type = 'A';
231 break;
232 case mst_file_text:
233 ms_type = 't';
234 break;
235 case mst_file_data:
236 ms_type = 'd';
237 break;
238 case mst_file_bss:
239 ms_type = 'b';
240 break;
241 default:
242 ms_type = '?';
243 break;
244 }
245 fprintf_filtered (outfile, "[%2d] %c %#10x %s", index, ms_type,
246 SYMBOL_VALUE_ADDRESS (msymbol), SYMBOL_NAME (msymbol));
247 if (SYMBOL_DEMANGLED_NAME (msymbol) != NULL)
248 {
249 fprintf_filtered (outfile, " %s", SYMBOL_DEMANGLED_NAME (msymbol));
250 }
251 fputs_filtered ("\n", outfile);
252 }
253 if (objfile -> minimal_symbol_count != index)
254 {
255 warning ("internal error: minimal symbol count %d != %d",
256 objfile -> minimal_symbol_count, index);
257 }
258 fprintf_filtered (outfile, "\n");
259 }
260
261 static void
262 dump_psymtab (objfile, psymtab, outfile)
263 struct objfile *objfile;
264 struct partial_symtab *psymtab;
265 FILE *outfile;
266 {
267
268 fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
269 psymtab -> filename);
270 fprintf_filtered (outfile, "(object 0x%x)\n\n", psymtab);
271 fprintf (outfile, " Read from object file %s (0x%x)\n",
272 objfile -> name, (unsigned int) objfile);
273
274 if (psymtab -> readin)
275 {
276 fprintf_filtered (outfile,
277 " Full symtab was read (at 0x%x by function at 0x%x)\n",
278 psymtab -> symtab, psymtab -> read_symtab);
279 }
280
281 /* FIXME, we need to be able to print the relocation stuff. */
282 /* This prints some garbage for anything but stabs right now. FIXME. */
283 if (psymtab->section_offsets)
284 fprintf_filtered (outfile, " Relocate symbols by 0x%x, 0x%x, 0x%x, 0x%x.\n",
285 ANOFFSET (psymtab->section_offsets, 0),
286 ANOFFSET (psymtab->section_offsets, 1),
287 ANOFFSET (psymtab->section_offsets, 2),
288 ANOFFSET (psymtab->section_offsets, 3));
289
290 fprintf_filtered (outfile, " Symbols cover text addresses 0x%x-0x%x\n",
291 psymtab -> textlow, psymtab -> texthigh);
292 fprintf_filtered (outfile, " Depends on %d other partial symtabs.\n",
293 psymtab -> number_of_dependencies);
294 if (psymtab -> n_global_syms > 0)
295 {
296 print_partial_symbol (objfile -> global_psymbols.list
297 + psymtab -> globals_offset,
298 psymtab -> n_global_syms, "Global", outfile);
299 }
300 if (psymtab -> n_static_syms > 0)
301 {
302 print_partial_symbol (objfile -> static_psymbols.list
303 + psymtab -> statics_offset,
304 psymtab -> n_static_syms, "Static", outfile);
305 }
306 fprintf_filtered (outfile, "\n");
307 }
308
309 static void
310 dump_symtab (objfile, symtab, outfile)
311 struct objfile *objfile;
312 struct symtab *symtab;
313 FILE *outfile;
314 {
315 register int i, j;
316 int len, blen;
317 register struct linetable *l;
318 struct blockvector *bv;
319 register struct block *b;
320 int depth;
321
322 fprintf (outfile, "\nSymtab for file %s\n", symtab->filename);
323 fprintf (outfile, "Read from object file %s (%x)\n", objfile->name,
324 (unsigned int) objfile);
325 fprintf (outfile, "Language: %s\n", language_str (symtab -> language));
326
327 /* First print the line table. */
328 l = LINETABLE (symtab);
329 if (l) {
330 fprintf (outfile, "\nLine table:\n\n");
331 len = l->nitems;
332 for (i = 0; i < len; i++)
333 fprintf (outfile, " line %d at %x\n", l->item[i].line,
334 l->item[i].pc);
335 }
336 /* Now print the block info. */
337 fprintf (outfile, "\nBlockvector:\n\n");
338 bv = BLOCKVECTOR (symtab);
339 len = BLOCKVECTOR_NBLOCKS (bv);
340 for (i = 0; i < len; i++)
341 {
342 b = BLOCKVECTOR_BLOCK (bv, i);
343 depth = block_depth (b) * 2;
344 print_spaces (depth, outfile);
345 fprintf (outfile, "block #%03d (object 0x%x) ", i, (unsigned int) b);
346 fprintf (outfile, "[0x%x..0x%x]", BLOCK_START (b), BLOCK_END (b));
347 if (BLOCK_SUPERBLOCK (b))
348 fprintf (outfile, " (under 0x%x)", (unsigned int) BLOCK_SUPERBLOCK (b));
349 if (BLOCK_FUNCTION (b))
350 {
351 fprintf (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
352 if (SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)) != NULL)
353 {
354 fprintf (outfile, " %s",
355 SYMBOL_DEMANGLED_NAME (BLOCK_FUNCTION (b)));
356 }
357 }
358 if (BLOCK_GCC_COMPILED(b))
359 fprintf (outfile, " gcc%d compiled", BLOCK_GCC_COMPILED(b));
360 fputc ('\n', outfile);
361 blen = BLOCK_NSYMS (b);
362 for (j = 0; j < blen; j++)
363 {
364 print_symbol (BLOCK_SYM (b, j), depth + 1, outfile);
365 }
366 }
367 fprintf (outfile, "\n");
368 }
369
370 void
371 maintenance_print_symbols (args, from_tty)
372 char *args;
373 int from_tty;
374 {
375 char **argv;
376 FILE *outfile;
377 struct cleanup *cleanups;
378 char *symname = NULL;
379 char *filename = DEV_TTY;
380 struct objfile *objfile;
381 struct symtab *s;
382
383 dont_repeat ();
384
385 if (args == NULL)
386 {
387 error ("print-symbols takes an output file name and optional symbol file name");
388 }
389 else if ((argv = buildargv (args)) == NULL)
390 {
391 nomem (0);
392 }
393 cleanups = make_cleanup (freeargv, (char *) argv);
394
395 if (argv[0] != NULL)
396 {
397 filename = argv[0];
398 /* If a second arg is supplied, it is a source file name to match on */
399 if (argv[1] != NULL)
400 {
401 symname = argv[1];
402 }
403 }
404
405 filename = tilde_expand (filename);
406 make_cleanup (free, filename);
407
408 outfile = fopen (filename, FOPEN_WT);
409 if (outfile == 0)
410 perror_with_name (filename);
411 make_cleanup (fclose, (char *) outfile);
412
413 immediate_quit++;
414 ALL_SYMTABS (objfile, s)
415 if (symname == NULL || (STREQ (symname, s -> filename)))
416 dump_symtab (objfile, s, outfile);
417 immediate_quit--;
418 do_cleanups (cleanups);
419 }
420
421 static void
422 print_symbol (symbol, depth, outfile)
423 struct symbol *symbol;
424 int depth;
425 FILE *outfile;
426 {
427 print_spaces (depth, outfile);
428 if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE)
429 {
430 fprintf (outfile, "label %s at 0x%x\n", SYMBOL_SOURCE_NAME (symbol),
431 SYMBOL_VALUE_ADDRESS (symbol));
432 return;
433 }
434 if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE)
435 {
436 if (TYPE_NAME (SYMBOL_TYPE (symbol)))
437 {
438 LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
439 }
440 else
441 {
442 fprintf (outfile, "%s %s = ",
443 (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM
444 ? "enum"
445 : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT
446 ? "struct" : "union")),
447 SYMBOL_NAME (symbol));
448 LA_PRINT_TYPE (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
449 }
450 fprintf (outfile, ";\n");
451 }
452 else
453 {
454 if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF)
455 fprintf (outfile, "typedef ");
456 if (SYMBOL_TYPE (symbol))
457 {
458 /* Print details of types, except for enums where it's clutter. */
459 LA_PRINT_TYPE (SYMBOL_TYPE (symbol), SYMBOL_SOURCE_NAME (symbol),
460 outfile,
461 TYPE_CODE (SYMBOL_TYPE (symbol)) != TYPE_CODE_ENUM,
462 depth);
463 fprintf (outfile, "; ");
464 }
465 else
466 fprintf (outfile, "%s ", SYMBOL_SOURCE_NAME (symbol));
467
468 switch (SYMBOL_CLASS (symbol))
469 {
470 case LOC_CONST:
471 fprintf (outfile, "const %ld (0x%lx),",
472 SYMBOL_VALUE (symbol), SYMBOL_VALUE (symbol));
473 break;
474
475 case LOC_CONST_BYTES:
476 fprintf (outfile, "const %u hex bytes:",
477 TYPE_LENGTH (SYMBOL_TYPE (symbol)));
478 {
479 unsigned i;
480 for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); i++)
481 fprintf (outfile, " %2x",
482 (unsigned)SYMBOL_VALUE_BYTES (symbol) [i]);
483 fprintf (outfile, ",");
484 }
485 break;
486
487 case LOC_STATIC:
488 fprintf (outfile, "static at 0x%x,", SYMBOL_VALUE_ADDRESS (symbol));
489 break;
490
491 case LOC_REGISTER:
492 fprintf (outfile, "register %ld,", SYMBOL_VALUE (symbol));
493 break;
494
495 case LOC_ARG:
496 if (SYMBOL_BASEREG_VALID (symbol))
497 {
498 fprintf (outfile, "arg at 0x%lx from register %d,",
499 SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
500 }
501 else
502 {
503 fprintf (outfile, "arg at 0x%lx,", SYMBOL_VALUE (symbol));
504 }
505 break;
506
507 case LOC_LOCAL_ARG:
508 if (SYMBOL_BASEREG_VALID (symbol))
509 {
510 fprintf (outfile, "arg at offset 0x%lx from register %d,",
511 SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
512 }
513 else
514 {
515 fprintf (outfile, "arg at offset 0x%lx from fp,",
516 SYMBOL_VALUE (symbol));
517 }
518
519 case LOC_REF_ARG:
520 fprintf (outfile, "reference arg at 0x%lx,", SYMBOL_VALUE (symbol));
521 break;
522
523 case LOC_REGPARM:
524 fprintf (outfile, "parameter register %ld,", SYMBOL_VALUE (symbol));
525 break;
526
527 case LOC_REGPARM_ADDR:
528 fprintf (outfile, "address parameter register %ld,", SYMBOL_VALUE (symbol));
529 break;
530
531 case LOC_LOCAL:
532 if (SYMBOL_BASEREG_VALID (symbol))
533 {
534 fprintf (outfile, "local at 0x%lx from register %d",
535 SYMBOL_VALUE (symbol), SYMBOL_BASEREG (symbol));
536 }
537 else
538 {
539 fprintf (outfile, "local at 0x%lx,", SYMBOL_VALUE (symbol));
540 }
541 break;
542
543 case LOC_TYPEDEF:
544 break;
545
546 case LOC_LABEL:
547 fprintf (outfile, "label at 0x%lx", SYMBOL_VALUE_ADDRESS (symbol));
548 break;
549
550 case LOC_BLOCK:
551 fprintf (outfile, "block (object 0x%x) starting at 0x%x,",
552 (unsigned int) SYMBOL_BLOCK_VALUE (symbol),
553 BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)));
554 break;
555
556 case LOC_OPTIMIZED_OUT:
557 fprintf (outfile, "optimized out");
558 break;
559
560 default:
561 fprintf (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol));
562 break;
563 }
564 }
565 fprintf (outfile, "\n");
566 }
567
568 void
569 maintenance_print_psymbols (args, from_tty)
570 char *args;
571 int from_tty;
572 {
573 char **argv;
574 FILE *outfile;
575 struct cleanup *cleanups;
576 char *symname = NULL;
577 char *filename = DEV_TTY;
578 struct objfile *objfile;
579 struct partial_symtab *ps;
580
581 dont_repeat ();
582
583 if (args == NULL)
584 {
585 error ("print-psymbols takes an output file name and optional symbol file name");
586 }
587 else if ((argv = buildargv (args)) == NULL)
588 {
589 nomem (0);
590 }
591 cleanups = make_cleanup (freeargv, (char *) argv);
592
593 if (argv[0] != NULL)
594 {
595 filename = argv[0];
596 /* If a second arg is supplied, it is a source file name to match on */
597 if (argv[1] != NULL)
598 {
599 symname = argv[1];
600 }
601 }
602
603 filename = tilde_expand (filename);
604 make_cleanup (free, filename);
605
606 outfile = fopen (filename, FOPEN_WT);
607 if (outfile == 0)
608 perror_with_name (filename);
609 make_cleanup (fclose, outfile);
610
611 immediate_quit++;
612 ALL_PSYMTABS (objfile, ps)
613 if (symname == NULL || (STREQ (symname, ps -> filename)))
614 dump_psymtab (objfile, ps, outfile);
615 immediate_quit--;
616 do_cleanups (cleanups);
617 }
618
619 static void
620 print_partial_symbol (p, count, what, outfile)
621 struct partial_symbol *p;
622 int count;
623 char *what;
624 FILE *outfile;
625 {
626
627 fprintf_filtered (outfile, " %s partial symbols:\n", what);
628 while (count-- > 0)
629 {
630 fprintf_filtered (outfile, " `%s'", SYMBOL_NAME(p));
631 if (SYMBOL_DEMANGLED_NAME (p) != NULL)
632 {
633 fprintf_filtered (outfile, " `%s'", SYMBOL_DEMANGLED_NAME (p));
634 }
635 fputs_filtered (", ", outfile);
636 switch (SYMBOL_NAMESPACE (p))
637 {
638 case UNDEF_NAMESPACE:
639 fputs_filtered ("undefined namespace, ", outfile);
640 break;
641 case VAR_NAMESPACE:
642 /* This is the usual thing -- don't print it */
643 break;
644 case STRUCT_NAMESPACE:
645 fputs_filtered ("struct namespace, ", outfile);
646 break;
647 case LABEL_NAMESPACE:
648 fputs_filtered ("label namespace, ", outfile);
649 break;
650 default:
651 fputs_filtered ("<invalid namespace>, ", outfile);
652 break;
653 }
654 switch (SYMBOL_CLASS (p))
655 {
656 case LOC_UNDEF:
657 fputs_filtered ("undefined", outfile);
658 break;
659 case LOC_CONST:
660 fputs_filtered ("constant int", outfile);
661 break;
662 case LOC_STATIC:
663 fputs_filtered ("static", outfile);
664 break;
665 case LOC_REGISTER:
666 fputs_filtered ("register", outfile);
667 break;
668 case LOC_ARG:
669 fputs_filtered ("pass by value", outfile);
670 break;
671 case LOC_REF_ARG:
672 fputs_filtered ("pass by reference", outfile);
673 break;
674 case LOC_REGPARM:
675 fputs_filtered ("register parameter", outfile);
676 break;
677 case LOC_REGPARM_ADDR:
678 fputs_filtered ("register address parameter", outfile);
679 break;
680 case LOC_LOCAL:
681 fputs_filtered ("stack parameter", outfile);
682 break;
683 case LOC_TYPEDEF:
684 fputs_filtered ("type", outfile);
685 break;
686 case LOC_LABEL:
687 fputs_filtered ("label", outfile);
688 break;
689 case LOC_BLOCK:
690 fputs_filtered ("function", outfile);
691 break;
692 case LOC_CONST_BYTES:
693 fputs_filtered ("constant bytes", outfile);
694 break;
695 case LOC_LOCAL_ARG:
696 fputs_filtered ("shuffled arg", outfile);
697 break;
698 case LOC_OPTIMIZED_OUT:
699 fputs_filtered ("optimized out", outfile);
700 break;
701 default:
702 fputs_filtered ("<invalid location>", outfile);
703 break;
704 }
705 fputs_filtered (", ", outfile);
706 fprintf_filtered (outfile, "0x%x\n", SYMBOL_VALUE (p));
707 p++;
708 }
709 }
710
711 void
712 maintenance_print_msymbols (args, from_tty)
713 char *args;
714 int from_tty;
715 {
716 char **argv;
717 FILE *outfile;
718 struct cleanup *cleanups;
719 char *filename = DEV_TTY;
720 char *symname = NULL;
721 struct objfile *objfile;
722
723 dont_repeat ();
724
725 if (args == NULL)
726 {
727 error ("print-msymbols takes an output file name and optional symbol file name");
728 }
729 else if ((argv = buildargv (args)) == NULL)
730 {
731 nomem (0);
732 }
733 cleanups = make_cleanup (freeargv, argv);
734
735 if (argv[0] != NULL)
736 {
737 filename = argv[0];
738 /* If a second arg is supplied, it is a source file name to match on */
739 if (argv[1] != NULL)
740 {
741 symname = argv[1];
742 }
743 }
744
745 filename = tilde_expand (filename);
746 make_cleanup (free, filename);
747
748 outfile = fopen (filename, FOPEN_WT);
749 if (outfile == 0)
750 perror_with_name (filename);
751 make_cleanup (fclose, outfile);
752
753 immediate_quit++;
754 ALL_OBJFILES (objfile)
755 if (symname == NULL || (STREQ (symname, objfile -> name)))
756 dump_msymbols (objfile, outfile);
757 immediate_quit--;
758 fprintf_filtered (outfile, "\n\n");
759 do_cleanups (cleanups);
760 }
761
762 void
763 maintenance_print_objfiles (ignore, from_tty)
764 char *ignore;
765 int from_tty;
766 {
767 struct objfile *objfile;
768
769 dont_repeat ();
770
771 immediate_quit++;
772 ALL_OBJFILES (objfile)
773 dump_objfile (objfile);
774 immediate_quit--;
775 }
776
777 \f
778 /* Return the nexting depth of a block within other blocks in its symtab. */
779
780 static int
781 block_depth (block)
782 struct block *block;
783 {
784 register int i = 0;
785 while ((block = BLOCK_SUPERBLOCK (block)) != NULL)
786 {
787 i++;
788 }
789 return i;
790 }
791
792 #endif /* MAINTENANCE_CMDS */
793
794 \f
795 /* Increase the space allocated for LISTP, which is probably
796 global_psymbol_list or static_psymbol_list. This space will eventually
797 be freed in free_objfile(). */
798
799 void
800 extend_psymbol_list (listp, objfile)
801 register struct psymbol_allocation_list *listp;
802 struct objfile *objfile;
803 {
804 int new_size;
805 if (listp->size == 0)
806 {
807 new_size = 255;
808 listp->list = (struct partial_symbol *)
809 xmmalloc (objfile -> md, new_size * sizeof (struct partial_symbol));
810 }
811 else
812 {
813 new_size = listp->size * 2;
814 listp->list = (struct partial_symbol *)
815 xmrealloc (objfile -> md, (char *) listp->list,
816 new_size * sizeof (struct partial_symbol));
817 }
818 /* Next assumes we only went one over. Should be good if
819 program works correctly */
820 listp->next = listp->list + listp->size;
821 listp->size = new_size;
822 }
823
824
825 /* Do early runtime initializations. */
826 void
827 _initialize_symmisc ()
828 {
829 std_in = stdin;
830 std_out = stdout;
831 std_err = stderr;
832 }