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