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