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