Globs of changes. See the ChangeLog for details. Most related to
[external/binutils.git] / gdb / symmisc.c
1 /* Do various things to symbol tables (other than lookup), for GDB.
2    Copyright 1986, 1987, 1989, 1991, 1992 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
21 #include "defs.h"
22 #include "symtab.h"
23 #include "gdbtypes.h"
24 #include "bfd.h"
25 #include "symfile.h"
26 #include "breakpoint.h"
27 #include "command.h"
28 #include "obstack.h"
29
30 #include <string.h>
31
32 #ifndef DEV_TTY
33 #define DEV_TTY "/dev/tty"
34 #endif
35
36 /* Prototypes for local functions */
37
38 static PTR 
39 dump_symtab PARAMS ((struct objfile *, struct symtab *, PTR, PTR, PTR));
40
41 static PTR 
42 dump_psymtab PARAMS ((struct objfile *, struct partial_symtab *, PTR, PTR,
43                       PTR));
44
45 static PTR 
46 dump_msymbols PARAMS ((struct objfile *, PTR, PTR, PTR));
47
48 static PTR 
49 dump_objfile PARAMS ((struct objfile *, PTR, PTR, PTR));
50
51 static void
52 printobjfiles_command PARAMS ((void));
53
54 static int
55 block_depth PARAMS ((struct block *));
56
57 static void
58 print_partial_symbol PARAMS ((struct partial_symbol *, int, char *, FILE *));
59
60 static void
61 printpsyms_command PARAMS ((char *, int));
62
63 static void
64 print_symbol PARAMS ((struct symbol *, int, FILE *));
65
66 static void
67 printsyms_command PARAMS ((char *, int));
68
69 static void
70 free_symtab_block PARAMS ((struct objfile *, struct block *));
71
72 static void
73 printmsyms_command PARAMS ((char *, int));
74
75 static void
76 dump_symtab_lines PARAMS ((struct symtab *));
77
78 static void
79 dump_symtabs PARAMS ((struct symtab *));
80
81 static void
82 dump_last_symtab PARAMS ((struct symtab *));
83
84 static void
85 dump_blockvector PARAMS ((struct blockvector *));
86
87 static void
88 dump_block PARAMS ((struct block *));
89
90 static char *
91 dump_addrclass PARAMS ((int));
92
93 static char *
94 dump_namespace PARAMS ((int));
95
96 static void
97 dump_symbol PARAMS ((struct symbol *));
98
99 static void
100 dump_type PARAMS ((struct type *));
101
102 static void
103 dump_linetable PARAMS ((struct linetable *));
104
105 static void
106 dump_strtbl PARAMS ((void));
107
108 \f
109 /* Free a struct block <- B and all the symbols defined in that block.  */
110
111 static void
112 free_symtab_block (objfile, b)
113      struct objfile *objfile;
114      struct block *b;
115 {
116   register int i, n;
117   n = BLOCK_NSYMS (b);
118   for (i = 0; i < n; i++)
119     {
120       mfree (objfile -> md, SYMBOL_NAME (BLOCK_SYM (b, i)));
121       mfree (objfile -> md, BLOCK_SYM (b, i));
122     }
123   mfree (objfile -> md, b);
124 }
125
126 /* Free all the storage associated with the struct symtab <- S.
127    Note that some symtabs have contents malloc'ed structure by structure,
128    while some have contents that all live inside one big block of memory,
129    and some share the contents of another symbol table and so you should
130    not free the contents on their behalf (except sometimes the linetable,
131    which maybe per symtab even when the rest is not).
132    It is s->free_code that says which alternative to use.  */
133
134 void
135 free_symtab (s)
136      register struct symtab *s;
137 {
138   register int i, n;
139   register struct blockvector *bv;
140
141   switch (s->free_code)
142     {
143     case free_nothing:
144       /* All the contents are part of a big block of memory (an obstack),
145          and some other symtab is in charge of freeing that block.
146          Therefore, do nothing.  */
147       break;
148
149     case free_contents:
150       /* Here all the contents were malloc'ed structure by structure
151          and must be freed that way.  */
152       /* First free the blocks (and their symbols.  */
153       bv = BLOCKVECTOR (s);
154       n = BLOCKVECTOR_NBLOCKS (bv);
155       for (i = 0; i < n; i++)
156         free_symtab_block (s -> objfile, BLOCKVECTOR_BLOCK (bv, i));
157       /* Free the blockvector itself.  */
158       mfree (s -> objfile -> md, bv);
159       /* Also free the linetable.  */
160       
161     case free_linetable:
162       /* Everything will be freed either by our `free_ptr'
163          or by some other symtab, except for our linetable.
164          Free that now.  */
165       if (LINETABLE (s))
166         mfree (s -> objfile -> md, LINETABLE (s));
167       break;
168     }
169
170   /* If there is a single block of memory to free, free it.  */
171   if (s -> free_ptr != NULL)
172     mfree (s -> objfile -> md, s -> free_ptr);
173
174   /* Free source-related stuff */
175   if (s -> line_charpos != NULL)
176     mfree (s -> objfile -> md, s -> line_charpos);
177   if (s -> fullname != NULL)
178     mfree (s -> objfile -> md, s -> fullname);
179   mfree (s -> objfile -> md, s);
180 }
181
182 static PTR 
183 dump_objfile (objfile, arg1, arg2, arg3)
184      struct objfile *objfile;
185      PTR arg1;
186      PTR arg2;
187      PTR arg3;
188 {
189   struct symtab *symtab;
190   struct partial_symtab *psymtab;
191
192   printf_filtered ("\nObject file %s:  ", objfile -> name);
193   printf_filtered ("Objfile at %x, bfd at %x, %d minsyms\n\n",
194                    objfile, objfile -> obfd, objfile->minimal_symbol_count);
195
196   if (objfile -> psymtabs)
197     {
198       printf_filtered ("Psymtabs:\n");
199       for (psymtab = objfile -> psymtabs;
200            psymtab != NULL;
201            psymtab = psymtab -> next)
202         {
203           printf_filtered ("%s at %x, ", psymtab -> filename, psymtab);
204           if (psymtab -> objfile != objfile)
205             {
206               printf_filtered ("NOT ON CHAIN!  ");
207             }
208           wrap_here ("  ");
209         }
210       printf_filtered ("\n\n");
211     }
212
213   if (objfile -> symtabs)
214     {
215       printf_filtered ("Symtabs:\n");
216       for (symtab = objfile -> symtabs;
217            symtab != NULL;
218            symtab = symtab->next)
219         {
220           printf_filtered ("%s at %x, ", symtab -> filename, symtab);
221           if (symtab -> objfile != objfile)
222             {
223               printf_filtered ("NOT ON CHAIN!  ");
224             }
225           wrap_here ("  ");
226         }
227       printf_filtered ("\n\n");
228     }
229   return (NULL);
230 }
231
232 static PTR 
233 dump_msymbols (objfile, arg1, arg2, arg3)
234      struct objfile *objfile;
235      PTR arg1;
236      PTR arg2;
237      PTR arg3;
238 {
239   FILE *outfile = (FILE *) arg1;
240   char *symname = (char *) arg2;
241   struct minimal_symbol *msymbol;
242   int index;
243   char ms_type;
244   
245   /* Print minimal symbols from this objfile unless a specific linkage
246      unit file was requested, in which case we only print the symbols
247      for that one. */
248   if (symname == NULL || (strcmp (symname, objfile -> name) == 0))
249     {
250       fprintf_filtered (outfile, "\nObject file %s:\n\n", objfile -> name);
251       for (index = 0, msymbol = objfile -> msymbols;
252            msymbol -> name != NULL; msymbol++, index++)
253         {
254           switch (msymbol -> type)
255             {
256               case mst_unknown:
257                 ms_type = 'u';
258                 break;
259               case mst_text:
260                 ms_type = 't';
261                 break;
262               case mst_data:
263                 ms_type = 'd';
264                 break;
265               case mst_bss:
266                 ms_type = 'b';
267                 break;
268               case mst_abs:
269                 ms_type = 'a';
270                 break;
271               default:
272                 ms_type = '?';
273                 break;
274             }
275           fprintf_filtered (outfile, "[%2d] %c %#10x %s\n", index, ms_type,
276                             msymbol -> address, msymbol -> name);
277         }
278       if (objfile -> minimal_symbol_count != index)
279         {
280           warning ("internal error:  minimal symbol count %d != %d",
281                    objfile -> minimal_symbol_count, index);
282         }
283       fprintf_filtered (outfile, "\n");
284     }
285   return (NULL);
286 }
287
288 static PTR 
289 dump_psymtab (objfile, psymtab, arg1, arg2, arg3)
290      struct objfile *objfile;
291      struct partial_symtab *psymtab;
292      PTR arg1;
293      PTR arg2;
294      PTR arg3;
295 {
296   FILE *outfile = (FILE *) arg1;
297   char *symname = (char *) arg2;
298
299   /* If source file name is specified, reject all but that one.  */
300   if (symname == NULL || (strcmp (symname, psymtab -> filename) == 0))
301     {
302       fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
303                         psymtab -> filename);
304       fprintf_filtered (outfile, "(object 0x%x)\n\n", psymtab);
305       fprintf (outfile, "  Read from object file %s (0x%x)\n",
306                objfile -> name, objfile);
307       
308       if (psymtab -> readin)
309         {
310           fprintf_filtered (outfile,
311                     "  Full symtab was read (at 0x%x by function at 0x%x)\n",
312                             psymtab -> symtab, psymtab -> read_symtab);
313         }
314       fprintf_filtered (outfile, "  Relocate symbols by 0x%x\n",
315                         psymtab -> addr);
316       fprintf_filtered (outfile, "  Symbols cover text addresses 0x%x-0x%x\n",
317                         psymtab -> textlow, psymtab -> texthigh);
318       fprintf_filtered (outfile, "  Depends on %d other partial symtabs.\n",
319                         psymtab -> number_of_dependencies);
320       if (psymtab -> n_global_syms > 0)
321         {
322           print_partial_symbol (objfile -> global_psymbols.list
323                                 + psymtab -> globals_offset,
324                                 psymtab -> n_global_syms, "Global", outfile);
325         }
326       if (psymtab -> n_static_syms > 0)
327         {
328           print_partial_symbol (objfile -> static_psymbols.list
329                                 + psymtab -> statics_offset,
330                                 psymtab -> n_static_syms, "Static", outfile);
331         }
332       fprintf_filtered (outfile, "\n");
333     }
334   return (NULL);
335 }
336
337 static PTR 
338 dump_symtab (objfile, symtab, arg1, arg2, arg3)
339      struct objfile *objfile;
340      struct symtab *symtab;
341      PTR arg1;
342      PTR arg2;
343      PTR arg3;
344 {
345   FILE *outfile = (FILE *) arg1;
346   char *symname = (char *) arg2;
347   register int i, j;
348   int len, blen;
349   register struct linetable *l;
350   struct blockvector *bv;
351   register struct block *b;
352   int depth;
353
354   if (symname == NULL || (strcmp (symname, symtab -> filename) == 0))
355     {
356       fprintf (outfile, "\nSymtab for file %s\n", symtab->filename);
357       fprintf (outfile, "Read from object file %s (%x)\n", objfile->name,
358                objfile);
359       
360       /* First print the line table.  */
361       l = LINETABLE (symtab);
362       if (l) {
363         fprintf (outfile, "\nLine table:\n\n");
364         len = l->nitems;
365         for (i = 0; i < len; i++)
366           fprintf (outfile, " line %d at %x\n", l->item[i].line,
367                    l->item[i].pc);
368       }
369       /* Now print the block info.  */
370       fprintf (outfile, "\nBlockvector:\n\n");
371       bv = BLOCKVECTOR (symtab);
372       len = BLOCKVECTOR_NBLOCKS (bv);
373       for (i = 0; i < len; i++)
374         {
375           b = BLOCKVECTOR_BLOCK (bv, i);
376           depth = block_depth (b) * 2;
377           print_spaces (depth, outfile);
378           fprintf (outfile, "block #%03d (object 0x%x) ", i, b);
379           fprintf (outfile, "[0x%x..0x%x]", BLOCK_START (b), BLOCK_END (b));
380           if (BLOCK_SUPERBLOCK (b))
381             fprintf (outfile, " (under 0x%x)", BLOCK_SUPERBLOCK (b));
382           if (BLOCK_FUNCTION (b))
383             fprintf (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
384           fputc ('\n', outfile);
385           blen = BLOCK_NSYMS (b);
386           for (j = 0; j < blen; j++)
387             {
388               print_symbol (BLOCK_SYM (b, j), depth + 1, outfile);
389             }
390         }
391       fprintf (outfile, "\n");
392     }
393   return (NULL);
394 }
395
396 static void
397 printsyms_command (args, from_tty)
398      char *args;
399      int from_tty;
400 {
401   char **argv;
402   FILE *outfile;
403   struct cleanup *cleanups;
404   char *symname = NULL;
405   char *filename = DEV_TTY;
406
407   dont_repeat ();
408
409   if (args == NULL)
410     {
411       error ("printsyms takes an output file name and optional symbol file name");
412     }
413   else if ((argv = buildargv (args)) == NULL)
414     {
415       nomem (0);
416     }
417   cleanups = make_cleanup (freeargv, (char *) argv);
418
419   if (argv[0] != NULL)
420     {
421       filename = argv[0];
422       /* If a second arg is supplied, it is a source file name to match on */
423       if (argv[1] != NULL)
424         {
425           symname = argv[1];
426         }
427     }
428
429   filename = tilde_expand (filename);
430   make_cleanup (free, filename);
431   
432   outfile = fopen (filename, "w");
433   if (outfile == 0)
434     perror_with_name (filename);
435   make_cleanup (fclose, (char *) outfile);
436
437   immediate_quit++;
438   iterate_over_symtabs (dump_symtab, (PTR) outfile, (PTR) symname, (PTR) NULL);
439   immediate_quit--;
440   do_cleanups (cleanups);
441 }
442
443 static void
444 print_symbol (symbol, depth, outfile)
445      struct symbol *symbol;
446      int depth;
447      FILE *outfile;
448 {
449   print_spaces (depth, outfile);
450   if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE)
451     {
452       fprintf (outfile, "label %s at 0x%x\n", SYMBOL_NAME (symbol),
453                SYMBOL_VALUE_ADDRESS (symbol));
454       return;
455     }
456   if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE)
457     {
458       if (TYPE_NAME (SYMBOL_TYPE (symbol)))
459         {
460           type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
461         }
462       else
463         {
464           fprintf (outfile, "%s %s = ",
465                (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM
466                 ? "enum"
467                 : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT
468                    ? "struct" : "union")),
469                SYMBOL_NAME (symbol));
470           type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
471         }
472       fprintf (outfile, ";\n");
473     }
474   else
475     {
476       if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF)
477         fprintf (outfile, "typedef ");
478       if (SYMBOL_TYPE (symbol))
479         {
480           type_print_1 (SYMBOL_TYPE (symbol), SYMBOL_NAME (symbol),
481                         outfile, 1, depth);
482           fprintf (outfile, "; ");
483         }
484       else
485         fprintf (outfile, "%s ", SYMBOL_NAME (symbol));
486
487       switch (SYMBOL_CLASS (symbol))
488         {
489         case LOC_CONST:
490           fprintf (outfile, "const %ld (0x%lx),",
491                    SYMBOL_VALUE (symbol), SYMBOL_VALUE (symbol));
492           break;
493
494         case LOC_CONST_BYTES:
495           fprintf (outfile, "const %u hex bytes:",
496                    TYPE_LENGTH (SYMBOL_TYPE (symbol)));
497           {
498             unsigned i;
499             for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); i++)
500               fprintf (outfile, " %2x",
501                          (unsigned)SYMBOL_VALUE_BYTES (symbol) [i]);
502             fprintf (outfile, ",");
503           }
504           break;
505
506         case LOC_STATIC:
507           fprintf (outfile, "static at 0x%x,", SYMBOL_VALUE_ADDRESS (symbol));
508           break;
509
510         case LOC_REGISTER:
511           fprintf (outfile, "register %ld,", SYMBOL_VALUE (symbol));
512           break;
513
514         case LOC_ARG:
515           fprintf (outfile, "arg at 0x%lx,", SYMBOL_VALUE (symbol));
516           break;
517
518         case LOC_LOCAL_ARG:
519           fprintf (outfile, "arg at offset 0x%x from fp,",
520                    SYMBOL_VALUE (symbol));
521
522         case LOC_REF_ARG:
523           fprintf (outfile, "reference arg at 0x%lx,", SYMBOL_VALUE (symbol));
524           break;
525
526         case LOC_REGPARM:
527           fprintf (outfile, "parameter register %ld,", SYMBOL_VALUE (symbol));
528           break;
529
530         case LOC_LOCAL:
531           fprintf (outfile, "local at 0x%lx,", SYMBOL_VALUE (symbol));
532           break;
533
534         case LOC_TYPEDEF:
535           break;
536
537         case LOC_LABEL:
538           fprintf (outfile, "label at 0x%lx", SYMBOL_VALUE_ADDRESS (symbol));
539           break;
540
541         case LOC_BLOCK:
542           fprintf (outfile, "block (object 0x%x) starting at 0x%x,",
543                    SYMBOL_BLOCK_VALUE (symbol),
544                    BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)));
545           break;
546
547         default:
548           fprintf (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol));
549           break;
550         }
551     }
552   fprintf (outfile, "\n");
553 }
554
555 static void
556 printpsyms_command (args, from_tty)
557      char *args;
558      int from_tty;
559 {
560   char **argv;
561   FILE *outfile;
562   struct cleanup *cleanups;
563   char *symname = NULL;
564   char *filename = DEV_TTY;
565
566   dont_repeat ();
567
568   if (args == NULL)
569     {
570       error ("printpsyms takes an output file name and optional symbol file name");
571     }
572   else if ((argv = buildargv (args)) == NULL)
573     {
574       nomem (0);
575     }
576   cleanups = make_cleanup (freeargv, (char *) argv);
577
578   if (argv[0] != NULL)
579     {
580       filename = argv[0];
581       /* If a second arg is supplied, it is a source file name to match on */
582       if (argv[1] != NULL)
583         {
584           symname = argv[1];
585         }
586     }
587
588   filename = tilde_expand (filename);
589   make_cleanup (free, filename);
590   
591   outfile = fopen (filename, "w");
592   if (outfile == 0)
593     perror_with_name (filename);
594   make_cleanup (fclose, outfile);
595
596   immediate_quit++;
597   iterate_over_psymtabs (dump_psymtab, (PTR) outfile, (PTR) symname,
598                          (PTR) NULL);
599   immediate_quit--;
600   do_cleanups (cleanups);
601 }
602
603 static void
604 print_partial_symbol (p, count, what, outfile)
605      struct partial_symbol *p;
606      int count;
607      char *what;
608      FILE *outfile;
609 {
610
611   fprintf_filtered (outfile, "  %s partial symbols:\n", what);
612   while (count-- > 0)
613     {
614       fprintf_filtered (outfile, "    `%s', ", SYMBOL_NAME(p));
615       switch (SYMBOL_NAMESPACE (p))
616         {
617         case UNDEF_NAMESPACE:
618           fputs_filtered ("undefined namespace, ", outfile);
619           break;
620         case VAR_NAMESPACE:
621           /* This is the usual thing -- don't print it */
622           break;
623         case STRUCT_NAMESPACE:
624           fputs_filtered ("struct namespace, ", outfile);
625           break;
626         case LABEL_NAMESPACE:
627           fputs_filtered ("label namespace, ", outfile);
628           break;
629         default:
630           fputs_filtered ("<invalid namespace>, ", outfile);
631           break;
632         }
633       switch (SYMBOL_CLASS (p))
634         {
635         case LOC_UNDEF:
636           fputs_filtered ("undefined", outfile);
637           break;
638         case LOC_CONST:
639           fputs_filtered ("constant int", outfile);
640           break;
641         case LOC_STATIC:
642           fputs_filtered ("static", outfile);
643           break;
644         case LOC_REGISTER:
645           fputs_filtered ("register", outfile);
646           break;
647         case LOC_ARG:
648           fputs_filtered ("pass by value", outfile);
649           break;
650         case LOC_REF_ARG:
651           fputs_filtered ("pass by reference", outfile);
652           break;
653         case LOC_REGPARM:
654           fputs_filtered ("register parameter", outfile);
655           break;
656         case LOC_LOCAL:
657           fputs_filtered ("stack parameter", outfile);
658           break;
659         case LOC_TYPEDEF:
660           fputs_filtered ("type", outfile);
661           break;
662         case LOC_LABEL:
663           fputs_filtered ("label", outfile);
664           break;
665         case LOC_BLOCK:
666           fputs_filtered ("function", outfile);
667           break;
668         case LOC_CONST_BYTES:
669           fputs_filtered ("constant bytes", outfile);
670           break;
671         case LOC_LOCAL_ARG:
672           fputs_filtered ("shuffled arg", outfile);
673           break;
674         default:
675           fputs_filtered ("<invalid location>", outfile);
676           break;
677         }
678       fputs_filtered (", ", outfile);
679       fprintf_filtered (outfile, "0x%x\n", SYMBOL_VALUE (p));
680       p++;
681     }
682 }
683
684 static void
685 printmsyms_command (args, from_tty)
686      char *args;
687      int from_tty;
688 {
689   char **argv;
690   FILE *outfile;
691   struct cleanup *cleanups;
692   char *filename = DEV_TTY;
693   char *symname = NULL;
694
695   dont_repeat ();
696
697   if (args == NULL)
698     {
699       error ("printmsyms takes an output file name and optional symbol file name");
700     }
701   else if ((argv = buildargv (args)) == NULL)
702     {
703       nomem (0);
704     }
705   cleanups = make_cleanup (freeargv, argv);
706
707   if (argv[0] != NULL)
708     {
709       filename = argv[0];
710       /* If a second arg is supplied, it is a source file name to match on */
711       if (argv[1] != NULL)
712         {
713           symname = argv[1];
714         }
715     }
716
717   filename = tilde_expand (filename);
718   make_cleanup (free, filename);
719   
720   outfile = fopen (filename, "w");
721   if (outfile == 0)
722     perror_with_name (filename);
723   make_cleanup (fclose, outfile);
724
725   immediate_quit++;
726   iterate_over_objfiles (dump_msymbols, (PTR) outfile, (PTR) symname,
727                          (PTR) NULL);
728   immediate_quit--;
729   fprintf_filtered (outfile, "\n\n");
730   do_cleanups (cleanups);
731 }
732
733 static void
734 printobjfiles_command ()
735 {
736   dont_repeat ();
737
738   immediate_quit++;
739   iterate_over_objfiles (dump_objfile, (PTR) NULL, (PTR) NULL, (PTR) NULL);
740   immediate_quit--;
741 }
742
743 \f
744 /* Debugging functions from xcoffread.c originally.   Some are redundant
745    and should probably disappear.  */
746
747 static void
748 dump_strtbl ()
749 {
750 #if 0           /* We don't know its length FIXME */
751   int ii;
752   printf ("===STRING TABLE DUMP...\n\n");
753   for ( ii=0; ii < strtbl_len; ++ii )
754     printf ("%c", isprint (*(strtbl+ii)) ? *(strtbl+ii) : ' ');
755   printf ("\n");
756 #endif
757 }
758
759 static void
760 dump_linetable (ltb)
761      struct linetable *ltb;
762 {
763   int ii;
764   for (ii=0; ii < ltb->nitems; ++ii)
765     printf ("line: %d, addr: 0x%x\n", ltb->item[ii].line, ltb->item[ii].pc);
766 }
767
768 static void
769 dump_type (typeP)
770      struct type *typeP;
771 {
772   printf ("0x%x: name: %s\n", typeP, typeP->name ? typeP->name : "(nil)");
773 }
774
775 static void
776 dump_symbol (pp)
777      struct symbol *pp;
778 {
779   printf (" sym: %s\t%s,\t%s\ttype: 0x%x, val: 0x%x end: 0x%x\n", 
780       pp->name, dump_namespace (pp->namespace),
781       dump_addrclass (pp->class), pp->type,
782       SYMBOL_CLASS(pp) == LOC_BLOCK ? BLOCK_START(SYMBOL_BLOCK_VALUE(pp))
783       : pp->value.value,
784       SYMBOL_CLASS(pp) == LOC_BLOCK ? BLOCK_END(SYMBOL_BLOCK_VALUE(pp)) : 0);
785 }
786
787 static char *
788 dump_namespace (ns)
789 int ns;
790 {
791   static char *ns_name [] = { 
792     "UNDEF_NS", "VAR_NS", "STRUCT_NS", "LABEL_NS"};
793
794   switch (ns) {
795   case UNDEF_NAMESPACE:
796   case VAR_NAMESPACE:
797   case STRUCT_NAMESPACE:
798   case LABEL_NAMESPACE:
799     return ns_name[ns];
800   }
801  
802   return "***ERROR***";
803 }
804
805 static char *
806 dump_addrclass (ac)
807 int ac;                                         /* address class */
808 {
809   static char *ac_name [] = {
810     "LOC_UNDEF",
811     "LOC_CONST",
812     "LOC_STATIC",
813     "LOC_REGISTER",
814     "LOC_ARG",
815     "LOC_REF_ARG",
816     "LOC_REGPARM",
817     "LOC_LOCAL",
818     "LOC_TYPEDEF",
819     "LOC_LABEL",
820     "LOC_BLOCK",
821     "LOC_CONST_BYTES",
822     "LOC_LOCAL_ARG",
823   };
824   switch (ac) {
825   case LOC_UNDEF:
826   case LOC_CONST:
827   case LOC_STATIC:
828   case LOC_REGISTER:
829   case LOC_ARG:
830   case LOC_REF_ARG:
831   case LOC_REGPARM:
832   case LOC_LOCAL:
833   case LOC_TYPEDEF:
834   case LOC_LABEL:
835   case LOC_BLOCK:
836   case LOC_CONST_BYTES:
837   case LOC_LOCAL_ARG:
838     return ac_name [ac];
839   }
840   return "***ERROR***";
841 }
842
843 static void
844 dump_block (pp)
845      struct block *pp;
846 {
847   int ii;
848   printf ("BLOCK..: start: 0x%x, end: 0x%x\n", pp->startaddr, pp->endaddr);
849   for (ii=0; ii < pp->nsyms; ++ii)
850     dump_symbol (pp->sym[ii]);
851 }
852
853 static void
854 dump_blockvector (pp)
855      struct blockvector *pp;
856 {
857   int ii;
858   for (ii=0; ii < pp->nblocks; ++ii)
859     dump_block (pp->block [ii]);
860 }
861
862 static void
863 dump_last_symtab (pp)
864      struct symtab *pp;
865 {
866   for ( ; pp; pp = pp->next) {
867     if ( pp->next == 0 ) {
868       printf ("SYMTAB NAME: %s\n", pp->filename);
869       dump_blockvector (pp->blockvector);
870     }
871   }
872 }
873
874 static void
875 dump_symtabs (pp)
876      struct symtab *pp;
877 {
878   for ( ; pp; pp = pp->next) {
879     printf ("SYMTAB NAME: %s\n", pp->filename ? pp->filename : "(nil)");
880 /*    if (pp->linetable)
881       dump_linetable (pp->linetable); */
882     dump_blockvector (pp->blockvector);
883   }
884 }
885
886 static void
887 dump_symtab_lines (pp)
888      struct symtab *pp;
889 {
890   for ( ; pp; pp = pp->next) {
891     printf ("SYMTAB NAME: %s\n", pp->filename ? pp->filename : "(nil)");
892     if (pp->linetable)
893       dump_linetable (pp->linetable);
894     /* dump_blockvector (pp->blockvector); */
895   }
896 }
897
898
899 \f
900 /* Return the nexting depth of a block within other blocks in its symtab.  */
901
902 static int
903 block_depth (block)
904      struct block *block;
905 {
906   register int i = 0;
907   while (block = BLOCK_SUPERBLOCK (block)) i++;
908   return i;
909 }
910
911 \f
912 /* Increase the space allocated for LISTP. */
913
914 void
915 extend_psymbol_list (listp, objfile)
916      register struct psymbol_allocation_list *listp;
917      struct objfile *objfile;
918 {
919   int new_size;
920   if (listp->size == 0)
921     {
922       new_size = 255;
923       listp->list = (struct partial_symbol *)
924         xmmalloc (objfile -> md, new_size * sizeof (struct partial_symbol));
925     }
926   else
927     {
928       new_size = listp->size * 2;
929       listp->list = (struct partial_symbol *)
930         xmrealloc (objfile -> md, (char *) listp->list,
931                    new_size * sizeof (struct partial_symbol));
932     }
933   /* Next assumes we only went one over.  Should be good if
934      program works correctly */
935   listp->next = listp->list + listp->size;
936   listp->size = new_size;
937 }
938
939 #ifdef DEBUG
940
941 /* The work performed by this function is normally done by the macro
942    ADD_PSYMBOL_TO_LIST defined in symfile.h.  When debugging gdb, this
943    function makes things easier. */
944
945 void
946 add_psymbol_to_list (name, namelength, namespace, class, listp, psymval)
947      char *name;
948      int namelength;
949      enum namespace namespace;
950      enum address_class class;
951      struct psymbol_allocation_list *listp;
952      unsigned long psymval;
953 {
954   register struct partial_symbol *psym;
955
956   if (listp -> next >= listp -> list + listp -> size)
957     extend_psymbol_list (listp, objfile);
958   psym = listp -> next++;
959   SYMBOL_NAME (psym) = (char *) obstack_alloc (&objfile->psymbol_obstack,
960                                                namelength + 1);
961   memcpy (SYMBOL_NAME (psym), name, namelength);
962   SYMBOL_NAME (psym)[namelength] = '\0';
963   SYMBOL_NAMESPACE (psym) = namespace;
964   SYMBOL_CLASS (psym) = class;
965   SYMBOL_VALUE (psym) = psymval;
966 }
967
968 /* The work performed by this function is normally done by the macro
969    ADD_PSYMBOL_ADDR_TO_LIST defined in symfile.h.  When debugging gdb, this
970    function makes things easier. */
971
972 void
973 add_psymbol_addr_to_list (name, namelength, namespace, class, listp, psymval)
974      char *name;
975      int namelength;
976      enum namespace namespace;
977      enum address_class class;
978      struct psymbol_allocation_list *listp;
979      CORE_ADDR psymval;
980 {
981   register struct partial_symbol *psym;
982
983   if (listp -> next >= listp -> list + listp -> size)
984     extend_psymbol_list (listp, objfile);
985   psym = listp -> next++;
986   SYMBOL_NAME (psym) = (char *) obstack_alloc (&objfile->psymbol_obstack,
987                                                namelength + 1);
988   memcpy (SYMBOL_NAME (psym), name, namelength);
989   SYMBOL_NAME (psym)[namelength] = '\0';
990   SYMBOL_NAMESPACE (psym) = namespace;
991   SYMBOL_CLASS (psym) = class;
992   SYMBOL_VALUE_ADDRESS (psym) = psymval;
993 }
994
995 #endif /* DEBUG */
996
997 void
998 _initialize_symmisc ()
999 {
1000   add_com ("printmsyms", class_obscure, printmsyms_command,
1001            "Print dump of current minimal symbol definitions to file OUTFILE.\n\
1002 If a SOURCE file is specified, dump only that file's symbols.");
1003   add_com ("printpsyms", class_obscure, printpsyms_command,
1004           "Print dump of current partial symbol definitions to file OUTFILE.\n\
1005 If a SOURCE file is specified, dump only that file's partial symbols.");
1006   add_com ("printsyms", class_obscure, printsyms_command,
1007            "Print dump of current symbol definitions to file OUTFILE.\n\
1008 If a SOURCE file is specified, dump only that file's symbols.");
1009   add_com ("printobjfiles", class_obscure, printobjfiles_command,
1010            "Print dump of current object file definitions.");
1011 }
1012