build_type_unit_groups and moved closer to only caller and renamed
[platform/upstream/binutils.git] / gdb / psymtab.c
1 /* Partial symbol tables.
2    
3    Copyright (C) 2009-2014 Free Software Foundation, Inc.
4
5    This file is part of GDB.
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
20 #include "defs.h"
21 #include "symtab.h"
22 #include "psympriv.h"
23 #include "objfiles.h"
24 #include "gdb_assert.h"
25 #include "block.h"
26 #include "filenames.h"
27 #include "source.h"
28 #include "addrmap.h"
29 #include "gdbtypes.h"
30 #include "bcache.h"
31 #include "ui-out.h"
32 #include "command.h"
33 #include "readline/readline.h"
34 #include "gdb_regex.h"
35 #include "dictionary.h"
36 #include "language.h"
37 #include "cp-support.h"
38 #include "gdbcmd.h"
39
40 #ifndef DEV_TTY
41 #define DEV_TTY "/dev/tty"
42 #endif
43
44 struct psymbol_bcache
45 {
46   struct bcache *bcache;
47 };
48
49 static struct partial_symbol *match_partial_symbol (struct objfile *,
50                                                     struct partial_symtab *,
51                                                     int,
52                                                     const char *, domain_enum,
53                                                     symbol_compare_ftype *,
54                                                     symbol_compare_ftype *);
55
56 static struct partial_symbol *lookup_partial_symbol (struct objfile *,
57                                                      struct partial_symtab *,
58                                                      const char *, int,
59                                                      domain_enum);
60
61 static const char *psymtab_to_fullname (struct partial_symtab *ps);
62
63 static struct partial_symbol *find_pc_sect_psymbol (struct objfile *,
64                                                     struct partial_symtab *,
65                                                     CORE_ADDR,
66                                                     struct obj_section *);
67
68 static void fixup_psymbol_section (struct partial_symbol *psym,
69                                    struct objfile *objfile);
70
71 static struct symtab *psymtab_to_symtab (struct objfile *objfile,
72                                          struct partial_symtab *pst);
73
74 /* Ensure that the partial symbols for OBJFILE have been loaded.  This
75    function always returns its argument, as a convenience.  */
76
77 struct objfile *
78 require_partial_symbols (struct objfile *objfile, int verbose)
79 {
80   if ((objfile->flags & OBJF_PSYMTABS_READ) == 0)
81     {
82       objfile->flags |= OBJF_PSYMTABS_READ;
83
84       if (objfile->sf->sym_read_psymbols)
85         {
86           if (verbose)
87             {
88               printf_unfiltered (_("Reading symbols from %s..."),
89                                  objfile_name (objfile));
90               gdb_flush (gdb_stdout);
91             }
92           (*objfile->sf->sym_read_psymbols) (objfile);
93           if (verbose)
94             {
95               if (!objfile_has_symbols (objfile))
96                 {
97                   wrap_here ("");
98                   printf_unfiltered (_("(no debugging symbols found)..."));
99                   wrap_here ("");
100                 }
101
102               printf_unfiltered (_("done.\n"));
103             }
104         }
105     }
106
107   return objfile;
108 }
109
110 /* Traverse all psymtabs in one objfile, requiring that the psymtabs
111    be read in.  */
112
113 #define ALL_OBJFILE_PSYMTABS_REQUIRED(objfile, p)               \
114     for ((p) = require_partial_symbols (objfile, 1)->psymtabs;  \
115          (p) != NULL;                                           \
116          (p) = (p)->next)
117
118 /* We want to make sure this file always requires psymtabs.  */
119
120 #undef ALL_OBJFILE_PSYMTABS
121
122 /* Traverse all psymtabs in all objfiles.  */
123
124 #define ALL_PSYMTABS(objfile, p) \
125   ALL_OBJFILES (objfile)         \
126     ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
127
128 /* Helper function for partial_map_symtabs_matching_filename that
129    expands the symtabs and calls the iterator.  */
130
131 static int
132 partial_map_expand_apply (struct objfile *objfile,
133                           const char *name,
134                           const char *real_path,
135                           struct partial_symtab *pst,
136                           int (*callback) (struct symtab *, void *),
137                           void *data)
138 {
139   struct symtab *last_made = objfile->symtabs;
140
141   /* Shared psymtabs should never be seen here.  Instead they should
142      be handled properly by the caller.  */
143   gdb_assert (pst->user == NULL);
144
145   /* Don't visit already-expanded psymtabs.  */
146   if (pst->readin)
147     return 0;
148
149   /* This may expand more than one symtab, and we want to iterate over
150      all of them.  */
151   psymtab_to_symtab (objfile, pst);
152
153   return iterate_over_some_symtabs (name, real_path, callback, data,
154                                     objfile->symtabs, last_made);
155 }
156
157 /* Implementation of the map_symtabs_matching_filename method.  */
158
159 static int
160 partial_map_symtabs_matching_filename (struct objfile *objfile,
161                                        const char *name,
162                                        const char *real_path,
163                                        int (*callback) (struct symtab *,
164                                                         void *),
165                                        void *data)
166 {
167   struct partial_symtab *pst;
168   const char *name_basename = lbasename (name);
169
170   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
171   {
172     /* We can skip shared psymtabs here, because any file name will be
173        attached to the unshared psymtab.  */
174     if (pst->user != NULL)
175       continue;
176
177     /* Anonymous psymtabs don't have a file name.  */
178     if (pst->anonymous)
179       continue;
180
181     if (compare_filenames_for_search (pst->filename, name))
182       {
183         if (partial_map_expand_apply (objfile, name, real_path,
184                                       pst, callback, data))
185           return 1;
186         continue;
187       }
188
189     /* Before we invoke realpath, which can get expensive when many
190        files are involved, do a quick comparison of the basenames.  */
191     if (! basenames_may_differ
192         && FILENAME_CMP (name_basename, lbasename (pst->filename)) != 0)
193       continue;
194
195     if (compare_filenames_for_search (psymtab_to_fullname (pst), name))
196       {
197         if (partial_map_expand_apply (objfile, name, real_path,
198                                       pst, callback, data))
199           return 1;
200         continue;
201       }
202
203     /* If the user gave us an absolute path, try to find the file in
204        this symtab and use its absolute path.  */
205     if (real_path != NULL)
206       {
207         gdb_assert (IS_ABSOLUTE_PATH (real_path));
208         gdb_assert (IS_ABSOLUTE_PATH (name));
209         if (filename_cmp (psymtab_to_fullname (pst), real_path) == 0)
210           {
211             if (partial_map_expand_apply (objfile, name, real_path,
212                                           pst, callback, data))
213               return 1;
214             continue;
215           }
216       }
217   }
218
219   return 0;
220 }
221
222 /* Find which partial symtab contains PC and SECTION starting at psymtab PST.
223    We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
224
225 static struct partial_symtab *
226 find_pc_sect_psymtab_closer (struct objfile *objfile,
227                              CORE_ADDR pc, struct obj_section *section,
228                              struct partial_symtab *pst,
229                              struct bound_minimal_symbol msymbol)
230 {
231   struct partial_symtab *tpst;
232   struct partial_symtab *best_pst = pst;
233   CORE_ADDR best_addr = pst->textlow;
234
235   gdb_assert (!pst->psymtabs_addrmap_supported);
236
237   /* An objfile that has its functions reordered might have
238      many partial symbol tables containing the PC, but
239      we want the partial symbol table that contains the
240      function containing the PC.  */
241   if (!(objfile->flags & OBJF_REORDERED) &&
242       section == 0)     /* Can't validate section this way.  */
243     return pst;
244
245   if (msymbol.minsym == NULL)
246     return (pst);
247
248   /* The code range of partial symtabs sometimes overlap, so, in
249      the loop below, we need to check all partial symtabs and
250      find the one that fits better for the given PC address.  We
251      select the partial symtab that contains a symbol whose
252      address is closest to the PC address.  By closest we mean
253      that find_pc_sect_symbol returns the symbol with address
254      that is closest and still less than the given PC.  */
255   for (tpst = pst; tpst != NULL; tpst = tpst->next)
256     {
257       if (pc >= tpst->textlow && pc < tpst->texthigh)
258         {
259           struct partial_symbol *p;
260           CORE_ADDR this_addr;
261
262           /* NOTE: This assumes that every psymbol has a
263              corresponding msymbol, which is not necessarily
264              true; the debug info might be much richer than the
265              object's symbol table.  */
266           p = find_pc_sect_psymbol (objfile, tpst, pc, section);
267           if (p != NULL
268               && SYMBOL_VALUE_ADDRESS (p)
269               == BMSYMBOL_VALUE_ADDRESS (msymbol))
270             return tpst;
271
272           /* Also accept the textlow value of a psymtab as a
273              "symbol", to provide some support for partial
274              symbol tables with line information but no debug
275              symbols (e.g. those produced by an assembler).  */
276           if (p != NULL)
277             this_addr = SYMBOL_VALUE_ADDRESS (p);
278           else
279             this_addr = tpst->textlow;
280
281           /* Check whether it is closer than our current
282              BEST_ADDR.  Since this symbol address is
283              necessarily lower or equal to PC, the symbol closer
284              to PC is the symbol which address is the highest.
285              This way we return the psymtab which contains such
286              best match symbol.  This can help in cases where the
287              symbol information/debuginfo is not complete, like
288              for instance on IRIX6 with gcc, where no debug info
289              is emitted for statics.  (See also the nodebug.exp
290              testcase.)  */
291           if (this_addr > best_addr)
292             {
293               best_addr = this_addr;
294               best_pst = tpst;
295             }
296         }
297     }
298   return best_pst;
299 }
300
301 /* Find which partial symtab contains PC and SECTION.  Return 0 if
302    none.  We return the psymtab that contains a symbol whose address
303    exactly matches PC, or, if we cannot find an exact match, the
304    psymtab that contains a symbol whose address is closest to PC.  */
305 static struct partial_symtab *
306 find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc,
307                       struct obj_section *section,
308                       struct bound_minimal_symbol msymbol)
309 {
310   struct partial_symtab *pst;
311
312   /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
313      than the later used TEXTLOW/TEXTHIGH one.  */
314
315   if (objfile->psymtabs_addrmap != NULL)
316     {
317       pst = addrmap_find (objfile->psymtabs_addrmap, pc);
318       if (pst != NULL)
319         {
320           /* FIXME: addrmaps currently do not handle overlayed sections,
321              so fall back to the non-addrmap case if we're debugging
322              overlays and the addrmap returned the wrong section.  */
323           if (overlay_debugging && msymbol.minsym && section)
324             {
325               struct partial_symbol *p;
326
327               /* NOTE: This assumes that every psymbol has a
328                  corresponding msymbol, which is not necessarily
329                  true; the debug info might be much richer than the
330                  object's symbol table.  */
331               p = find_pc_sect_psymbol (objfile, pst, pc, section);
332               if (!p
333                   || SYMBOL_VALUE_ADDRESS (p)
334                   != BMSYMBOL_VALUE_ADDRESS (msymbol))
335                 goto next;
336             }
337
338           /* We do not try to call FIND_PC_SECT_PSYMTAB_CLOSER as
339              PSYMTABS_ADDRMAP we used has already the best 1-byte
340              granularity and FIND_PC_SECT_PSYMTAB_CLOSER may mislead us into
341              a worse chosen section due to the TEXTLOW/TEXTHIGH ranges
342              overlap.  */
343
344           return pst;
345         }
346     }
347
348  next:
349
350   /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
351      which still have no corresponding full SYMTABs read.  But it is not
352      present for non-DWARF2 debug infos not supporting PSYMTABS_ADDRMAP in GDB
353      so far.  */
354
355   /* Check even OBJFILE with non-zero PSYMTABS_ADDRMAP as only several of
356      its CUs may be missing in PSYMTABS_ADDRMAP as they may be varying
357      debug info type in single OBJFILE.  */
358
359   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
360     if (!pst->psymtabs_addrmap_supported
361         && pc >= pst->textlow && pc < pst->texthigh)
362       {
363         struct partial_symtab *best_pst;
364
365         best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst,
366                                                 msymbol);
367         if (best_pst != NULL)
368           return best_pst;
369       }
370
371   return NULL;
372 }
373
374 static struct symtab *
375 find_pc_sect_symtab_from_partial (struct objfile *objfile,
376                                   struct bound_minimal_symbol msymbol,
377                                   CORE_ADDR pc, struct obj_section *section,
378                                   int warn_if_readin)
379 {
380   struct partial_symtab *ps = find_pc_sect_psymtab (objfile, pc, section,
381                                                     msymbol);
382   if (ps)
383     {
384       if (warn_if_readin && ps->readin)
385         /* Might want to error() here (in case symtab is corrupt and
386            will cause a core dump), but maybe we can successfully
387            continue, so let's not.  */
388         warning (_("\
389 (Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
390                  paddress (get_objfile_arch (objfile), pc));
391       psymtab_to_symtab (objfile, ps);
392       return ps->symtab;
393     }
394   return NULL;
395 }
396
397 /* Find which partial symbol within a psymtab matches PC and SECTION.
398    Return 0 if none.  */
399
400 static struct partial_symbol *
401 find_pc_sect_psymbol (struct objfile *objfile,
402                       struct partial_symtab *psymtab, CORE_ADDR pc,
403                       struct obj_section *section)
404 {
405   struct partial_symbol *best = NULL, *p, **pp;
406   CORE_ADDR best_pc;
407
408   gdb_assert (psymtab != NULL);
409
410   /* Cope with programs that start at address 0.  */
411   best_pc = (psymtab->textlow != 0) ? psymtab->textlow - 1 : 0;
412
413   /* Search the global symbols as well as the static symbols, so that
414      find_pc_partial_function doesn't use a minimal symbol and thus
415      cache a bad endaddr.  */
416   for (pp = objfile->global_psymbols.list + psymtab->globals_offset;
417     (pp - (objfile->global_psymbols.list + psymtab->globals_offset)
418      < psymtab->n_global_syms);
419        pp++)
420     {
421       p = *pp;
422       if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
423           && PSYMBOL_CLASS (p) == LOC_BLOCK
424           && pc >= SYMBOL_VALUE_ADDRESS (p)
425           && (SYMBOL_VALUE_ADDRESS (p) > best_pc
426               || (psymtab->textlow == 0
427                   && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
428         {
429           if (section)          /* Match on a specific section.  */
430             {
431               fixup_psymbol_section (p, objfile);
432               if (!matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, p),
433                                           section))
434                 continue;
435             }
436           best_pc = SYMBOL_VALUE_ADDRESS (p);
437           best = p;
438         }
439     }
440
441   for (pp = objfile->static_psymbols.list + psymtab->statics_offset;
442     (pp - (objfile->static_psymbols.list + psymtab->statics_offset)
443      < psymtab->n_static_syms);
444        pp++)
445     {
446       p = *pp;
447       if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
448           && PSYMBOL_CLASS (p) == LOC_BLOCK
449           && pc >= SYMBOL_VALUE_ADDRESS (p)
450           && (SYMBOL_VALUE_ADDRESS (p) > best_pc
451               || (psymtab->textlow == 0
452                   && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
453         {
454           if (section)          /* Match on a specific section.  */
455             {
456               fixup_psymbol_section (p, objfile);
457               if (!matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, p),
458                                           section))
459                 continue;
460             }
461           best_pc = SYMBOL_VALUE_ADDRESS (p);
462           best = p;
463         }
464     }
465
466   return best;
467 }
468
469 static void
470 fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
471 {
472   CORE_ADDR addr;
473
474   if (!psym)
475     return;
476
477   if (SYMBOL_SECTION (psym) >= 0)
478     return;
479
480   gdb_assert (objfile);
481
482   switch (PSYMBOL_CLASS (psym))
483     {
484     case LOC_STATIC:
485     case LOC_LABEL:
486     case LOC_BLOCK:
487       addr = SYMBOL_VALUE_ADDRESS (psym);
488       break;
489     default:
490       /* Nothing else will be listed in the minsyms -- no use looking
491          it up.  */
492       return;
493     }
494
495   fixup_section (&psym->ginfo, addr, objfile);
496 }
497
498 static struct symtab *
499 lookup_symbol_aux_psymtabs (struct objfile *objfile,
500                             int block_index, const char *name,
501                             const domain_enum domain)
502 {
503   struct partial_symtab *ps;
504   const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
505   struct symtab *stab_best = NULL;
506
507   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
508   {
509     if (!ps->readin && lookup_partial_symbol (objfile, ps, name,
510                                               psymtab_index, domain))
511       {
512         struct symbol *sym = NULL;
513         struct symtab *stab = psymtab_to_symtab (objfile, ps);
514
515         /* Some caution must be observed with overloaded functions
516            and methods, since the psymtab will not contain any overload
517            information (but NAME might contain it).  */
518         if (stab->primary)
519           {
520             struct blockvector *bv = BLOCKVECTOR (stab);
521             struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
522
523             sym = lookup_block_symbol (block, name, domain);
524           }
525
526         if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
527           {
528             if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
529               return stab;
530
531             stab_best = stab;
532           }
533
534         /* Keep looking through other psymtabs.  */
535       }
536   }
537
538   return stab_best;
539 }
540
541 /* Look in PST for a symbol in DOMAIN whose name matches NAME.  Search
542    the global block of PST if GLOBAL, and otherwise the static block.
543    MATCH is the comparison operation that returns true iff MATCH (s,
544    NAME), where s is a SYMBOL_SEARCH_NAME.  If ORDERED_COMPARE is
545    non-null, the symbols in the block are assumed to be ordered
546    according to it (allowing binary search).  It must be compatible
547    with MATCH.  Returns the symbol, if found, and otherwise NULL.  */
548
549 static struct partial_symbol *
550 match_partial_symbol (struct objfile *objfile,
551                       struct partial_symtab *pst, int global,
552                       const char *name, domain_enum domain,
553                       symbol_compare_ftype *match,
554                       symbol_compare_ftype *ordered_compare)
555 {
556   struct partial_symbol **start, **psym;
557   struct partial_symbol **top, **real_top, **bottom, **center;
558   int length = (global ? pst->n_global_syms : pst->n_static_syms);
559   int do_linear_search = 1;
560
561   if (length == 0)
562       return NULL;
563   start = (global ?
564            objfile->global_psymbols.list + pst->globals_offset :
565            objfile->static_psymbols.list + pst->statics_offset);
566
567   if (global && ordered_compare)  /* Can use a binary search.  */
568     {
569       do_linear_search = 0;
570
571       /* Binary search.  This search is guaranteed to end with center
572          pointing at the earliest partial symbol whose name might be
573          correct.  At that point *all* partial symbols with an
574          appropriate name will be checked against the correct
575          domain.  */
576
577       bottom = start;
578       top = start + length - 1;
579       real_top = top;
580       while (top > bottom)
581         {
582           center = bottom + (top - bottom) / 2;
583           gdb_assert (center < top);
584           if (!do_linear_search
585               && (SYMBOL_LANGUAGE (*center) == language_java))
586             do_linear_search = 1;
587           if (ordered_compare (SYMBOL_SEARCH_NAME (*center), name) >= 0)
588             top = center;
589           else
590             bottom = center + 1;
591         }
592       gdb_assert (top == bottom);
593
594       while (top <= real_top
595              && match (SYMBOL_SEARCH_NAME (*top), name) == 0)
596         {
597           if (SYMBOL_DOMAIN (*top) == domain)
598             return *top;
599           top++;
600         }
601     }
602
603   /* Can't use a binary search or else we found during the binary search that
604      we should also do a linear search.  */
605
606   if (do_linear_search)
607     {
608       for (psym = start; psym < start + length; psym++)
609         {
610           if (SYMBOL_DOMAIN (*psym) == domain
611               && match (SYMBOL_SEARCH_NAME (*psym), name) == 0)
612             return *psym;
613         }
614     }
615
616   return NULL;
617 }
618
619 /* Returns the name used to search psymtabs.  Unlike symtabs, psymtabs do
620    not contain any method/function instance information (since this would
621    force reading type information while reading psymtabs).  Therefore,
622    if NAME contains overload information, it must be stripped before searching
623    psymtabs.
624
625    The caller is responsible for freeing the return result.  */
626
627 static char *
628 psymtab_search_name (const char *name)
629 {
630   switch (current_language->la_language)
631     {
632     case language_cplus:
633     case language_java:
634       {
635        if (strchr (name, '('))
636          {
637            char *ret = cp_remove_params (name);
638
639            if (ret)
640              return ret;
641          }
642       }
643       break;
644
645     default:
646       break;
647     }
648
649   return xstrdup (name);
650 }
651
652 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
653    Check the global symbols if GLOBAL, the static symbols if not.  */
654
655 static struct partial_symbol *
656 lookup_partial_symbol (struct objfile *objfile,
657                        struct partial_symtab *pst, const char *name,
658                        int global, domain_enum domain)
659 {
660   struct partial_symbol **start, **psym;
661   struct partial_symbol **top, **real_top, **bottom, **center;
662   int length = (global ? pst->n_global_syms : pst->n_static_syms);
663   int do_linear_search = 1;
664   char *search_name;
665   struct cleanup *cleanup;
666
667   if (length == 0)
668     {
669       return (NULL);
670     }
671
672   search_name = psymtab_search_name (name);
673   cleanup = make_cleanup (xfree, search_name);
674   start = (global ?
675            objfile->global_psymbols.list + pst->globals_offset :
676            objfile->static_psymbols.list + pst->statics_offset);
677
678   if (global)                   /* This means we can use a binary search.  */
679     {
680       do_linear_search = 0;
681
682       /* Binary search.  This search is guaranteed to end with center
683          pointing at the earliest partial symbol whose name might be
684          correct.  At that point *all* partial symbols with an
685          appropriate name will be checked against the correct
686          domain.  */
687
688       bottom = start;
689       top = start + length - 1;
690       real_top = top;
691       while (top > bottom)
692         {
693           center = bottom + (top - bottom) / 2;
694           if (!(center < top))
695             internal_error (__FILE__, __LINE__,
696                             _("failed internal consistency check"));
697           if (!do_linear_search
698               && SYMBOL_LANGUAGE (*center) == language_java)
699             {
700               do_linear_search = 1;
701             }
702           if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center),
703                                  search_name) >= 0)
704             {
705               top = center;
706             }
707           else
708             {
709               bottom = center + 1;
710             }
711         }
712       if (!(top == bottom))
713         internal_error (__FILE__, __LINE__,
714                         _("failed internal consistency check"));
715
716       /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
717          search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME.  */
718       while (top >= start && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
719         top--;
720
721       /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME.  */
722       top++;
723
724       while (top <= real_top && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
725         {
726           if (SYMBOL_DOMAIN (*top) == domain)
727             {
728               do_cleanups (cleanup);
729               return (*top);
730             }
731           top++;
732         }
733     }
734
735   /* Can't use a binary search or else we found during the binary search that
736      we should also do a linear search.  */
737
738   if (do_linear_search)
739     {
740       for (psym = start; psym < start + length; psym++)
741         {
742           if (SYMBOL_DOMAIN (*psym) == domain
743               && SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name))
744             {
745               do_cleanups (cleanup);
746               return (*psym);
747             }
748         }
749     }
750
751   do_cleanups (cleanup);
752   return (NULL);
753 }
754
755 /* Get the symbol table that corresponds to a partial_symtab.
756    This is fast after the first time you do it.  */
757
758 static struct symtab *
759 psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
760 {
761   /* If it is a shared psymtab, find an unshared psymtab that includes
762      it.  Any such psymtab will do.  */
763   while (pst->user != NULL)
764     pst = pst->user;
765
766   /* If it's been looked up before, return it.  */
767   if (pst->symtab)
768     return pst->symtab;
769
770   /* If it has not yet been read in, read it.  */
771   if (!pst->readin)
772     {
773       struct cleanup *back_to = increment_reading_symtab ();
774
775       (*pst->read_symtab) (pst, objfile);
776       do_cleanups (back_to);
777     }
778
779   return pst->symtab;
780 }
781
782 static void
783 relocate_psymtabs (struct objfile *objfile,
784                    const struct section_offsets *new_offsets,
785                    const struct section_offsets *delta)
786 {
787   struct partial_symbol **psym;
788   struct partial_symtab *p;
789
790   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
791     {
792       p->textlow += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
793       p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
794     }
795
796   for (psym = objfile->global_psymbols.list;
797        psym < objfile->global_psymbols.next;
798        psym++)
799     {
800       fixup_psymbol_section (*psym, objfile);
801       if (SYMBOL_SECTION (*psym) >= 0)
802         SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
803                                                   SYMBOL_SECTION (*psym));
804     }
805   for (psym = objfile->static_psymbols.list;
806        psym < objfile->static_psymbols.next;
807        psym++)
808     {
809       fixup_psymbol_section (*psym, objfile);
810       if (SYMBOL_SECTION (*psym) >= 0)
811         SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
812                                                   SYMBOL_SECTION (*psym));
813     }
814 }
815
816 static struct symtab *
817 find_last_source_symtab_from_partial (struct objfile *ofp)
818 {
819   struct partial_symtab *ps;
820   struct partial_symtab *cs_pst = 0;
821
822   ALL_OBJFILE_PSYMTABS_REQUIRED (ofp, ps)
823     {
824       const char *name = ps->filename;
825       int len = strlen (name);
826
827       if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
828                         || strcmp (name, "<<C++-namespaces>>") == 0)))
829         cs_pst = ps;
830     }
831
832   if (cs_pst)
833     {
834       if (cs_pst->readin)
835         {
836           internal_error (__FILE__, __LINE__,
837                           _("select_source_symtab: "
838                           "readin pst found and no symtabs."));
839         }
840       else
841         return psymtab_to_symtab (ofp, cs_pst);
842     }
843   return NULL;
844 }
845
846 static void
847 forget_cached_source_info_partial (struct objfile *objfile)
848 {
849   struct partial_symtab *pst;
850
851   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
852     {
853       if (pst->fullname != NULL)
854         {
855           xfree (pst->fullname);
856           pst->fullname = NULL;
857         }
858     }
859 }
860
861 static void
862 print_partial_symbols (struct gdbarch *gdbarch,
863                        struct partial_symbol **p, int count, char *what,
864                        struct ui_file *outfile)
865 {
866   fprintf_filtered (outfile, "  %s partial symbols:\n", what);
867   while (count-- > 0)
868     {
869       QUIT;
870       fprintf_filtered (outfile, "    `%s'", SYMBOL_LINKAGE_NAME (*p));
871       if (SYMBOL_DEMANGLED_NAME (*p) != NULL)
872         {
873           fprintf_filtered (outfile, "  `%s'", SYMBOL_DEMANGLED_NAME (*p));
874         }
875       fputs_filtered (", ", outfile);
876       switch (SYMBOL_DOMAIN (*p))
877         {
878         case UNDEF_DOMAIN:
879           fputs_filtered ("undefined domain, ", outfile);
880           break;
881         case VAR_DOMAIN:
882           /* This is the usual thing -- don't print it.  */
883           break;
884         case STRUCT_DOMAIN:
885           fputs_filtered ("struct domain, ", outfile);
886           break;
887         case LABEL_DOMAIN:
888           fputs_filtered ("label domain, ", outfile);
889           break;
890         default:
891           fputs_filtered ("<invalid domain>, ", outfile);
892           break;
893         }
894       switch (PSYMBOL_CLASS (*p))
895         {
896         case LOC_UNDEF:
897           fputs_filtered ("undefined", outfile);
898           break;
899         case LOC_CONST:
900           fputs_filtered ("constant int", outfile);
901           break;
902         case LOC_STATIC:
903           fputs_filtered ("static", outfile);
904           break;
905         case LOC_REGISTER:
906           fputs_filtered ("register", outfile);
907           break;
908         case LOC_ARG:
909           fputs_filtered ("pass by value", outfile);
910           break;
911         case LOC_REF_ARG:
912           fputs_filtered ("pass by reference", outfile);
913           break;
914         case LOC_REGPARM_ADDR:
915           fputs_filtered ("register address parameter", outfile);
916           break;
917         case LOC_LOCAL:
918           fputs_filtered ("stack parameter", outfile);
919           break;
920         case LOC_TYPEDEF:
921           fputs_filtered ("type", outfile);
922           break;
923         case LOC_LABEL:
924           fputs_filtered ("label", outfile);
925           break;
926         case LOC_BLOCK:
927           fputs_filtered ("function", outfile);
928           break;
929         case LOC_CONST_BYTES:
930           fputs_filtered ("constant bytes", outfile);
931           break;
932         case LOC_UNRESOLVED:
933           fputs_filtered ("unresolved", outfile);
934           break;
935         case LOC_OPTIMIZED_OUT:
936           fputs_filtered ("optimized out", outfile);
937           break;
938         case LOC_COMPUTED:
939           fputs_filtered ("computed at runtime", outfile);
940           break;
941         default:
942           fputs_filtered ("<invalid location>", outfile);
943           break;
944         }
945       fputs_filtered (", ", outfile);
946       fputs_filtered (paddress (gdbarch, SYMBOL_VALUE_ADDRESS (*p)), outfile);
947       fprintf_filtered (outfile, "\n");
948       p++;
949     }
950 }
951
952 static void
953 dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
954               struct ui_file *outfile)
955 {
956   struct gdbarch *gdbarch = get_objfile_arch (objfile);
957   int i;
958
959   if (psymtab->anonymous)
960     {
961       fprintf_filtered (outfile, "\nAnonymous partial symtab (%s) ",
962                         psymtab->filename);
963     }
964   else
965     {
966       fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
967                         psymtab->filename);
968     }
969   fprintf_filtered (outfile, "(object ");
970   gdb_print_host_address (psymtab, outfile);
971   fprintf_filtered (outfile, ")\n\n");
972   fprintf_unfiltered (outfile, "  Read from object file %s (",
973                       objfile_name (objfile));
974   gdb_print_host_address (objfile, outfile);
975   fprintf_unfiltered (outfile, ")\n");
976
977   if (psymtab->readin)
978     {
979       fprintf_filtered (outfile,
980                         "  Full symtab was read (at ");
981       gdb_print_host_address (psymtab->symtab, outfile);
982       fprintf_filtered (outfile, " by function at ");
983       gdb_print_host_address (psymtab->read_symtab, outfile);
984       fprintf_filtered (outfile, ")\n");
985     }
986
987   fprintf_filtered (outfile, "  Relocate symbols by ");
988   for (i = 0; i < objfile->num_sections; ++i)
989     {
990       if (i != 0)
991         fprintf_filtered (outfile, ", ");
992       wrap_here ("    ");
993       fputs_filtered (paddress (gdbarch,
994                                 ANOFFSET (psymtab->section_offsets, i)),
995                       outfile);
996     }
997   fprintf_filtered (outfile, "\n");
998
999   fprintf_filtered (outfile, "  Symbols cover text addresses ");
1000   fputs_filtered (paddress (gdbarch, psymtab->textlow), outfile);
1001   fprintf_filtered (outfile, "-");
1002   fputs_filtered (paddress (gdbarch, psymtab->texthigh), outfile);
1003   fprintf_filtered (outfile, "\n");
1004   fprintf_filtered (outfile, "  Address map supported - %s.\n",
1005                     psymtab->psymtabs_addrmap_supported ? "yes" : "no");
1006   fprintf_filtered (outfile, "  Depends on %d other partial symtabs.\n",
1007                     psymtab->number_of_dependencies);
1008   for (i = 0; i < psymtab->number_of_dependencies; i++)
1009     {
1010       fprintf_filtered (outfile, "    %d ", i);
1011       gdb_print_host_address (psymtab->dependencies[i], outfile);
1012       fprintf_filtered (outfile, " %s\n",
1013                         psymtab->dependencies[i]->filename);
1014     }
1015   if (psymtab->user != NULL)
1016     {
1017       fprintf_filtered (outfile, "  Shared partial symtab with user ");
1018       gdb_print_host_address (psymtab->user, outfile);
1019       fprintf_filtered (outfile, "\n");
1020     }
1021   if (psymtab->n_global_syms > 0)
1022     {
1023       print_partial_symbols (gdbarch,
1024                              objfile->global_psymbols.list
1025                              + psymtab->globals_offset,
1026                              psymtab->n_global_syms, "Global", outfile);
1027     }
1028   if (psymtab->n_static_syms > 0)
1029     {
1030       print_partial_symbols (gdbarch,
1031                              objfile->static_psymbols.list
1032                              + psymtab->statics_offset,
1033                              psymtab->n_static_syms, "Static", outfile);
1034     }
1035   fprintf_filtered (outfile, "\n");
1036 }
1037
1038 static void
1039 print_psymtab_stats_for_objfile (struct objfile *objfile)
1040 {
1041   int i;
1042   struct partial_symtab *ps;
1043
1044   i = 0;
1045   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
1046     {
1047       if (ps->readin == 0)
1048         i++;
1049     }
1050   printf_filtered (_("  Number of psym tables (not yet expanded): %d\n"), i);
1051 }
1052
1053 static void
1054 dump_psymtabs_for_objfile (struct objfile *objfile)
1055 {
1056   struct partial_symtab *psymtab;
1057
1058   if (objfile->psymtabs)
1059     {
1060       printf_filtered ("Psymtabs:\n");
1061       for (psymtab = objfile->psymtabs;
1062            psymtab != NULL;
1063            psymtab = psymtab->next)
1064         {
1065           printf_filtered ("%s at ",
1066                            psymtab->filename);
1067           gdb_print_host_address (psymtab, gdb_stdout);
1068           printf_filtered (", ");
1069           wrap_here ("  ");
1070         }
1071       printf_filtered ("\n\n");
1072     }
1073 }
1074
1075 /* Look through the partial symtabs for all symbols which begin
1076    by matching FUNC_NAME.  Make sure we read that symbol table in.  */
1077
1078 static void
1079 read_symtabs_for_function (struct objfile *objfile, const char *func_name)
1080 {
1081   struct partial_symtab *ps;
1082
1083   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
1084   {
1085     if (ps->readin)
1086       continue;
1087
1088     if ((lookup_partial_symbol (objfile, ps, func_name, 1, VAR_DOMAIN)
1089          != NULL)
1090         || (lookup_partial_symbol (objfile, ps, func_name, 0, VAR_DOMAIN)
1091             != NULL))
1092       psymtab_to_symtab (objfile, ps);
1093   }
1094 }
1095
1096 static void
1097 expand_partial_symbol_tables (struct objfile *objfile)
1098 {
1099   struct partial_symtab *psymtab;
1100
1101   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab)
1102     {
1103       psymtab_to_symtab (objfile, psymtab);
1104     }
1105 }
1106
1107 static void
1108 read_psymtabs_with_fullname (struct objfile *objfile, const char *fullname)
1109 {
1110   struct partial_symtab *p;
1111
1112   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
1113     {
1114       /* Anonymous psymtabs don't have a name of a source file.  */
1115       if (p->anonymous)
1116         continue;
1117
1118       /* psymtab_to_fullname tries to open the file which is slow.
1119          Don't call it if we know the basenames don't match.  */
1120       if ((basenames_may_differ
1121            || filename_cmp (lbasename (fullname), lbasename (p->filename)) == 0)
1122           && filename_cmp (fullname, psymtab_to_fullname (p)) == 0)
1123         psymtab_to_symtab (objfile, p);
1124     }
1125 }
1126
1127 static void
1128 map_symbol_filenames_psymtab (struct objfile *objfile,
1129                               symbol_filename_ftype *fun, void *data,
1130                               int need_fullname)
1131 {
1132   struct partial_symtab *ps;
1133
1134   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
1135     {
1136       const char *fullname;
1137
1138       if (ps->readin)
1139         continue;
1140
1141       /* We can skip shared psymtabs here, because any file name will be
1142          attached to the unshared psymtab.  */
1143       if (ps->user != NULL)
1144         continue;
1145
1146       /* Anonymous psymtabs don't have a file name.  */
1147       if (ps->anonymous)
1148         continue;
1149
1150       QUIT;
1151       if (need_fullname)
1152         fullname = psymtab_to_fullname (ps);
1153       else
1154         fullname = NULL;
1155       (*fun) (ps->filename, fullname, data);
1156     }
1157 }
1158
1159 /* Finds the fullname that a partial_symtab represents.
1160
1161    If this functions finds the fullname, it will save it in ps->fullname
1162    and it will also return the value.
1163
1164    If this function fails to find the file that this partial_symtab represents,
1165    NULL will be returned and ps->fullname will be set to NULL.  */
1166
1167 static const char *
1168 psymtab_to_fullname (struct partial_symtab *ps)
1169 {
1170   gdb_assert (!ps->anonymous);
1171
1172   /* Use cached copy if we have it.
1173      We rely on forget_cached_source_info being called appropriately
1174      to handle cases like the file being moved.  */
1175   if (ps->fullname == NULL)
1176     {
1177       int fd = find_and_open_source (ps->filename, ps->dirname, &ps->fullname);
1178
1179       if (fd >= 0)
1180         close (fd);
1181       else
1182         {
1183           char *fullname;
1184           struct cleanup *back_to;
1185
1186           /* rewrite_source_path would be applied by find_and_open_source, we
1187              should report the pathname where GDB tried to find the file.  */
1188
1189           if (ps->dirname == NULL || IS_ABSOLUTE_PATH (ps->filename))
1190             fullname = xstrdup (ps->filename);
1191           else
1192             fullname = concat (ps->dirname, SLASH_STRING, ps->filename, NULL);
1193
1194           back_to = make_cleanup (xfree, fullname);
1195           ps->fullname = rewrite_source_path (fullname);
1196           if (ps->fullname == NULL)
1197             ps->fullname = xstrdup (fullname);
1198           do_cleanups (back_to);
1199         }
1200     } 
1201
1202   return ps->fullname;
1203 }
1204
1205 /*  For all symbols, s, in BLOCK that are in NAMESPACE and match NAME
1206     according to the function MATCH, call CALLBACK(BLOCK, s, DATA).
1207     BLOCK is assumed to come from OBJFILE.  Returns 1 iff CALLBACK
1208     ever returns non-zero, and otherwise returns 0.  */
1209
1210 static int
1211 map_block (const char *name, domain_enum namespace, struct objfile *objfile,
1212            struct block *block,
1213            int (*callback) (struct block *, struct symbol *, void *),
1214            void *data, symbol_compare_ftype *match)
1215 {
1216   struct block_iterator iter;
1217   struct symbol *sym;
1218
1219   for (sym = block_iter_match_first (block, name, match, &iter);
1220        sym != NULL; sym = block_iter_match_next (name, match, &iter))
1221     {
1222       if (SYMBOL_DOMAIN (sym) == namespace)
1223         {
1224           if (callback (block, sym, data))
1225             return 1;
1226         }
1227     }
1228
1229   return 0;
1230 }
1231
1232 /*  Psymtab version of map_matching_symbols.  See its definition in
1233     the definition of quick_symbol_functions in symfile.h.  */
1234
1235 static void
1236 map_matching_symbols_psymtab (struct objfile *objfile,
1237                               const char *name, domain_enum namespace,
1238                               int global,
1239                               int (*callback) (struct block *,
1240                                                struct symbol *, void *),
1241                               void *data,
1242                               symbol_compare_ftype *match,
1243                               symbol_compare_ftype *ordered_compare)
1244 {
1245   const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
1246   struct partial_symtab *ps;
1247
1248   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
1249     {
1250       QUIT;
1251       if (ps->readin
1252           || match_partial_symbol (objfile, ps, global, name, namespace, match,
1253                                    ordered_compare))
1254         {
1255           struct symtab *s = psymtab_to_symtab (objfile, ps);
1256           struct block *block;
1257
1258           if (s == NULL || !s->primary)
1259             continue;
1260           block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind);
1261           if (map_block (name, namespace, objfile, block,
1262                          callback, data, match))
1263             return;
1264           if (callback (block, NULL, data))
1265             return;
1266         }
1267     }
1268 }           
1269
1270 /* A helper for expand_symtabs_matching_via_partial that handles
1271    searching included psymtabs.  This returns 1 if a symbol is found,
1272    and zero otherwise.  It also updates the 'searched_flag' on the
1273    various psymtabs that it searches.  */
1274
1275 static int
1276 recursively_search_psymtabs (struct partial_symtab *ps,
1277                              struct objfile *objfile,
1278                              enum search_domain kind,
1279                              expand_symtabs_symbol_matcher_ftype *sym_matcher,
1280                              void *data)
1281 {
1282   struct partial_symbol **psym;
1283   struct partial_symbol **bound, **gbound, **sbound;
1284   int keep_going = 1;
1285   int result = PST_SEARCHED_AND_NOT_FOUND;
1286   int i;
1287
1288   if (ps->searched_flag != PST_NOT_SEARCHED)
1289     return ps->searched_flag == PST_SEARCHED_AND_FOUND;
1290
1291   /* Recurse into shared psymtabs first, because they may have already
1292      been searched, and this could save some time.  */
1293   for (i = 0; i < ps->number_of_dependencies; ++i)
1294     {
1295       int r;
1296
1297       /* Skip non-shared dependencies, these are handled elsewhere.  */
1298       if (ps->dependencies[i]->user == NULL)
1299         continue;
1300
1301       r = recursively_search_psymtabs (ps->dependencies[i],
1302                                        objfile, kind, sym_matcher, data);
1303       if (r != 0)
1304         {
1305           ps->searched_flag = PST_SEARCHED_AND_FOUND;
1306           return 1;
1307         }
1308     }
1309
1310   gbound = (objfile->global_psymbols.list
1311             + ps->globals_offset + ps->n_global_syms);
1312   sbound = (objfile->static_psymbols.list
1313             + ps->statics_offset + ps->n_static_syms);
1314   bound = gbound;
1315
1316   /* Go through all of the symbols stored in a partial
1317      symtab in one loop.  */
1318   psym = objfile->global_psymbols.list + ps->globals_offset;
1319   while (keep_going)
1320     {
1321       if (psym >= bound)
1322         {
1323           if (bound == gbound && ps->n_static_syms != 0)
1324             {
1325               psym = objfile->static_psymbols.list + ps->statics_offset;
1326               bound = sbound;
1327             }
1328           else
1329             keep_going = 0;
1330           continue;
1331         }
1332       else
1333         {
1334           QUIT;
1335
1336           if ((kind == ALL_DOMAIN
1337                || (kind == VARIABLES_DOMAIN
1338                    && PSYMBOL_CLASS (*psym) != LOC_TYPEDEF
1339                    && PSYMBOL_CLASS (*psym) != LOC_BLOCK)
1340                || (kind == FUNCTIONS_DOMAIN
1341                    && PSYMBOL_CLASS (*psym) == LOC_BLOCK)
1342                || (kind == TYPES_DOMAIN
1343                    && PSYMBOL_CLASS (*psym) == LOC_TYPEDEF))
1344               && (*sym_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
1345             {
1346               /* Found a match, so notify our caller.  */
1347               result = PST_SEARCHED_AND_FOUND;
1348               keep_going = 0;
1349             }
1350         }
1351       psym++;
1352     }
1353
1354   ps->searched_flag = result;
1355   return result == PST_SEARCHED_AND_FOUND;
1356 }
1357
1358 static void
1359 expand_symtabs_matching_via_partial
1360   (struct objfile *objfile,
1361    expand_symtabs_file_matcher_ftype *file_matcher,
1362    expand_symtabs_symbol_matcher_ftype *symbol_matcher,
1363    enum search_domain kind,
1364    void *data)
1365 {
1366   struct partial_symtab *ps;
1367
1368   /* Clear the search flags.  */
1369   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
1370     {
1371       ps->searched_flag = PST_NOT_SEARCHED;
1372     }
1373
1374   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
1375     {
1376       if (ps->readin)
1377         continue;
1378
1379       /* We skip shared psymtabs because file-matching doesn't apply
1380          to them; but we search them later in the loop.  */
1381       if (ps->user != NULL)
1382         continue;
1383
1384       if (file_matcher)
1385         {
1386           int match;
1387
1388           if (ps->anonymous)
1389             continue;
1390
1391           match = (*file_matcher) (ps->filename, data, 0);
1392           if (!match)
1393             {
1394               /* Before we invoke realpath, which can get expensive when many
1395                  files are involved, do a quick comparison of the basenames.  */
1396               if (basenames_may_differ
1397                   || (*file_matcher) (lbasename (ps->filename), data, 1))
1398                 match = (*file_matcher) (psymtab_to_fullname (ps), data, 0);
1399             }
1400           if (!match)
1401             continue;
1402         }
1403
1404       if (recursively_search_psymtabs (ps, objfile, kind, symbol_matcher, data))
1405         psymtab_to_symtab (objfile, ps);
1406     }
1407 }
1408
1409 static int
1410 objfile_has_psyms (struct objfile *objfile)
1411 {
1412   return objfile->psymtabs != NULL;
1413 }
1414
1415 const struct quick_symbol_functions psym_functions =
1416 {
1417   objfile_has_psyms,
1418   find_last_source_symtab_from_partial,
1419   forget_cached_source_info_partial,
1420   partial_map_symtabs_matching_filename,
1421   lookup_symbol_aux_psymtabs,
1422   print_psymtab_stats_for_objfile,
1423   dump_psymtabs_for_objfile,
1424   relocate_psymtabs,
1425   read_symtabs_for_function,
1426   expand_partial_symbol_tables,
1427   read_psymtabs_with_fullname,
1428   map_matching_symbols_psymtab,
1429   expand_symtabs_matching_via_partial,
1430   find_pc_sect_symtab_from_partial,
1431   map_symbol_filenames_psymtab
1432 };
1433
1434 \f
1435
1436 /* This compares two partial symbols by names, using strcmp_iw_ordered
1437    for the comparison.  */
1438
1439 static int
1440 compare_psymbols (const void *s1p, const void *s2p)
1441 {
1442   struct partial_symbol *const *s1 = s1p;
1443   struct partial_symbol *const *s2 = s2p;
1444
1445   return strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*s1),
1446                             SYMBOL_SEARCH_NAME (*s2));
1447 }
1448
1449 void
1450 sort_pst_symbols (struct objfile *objfile, struct partial_symtab *pst)
1451 {
1452   /* Sort the global list; don't sort the static list.  */
1453
1454   qsort (objfile->global_psymbols.list + pst->globals_offset,
1455          pst->n_global_syms, sizeof (struct partial_symbol *),
1456          compare_psymbols);
1457 }
1458
1459 /* Allocate and partially fill a partial symtab.  It will be
1460    completely filled at the end of the symbol list.
1461
1462    FILENAME is the name of the symbol-file we are reading from.  */
1463
1464 struct partial_symtab *
1465 start_psymtab_common (struct objfile *objfile,
1466                       struct section_offsets *section_offsets,
1467                       const char *filename,
1468                       CORE_ADDR textlow, struct partial_symbol **global_syms,
1469                       struct partial_symbol **static_syms)
1470 {
1471   struct partial_symtab *psymtab;
1472
1473   psymtab = allocate_psymtab (filename, objfile);
1474   psymtab->section_offsets = section_offsets;
1475   psymtab->textlow = textlow;
1476   psymtab->texthigh = psymtab->textlow;         /* default */
1477   psymtab->globals_offset = global_syms - objfile->global_psymbols.list;
1478   psymtab->statics_offset = static_syms - objfile->static_psymbols.list;
1479   return (psymtab);
1480 }
1481
1482 /* Calculate a hash code for the given partial symbol.  The hash is
1483    calculated using the symbol's value, language, domain, class
1484    and name.  These are the values which are set by
1485    add_psymbol_to_bcache.  */
1486
1487 static unsigned long
1488 psymbol_hash (const void *addr, int length)
1489 {
1490   unsigned long h = 0;
1491   struct partial_symbol *psymbol = (struct partial_symbol *) addr;
1492   unsigned int lang = psymbol->ginfo.language;
1493   unsigned int domain = PSYMBOL_DOMAIN (psymbol);
1494   unsigned int class = PSYMBOL_CLASS (psymbol);
1495
1496   h = hash_continue (&psymbol->ginfo.value, sizeof (psymbol->ginfo.value), h);
1497   h = hash_continue (&lang, sizeof (unsigned int), h);
1498   h = hash_continue (&domain, sizeof (unsigned int), h);
1499   h = hash_continue (&class, sizeof (unsigned int), h);
1500   h = hash_continue (psymbol->ginfo.name, strlen (psymbol->ginfo.name), h);
1501
1502   return h;
1503 }
1504
1505 /* Returns true if the symbol at addr1 equals the symbol at addr2.
1506    For the comparison this function uses a symbols value,
1507    language, domain, class and name.  */
1508
1509 static int
1510 psymbol_compare (const void *addr1, const void *addr2, int length)
1511 {
1512   struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
1513   struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
1514
1515   return (memcmp (&sym1->ginfo.value, &sym1->ginfo.value,
1516                   sizeof (sym1->ginfo.value)) == 0
1517           && sym1->ginfo.language == sym2->ginfo.language
1518           && PSYMBOL_DOMAIN (sym1) == PSYMBOL_DOMAIN (sym2)
1519           && PSYMBOL_CLASS (sym1) == PSYMBOL_CLASS (sym2)
1520           && sym1->ginfo.name == sym2->ginfo.name);
1521 }
1522
1523 /* Initialize a partial symbol bcache.  */
1524
1525 struct psymbol_bcache *
1526 psymbol_bcache_init (void)
1527 {
1528   struct psymbol_bcache *bcache = XCNEW (struct psymbol_bcache);
1529   bcache->bcache = bcache_xmalloc (psymbol_hash, psymbol_compare);
1530   return bcache;
1531 }
1532
1533 /* Free a partial symbol bcache.  */
1534 void
1535 psymbol_bcache_free (struct psymbol_bcache *bcache)
1536 {
1537   if (bcache == NULL)
1538     return;
1539
1540   bcache_xfree (bcache->bcache);
1541   xfree (bcache);
1542 }
1543
1544 /* Return the internal bcache of the psymbol_bcache BCACHE.  */
1545
1546 struct bcache *
1547 psymbol_bcache_get_bcache (struct psymbol_bcache *bcache)
1548 {
1549   return bcache->bcache;
1550 }
1551
1552 /* Find a copy of the SYM in BCACHE.  If BCACHE has never seen this
1553    symbol before, add a copy to BCACHE.  In either case, return a pointer
1554    to BCACHE's copy of the symbol.  If optional ADDED is not NULL, return
1555    1 in case of new entry or 0 if returning an old entry.  */
1556
1557 static const struct partial_symbol *
1558 psymbol_bcache_full (struct partial_symbol *sym,
1559                      struct psymbol_bcache *bcache,
1560                      int *added)
1561 {
1562   return bcache_full (sym,
1563                       sizeof (struct partial_symbol),
1564                       bcache->bcache,
1565                       added);
1566 }
1567
1568 /* Helper function, initialises partial symbol structure and stashes 
1569    it into objfile's bcache.  Note that our caching mechanism will
1570    use all fields of struct partial_symbol to determine hash value of the
1571    structure.  In other words, having two symbols with the same name but
1572    different domain (or address) is possible and correct.  */
1573
1574 static const struct partial_symbol *
1575 add_psymbol_to_bcache (const char *name, int namelength, int copy_name,
1576                        domain_enum domain,
1577                        enum address_class class,
1578                        long val,        /* Value as a long */
1579                        CORE_ADDR coreaddr,      /* Value as a CORE_ADDR */
1580                        enum language language, struct objfile *objfile,
1581                        int *added)
1582 {
1583   struct partial_symbol psymbol;
1584
1585   /* We must ensure that the entire struct has been zeroed before
1586      assigning to it, because an assignment may not touch some of the
1587      holes.  */
1588   memset (&psymbol, 0, sizeof (psymbol));
1589
1590   /* val and coreaddr are mutually exclusive, one of them *will* be zero.  */
1591   if (val != 0)
1592     {
1593       SYMBOL_VALUE (&psymbol) = val;
1594     }
1595   else
1596     {
1597       SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
1598     }
1599   SYMBOL_SECTION (&psymbol) = -1;
1600   SYMBOL_SET_LANGUAGE (&psymbol, language, &objfile->objfile_obstack);
1601   PSYMBOL_DOMAIN (&psymbol) = domain;
1602   PSYMBOL_CLASS (&psymbol) = class;
1603
1604   SYMBOL_SET_NAMES (&psymbol, name, namelength, copy_name, objfile);
1605
1606   /* Stash the partial symbol away in the cache.  */
1607   return psymbol_bcache_full (&psymbol,
1608                               objfile->psymbol_cache,
1609                               added);
1610 }
1611
1612 /* Increase the space allocated for LISTP, which is probably
1613    global_psymbols or static_psymbols.  This space will eventually
1614    be freed in free_objfile().  */
1615
1616 static void
1617 extend_psymbol_list (struct psymbol_allocation_list *listp,
1618                      struct objfile *objfile)
1619 {
1620   int new_size;
1621
1622   if (listp->size == 0)
1623     {
1624       new_size = 255;
1625       listp->list = (struct partial_symbol **)
1626         xmalloc (new_size * sizeof (struct partial_symbol *));
1627     }
1628   else
1629     {
1630       new_size = listp->size * 2;
1631       listp->list = (struct partial_symbol **)
1632         xrealloc ((char *) listp->list,
1633                   new_size * sizeof (struct partial_symbol *));
1634     }
1635   /* Next assumes we only went one over.  Should be good if
1636      program works correctly.  */
1637   listp->next = listp->list + listp->size;
1638   listp->size = new_size;
1639 }
1640
1641 /* Helper function, adds partial symbol to the given partial symbol
1642    list.  */
1643
1644 static void
1645 append_psymbol_to_list (struct psymbol_allocation_list *list,
1646                         const struct partial_symbol *psym,
1647                         struct objfile *objfile)
1648 {
1649   if (list->next >= list->list + list->size)
1650     extend_psymbol_list (list, objfile);
1651   *list->next++ = (struct partial_symbol *) psym;
1652   OBJSTAT (objfile, n_psyms++);
1653 }
1654
1655 /* Add a symbol with a long value to a psymtab.
1656    Since one arg is a struct, we pass in a ptr and deref it (sigh).
1657    Return the partial symbol that has been added.  */
1658
1659 void
1660 add_psymbol_to_list (const char *name, int namelength, int copy_name,
1661                      domain_enum domain,
1662                      enum address_class class,
1663                      struct psymbol_allocation_list *list, 
1664                      long val,  /* Value as a long */
1665                      CORE_ADDR coreaddr,        /* Value as a CORE_ADDR */
1666                      enum language language, struct objfile *objfile)
1667 {
1668   const struct partial_symbol *psym;
1669
1670   int added;
1671
1672   /* Stash the partial symbol away in the cache.  */
1673   psym = add_psymbol_to_bcache (name, namelength, copy_name, domain, class,
1674                                 val, coreaddr, language, objfile, &added);
1675
1676   /* Do not duplicate global partial symbols.  */
1677   if (list == &objfile->global_psymbols
1678       && !added)
1679     return;
1680
1681   /* Save pointer to partial symbol in psymtab, growing symtab if needed.  */
1682   append_psymbol_to_list (list, psym, objfile);
1683 }
1684
1685 /* Initialize storage for partial symbols.  */
1686
1687 void
1688 init_psymbol_list (struct objfile *objfile, int total_symbols)
1689 {
1690   /* Free any previously allocated psymbol lists.  */
1691
1692   if (objfile->global_psymbols.list)
1693     {
1694       xfree (objfile->global_psymbols.list);
1695     }
1696   if (objfile->static_psymbols.list)
1697     {
1698       xfree (objfile->static_psymbols.list);
1699     }
1700
1701   /* Current best guess is that approximately a twentieth
1702      of the total symbols (in a debugging file) are global or static
1703      oriented symbols, then multiply that by slop factor of two.  */
1704
1705   objfile->global_psymbols.size = total_symbols / 10;
1706   objfile->static_psymbols.size = total_symbols / 10;
1707
1708   if (objfile->global_psymbols.size > 0)
1709     {
1710       objfile->global_psymbols.next =
1711         objfile->global_psymbols.list = (struct partial_symbol **)
1712         xmalloc ((objfile->global_psymbols.size
1713                   * sizeof (struct partial_symbol *)));
1714     }
1715   if (objfile->static_psymbols.size > 0)
1716     {
1717       objfile->static_psymbols.next =
1718         objfile->static_psymbols.list = (struct partial_symbol **)
1719         xmalloc ((objfile->static_psymbols.size
1720                   * sizeof (struct partial_symbol *)));
1721     }
1722 }
1723
1724 struct partial_symtab *
1725 allocate_psymtab (const char *filename, struct objfile *objfile)
1726 {
1727   struct partial_symtab *psymtab;
1728
1729   if (objfile->free_psymtabs)
1730     {
1731       psymtab = objfile->free_psymtabs;
1732       objfile->free_psymtabs = psymtab->next;
1733     }
1734   else
1735     psymtab = (struct partial_symtab *)
1736       obstack_alloc (&objfile->objfile_obstack,
1737                      sizeof (struct partial_symtab));
1738
1739   memset (psymtab, 0, sizeof (struct partial_symtab));
1740   psymtab->filename = bcache (filename, strlen (filename) + 1,
1741                               objfile->per_bfd->filename_cache);
1742   psymtab->symtab = NULL;
1743
1744   /* Prepend it to the psymtab list for the objfile it belongs to.
1745      Psymtabs are searched in most recent inserted -> least recent
1746      inserted order.  */
1747
1748   psymtab->next = objfile->psymtabs;
1749   objfile->psymtabs = psymtab;
1750
1751   if (symtab_create_debug)
1752     {
1753       /* Be a bit clever with debugging messages, and don't print objfile
1754          every time, only when it changes.  */
1755       static char *last_objfile_name = NULL;
1756
1757       if (last_objfile_name == NULL
1758           || strcmp (last_objfile_name, objfile_name (objfile)) != 0)
1759         {
1760           xfree (last_objfile_name);
1761           last_objfile_name = xstrdup (objfile_name (objfile));
1762           fprintf_unfiltered (gdb_stdlog,
1763                               "Creating one or more psymtabs for objfile %s ...\n",
1764                               last_objfile_name);
1765         }
1766       fprintf_unfiltered (gdb_stdlog,
1767                           "Created psymtab %s for module %s.\n",
1768                           host_address_to_string (psymtab), filename);
1769     }
1770
1771   return (psymtab);
1772 }
1773
1774 void
1775 discard_psymtab (struct objfile *objfile, struct partial_symtab *pst)
1776 {
1777   struct partial_symtab **prev_pst;
1778
1779   /* From dbxread.c:
1780      Empty psymtabs happen as a result of header files which don't
1781      have any symbols in them.  There can be a lot of them.  But this
1782      check is wrong, in that a psymtab with N_SLINE entries but
1783      nothing else is not empty, but we don't realize that.  Fixing
1784      that without slowing things down might be tricky.  */
1785
1786   /* First, snip it out of the psymtab chain.  */
1787
1788   prev_pst = &(objfile->psymtabs);
1789   while ((*prev_pst) != pst)
1790     prev_pst = &((*prev_pst)->next);
1791   (*prev_pst) = pst->next;
1792
1793   /* Next, put it on a free list for recycling.  */
1794
1795   pst->next = objfile->free_psymtabs;
1796   objfile->free_psymtabs = pst;
1797 }
1798
1799 /* An object of this type is passed to discard_psymtabs_upto.  */
1800
1801 struct psymtab_state
1802 {
1803   /* The objfile where psymtabs are discarded.  */
1804
1805   struct objfile *objfile;
1806
1807   /* The first psymtab to save.  */
1808
1809   struct partial_symtab *save;
1810 };
1811
1812 /* A cleanup function used by make_cleanup_discard_psymtabs.  */
1813
1814 static void
1815 discard_psymtabs_upto (void *arg)
1816 {
1817   struct psymtab_state *state = arg;
1818
1819   while (state->objfile->psymtabs != state->save)
1820     discard_psymtab (state->objfile, state->objfile->psymtabs);
1821 }
1822
1823 /* Return a new cleanup that discards all psymtabs created in OBJFILE
1824    after this function is called.  */
1825
1826 struct cleanup *
1827 make_cleanup_discard_psymtabs (struct objfile *objfile)
1828 {
1829   struct psymtab_state *state = XNEW (struct psymtab_state);
1830
1831   state->objfile = objfile;
1832   state->save = objfile->psymtabs;
1833
1834   return make_cleanup_dtor (discard_psymtabs_upto, state, xfree);
1835 }
1836
1837 \f
1838
1839 static void
1840 maintenance_print_psymbols (char *args, int from_tty)
1841 {
1842   char **argv;
1843   struct ui_file *outfile;
1844   struct cleanup *cleanups;
1845   char *symname = NULL;
1846   char *filename = DEV_TTY;
1847   struct objfile *objfile;
1848   struct partial_symtab *ps;
1849
1850   dont_repeat ();
1851
1852   if (args == NULL)
1853     {
1854       error (_("\
1855 print-psymbols takes an output file name and optional symbol file name"));
1856     }
1857   argv = gdb_buildargv (args);
1858   cleanups = make_cleanup_freeargv (argv);
1859
1860   if (argv[0] != NULL)
1861     {
1862       filename = argv[0];
1863       /* If a second arg is supplied, it is a source file name to match on.  */
1864       if (argv[1] != NULL)
1865         {
1866           symname = argv[1];
1867         }
1868     }
1869
1870   filename = tilde_expand (filename);
1871   make_cleanup (xfree, filename);
1872
1873   outfile = gdb_fopen (filename, FOPEN_WT);
1874   if (outfile == 0)
1875     perror_with_name (filename);
1876   make_cleanup_ui_file_delete (outfile);
1877
1878   ALL_PSYMTABS (objfile, ps)
1879     {
1880       QUIT;
1881       if (symname == NULL || filename_cmp (symname, ps->filename) == 0)
1882         dump_psymtab (objfile, ps, outfile);
1883     }
1884   do_cleanups (cleanups);
1885 }
1886
1887 /* List all the partial symbol tables whose names match REGEXP (optional).  */
1888 static void
1889 maintenance_info_psymtabs (char *regexp, int from_tty)
1890 {
1891   struct program_space *pspace;
1892   struct objfile *objfile;
1893
1894   if (regexp)
1895     re_comp (regexp);
1896
1897   ALL_PSPACES (pspace)
1898     ALL_PSPACE_OBJFILES (pspace, objfile)
1899     {
1900       struct gdbarch *gdbarch = get_objfile_arch (objfile);
1901       struct partial_symtab *psymtab;
1902
1903       /* We don't want to print anything for this objfile until we
1904          actually find a symtab whose name matches.  */
1905       int printed_objfile_start = 0;
1906
1907       ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab)
1908         {
1909           QUIT;
1910
1911           if (! regexp
1912               || re_exec (psymtab->filename))
1913             {
1914               if (! printed_objfile_start)
1915                 {
1916                   printf_filtered ("{ objfile %s ", objfile_name (objfile));
1917                   wrap_here ("  ");
1918                   printf_filtered ("((struct objfile *) %s)\n", 
1919                                    host_address_to_string (objfile));
1920                   printed_objfile_start = 1;
1921                 }
1922
1923               printf_filtered ("  { psymtab %s ", psymtab->filename);
1924               wrap_here ("    ");
1925               printf_filtered ("((struct partial_symtab *) %s)\n", 
1926                                host_address_to_string (psymtab));
1927
1928               printf_filtered ("    readin %s\n",
1929                                psymtab->readin ? "yes" : "no");
1930               printf_filtered ("    fullname %s\n",
1931                                psymtab->fullname
1932                                ? psymtab->fullname : "(null)");
1933               printf_filtered ("    text addresses ");
1934               fputs_filtered (paddress (gdbarch, psymtab->textlow),
1935                               gdb_stdout);
1936               printf_filtered (" -- ");
1937               fputs_filtered (paddress (gdbarch, psymtab->texthigh),
1938                               gdb_stdout);
1939               printf_filtered ("\n");
1940               printf_filtered ("    psymtabs_addrmap_supported %s\n",
1941                                (psymtab->psymtabs_addrmap_supported
1942                                 ? "yes" : "no"));
1943               printf_filtered ("    globals ");
1944               if (psymtab->n_global_syms)
1945                 {
1946                   printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n",
1947                                    host_address_to_string (objfile->global_psymbols.list
1948                                     + psymtab->globals_offset),
1949                                    psymtab->n_global_syms);
1950                 }
1951               else
1952                 printf_filtered ("(none)\n");
1953               printf_filtered ("    statics ");
1954               if (psymtab->n_static_syms)
1955                 {
1956                   printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n",
1957                                    host_address_to_string (objfile->static_psymbols.list
1958                                     + psymtab->statics_offset),
1959                                    psymtab->n_static_syms);
1960                 }
1961               else
1962                 printf_filtered ("(none)\n");
1963               printf_filtered ("    dependencies ");
1964               if (psymtab->number_of_dependencies)
1965                 {
1966                   int i;
1967
1968                   printf_filtered ("{\n");
1969                   for (i = 0; i < psymtab->number_of_dependencies; i++)
1970                     {
1971                       struct partial_symtab *dep = psymtab->dependencies[i];
1972
1973                       /* Note the string concatenation there --- no comma.  */
1974                       printf_filtered ("      psymtab %s "
1975                                        "((struct partial_symtab *) %s)\n",
1976                                        dep->filename, 
1977                                        host_address_to_string (dep));
1978                     }
1979                   printf_filtered ("    }\n");
1980                 }
1981               else
1982                 printf_filtered ("(none)\n");
1983               printf_filtered ("  }\n");
1984             }
1985         }
1986
1987       if (printed_objfile_start)
1988         printf_filtered ("}\n");
1989     }
1990 }
1991
1992 /* Check consistency of currently expanded psymtabs vs symtabs.  */
1993
1994 static void
1995 maintenance_check_psymtabs (char *ignore, int from_tty)
1996 {
1997   struct symbol *sym;
1998   struct partial_symbol **psym;
1999   struct symtab *s = NULL;
2000   struct partial_symtab *ps;
2001   struct blockvector *bv;
2002   struct objfile *objfile;
2003   struct block *b;
2004   int length;
2005
2006   ALL_PSYMTABS (objfile, ps)
2007   {
2008     struct gdbarch *gdbarch = get_objfile_arch (objfile);
2009
2010     /* We don't call psymtab_to_symtab here because that may cause symtab
2011        expansion.  When debugging a problem it helps if checkers leave
2012        things unchanged.  */
2013     s = ps->symtab;
2014
2015     /* First do some checks that don't require the associated symtab.  */
2016     if (ps->texthigh < ps->textlow)
2017       {
2018         printf_filtered ("Psymtab ");
2019         puts_filtered (ps->filename);
2020         printf_filtered (" covers bad range ");
2021         fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout);
2022         printf_filtered (" - ");
2023         fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout);
2024         printf_filtered ("\n");
2025         continue;
2026       }
2027
2028     /* Now do checks requiring the associated symtab.  */
2029     if (s == NULL)
2030       continue;
2031     bv = BLOCKVECTOR (s);
2032     b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
2033     psym = objfile->static_psymbols.list + ps->statics_offset;
2034     length = ps->n_static_syms;
2035     while (length--)
2036       {
2037         sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
2038                                    SYMBOL_DOMAIN (*psym));
2039         if (!sym)
2040           {
2041             printf_filtered ("Static symbol `");
2042             puts_filtered (SYMBOL_LINKAGE_NAME (*psym));
2043             printf_filtered ("' only found in ");
2044             puts_filtered (ps->filename);
2045             printf_filtered (" psymtab\n");
2046           }
2047         psym++;
2048       }
2049     b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
2050     psym = objfile->global_psymbols.list + ps->globals_offset;
2051     length = ps->n_global_syms;
2052     while (length--)
2053       {
2054         sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
2055                                    SYMBOL_DOMAIN (*psym));
2056         if (!sym)
2057           {
2058             printf_filtered ("Global symbol `");
2059             puts_filtered (SYMBOL_LINKAGE_NAME (*psym));
2060             printf_filtered ("' only found in ");
2061             puts_filtered (ps->filename);
2062             printf_filtered (" psymtab\n");
2063           }
2064         psym++;
2065       }
2066     if (ps->texthigh != 0
2067         && (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b)))
2068       {
2069         printf_filtered ("Psymtab ");
2070         puts_filtered (ps->filename);
2071         printf_filtered (" covers ");
2072         fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout);
2073         printf_filtered (" - ");
2074         fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout);
2075         printf_filtered (" but symtab covers only ");
2076         fputs_filtered (paddress (gdbarch, BLOCK_START (b)), gdb_stdout);
2077         printf_filtered (" - ");
2078         fputs_filtered (paddress (gdbarch, BLOCK_END (b)), gdb_stdout);
2079         printf_filtered ("\n");
2080       }
2081   }
2082 }
2083
2084 \f
2085
2086 extern initialize_file_ftype _initialize_psymtab;
2087
2088 void
2089 _initialize_psymtab (void)
2090 {
2091   add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\
2092 Print dump of current partial symbol definitions.\n\
2093 Entries in the partial symbol table are dumped to file OUTFILE.\n\
2094 If a SOURCE file is specified, dump only that file's partial symbols."),
2095            &maintenanceprintlist);
2096
2097   add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\
2098 List the partial symbol tables for all object files.\n\
2099 This does not include information about individual partial symbols,\n\
2100 just the symbol table structures themselves."),
2101            &maintenanceinfolist);
2102
2103   add_cmd ("check-psymtabs", class_maintenance, maintenance_check_psymtabs,
2104            _("\
2105 Check consistency of currently expanded psymtabs versus symtabs."),
2106            &maintenancelist);
2107 }