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