Various changes to clean up ADD_PSYMBOL_TO_LIST and ADD_PSYMBOL_ADDR_TO_LIST
[platform/upstream/binutils.git] / gdb / symmisc.c
1 /* Do various things to symbol tables (other than lookup), for GDB.
2    Copyright 1986, 1987, 1989, 1991 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 <stdio.h>
22 #include "defs.h"
23 #include "symtab.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 \f
32 /* Free a struct block <- B and all the symbols defined in that block.  */
33
34 static void
35 free_symtab_block (b)
36      struct block *b;
37 {
38   register int i, n;
39   n = BLOCK_NSYMS (b);
40   for (i = 0; i < n; i++)
41     {
42       free (SYMBOL_NAME (BLOCK_SYM (b, i)));
43       free (BLOCK_SYM (b, i));
44     }
45   free (b);
46 }
47
48 /* Free all the storage associated with the struct symtab <- S.
49    Note that some symtabs have contents malloc'ed structure by structure,
50    while some have contents that all live inside one big block of memory,
51    and some share the contents of another symbol table and so you should
52    not free the contents on their behalf (except sometimes the linetable,
53    which maybe per symtab even when the rest is not).
54    It is s->free_code that says which alternative to use.  */
55
56 void
57 free_symtab (s)
58      register struct symtab *s;
59 {
60   register int i, n;
61   register struct blockvector *bv;
62
63   switch (s->free_code)
64     {
65     case free_nothing:
66       /* All the contents are part of a big block of memory (an obstack),
67          and some other symtab is in charge of freeing that block.
68          Therefore, do nothing.  */
69       break;
70
71     case free_contents:
72       /* Here all the contents were malloc'ed structure by structure
73          and must be freed that way.  */
74       /* First free the blocks (and their symbols.  */
75       bv = BLOCKVECTOR (s);
76       n = BLOCKVECTOR_NBLOCKS (bv);
77       for (i = 0; i < n; i++)
78         free_symtab_block (BLOCKVECTOR_BLOCK (bv, i));
79       /* Free the blockvector itself.  */
80       free (bv);
81       /* Also free the linetable.  */
82       
83     case free_linetable:
84       /* Everything will be freed either by our `free_ptr'
85          or by some other symtab, except for our linetable.
86          Free that now.  */
87       if (LINETABLE (s))
88         free (LINETABLE (s));
89       break;
90     }
91
92   /* If there is a single block of memory to free, free it.  */
93   if (s->free_ptr)
94     free (s->free_ptr);
95
96   /* Free source-related stuff */
97   if (s->line_charpos)
98     free (s->line_charpos);
99   if (s->fullname)
100     free (s->fullname);
101   free (s);
102 }
103 \f
104 static int block_depth ();
105 static void print_symbol ();
106 static void print_partial_symbol ();
107
108 void
109 printsyms_command (filename)
110      char *filename;
111 {
112   FILE *outfile;
113   register struct symtab *s;
114   register int i, j;
115   int len, blen;
116   register struct linetable *l;
117   struct blockvector *bv;
118   register struct block *b;
119   int depth;
120   struct cleanup *cleanups;
121   extern int fclose();
122   char *symname;
123
124   if (filename == 0)
125     error_no_arg ("file to write symbol data in");
126
127   /* If a second arg is supplied, it is a source file name to match on */
128   symname = strchr (filename, ' ');
129   if (symname)
130     *symname++ = '\0';
131
132   filename = tilde_expand (filename);
133   make_cleanup (free, filename);
134   
135   outfile = fopen (filename, "w");
136   if (outfile == 0)
137     perror_with_name (filename);
138
139   cleanups = make_cleanup (fclose, outfile);
140   immediate_quit++;
141
142   for (s = symtab_list; s; s = s->next)
143     {
144       /* If source file name is specified, reject all but that one.  */
145       if (symname)
146         if (0 != strncmp (symname, s->filename, strlen (symname)))
147           continue;
148
149       fprintf (outfile, "Symtab for file %s\n", s->filename);
150       fprintf (outfile, "Read from object file %s (%x)\n", s->objfile->name,
151                         s->objfile);
152
153       /* First print the line table.  */
154       l = LINETABLE (s);
155       if (l) {
156         fprintf (outfile, "\nLine table:\n\n");
157         len = l->nitems;
158         for (i = 0; i < len; i++)
159           fprintf (outfile, " line %d at %x\n", l->item[i].line,
160                    l->item[i].pc);
161       }
162       /* Now print the block info.  */
163       fprintf (outfile, "\nBlockvector:\n\n");
164       bv = BLOCKVECTOR (s);
165       len = BLOCKVECTOR_NBLOCKS (bv);
166       for (i = 0; i < len; i++)
167         {
168           b = BLOCKVECTOR_BLOCK (bv, i);
169           depth = block_depth (b) * 2;
170           print_spaces (depth, outfile);
171           fprintf (outfile, "block #%03d (object 0x%x) ", i, b);
172           fprintf (outfile, "[0x%x..0x%x]", BLOCK_START (b), BLOCK_END (b));
173           if (BLOCK_SUPERBLOCK (b))
174             fprintf (outfile, " (under 0x%x)", BLOCK_SUPERBLOCK (b));
175           if (BLOCK_FUNCTION (b))
176             fprintf (outfile, " %s", SYMBOL_NAME (BLOCK_FUNCTION (b)));
177           fputc ('\n', outfile);
178           blen = BLOCK_NSYMS (b);
179           for (j = 0; j < blen; j++)
180             {
181               print_symbol (BLOCK_SYM (b, j), depth + 1, outfile);
182             }
183         }
184
185       fprintf (outfile, "\n\n");
186     }
187
188   immediate_quit--;
189   do_cleanups (cleanups);
190 }
191
192 static void
193 print_symbol (symbol, depth, outfile)
194      struct symbol *symbol;
195      int depth;
196      FILE *outfile;
197 {
198   print_spaces (depth, outfile);
199   if (SYMBOL_NAMESPACE (symbol) == LABEL_NAMESPACE)
200     {
201       fprintf (outfile, "label %s at 0x%x\n", SYMBOL_NAME (symbol),
202                SYMBOL_VALUE_ADDRESS (symbol));
203       return;
204     }
205   if (SYMBOL_NAMESPACE (symbol) == STRUCT_NAMESPACE)
206     {
207       if (TYPE_NAME (SYMBOL_TYPE (symbol)))
208         {
209           type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
210         }
211       else
212         {
213           fprintf (outfile, "%s %s = ",
214                (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_ENUM
215                 ? "enum"
216                 : (TYPE_CODE (SYMBOL_TYPE (symbol)) == TYPE_CODE_STRUCT
217                    ? "struct" : "union")),
218                SYMBOL_NAME (symbol));
219           type_print_1 (SYMBOL_TYPE (symbol), "", outfile, 1, depth);
220         }
221       fprintf (outfile, ";\n");
222     }
223   else
224     {
225       if (SYMBOL_CLASS (symbol) == LOC_TYPEDEF)
226         fprintf (outfile, "typedef ");
227       if (SYMBOL_TYPE (symbol))
228         {
229           type_print_1 (SYMBOL_TYPE (symbol), SYMBOL_NAME (symbol),
230                         outfile, 1, depth);
231           fprintf (outfile, "; ");
232         }
233       else
234         fprintf (outfile, "%s ", SYMBOL_NAME (symbol));
235
236       switch (SYMBOL_CLASS (symbol))
237         {
238         case LOC_CONST:
239           fprintf (outfile, "const %ld (0x%lx),",
240                    SYMBOL_VALUE (symbol), SYMBOL_VALUE (symbol));
241           break;
242
243         case LOC_CONST_BYTES:
244           fprintf (outfile, "const %u hex bytes:",
245                    TYPE_LENGTH (SYMBOL_TYPE (symbol)));
246           {
247             unsigned i;
248             for (i = 0; i < TYPE_LENGTH (SYMBOL_TYPE (symbol)); i++)
249               fprintf (outfile, " %2x",
250                          (unsigned)SYMBOL_VALUE_BYTES (symbol) [i]);
251             fprintf (outfile, ",");
252           }
253           break;
254
255         case LOC_STATIC:
256           fprintf (outfile, "static at 0x%x,", SYMBOL_VALUE_ADDRESS (symbol));
257           break;
258
259         case LOC_REGISTER:
260           fprintf (outfile, "register %ld,", SYMBOL_VALUE (symbol));
261           break;
262
263         case LOC_ARG:
264           fprintf (outfile, "arg at 0x%lx,", SYMBOL_VALUE (symbol));
265           break;
266
267         case LOC_LOCAL_ARG:
268           fprintf (outfile, "arg at offset 0x%x from fp,",
269                    SYMBOL_VALUE (symbol));
270
271         case LOC_REF_ARG:
272           fprintf (outfile, "reference arg at 0x%lx,", SYMBOL_VALUE (symbol));
273           break;
274
275         case LOC_REGPARM:
276           fprintf (outfile, "parameter register %ld,", SYMBOL_VALUE (symbol));
277           break;
278
279         case LOC_LOCAL:
280           fprintf (outfile, "local at 0x%lx,", SYMBOL_VALUE (symbol));
281           break;
282
283         case LOC_TYPEDEF:
284           break;
285
286         case LOC_LABEL:
287           fprintf (outfile, "label at 0x%lx", SYMBOL_VALUE_ADDRESS (symbol));
288           break;
289
290         case LOC_BLOCK:
291           fprintf (outfile, "block (object 0x%x) starting at 0x%x,",
292                    SYMBOL_BLOCK_VALUE (symbol),
293                    BLOCK_START (SYMBOL_BLOCK_VALUE (symbol)));
294           break;
295
296         default:
297           fprintf (outfile, "botched symbol class %x", SYMBOL_CLASS (symbol));
298           break;
299         }
300     }
301   fprintf (outfile, "\n");
302 }
303
304 void
305 printpsyms_command (filename)
306      char *filename;
307 {
308   FILE *outfile;
309   struct partial_symtab *p;
310   struct cleanup *cleanups;
311   extern int fclose();
312   char *symname;
313
314   if (filename == 0)
315     error_no_arg ("file to write partial symbol data in");
316
317   /* If a second arg is supplied, it is a source file name to match on */
318   symname = strchr (filename, ' ');
319   if (symname)
320     *symname++ = '\0';
321
322   filename = tilde_expand (filename);
323   make_cleanup (free, filename);
324   
325   outfile = fopen (filename, "w");
326   if (outfile == 0)
327     perror_with_name (filename);
328
329   cleanups = make_cleanup (fclose, outfile);
330   immediate_quit++;
331
332   for (p = partial_symtab_list; p; p = p->next)
333     {
334       /* If source file name is specified, reject all but that one.  */
335       if (symname)
336         if (0 != strncmp (symname, p->filename, strlen (symname)))
337           continue;
338
339       fprintf_filtered (outfile, "Partial symtab for source file %s ",
340                p->filename);
341       fprintf_filtered (outfile, "(object 0x%x)\n\n", p);
342       fprintf (outfile, "  Read from object file %s (0x%x)\n", p->objfile->name,
343                         p->objfile);
344
345       if (p->readin)
346         fprintf_filtered (outfile, "  Full symtab was read (at 0x%x by function at 0x%x)\n",
347                           p->symtab, p->read_symtab);
348       fprintf_filtered (outfile, "  Relocate symbols by 0x%x\n", p->addr);
349       fprintf_filtered (outfile, "  Symbols cover text addresses 0x%x-0x%x\n",
350                         p->textlow, p->texthigh);
351       fprintf_filtered (outfile, "  Depends on %d other partial symtabs.\n",
352                         p->number_of_dependencies);
353       if (p->n_global_syms > 0)
354         print_partial_symbol (global_psymbols.list + p->globals_offset,
355                               p->n_global_syms, "Global", outfile);
356       if (p->n_static_syms > 0)
357         print_partial_symbol (static_psymbols.list + p->statics_offset,
358                               p->n_static_syms, "Static", outfile);
359       fprintf_filtered (outfile, "\n\n");
360     }
361
362   immediate_quit--;
363   do_cleanups (cleanups);
364 }
365
366 static void
367 print_partial_symbol (p, count, what, outfile)
368 struct partial_symbol *p;
369 int count;
370 char *what;
371 FILE *outfile;
372 {
373
374   fprintf_filtered (outfile, "  %s partial symbols:\n", what);
375   while (count-- > 0)
376     {
377       fprintf_filtered (outfile, "    `%s', ", SYMBOL_NAME(p));
378       switch (SYMBOL_NAMESPACE (p))
379         {
380         case UNDEF_NAMESPACE:
381           fputs_filtered ("undefined namespace, ", outfile);
382           break;
383         case VAR_NAMESPACE:
384           /* This is the usual thing -- don't print it */
385           break;
386         case STRUCT_NAMESPACE:
387           fputs_filtered ("struct namespace, ", outfile);
388           break;
389         case LABEL_NAMESPACE:
390           fputs_filtered ("label namespace, ", outfile);
391           break;
392         default:
393           fputs_filtered ("<invalid namespace>, ", outfile);
394           break;
395         }
396       switch (SYMBOL_CLASS (p))
397         {
398         case LOC_UNDEF:
399           fputs_filtered ("undefined", outfile);
400           break;
401         case LOC_CONST:
402           fputs_filtered ("constant int", outfile);
403           break;
404         case LOC_STATIC:
405           fputs_filtered ("static", outfile);
406           break;
407         case LOC_REGISTER:
408           fputs_filtered ("register", outfile);
409           break;
410         case LOC_ARG:
411           fputs_filtered ("pass by value", outfile);
412           break;
413         case LOC_REF_ARG:
414           fputs_filtered ("pass by reference", outfile);
415           break;
416         case LOC_REGPARM:
417           fputs_filtered ("register parameter", outfile);
418           break;
419         case LOC_LOCAL:
420           fputs_filtered ("stack parameter", outfile);
421           break;
422         case LOC_TYPEDEF:
423           fputs_filtered ("type", outfile);
424           break;
425         case LOC_LABEL:
426           fputs_filtered ("label", outfile);
427           break;
428         case LOC_BLOCK:
429           fputs_filtered ("function", outfile);
430           break;
431         case LOC_CONST_BYTES:
432           fputs_filtered ("constant bytes", outfile);
433           break;
434         case LOC_LOCAL_ARG:
435           fputs_filtered ("shuffled arg", outfile);
436           break;
437         default:
438           fputs_filtered ("<invalid location>", outfile);
439           break;
440         }
441       fputs_filtered (", ", outfile);
442       fprintf_filtered (outfile, "0x%x\n", SYMBOL_VALUE (p));
443       p++;
444     }
445 }
446
447 /* Return the nexting depth of a block within other blocks in its symtab.  */
448
449 static int
450 block_depth (block)
451      struct block *block;
452 {
453   register int i = 0;
454   while (block = BLOCK_SUPERBLOCK (block)) i++;
455   return i;
456 }
457 \f
458 static void
459 printobjfiles_command ()
460 {
461   struct objfile *objfile;
462   struct symtab *symtab;
463   struct partial_symtab *psymtab;
464   int first;
465
466   for (objfile = object_files;  objfile;  objfile = objfile->next) {
467     printf_filtered ("\nObject file %s:  ", objfile->name);
468     printf_filtered ("Objfile at %x, bfd at %x\n\n", objfile, objfile->obfd);
469
470     if (objfile->psymtabs) {
471       printf_filtered ("Psymtabs:\n");
472       for (psymtab = objfile->psymtabs;
473            psymtab;
474            psymtab = psymtab->objfile_chain) {
475         printf_filtered ("%s at %x, ", psymtab->filename, psymtab);
476         if (psymtab->objfile != objfile)
477           printf_filtered ("NOT ON CHAIN!  ");
478         wrap_here ("  ");
479       }
480       printf_filtered ("\n\n");
481     }
482
483     if (objfile->symtabs) {
484       printf_filtered ("Symtabs:\n");
485       for (symtab = objfile->symtabs;
486            symtab;
487            symtab = symtab->objfile_chain) {
488         printf_filtered ("%s at %x, ", symtab->filename, symtab);
489         if (symtab->objfile != objfile)
490           printf_filtered ("NOT ON CHAIN!  ");
491         wrap_here ("  ");
492       }
493       printf_filtered ("\n\n");
494     }
495   }
496
497   /* Now check for psymtabs that aren't owned by an objfile.  */
498
499   first = 1;
500   for (psymtab = partial_symtab_list; psymtab; psymtab = psymtab->next) {
501     for (objfile = object_files; objfile; objfile = objfile->next) {
502       if (psymtab->objfile == objfile)
503         goto next;
504     }
505     if (first)
506       printf_filtered ("Psymtabs that aren't owned by any objfile:\n");
507     first = 0;
508     printf_filtered ("  %s at %x, psymtab->objfile %x\n", psymtab->filename,
509                      psymtab, psymtab->objfile);
510   next: ;
511   }
512
513   /* Now check for symtabs that aren't owned by an objfile.  */
514
515   first = 1;
516   for (symtab = symtab_list; symtab; symtab = symtab->next) {
517     for (objfile = object_files; objfile; objfile = objfile->next) {
518       if (symtab->objfile == objfile)
519         goto next2;
520     }
521     if (first)
522       printf_filtered ("Symtabs that aren't owned by any objfile:\n");
523     first = 0;
524     printf_filtered ("  %s at %x, symtab->objfile %x\n", symtab->filename,
525                      symtab, symtab->objfile);
526   next2: ;
527   }
528 }
529 \f
530 struct cplus_struct_type cplus_struct_default;
531
532 void
533 allocate_cplus_struct_type (type)
534      struct type *type;
535 {
536   if (!HAVE_CPLUS_STRUCT (type))
537     {
538       int nfields = TYPE_NFIELDS (type);
539       TYPE_CPLUS_SPECIFIC (type) = (struct cplus_struct_type *)
540         obstack_alloc (symbol_obstack, sizeof (struct cplus_struct_type));
541       *(TYPE_CPLUS_SPECIFIC(type)) = cplus_struct_default;
542     }
543 }
544
545 /* Increase the space allocated for LISTP. */
546
547 void
548 extend_psymbol_list(listp)
549      register struct psymbol_allocation_list *listp;
550 {
551   int new_size;
552   if (listp->size == 0)
553     {
554       new_size = 255;
555       listp->list = (struct partial_symbol *)
556         xmalloc (new_size * sizeof (struct partial_symbol));
557     }
558   else
559     {
560       new_size = listp->size * 2;
561       listp->list = (struct partial_symbol *)
562         xrealloc (listp->list, new_size * sizeof (struct partial_symbol));
563     }
564   /* Next assumes we only went one over.  Should be good if
565      program works correctly */
566   listp->next = listp->list + listp->size;
567   listp->size = new_size;
568 }
569
570 #ifdef DEBUG
571
572 /* The work performed by this function is normally done by the macro
573    ADD_PSYMBOL_TO_LIST defined in symfile.h.  When debugging gdb, this
574    function makes things easier. */
575
576 void
577 add_psymbol_to_list (name, namelength, namespace, class, listp, psymval)
578      char *name;
579      int namelength;
580      enum namespace namespace;
581      enum address_class class;
582      struct psymbol_allocation_list *listp;
583      unsigned long psymval;
584 {
585   register struct partial_symbol *psym;
586
587   if (listp -> next >= listp -> list + listp -> size)
588     extend_psymbol_list (listp);
589   psym = listp -> next++;
590   SYMBOL_NAME (psym) = (char *) obstack_alloc (psymbol_obstack,
591                                                namelength + 1);
592   memcpy (SYMBOL_NAME (psym), name, namelength);
593   SYMBOL_NAME (psym)[namelength] = '\0';
594   SYMBOL_NAMESPACE (psym) = namespace;
595   SYMBOL_CLASS (psym) = class;
596   SYMBOL_VALUE (psym) = psymval;
597 }
598
599 /* The work performed by this function is normally done by the macro
600    ADD_PSYMBOL_ADDR_TO_LIST defined in symfile.h.  When debugging gdb, this
601    function makes things easier. */
602
603 void
604 add_psymbol_addr_to_list (name, namelength, namespace, class, listp, psymval)
605      char *name;
606      int namelength;
607      enum namespace namespace;
608      enum address_class class;
609      struct psymbol_allocation_list *listp;
610      CORE_ADDR psymval;
611 {
612   register struct partial_symbol *psym;
613
614   if (listp -> next >= listp -> list + listp -> size)
615     extend_psymbol_list (listp);
616   psym = listp -> next++;
617   SYMBOL_NAME (psym) = (char *) obstack_alloc (psymbol_obstack,
618                                                namelength + 1);
619   memcpy (SYMBOL_NAME (psym), name, namelength);
620   SYMBOL_NAME (psym)[namelength] = '\0';
621   SYMBOL_NAMESPACE (psym) = namespace;
622   SYMBOL_CLASS (psym) = class;
623   SYMBOL_VALUE_ADDRESS (psym) = psymval;
624 }
625
626 #endif /* DEBUG */
627
628 void
629 _initialize_symmisc ()
630 {
631   symtab_list = (struct symtab *) 0;
632   partial_symtab_list = (struct partial_symtab *) 0;
633   
634   add_com ("printsyms", class_obscure, printsyms_command,
635            "Print dump of current symbol definitions to file OUTFILE.\n\
636 If a SOURCE file is specified, dump only that file's symbols.");
637   add_com ("printpsyms", class_obscure, printpsyms_command,
638           "Print dump of current partial symbol definitions to file OUTFILE.\n\
639 If a SOURCE file is specified, dump only that file's partial symbols.");
640   add_com ("printobjfiles", class_obscure, printobjfiles_command,
641            "Print dump of current object file definitions.");
642 }
643