1 /* Partial symbol tables.
2 
3    Copyright (C) 2009-2024 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 "event-top.h"
21 #include "symtab.h"
22 #include "objfiles.h"
23 #include "psymtab.h"
24 #include "block.h"
25 #include "filenames.h"
26 #include "source.h"
27 #include "gdbtypes.h"
28 #include "ui-out.h"
29 #include "command.h"
30 #include "readline/tilde.h"
31 #include "gdbsupport/gdb_regex.h"
32 #include "dictionary.h"
33 #include "language.h"
34 #include "cp-support.h"
35 #include "cli/cli-cmds.h"
36 #include <algorithm>
37 #include <set>
38 #include "gdbsupport/buildargv.h"
39 
40 static struct partial_symbol *lookup_partial_symbol (struct objfile *,
41                                                                  struct partial_symtab *,
42                                                                  const lookup_name_info &,
43                                                                  int,
44                                                                  domain_search_flags);
45 
46 static const char *psymtab_to_fullname (struct partial_symtab *ps);
47 
48 static struct partial_symbol *find_pc_sect_psymbol (struct objfile *,
49                                                                 struct partial_symtab *,
50                                                                 CORE_ADDR,
51                                                                 struct obj_section *);
52 
53 static struct compunit_symtab *psymtab_to_symtab (struct objfile *objfile,
54                                                               struct partial_symtab *pst);
55 
~psymtab_storage()56 psymtab_storage::~psymtab_storage ()
57 {
58   partial_symtab *iter = psymtabs;
59   while (iter != nullptr)
60     {
61       partial_symtab *next = iter->next;
62       delete iter;
63       iter = next;
64     }
65 }
66 
67 /* See psymtab.h.  */
68 
69 void
install_psymtab(partial_symtab * pst)70 psymtab_storage::install_psymtab (partial_symtab *pst)
71 {
72   pst->next = psymtabs;
73   psymtabs = pst;
74 }
75 
76 
77 
78 /* See psymtab.h.  */
79 
80 psymtab_storage::partial_symtab_range
partial_symbols(struct objfile * objfile)81 psymbol_functions::partial_symbols (struct objfile *objfile)
82 {
83   return m_partial_symtabs->range ();
84 }
85 
86 /* Find which partial symtab contains PC and SECTION starting at psymtab PST.
87    We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
88 
89 static struct partial_symtab *
find_pc_sect_psymtab_closer(struct objfile * objfile,CORE_ADDR pc,struct obj_section * section,struct partial_symtab * pst,struct bound_minimal_symbol msymbol)90 find_pc_sect_psymtab_closer (struct objfile *objfile,
91                                    CORE_ADDR pc, struct obj_section *section,
92                                    struct partial_symtab *pst,
93                                    struct bound_minimal_symbol msymbol)
94 {
95   struct partial_symtab *tpst;
96   struct partial_symtab *best_pst = pst;
97   CORE_ADDR best_addr = pst->text_low (objfile);
98 
99   /* An objfile that has its functions reordered might have
100      many partial symbol tables containing the PC, but
101      we want the partial symbol table that contains the
102      function containing the PC.  */
103   if (section == nullptr)
104     return pst;
105 
106   if (msymbol.minsym == NULL)
107     return pst;
108 
109   /* The code range of partial symtabs sometimes overlap, so, in
110      the loop below, we need to check all partial symtabs and
111      find the one that fits better for the given PC address.  We
112      select the partial symtab that contains a symbol whose
113      address is closest to the PC address.  By closest we mean
114      that find_pc_sect_symbol returns the symbol with address
115      that is closest and still less than the given PC.  */
116   for (tpst = pst; tpst != NULL; tpst = tpst->next)
117     {
118       if (pc >= tpst->text_low (objfile) && pc < tpst->text_high (objfile))
119           {
120             struct partial_symbol *p;
121             CORE_ADDR this_addr;
122 
123             /* NOTE: This assumes that every psymbol has a
124                corresponding msymbol, which is not necessarily
125                true; the debug info might be much richer than the
126                object's symbol table.  */
127             p = find_pc_sect_psymbol (objfile, tpst, pc, section);
128             if (p != NULL
129                 && (p->address (objfile) == msymbol.value_address ()))
130               return tpst;
131 
132             /* Also accept the textlow value of a psymtab as a
133                "symbol", to provide some support for partial
134                symbol tables with line information but no debug
135                symbols (e.g. those produced by an assembler).  */
136             if (p != NULL)
137               this_addr = p->address (objfile);
138             else
139               this_addr = tpst->text_low (objfile);
140 
141             /* Check whether it is closer than our current
142                BEST_ADDR.  Since this symbol address is
143                necessarily lower or equal to PC, the symbol closer
144                to PC is the symbol which address is the highest.
145                This way we return the psymtab which contains such
146                best match symbol.  This can help in cases where the
147                symbol information/debuginfo is not complete, like
148                for instance on IRIX6 with gcc, where no debug info
149                is emitted for statics.  (See also the nodebug.exp
150                testcase.)  */
151             if (this_addr > best_addr)
152               {
153                 best_addr = this_addr;
154                 best_pst = tpst;
155               }
156           }
157     }
158   return best_pst;
159 }
160 
161 /* See psymtab.h.  */
162 
163 struct partial_symtab *
find_pc_sect_psymtab(struct objfile * objfile,CORE_ADDR pc,struct obj_section * section,struct bound_minimal_symbol msymbol)164 psymbol_functions::find_pc_sect_psymtab (struct objfile *objfile,
165                                                    CORE_ADDR pc,
166                                                    struct obj_section *section,
167                                                    struct bound_minimal_symbol msymbol)
168 {
169   for (partial_symtab *pst : partial_symbols (objfile))
170     if (pc >= pst->text_low (objfile) && pc < pst->text_high (objfile))
171       {
172           struct partial_symtab *best_pst;
173 
174           best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst,
175                                                             msymbol);
176           if (best_pst != NULL)
177             return best_pst;
178       }
179 
180   return NULL;
181 }
182 
183 /* Psymtab version of find_pc_sect_compunit_symtab.  See its definition in
184    the definition of quick_symbol_functions in symfile.h.  */
185 
186 struct compunit_symtab *
find_pc_sect_compunit_symtab(struct objfile * objfile,struct bound_minimal_symbol msymbol,CORE_ADDR pc,struct obj_section * section,int warn_if_readin)187 psymbol_functions::find_pc_sect_compunit_symtab
188      (struct objfile *objfile,
189       struct bound_minimal_symbol msymbol,
190       CORE_ADDR pc,
191       struct obj_section *section,
192       int warn_if_readin)
193 {
194   struct partial_symtab *ps = find_pc_sect_psymtab (objfile,
195                                                                 pc, section,
196                                                                 msymbol);
197   if (ps != NULL)
198     {
199       if (warn_if_readin && ps->readin_p (objfile))
200           /* Might want to error() here (in case symtab is corrupt and
201              will cause a core dump), but maybe we can successfully
202              continue, so let's not.  */
203           warning (_("\
204 (Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
205                      paddress (objfile->arch (), pc));
206       psymtab_to_symtab (objfile, ps);
207       return ps->get_compunit_symtab (objfile);
208     }
209   return NULL;
210 }
211 
212 /* Find which partial symbol within a psymtab matches PC and SECTION.
213    Return NULL if none.  */
214 
215 static struct partial_symbol *
find_pc_sect_psymbol(struct objfile * objfile,struct partial_symtab * psymtab,CORE_ADDR pc,struct obj_section * section)216 find_pc_sect_psymbol (struct objfile *objfile,
217                           struct partial_symtab *psymtab, CORE_ADDR pc,
218                           struct obj_section *section)
219 {
220   struct partial_symbol *best = NULL;
221   CORE_ADDR best_pc;
222   const CORE_ADDR textlow = psymtab->text_low (objfile);
223 
224   gdb_assert (psymtab != NULL);
225 
226   /* Cope with programs that start at address 0.  */
227   best_pc = (textlow != 0) ? textlow - 1 : 0;
228 
229   /* Search the global symbols as well as the static symbols, so that
230      find_pc_partial_function doesn't use a minimal symbol and thus
231      cache a bad endaddr.  */
232   for (partial_symbol *p : psymtab->global_psymbols)
233     {
234       if (p->domain == VAR_DOMAIN
235             && p->aclass == LOC_BLOCK
236             && pc >= p->address (objfile)
237             && (p->address (objfile) > best_pc
238                 || (psymtab->text_low (objfile) == 0
239                       && best_pc == 0 && p->address (objfile) == 0)))
240           {
241             if (section != NULL)  /* Match on a specific section.  */
242               {
243                 if (!matching_obj_sections (p->obj_section (objfile),
244                                                     section))
245                     continue;
246               }
247             best_pc = p->address (objfile);
248             best = p;
249           }
250     }
251 
252   for (partial_symbol *p : psymtab->static_psymbols)
253     {
254       if (p->domain == VAR_DOMAIN
255             && p->aclass == LOC_BLOCK
256             && pc >= p->address (objfile)
257             && (p->address (objfile) > best_pc
258                 || (psymtab->text_low (objfile) == 0
259                       && best_pc == 0 && p->address (objfile) == 0)))
260           {
261             if (section != NULL)  /* Match on a specific section.  */
262               {
263                 if (!matching_obj_sections (p->obj_section (objfile),
264                                                     section))
265                     continue;
266               }
267             best_pc = p->address (objfile);
268             best = p;
269           }
270     }
271 
272   return best;
273 }
274 
275 /* Psymtab version of lookup_global_symbol_language.  See its definition in
276    the definition of quick_symbol_functions in symfile.h.  */
277 
278 enum language
lookup_global_symbol_language(struct objfile * objfile,const char * name,domain_search_flags domain,bool * symbol_found_p)279 psymbol_functions::lookup_global_symbol_language (struct objfile *objfile,
280                                                               const char *name,
281                                                               domain_search_flags domain,
282                                                               bool *symbol_found_p)
283 {
284   *symbol_found_p = false;
285   if (objfile->sf == NULL)
286     return language_unknown;
287 
288   lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
289 
290   for (partial_symtab *ps : partial_symbols (objfile))
291     {
292       struct partial_symbol *psym;
293       if (ps->readin_p (objfile))
294           continue;
295 
296       psym = lookup_partial_symbol (objfile, ps, lookup_name, 1, domain);
297       if (psym)
298           {
299             *symbol_found_p = true;
300             return psym->ginfo.language ();
301           }
302     }
303 
304   return language_unknown;
305 }
306 
307 /* Returns true if PSYM matches LOOKUP_NAME.  */
308 
309 static bool
psymbol_name_matches(partial_symbol * psym,const lookup_name_info & lookup_name)310 psymbol_name_matches (partial_symbol *psym,
311                           const lookup_name_info &lookup_name)
312 {
313   const language_defn *lang = language_def (psym->ginfo.language ());
314   symbol_name_matcher_ftype *name_match
315     = lang->get_symbol_name_matcher (lookup_name);
316   return name_match (psym->ginfo.search_name (), lookup_name, NULL);
317 }
318 
319 /* Look, in partial_symtab PST, for symbol whose natural name is
320    LOOKUP_NAME.  Check the global symbols if GLOBAL, the static
321    symbols if not.  */
322 
323 static struct partial_symbol *
lookup_partial_symbol(struct objfile * objfile,struct partial_symtab * pst,const lookup_name_info & lookup_name,int global,domain_search_flags domain)324 lookup_partial_symbol (struct objfile *objfile,
325                            struct partial_symtab *pst,
326                            const lookup_name_info &lookup_name,
327                            int global, domain_search_flags domain)
328 {
329   struct partial_symbol **start, **psym;
330   struct partial_symbol **top, **real_top, **bottom, **center;
331   int length = (global
332                     ? pst->global_psymbols.size ()
333                     : pst->static_psymbols.size ());
334   int do_linear_search = 1;
335 
336   if (length == 0)
337     return NULL;
338 
339   start = (global ?
340              &pst->global_psymbols[0] :
341              &pst->static_psymbols[0]);
342 
343   if (global)                           /* This means we can use a binary search.  */
344     {
345       do_linear_search = 0;
346 
347       /* Binary search.  This search is guaranteed to end with center
348            pointing at the earliest partial symbol whose name might be
349            correct.  At that point *all* partial symbols with an
350            appropriate name will be checked against the correct
351            domain.  */
352 
353       bottom = start;
354       top = start + length - 1;
355       real_top = top;
356       while (top > bottom)
357           {
358             center = bottom + (top - bottom) / 2;
359 
360             gdb_assert (center < top);
361 
362             if (strcmp_iw_ordered ((*center)->ginfo.search_name (),
363                                          lookup_name.c_str ()) >= 0)
364               {
365                 top = center;
366               }
367             else
368               {
369                 bottom = center + 1;
370               }
371           }
372 
373       gdb_assert (top == bottom);
374 
375       /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
376            search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME.  */
377       while (top >= start && symbol_matches_search_name (&(*top)->ginfo,
378                                                                        lookup_name))
379           top--;
380 
381       /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME.  */
382       top++;
383 
384       while (top <= real_top && symbol_matches_search_name (&(*top)->ginfo,
385                                                                           lookup_name))
386           {
387             if (search_flags_matches (domain, (*top)->domain))
388               return *top;
389             top++;
390           }
391     }
392 
393   /* Can't use a binary search or else we found during the binary search that
394      we should also do a linear search.  */
395 
396   if (do_linear_search)
397     {
398       for (psym = start; psym < start + length; psym++)
399           {
400             if (search_flags_matches (domain, (*psym)->domain)
401                 && symbol_matches_search_name (&(*psym)->ginfo, lookup_name))
402               return *psym;
403           }
404     }
405 
406   return NULL;
407 }
408 
409 /* Get the symbol table that corresponds to a partial_symtab.
410    This is fast after the first time you do it.
411    The result will be NULL if the primary symtab has no symbols,
412    which can happen.  Otherwise the result is the primary symtab
413    that contains PST.  */
414 
415 static struct compunit_symtab *
psymtab_to_symtab(struct objfile * objfile,struct partial_symtab * pst)416 psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
417 {
418   /* If it is a shared psymtab, find an unshared psymtab that includes
419      it.  Any such psymtab will do.  */
420   while (pst->user != NULL)
421     pst = pst->user;
422 
423   /* If it's been looked up before, return it.  */
424   if (pst->get_compunit_symtab (objfile))
425     return pst->get_compunit_symtab (objfile);
426 
427   /* If it has not yet been read in, read it.  */
428   if (!pst->readin_p (objfile))
429     {
430       scoped_restore decrementer = increment_reading_symtab ();
431 
432       if (info_verbose)
433           {
434             gdb_printf (_("Reading in symbols for %s...\n"),
435                           pst->filename);
436             gdb_flush (gdb_stdout);
437           }
438 
439       pst->read_symtab (objfile);
440     }
441 
442   return pst->get_compunit_symtab (objfile);
443 }
444 
445 /* Psymtab version of find_last_source_symtab.  See its definition in
446    the definition of quick_symbol_functions in symfile.h.  */
447 
448 struct symtab *
find_last_source_symtab(struct objfile * ofp)449 psymbol_functions::find_last_source_symtab (struct objfile *ofp)
450 {
451   struct partial_symtab *cs_pst = NULL;
452 
453   for (partial_symtab *ps : partial_symbols (ofp))
454     {
455       const char *name = ps->filename;
456       int len = strlen (name);
457 
458       if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
459                               || strcmp (name, "<<C++-namespaces>>") == 0)))
460           cs_pst = ps;
461     }
462 
463   if (cs_pst)
464     {
465       if (cs_pst->readin_p (ofp))
466           {
467             internal_error (_("select_source_symtab: "
468                                 "readin pst found and no symtabs."));
469           }
470       else
471           {
472             struct compunit_symtab *cust = psymtab_to_symtab (ofp, cs_pst);
473 
474             if (cust == NULL)
475               return NULL;
476             return cust->primary_filetab ();
477           }
478     }
479   return NULL;
480 }
481 
482 /* Psymtab version of forget_cached_source_info.  See its definition in
483    the definition of quick_symbol_functions in symfile.h.  */
484 
485 void
forget_cached_source_info(struct objfile * objfile)486 psymbol_functions::forget_cached_source_info (struct objfile *objfile)
487 {
488   for (partial_symtab *pst : partial_symbols (objfile))
489     {
490       if (pst->fullname != NULL)
491           {
492             xfree (pst->fullname);
493             pst->fullname = NULL;
494           }
495     }
496 }
497 
498 static void
print_partial_symbols(struct gdbarch * gdbarch,struct objfile * objfile,const std::vector<partial_symbol * > & symbols,const char * what,struct ui_file * outfile)499 print_partial_symbols (struct gdbarch *gdbarch, struct objfile *objfile,
500                            const std::vector<partial_symbol *> &symbols,
501                            const char *what, struct ui_file *outfile)
502 {
503   gdb_printf (outfile, "  %s partial symbols:\n", what);
504   for (partial_symbol *p : symbols)
505     {
506       QUIT;
507       gdb_printf (outfile, "    `%s'", p->ginfo.linkage_name ());
508       if (p->ginfo.demangled_name () != NULL)
509           {
510             gdb_printf (outfile, "  `%s'",
511                           p->ginfo.demangled_name ());
512           }
513       gdb_puts (", ", outfile);
514       switch (p->domain)
515           {
516           case UNDEF_DOMAIN:
517             gdb_puts ("undefined domain, ", outfile);
518             break;
519           case VAR_DOMAIN:
520             /* This is the usual thing -- don't print it.  */
521             break;
522           case STRUCT_DOMAIN:
523             gdb_puts ("struct domain, ", outfile);
524             break;
525           case MODULE_DOMAIN:
526             gdb_puts ("module domain, ", outfile);
527             break;
528           case LABEL_DOMAIN:
529             gdb_puts ("label domain, ", outfile);
530             break;
531           case COMMON_BLOCK_DOMAIN:
532             gdb_puts ("common block domain, ", outfile);
533             break;
534           default:
535             gdb_puts ("<invalid domain>, ", outfile);
536             break;
537           }
538       switch (p->aclass)
539           {
540           case LOC_UNDEF:
541             gdb_puts ("undefined", outfile);
542             break;
543           case LOC_CONST:
544             gdb_puts ("constant int", outfile);
545             break;
546           case LOC_STATIC:
547             gdb_puts ("static", outfile);
548             break;
549           case LOC_REGISTER:
550             gdb_puts ("register", outfile);
551             break;
552           case LOC_ARG:
553             gdb_puts ("pass by value", outfile);
554             break;
555           case LOC_REF_ARG:
556             gdb_puts ("pass by reference", outfile);
557             break;
558           case LOC_REGPARM_ADDR:
559             gdb_puts ("register address parameter", outfile);
560             break;
561           case LOC_LOCAL:
562             gdb_puts ("stack parameter", outfile);
563             break;
564           case LOC_TYPEDEF:
565             gdb_puts ("type", outfile);
566             break;
567           case LOC_LABEL:
568             gdb_puts ("label", outfile);
569             break;
570           case LOC_BLOCK:
571             gdb_puts ("function", outfile);
572             break;
573           case LOC_CONST_BYTES:
574             gdb_puts ("constant bytes", outfile);
575             break;
576           case LOC_UNRESOLVED:
577             gdb_puts ("unresolved", outfile);
578             break;
579           case LOC_OPTIMIZED_OUT:
580             gdb_puts ("optimized out", outfile);
581             break;
582           case LOC_COMPUTED:
583             gdb_puts ("computed at runtime", outfile);
584             break;
585           default:
586             gdb_puts ("<invalid location>", outfile);
587             break;
588           }
589       gdb_puts (", ", outfile);
590       gdb_puts (paddress (gdbarch, CORE_ADDR (p->unrelocated_address ())),
591                     outfile);
592       gdb_printf (outfile, "\n");
593     }
594 }
595 
596 static void
dump_psymtab(struct objfile * objfile,struct partial_symtab * psymtab,struct ui_file * outfile)597 dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
598                 struct ui_file *outfile)
599 {
600   struct gdbarch *gdbarch = objfile->arch ();
601   int i;
602 
603   if (psymtab->anonymous)
604     {
605       gdb_printf (outfile, "\nAnonymous partial symtab (%s) ",
606                       psymtab->filename);
607     }
608   else
609     {
610       gdb_printf (outfile, "\nPartial symtab for source file %s ",
611                       psymtab->filename);
612     }
613   gdb_printf (outfile, "(object %s)\n\n",
614                 host_address_to_string (psymtab));
615   gdb_printf (outfile, "  Read from object file %s (%s)\n",
616                 objfile_name (objfile),
617                 host_address_to_string (objfile));
618 
619   if (psymtab->readin_p (objfile))
620     gdb_printf
621       (outfile,
622        "  Full symtab was read (at %s)\n",
623        host_address_to_string (psymtab->get_compunit_symtab (objfile)));
624 
625   gdb_printf (outfile, "  Symbols cover text addresses ");
626   gdb_puts (paddress (gdbarch, psymtab->text_low (objfile)), outfile);
627   gdb_printf (outfile, "-");
628   gdb_puts (paddress (gdbarch, psymtab->text_high (objfile)), outfile);
629   gdb_printf (outfile, "\n");
630   gdb_printf (outfile, "  Depends on %d other partial symtabs.\n",
631                 psymtab->number_of_dependencies);
632   for (i = 0; i < psymtab->number_of_dependencies; i++)
633     gdb_printf (outfile, "    %d %s\n", i,
634                     host_address_to_string (psymtab->dependencies[i]));
635   if (psymtab->user != NULL)
636     gdb_printf (outfile, "  Shared partial symtab with user %s\n",
637                     host_address_to_string (psymtab->user));
638   if (!psymtab->global_psymbols.empty ())
639     {
640       print_partial_symbols
641           (gdbarch, objfile, psymtab->global_psymbols,
642            "Global", outfile);
643     }
644   if (!psymtab->static_psymbols.empty ())
645     {
646       print_partial_symbols
647           (gdbarch, objfile, psymtab->static_psymbols,
648            "Static", outfile);
649     }
650   gdb_printf (outfile, "\n");
651 }
652 
653 /* Count the number of partial symbols in OBJFILE.  */
654 
655 int
count_psyms()656 psymbol_functions::count_psyms ()
657 {
658   int count = 0;
659   for (partial_symtab *pst : m_partial_symtabs->range ())
660     {
661       count += pst->global_psymbols.size ();
662       count += pst->static_psymbols.size ();
663     }
664   return count;
665 }
666 
667 /* Psymtab version of print_stats.  See its definition in
668    the definition of quick_symbol_functions in symfile.h.  */
669 
670 void
print_stats(struct objfile * objfile,bool print_bcache)671 psymbol_functions::print_stats (struct objfile *objfile, bool print_bcache)
672 {
673   int i;
674 
675   if (!print_bcache)
676     {
677       int n_psyms = count_psyms ();
678       if (n_psyms > 0)
679           gdb_printf (_("  Number of \"partial\" symbols read: %d\n"),
680                         n_psyms);
681 
682       i = 0;
683       for (partial_symtab *ps : partial_symbols (objfile))
684           {
685             if (!ps->readin_p (objfile))
686               i++;
687           }
688       gdb_printf (_("  Number of psym tables (not yet expanded): %d\n"),
689                       i);
690       gdb_printf (_("  Total memory used for psymbol cache: %d\n"),
691                       m_partial_symtabs->psymbol_cache.memory_used ());
692     }
693   else
694     {
695       gdb_printf (_("Psymbol byte cache statistics:\n"));
696       m_partial_symtabs->psymbol_cache.print_statistics
697           ("partial symbol cache");
698     }
699 }
700 
701 /* Psymtab version of dump.  See its definition in
702    the definition of quick_symbol_functions in symfile.h.  */
703 
704 void
dump(struct objfile * objfile)705 psymbol_functions::dump (struct objfile *objfile)
706 {
707   struct partial_symtab *psymtab;
708 
709   if (m_partial_symtabs->psymtabs)
710     {
711       gdb_printf ("Psymtabs:\n");
712       for (psymtab = m_partial_symtabs->psymtabs;
713              psymtab != NULL;
714              psymtab = psymtab->next)
715           gdb_printf ("%s at %s\n",
716                         psymtab->filename,
717                         host_address_to_string (psymtab));
718       gdb_printf ("\n\n");
719     }
720 }
721 
722 /* Psymtab version of expand_all_symtabs.  See its definition in
723    the definition of quick_symbol_functions in symfile.h.  */
724 
725 void
expand_all_symtabs(struct objfile * objfile)726 psymbol_functions::expand_all_symtabs (struct objfile *objfile)
727 {
728   for (partial_symtab *psymtab : partial_symbols (objfile))
729     psymtab_to_symtab (objfile, psymtab);
730 }
731 
732 /* Psymtab version of map_symbol_filenames.  See its definition in
733    the definition of quick_symbol_functions in symfile.h.  */
734 
735 void
map_symbol_filenames(struct objfile * objfile,gdb::function_view<symbol_filename_ftype> fun,bool need_fullname)736 psymbol_functions::map_symbol_filenames
737      (struct objfile *objfile,
738       gdb::function_view<symbol_filename_ftype> fun,
739       bool need_fullname)
740 {
741   for (partial_symtab *ps : partial_symbols (objfile))
742     {
743       const char *fullname;
744 
745       if (ps->readin_p (objfile))
746           continue;
747 
748       /* We can skip shared psymtabs here, because any file name will be
749            attached to the unshared psymtab.  */
750       if (ps->user != NULL)
751           continue;
752 
753       /* Anonymous psymtabs don't have a file name.  */
754       if (ps->anonymous)
755           continue;
756 
757       QUIT;
758       if (need_fullname)
759           fullname = psymtab_to_fullname (ps);
760       else
761           fullname = NULL;
762       fun (ps->filename, fullname);
763     }
764 }
765 
766 /* Finds the fullname that a partial_symtab represents.
767 
768    If this functions finds the fullname, it will save it in ps->fullname
769    and it will also return the value.
770 
771    If this function fails to find the file that this partial_symtab represents,
772    NULL will be returned and ps->fullname will be set to NULL.  */
773 
774 static const char *
psymtab_to_fullname(struct partial_symtab * ps)775 psymtab_to_fullname (struct partial_symtab *ps)
776 {
777   gdb_assert (!ps->anonymous);
778 
779   /* Use cached copy if we have it.
780      We rely on forget_cached_source_info being called appropriately
781      to handle cases like the file being moved.  */
782   if (ps->fullname == NULL)
783     {
784       gdb::unique_xmalloc_ptr<char> fullname
785           = find_source_or_rewrite (ps->filename, ps->dirname);
786       ps->fullname = fullname.release ();
787     }
788 
789   return ps->fullname;
790 }
791 
792 /* A helper for psym_expand_symtabs_matching that handles searching
793    included psymtabs.  This returns true if a symbol is found, and
794    false otherwise.  It also updates the 'searched_flag' on the
795    various psymtabs that it searches.  */
796 
797 static bool
recursively_search_psymtabs(struct partial_symtab * ps,struct objfile * objfile,block_search_flags search_flags,domain_search_flags domain,const lookup_name_info & lookup_name,gdb::function_view<expand_symtabs_symbol_matcher_ftype> sym_matcher)798 recursively_search_psymtabs
799   (struct partial_symtab *ps,
800    struct objfile *objfile,
801    block_search_flags search_flags,
802    domain_search_flags domain,
803    const lookup_name_info &lookup_name,
804    gdb::function_view<expand_symtabs_symbol_matcher_ftype> sym_matcher)
805 {
806   int keep_going = 1;
807   enum psymtab_search_status result = PST_SEARCHED_AND_NOT_FOUND;
808   int i;
809 
810   if (ps->searched_flag != PST_NOT_SEARCHED)
811     return ps->searched_flag == PST_SEARCHED_AND_FOUND;
812 
813   /* Recurse into shared psymtabs first, because they may have already
814      been searched, and this could save some time.  */
815   for (i = 0; i < ps->number_of_dependencies; ++i)
816     {
817       int r;
818 
819       /* Skip non-shared dependencies, these are handled elsewhere.  */
820       if (ps->dependencies[i]->user == NULL)
821           continue;
822 
823       r = recursively_search_psymtabs (ps->dependencies[i],
824                                                objfile, search_flags, domain,
825                                                lookup_name, sym_matcher);
826       if (r != 0)
827           {
828             ps->searched_flag = PST_SEARCHED_AND_FOUND;
829             return true;
830           }
831     }
832 
833   partial_symbol **gbound = (ps->global_psymbols.data ()
834                                    + ps->global_psymbols.size ());
835   partial_symbol **sbound = (ps->static_psymbols.data ()
836                                    + ps->static_psymbols.size ());
837   partial_symbol **bound = gbound;
838 
839   /* Go through all of the symbols stored in a partial
840      symtab in one loop.  */
841   partial_symbol **psym = ps->global_psymbols.data ();
842 
843   if ((search_flags & SEARCH_GLOBAL_BLOCK) == 0)
844     {
845       if (ps->static_psymbols.empty ())
846           keep_going = 0;
847       else
848           {
849             psym = ps->static_psymbols.data ();
850             bound = sbound;
851           }
852     }
853 
854   while (keep_going)
855     {
856       if (psym >= bound)
857           {
858             if (bound == gbound && !ps->static_psymbols.empty ()
859                 && (search_flags & SEARCH_STATIC_BLOCK) != 0)
860               {
861                 psym = ps->static_psymbols.data ();
862                 bound = sbound;
863               }
864             else
865               keep_going = 0;
866             continue;
867           }
868       else
869           {
870             QUIT;
871 
872             if (search_flags_matches (domain, (*psym)->domain)
873                 && psymbol_name_matches (*psym, lookup_name)
874                 && (sym_matcher == NULL
875                       || sym_matcher ((*psym)->ginfo.search_name ())))
876               {
877                 /* Found a match, so notify our caller.  */
878                 result = PST_SEARCHED_AND_FOUND;
879                 keep_going = 0;
880               }
881           }
882       psym++;
883     }
884 
885   ps->searched_flag = result;
886   return result == PST_SEARCHED_AND_FOUND;
887 }
888 
889 /* Psymtab version of expand_symtabs_matching.  See its definition in
890    the definition of quick_symbol_functions in symfile.h.  */
891 
892 bool
expand_symtabs_matching(struct objfile * objfile,gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,const lookup_name_info * lookup_name,gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,block_search_flags search_flags,domain_search_flags domain)893 psymbol_functions::expand_symtabs_matching
894   (struct objfile *objfile,
895    gdb::function_view<expand_symtabs_file_matcher_ftype> file_matcher,
896    const lookup_name_info *lookup_name,
897    gdb::function_view<expand_symtabs_symbol_matcher_ftype> symbol_matcher,
898    gdb::function_view<expand_symtabs_exp_notify_ftype> expansion_notify,
899    block_search_flags search_flags,
900    domain_search_flags domain)
901 {
902   /* Clear the search flags.  */
903   for (partial_symtab *ps : partial_symbols (objfile))
904     ps->searched_flag = PST_NOT_SEARCHED;
905 
906   std::optional<lookup_name_info> psym_lookup_name;
907   if (lookup_name != nullptr)
908     psym_lookup_name = lookup_name->make_ignore_params ();
909 
910   /* This invariant is documented in quick-functions.h.  */
911   gdb_assert (lookup_name != nullptr || symbol_matcher == nullptr);
912 
913   for (partial_symtab *ps : m_partial_symtabs->range ())
914     {
915       QUIT;
916 
917       if (ps->readin_p (objfile))
918           continue;
919 
920       if (file_matcher)
921           {
922             bool match;
923 
924             if (ps->anonymous)
925               continue;
926 
927             match = file_matcher (ps->filename, false);
928             if (!match)
929               {
930                 /* Before we invoke realpath, which can get expensive when many
931                      files are involved, do a quick comparison of the basenames.  */
932                 if (basenames_may_differ
933                       || file_matcher (lbasename (ps->filename), true))
934                     match = file_matcher (psymtab_to_fullname (ps), false);
935               }
936             if (!match)
937               continue;
938           }
939 
940       if (lookup_name == nullptr
941             || recursively_search_psymtabs (ps, objfile, search_flags,
942                                                     domain, *psym_lookup_name,
943                                                     symbol_matcher))
944           {
945             compunit_symtab *cust = psymtab_to_symtab (objfile, ps);
946 
947             if (cust != nullptr && expansion_notify != nullptr)
948               if (!expansion_notify (cust))
949                 return false;
950           }
951     }
952 
953   return true;
954 }
955 
956 /* Psymtab version of has_symbols.  See its definition in
957    the definition of quick_symbol_functions in symfile.h.  */
958 
959 bool
has_symbols(struct objfile * objfile)960 psymbol_functions::has_symbols (struct objfile *objfile)
961 {
962   return m_partial_symtabs->psymtabs != NULL;
963 }
964 
965 /* See quick_symbol_functions::has_unexpanded_symtabs in quick-symbol.h.  */
966 
967 bool
has_unexpanded_symtabs(struct objfile * objfile)968 psymbol_functions::has_unexpanded_symtabs (struct objfile *objfile)
969 {
970   for (partial_symtab *psymtab : partial_symbols (objfile))
971     {
972       /* Is this already expanded?  */
973       if (psymtab->readin_p (objfile))
974           continue;
975 
976       /* It has not yet been expanded.  */
977       return true;
978     }
979 
980   return false;
981 }
982 
983 
984 
985 /* Partially fill a partial symtab.  It will be completely filled at
986    the end of the symbol list.  */
987 
partial_symtab(const char * filename,psymtab_storage * partial_symtabs,objfile_per_bfd_storage * objfile_per_bfd,unrelocated_addr textlow)988 partial_symtab::partial_symtab (const char *filename,
989                                         psymtab_storage *partial_symtabs,
990                                         objfile_per_bfd_storage *objfile_per_bfd,
991                                         unrelocated_addr textlow)
992   : partial_symtab (filename, partial_symtabs, objfile_per_bfd)
993 {
994   set_text_low (textlow);
995   set_text_high (unrelocated_text_low ()); /* default */
996 }
997 
998 /* Perform "finishing up" operations of a partial symtab.  */
999 
1000 void
end()1001 partial_symtab::end ()
1002 {
1003   global_psymbols.shrink_to_fit ();
1004   static_psymbols.shrink_to_fit ();
1005 
1006   /* Sort the global list; don't sort the static list.  */
1007   std::sort (global_psymbols.begin (),
1008                global_psymbols.end (),
1009                [] (partial_symbol *s1, partial_symbol *s2)
1010     {
1011       return strcmp_iw_ordered (s1->ginfo.search_name (),
1012                                         s2->ginfo.search_name ()) < 0;
1013     });
1014 }
1015 
1016 /* See psymtab.h.  */
1017 
1018 unsigned long
hash(const void * addr,int length)1019 psymbol_bcache::hash (const void *addr, int length)
1020 {
1021   unsigned long h = 0;
1022   struct partial_symbol *psymbol = (struct partial_symbol *) addr;
1023   unsigned int lang = psymbol->ginfo.language ();
1024   unsigned int domain = psymbol->domain;
1025   unsigned int theclass = psymbol->aclass;
1026 
1027   h = fast_hash (&psymbol->ginfo.m_value, sizeof (psymbol->ginfo.m_value), h);
1028   h = fast_hash (&lang, sizeof (unsigned int), h);
1029   h = fast_hash (&domain, sizeof (unsigned int), h);
1030   h = fast_hash (&theclass, sizeof (unsigned int), h);
1031   /* Note that psymbol names are interned via compute_and_set_names, so
1032      there's no need to hash the contents of the name here.  */
1033   h = fast_hash (&psymbol->ginfo.m_name, sizeof (psymbol->ginfo.m_name), h);
1034 
1035   return h;
1036 }
1037 
1038 /* See psymtab.h.  */
1039 
1040 int
compare(const void * addr1,const void * addr2,int length)1041 psymbol_bcache::compare (const void *addr1, const void *addr2, int length)
1042 {
1043   struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
1044   struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
1045 
1046   return (memcmp (&sym1->ginfo.m_value, &sym2->ginfo.m_value,
1047                       sizeof (sym1->ginfo.m_value)) == 0
1048             && sym1->ginfo.language () == sym2->ginfo.language ()
1049             && sym1->domain == sym2->domain
1050             && sym1->aclass == sym2->aclass
1051             /* Note that psymbol names are interned via
1052                compute_and_set_names, so there's no need to compare the
1053                contents of the name here.  */
1054             && sym1->ginfo.linkage_name () == sym2->ginfo.linkage_name ());
1055 }
1056 
1057 /* See psymtab.h.  */
1058 
1059 void
add_psymbol(const partial_symbol & psymbol,psymbol_placement where,psymtab_storage * partial_symtabs,struct objfile * objfile)1060 partial_symtab::add_psymbol (const partial_symbol &psymbol,
1061                                    psymbol_placement where,
1062                                    psymtab_storage *partial_symtabs,
1063                                    struct objfile *objfile)
1064 {
1065   bool added;
1066 
1067   /* Stash the partial symbol away in the cache.  */
1068   partial_symbol *psym
1069     = ((struct partial_symbol *)
1070        partial_symtabs->psymbol_cache.insert
1071        (&psymbol, sizeof (struct partial_symbol), &added));
1072 
1073   /* Do not duplicate global partial symbols.  */
1074   if (where == psymbol_placement::GLOBAL && !added)
1075     return;
1076 
1077   /* Save pointer to partial symbol in psymtab, growing symtab if needed.  */
1078   std::vector<partial_symbol *> &list
1079     = (where == psymbol_placement::STATIC
1080        ? static_psymbols
1081        : global_psymbols);
1082   list.push_back (psym);
1083 }
1084 
1085 /* See psymtab.h.  */
1086 
1087 void
add_psymbol(std::string_view name,bool copy_name,domain_enum domain,enum address_class theclass,short section,psymbol_placement where,unrelocated_addr coreaddr,enum language language,psymtab_storage * partial_symtabs,struct objfile * objfile)1088 partial_symtab::add_psymbol (std::string_view name, bool copy_name,
1089                                    domain_enum domain,
1090                                    enum address_class theclass,
1091                                    short section,
1092                                    psymbol_placement where,
1093                                    unrelocated_addr coreaddr,
1094                                    enum language language,
1095                                    psymtab_storage *partial_symtabs,
1096                                    struct objfile *objfile)
1097 {
1098   struct partial_symbol psymbol;
1099   memset (&psymbol, 0, sizeof (psymbol));
1100 
1101   psymbol.set_unrelocated_address (coreaddr);
1102   psymbol.ginfo.set_section_index (section);
1103   psymbol.domain = domain;
1104   psymbol.aclass = theclass;
1105   psymbol.ginfo.set_language (language, partial_symtabs->obstack ());
1106   psymbol.ginfo.compute_and_set_names (name, copy_name, objfile->per_bfd);
1107 
1108   add_psymbol (psymbol, where, partial_symtabs, objfile);
1109 }
1110 
1111 /* See psymtab.h.  */
1112 
partial_symtab(const char * filename_,psymtab_storage * partial_symtabs,objfile_per_bfd_storage * objfile_per_bfd)1113 partial_symtab::partial_symtab (const char *filename_,
1114                                         psymtab_storage *partial_symtabs,
1115                                         objfile_per_bfd_storage *objfile_per_bfd)
1116   : searched_flag (PST_NOT_SEARCHED),
1117     text_low_valid (0),
1118     text_high_valid (0)
1119 {
1120   partial_symtabs->install_psymtab (this);
1121 
1122   filename = objfile_per_bfd->intern (filename_);
1123 
1124   if (symtab_create_debug >= 1)
1125     {
1126       /* Be a bit clever with debugging messages, and don't print objfile
1127            every time, only when it changes.  */
1128       static std::string last_bfd_name;
1129       const char *this_bfd_name
1130           = bfd_get_filename (objfile_per_bfd->get_bfd ());
1131 
1132       if (last_bfd_name.empty () || last_bfd_name != this_bfd_name)
1133           {
1134             last_bfd_name = this_bfd_name;
1135 
1136             symtab_create_debug_printf ("creating one or more psymtabs for %s",
1137                                               this_bfd_name);
1138           }
1139 
1140       symtab_create_debug_printf ("created psymtab %s for module %s",
1141                                           host_address_to_string (this), filename);
1142     }
1143 }
1144 
1145 /* See psymtab.h.  */
1146 
1147 void
expand_dependencies(struct objfile * objfile)1148 partial_symtab::expand_dependencies (struct objfile *objfile)
1149 {
1150   for (int i = 0; i < number_of_dependencies; ++i)
1151     {
1152       if (!dependencies[i]->readin_p (objfile)
1153             && dependencies[i]->user == NULL)
1154           {
1155             /* Inform about additional files to be read in.  */
1156             if (info_verbose)
1157               {
1158                 gdb_puts (" ");
1159                 gdb_stdout->wrap_here (0);
1160                 gdb_puts ("and ");
1161                 gdb_stdout->wrap_here (0);
1162                 gdb_printf ("%s...", dependencies[i]->filename);
1163                 gdb_flush (gdb_stdout);
1164               }
1165             dependencies[i]->expand_psymtab (objfile);
1166           }
1167     }
1168 }
1169 
1170 
1171 void
discard_psymtab(struct partial_symtab * pst)1172 psymtab_storage::discard_psymtab (struct partial_symtab *pst)
1173 {
1174   struct partial_symtab **prev_pst;
1175 
1176   /* From dbxread.c:
1177      Empty psymtabs happen as a result of header files which don't
1178      have any symbols in them.  There can be a lot of them.  But this
1179      check is wrong, in that a psymtab with N_SLINE entries but
1180      nothing else is not empty, but we don't realize that.  Fixing
1181      that without slowing things down might be tricky.  */
1182 
1183   /* First, snip it out of the psymtab chain.  */
1184 
1185   prev_pst = &psymtabs;
1186   while ((*prev_pst) != pst)
1187     prev_pst = &((*prev_pst)->next);
1188   (*prev_pst) = pst->next;
1189   delete pst;
1190 }
1191 
1192 
1193 
1194 static void
maintenance_print_psymbols(const char * args,int from_tty)1195 maintenance_print_psymbols (const char *args, int from_tty)
1196 {
1197   struct ui_file *outfile = gdb_stdout;
1198   char *address_arg = NULL, *source_arg = NULL, *objfile_arg = NULL;
1199   int i, outfile_idx, found;
1200   CORE_ADDR pc = 0;
1201   struct obj_section *section = NULL;
1202 
1203   dont_repeat ();
1204 
1205   gdb_argv argv (args);
1206 
1207   for (i = 0; argv != NULL && argv[i] != NULL; ++i)
1208     {
1209       if (strcmp (argv[i], "-pc") == 0)
1210           {
1211             if (argv[i + 1] == NULL)
1212               error (_("Missing pc value"));
1213             address_arg = argv[++i];
1214           }
1215       else if (strcmp (argv[i], "-source") == 0)
1216           {
1217             if (argv[i + 1] == NULL)
1218               error (_("Missing source file"));
1219             source_arg = argv[++i];
1220           }
1221       else if (strcmp (argv[i], "-objfile") == 0)
1222           {
1223             if (argv[i + 1] == NULL)
1224               error (_("Missing objfile name"));
1225             objfile_arg = argv[++i];
1226           }
1227       else if (strcmp (argv[i], "--") == 0)
1228           {
1229             /* End of options.  */
1230             ++i;
1231             break;
1232           }
1233       else if (argv[i][0] == '-')
1234           {
1235             /* Future proofing: Don't allow OUTFILE to begin with "-".  */
1236             error (_("Unknown option: %s"), argv[i]);
1237           }
1238       else
1239           break;
1240     }
1241   outfile_idx = i;
1242 
1243   if (address_arg != NULL && source_arg != NULL)
1244     error (_("Must specify at most one of -pc and -source"));
1245 
1246   stdio_file arg_outfile;
1247 
1248   if (argv != NULL && argv[outfile_idx] != NULL)
1249     {
1250       if (argv[outfile_idx + 1] != NULL)
1251           error (_("Junk at end of command"));
1252       gdb::unique_xmalloc_ptr<char> outfile_name
1253           (tilde_expand (argv[outfile_idx]));
1254       if (!arg_outfile.open (outfile_name.get (), FOPEN_WT))
1255           perror_with_name (outfile_name.get ());
1256       outfile = &arg_outfile;
1257     }
1258 
1259   if (address_arg != NULL)
1260     {
1261       pc = parse_and_eval_address (address_arg);
1262       /* If we fail to find a section, that's ok, try the lookup anyway.  */
1263       section = find_pc_section (pc);
1264     }
1265 
1266   found = 0;
1267   for (objfile *objfile : current_program_space->objfiles ())
1268     {
1269       int printed_objfile_header = 0;
1270       int print_for_objfile = 1;
1271 
1272       QUIT;
1273       if (objfile_arg != NULL)
1274           print_for_objfile
1275             = compare_filenames_for_search (objfile_name (objfile),
1276                                                     objfile_arg);
1277       if (!print_for_objfile)
1278           continue;
1279 
1280       for (const auto &iter : objfile->qf)
1281           {
1282             psymbol_functions *psf
1283               = dynamic_cast<psymbol_functions *> (iter.get ());
1284             if (psf == nullptr)
1285               continue;
1286 
1287             if (address_arg != NULL)
1288               {
1289                 struct bound_minimal_symbol msymbol;
1290 
1291                 /* We don't assume each pc has a unique objfile (this is for
1292                      debugging).  */
1293                 struct partial_symtab *ps
1294                     = psf->find_pc_sect_psymtab (objfile, pc, section, msymbol);
1295                 if (ps != NULL)
1296                     {
1297                       if (!printed_objfile_header)
1298                         {
1299                           outfile->printf ("\nPartial symtabs for objfile %s\n",
1300                                                objfile_name (objfile));
1301                           printed_objfile_header = 1;
1302                         }
1303                       dump_psymtab (objfile, ps, outfile);
1304                       found = 1;
1305                     }
1306               }
1307             else
1308               {
1309                 for (partial_symtab *ps : psf->partial_symbols (objfile))
1310                     {
1311                       int print_for_source = 0;
1312 
1313                       QUIT;
1314                       if (source_arg != NULL)
1315                         {
1316                           print_for_source
1317                               = compare_filenames_for_search (ps->filename, source_arg);
1318                           found = 1;
1319                         }
1320                       if (source_arg == NULL
1321                           || print_for_source)
1322                         {
1323                           if (!printed_objfile_header)
1324                               {
1325                                 outfile->printf ("\nPartial symtabs for objfile %s\n",
1326                                                      objfile_name (objfile));
1327                                 printed_objfile_header = 1;
1328                               }
1329                           dump_psymtab (objfile, ps, outfile);
1330                         }
1331                     }
1332               }
1333           }
1334     }
1335 
1336   if (!found)
1337     {
1338       if (address_arg != NULL)
1339           error (_("No partial symtab for address: %s"), address_arg);
1340       if (source_arg != NULL)
1341           error (_("No partial symtab for source file: %s"), source_arg);
1342     }
1343 }
1344 
1345 /* List all the partial symbol tables whose names match REGEXP (optional).  */
1346 
1347 static void
maintenance_info_psymtabs(const char * regexp,int from_tty)1348 maintenance_info_psymtabs (const char *regexp, int from_tty)
1349 {
1350   if (regexp)
1351     re_comp (regexp);
1352 
1353   for (struct program_space *pspace : program_spaces)
1354     for (objfile *objfile : pspace->objfiles ())
1355       {
1356           struct gdbarch *gdbarch = objfile->arch ();
1357 
1358           /* We don't want to print anything for this objfile until we
1359              actually find a symtab whose name matches.  */
1360           int printed_objfile_start = 0;
1361 
1362           for (const auto &iter : objfile->qf)
1363             {
1364               psymbol_functions *psf
1365                 = dynamic_cast<psymbol_functions *> (iter.get ());
1366               if (psf == nullptr)
1367                 continue;
1368               for (partial_symtab *psymtab : psf->partial_symbols (objfile))
1369                 {
1370                     QUIT;
1371 
1372                     if (! regexp
1373                         || re_exec (psymtab->filename))
1374                       {
1375                         if (! printed_objfile_start)
1376                           {
1377                               gdb_printf ("{ objfile %s ", objfile_name (objfile));
1378                               gdb_stdout->wrap_here (2);
1379                               gdb_printf ("((struct objfile *) %s)\n",
1380                                             host_address_to_string (objfile));
1381                               printed_objfile_start = 1;
1382                           }
1383 
1384                         gdb_printf ("  { psymtab %s ", psymtab->filename);
1385                         gdb_stdout->wrap_here (4);
1386                         gdb_printf ("((struct partial_symtab *) %s)\n",
1387                                         host_address_to_string (psymtab));
1388 
1389                         gdb_printf ("    readin %s\n",
1390                                         psymtab->readin_p (objfile) ? "yes" : "no");
1391                         gdb_printf ("    fullname %s\n",
1392                                         psymtab->fullname
1393                                         ? psymtab->fullname : "(null)");
1394                         gdb_printf ("    text addresses ");
1395                         gdb_puts (paddress (gdbarch,
1396                                                   psymtab->text_low (objfile)));
1397                         gdb_printf (" -- ");
1398                         gdb_puts (paddress (gdbarch,
1399                                                   psymtab->text_high (objfile)));
1400                         gdb_printf ("\n");
1401                         gdb_printf ("    globals ");
1402                         if (!psymtab->global_psymbols.empty ())
1403                           gdb_printf
1404                               ("(* (struct partial_symbol **) %s @ %d)\n",
1405                                host_address_to_string (psymtab->global_psymbols.data ()),
1406                                (int) psymtab->global_psymbols.size ());
1407                         else
1408                           gdb_printf ("(none)\n");
1409                         gdb_printf ("    statics ");
1410                         if (!psymtab->static_psymbols.empty ())
1411                           gdb_printf
1412                               ("(* (struct partial_symbol **) %s @ %d)\n",
1413                                host_address_to_string (psymtab->static_psymbols.data ()),
1414                                (int) psymtab->static_psymbols.size ());
1415                         else
1416                           gdb_printf ("(none)\n");
1417                         if (psymtab->user)
1418                           gdb_printf ("    user %s "
1419                                           "((struct partial_symtab *) %s)\n",
1420                                           psymtab->user->filename,
1421                                           host_address_to_string (psymtab->user));
1422                         gdb_printf ("    dependencies ");
1423                         if (psymtab->number_of_dependencies)
1424                           {
1425                               int i;
1426 
1427                               gdb_printf ("{\n");
1428                               for (i = 0; i < psymtab->number_of_dependencies; i++)
1429                                 {
1430                                   struct partial_symtab *dep = psymtab->dependencies[i];
1431 
1432                                   /* Note the string concatenation there --- no
1433                                      comma.  */
1434                                   gdb_printf ("      psymtab %s "
1435                                                   "((struct partial_symtab *) %s)\n",
1436                                                   dep->filename,
1437                                                   host_address_to_string (dep));
1438                                 }
1439                               gdb_printf ("    }\n");
1440                           }
1441                         else
1442                           gdb_printf ("(none)\n");
1443                         gdb_printf ("  }\n");
1444                       }
1445                 }
1446             }
1447 
1448           if (printed_objfile_start)
1449             gdb_printf ("}\n");
1450       }
1451 }
1452 
1453 /* Check consistency of currently expanded psymtabs vs symtabs.  */
1454 
1455 static void
maintenance_check_psymtabs(const char * ignore,int from_tty)1456 maintenance_check_psymtabs (const char *ignore, int from_tty)
1457 {
1458   struct symbol *sym;
1459   struct compunit_symtab *cust = NULL;
1460   const struct blockvector *bv;
1461   const struct block *b;
1462 
1463   for (objfile *objfile : current_program_space->objfiles ())
1464     {
1465       for (const auto &iter : objfile->qf)
1466           {
1467             psymbol_functions *psf
1468               = dynamic_cast<psymbol_functions *> (iter.get ());
1469             if (psf == nullptr)
1470               continue;
1471 
1472             for (partial_symtab *ps : psf->partial_symbols (objfile))
1473               {
1474                 struct gdbarch *gdbarch = objfile->arch ();
1475 
1476                 /* We don't call psymtab_to_symtab here because that may cause symtab
1477                      expansion.  When debugging a problem it helps if checkers leave
1478                      things unchanged.  */
1479                 cust = ps->get_compunit_symtab (objfile);
1480 
1481                 /* First do some checks that don't require the associated symtab.  */
1482                 if (ps->text_high (objfile) < ps->text_low (objfile))
1483                     {
1484                       gdb_printf ("Psymtab ");
1485                       gdb_puts (ps->filename);
1486                       gdb_printf (" covers bad range ");
1487                       gdb_puts (paddress (gdbarch, ps->text_low (objfile)));
1488                       gdb_printf (" - ");
1489                       gdb_puts (paddress (gdbarch, ps->text_high (objfile)));
1490                       gdb_printf ("\n");
1491                       continue;
1492                     }
1493 
1494                 /* Now do checks requiring the associated symtab.  */
1495                 if (cust == NULL)
1496                     continue;
1497                 bv = cust->blockvector ();
1498                 b = bv->static_block ();
1499                 for (partial_symbol *psym : ps->static_psymbols)
1500                     {
1501                       /* Skip symbols for inlined functions without address.  These may
1502                          or may not have a match in the full symtab.  */
1503                       if (psym->aclass == LOC_BLOCK
1504                           && psym->ginfo.value_address () == 0)
1505                         continue;
1506 
1507                       lookup_name_info lookup_name
1508                         (psym->ginfo.search_name (), symbol_name_match_type::SEARCH_NAME);
1509                       sym = block_lookup_symbol (b, lookup_name,
1510                                                        to_search_flags (psym->domain));
1511                       if (!sym)
1512                         {
1513                           gdb_printf ("Static symbol `");
1514                           gdb_puts (psym->ginfo.linkage_name ());
1515                           gdb_printf ("' only found in ");
1516                           gdb_puts (ps->filename);
1517                           gdb_printf (" psymtab\n");
1518                         }
1519                     }
1520                 b = bv->global_block ();
1521                 for (partial_symbol *psym : ps->global_psymbols)
1522                     {
1523                       lookup_name_info lookup_name
1524                         (psym->ginfo.search_name (), symbol_name_match_type::SEARCH_NAME);
1525                       sym = block_lookup_symbol (b, lookup_name,
1526                                                        to_search_flags (psym->domain));
1527                       if (!sym)
1528                         {
1529                           gdb_printf ("Global symbol `");
1530                           gdb_puts (psym->ginfo.linkage_name ());
1531                           gdb_printf ("' only found in ");
1532                           gdb_puts (ps->filename);
1533                           gdb_printf (" psymtab\n");
1534                         }
1535                     }
1536                 if (ps->unrelocated_text_high () != unrelocated_addr (0)
1537                       && (ps->text_low (objfile) < b->start ()
1538                           || ps->text_high (objfile) > b->end ()))
1539                     {
1540                       gdb_printf ("Psymtab ");
1541                       gdb_puts (ps->filename);
1542                       gdb_printf (" covers ");
1543                       gdb_puts (paddress (gdbarch, ps->text_low (objfile)));
1544                       gdb_printf (" - ");
1545                       gdb_puts (paddress (gdbarch, ps->text_high (objfile)));
1546                       gdb_printf (" but symtab covers only ");
1547                       gdb_puts (paddress (gdbarch, b->start ()));
1548                       gdb_printf (" - ");
1549                       gdb_puts (paddress (gdbarch, b->end ()));
1550                       gdb_printf ("\n");
1551                     }
1552               }
1553           }
1554     }
1555 }
1556 
1557 void _initialize_psymtab ();
1558 void
_initialize_psymtab()1559 _initialize_psymtab ()
1560 {
1561   add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\
1562 Print dump of current partial symbol definitions.\n\
1563 Usage: mt print psymbols [-objfile OBJFILE] [-pc ADDRESS] [--] [OUTFILE]\n\
1564        mt print psymbols [-objfile OBJFILE] [-source SOURCE] [--] [OUTFILE]\n\
1565 Entries in the partial symbol table are dumped to file OUTFILE,\n\
1566 or the terminal if OUTFILE is unspecified.\n\
1567 If ADDRESS is provided, dump only the symbols for the file with code at that address.\n\
1568 If SOURCE is provided, dump only that file's symbols.\n\
1569 If OBJFILE is provided, dump only that object file's symbols."),
1570              &maintenanceprintlist);
1571 
1572   add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\
1573 List the partial symbol tables for all object files.\n\
1574 This does not include information about individual partial symbols,\n\
1575 just the symbol table structures themselves."),
1576              &maintenanceinfolist);
1577 
1578   add_cmd ("check-psymtabs", class_maintenance, maintenance_check_psymtabs,
1579              _("\
1580 Check consistency of currently expanded psymtabs versus symtabs."),
1581              &maintenancelist);
1582 }
1583