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