GDB (API)
/home/stan/gdb/src/gdb/psymtab.c
Go to the documentation of this file.
00001 /* Partial symbol tables.
00002    
00003    Copyright (C) 2009-2013 Free Software Foundation, Inc.
00004 
00005    This file is part of GDB.
00006 
00007    This program is free software; you can redistribute it and/or modify
00008    it under the terms of the GNU General Public License as published by
00009    the Free Software Foundation; either version 3 of the License, or
00010    (at your option) any later version.
00011 
00012    This program is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015    GNU General Public License for more details.
00016 
00017    You should have received a copy of the GNU General Public License
00018    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00019 
00020 #include "defs.h"
00021 #include "symtab.h"
00022 #include "psympriv.h"
00023 #include "objfiles.h"
00024 #include "gdb_assert.h"
00025 #include "block.h"
00026 #include "filenames.h"
00027 #include "source.h"
00028 #include "addrmap.h"
00029 #include "gdbtypes.h"
00030 #include "bcache.h"
00031 #include "ui-out.h"
00032 #include "command.h"
00033 #include "readline/readline.h"
00034 #include "gdb_regex.h"
00035 #include "dictionary.h"
00036 #include "language.h"
00037 #include "cp-support.h"
00038 #include "gdbcmd.h"
00039 
00040 #ifndef DEV_TTY
00041 #define DEV_TTY "/dev/tty"
00042 #endif
00043 
00044 struct psymbol_bcache
00045 {
00046   struct bcache *bcache;
00047 };
00048 
00049 static struct partial_symbol *match_partial_symbol (struct objfile *,
00050                                                     struct partial_symtab *,
00051                                                     int,
00052                                                     const char *, domain_enum,
00053                                                     symbol_compare_ftype *,
00054                                                     symbol_compare_ftype *);
00055 
00056 static struct partial_symbol *lookup_partial_symbol (struct objfile *,
00057                                                      struct partial_symtab *,
00058                                                      const char *, int,
00059                                                      domain_enum);
00060 
00061 static const char *psymtab_to_fullname (struct partial_symtab *ps);
00062 
00063 static struct partial_symbol *find_pc_sect_psymbol (struct objfile *,
00064                                                     struct partial_symtab *,
00065                                                     CORE_ADDR,
00066                                                     struct obj_section *);
00067 
00068 static void fixup_psymbol_section (struct partial_symbol *psym,
00069                                    struct objfile *objfile);
00070 
00071 static struct symtab *psymtab_to_symtab (struct objfile *objfile,
00072                                          struct partial_symtab *pst);
00073 
00074 /* Ensure that the partial symbols for OBJFILE have been loaded.  This
00075    function always returns its argument, as a convenience.  */
00076 
00077 struct objfile *
00078 require_partial_symbols (struct objfile *objfile, int verbose)
00079 {
00080   if ((objfile->flags & OBJF_PSYMTABS_READ) == 0)
00081     {
00082       objfile->flags |= OBJF_PSYMTABS_READ;
00083 
00084       if (objfile->sf->sym_read_psymbols)
00085         {
00086           if (verbose)
00087             {
00088               printf_unfiltered (_("Reading symbols from %s..."),
00089                                  objfile_name (objfile));
00090               gdb_flush (gdb_stdout);
00091             }
00092           (*objfile->sf->sym_read_psymbols) (objfile);
00093           if (verbose)
00094             {
00095               if (!objfile_has_symbols (objfile))
00096                 {
00097                   wrap_here ("");
00098                   printf_unfiltered (_("(no debugging symbols found)..."));
00099                   wrap_here ("");
00100                 }
00101 
00102               printf_unfiltered (_("done.\n"));
00103             }
00104         }
00105     }
00106 
00107   return objfile;
00108 }
00109 
00110 /* Traverse all psymtabs in one objfile, requiring that the psymtabs
00111    be read in.  */
00112 
00113 #define ALL_OBJFILE_PSYMTABS_REQUIRED(objfile, p)               \
00114     for ((p) = require_partial_symbols (objfile, 1)->psymtabs;  \
00115          (p) != NULL;                                           \
00116          (p) = (p)->next)
00117 
00118 /* We want to make sure this file always requires psymtabs.  */
00119 
00120 #undef ALL_OBJFILE_PSYMTABS
00121 
00122 /* Traverse all psymtabs in all objfiles.  */
00123 
00124 #define ALL_PSYMTABS(objfile, p) \
00125   ALL_OBJFILES (objfile)         \
00126     ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
00127 
00128 /* Helper function for partial_map_symtabs_matching_filename that
00129    expands the symtabs and calls the iterator.  */
00130 
00131 static int
00132 partial_map_expand_apply (struct objfile *objfile,
00133                           const char *name,
00134                           const char *real_path,
00135                           struct partial_symtab *pst,
00136                           int (*callback) (struct symtab *, void *),
00137                           void *data)
00138 {
00139   struct symtab *last_made = objfile->symtabs;
00140 
00141   /* Shared psymtabs should never be seen here.  Instead they should
00142      be handled properly by the caller.  */
00143   gdb_assert (pst->user == NULL);
00144 
00145   /* Don't visit already-expanded psymtabs.  */
00146   if (pst->readin)
00147     return 0;
00148 
00149   /* This may expand more than one symtab, and we want to iterate over
00150      all of them.  */
00151   psymtab_to_symtab (objfile, pst);
00152 
00153   return iterate_over_some_symtabs (name, real_path, callback, data,
00154                                     objfile->symtabs, last_made);
00155 }
00156 
00157 /* Implementation of the map_symtabs_matching_filename method.  */
00158 
00159 static int
00160 partial_map_symtabs_matching_filename (struct objfile *objfile,
00161                                        const char *name,
00162                                        const char *real_path,
00163                                        int (*callback) (struct symtab *,
00164                                                         void *),
00165                                        void *data)
00166 {
00167   struct partial_symtab *pst;
00168   const char *name_basename = lbasename (name);
00169 
00170   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
00171   {
00172     /* We can skip shared psymtabs here, because any file name will be
00173        attached to the unshared psymtab.  */
00174     if (pst->user != NULL)
00175       continue;
00176 
00177     /* Anonymous psymtabs don't have a file name.  */
00178     if (pst->anonymous)
00179       continue;
00180 
00181     if (compare_filenames_for_search (pst->filename, name))
00182       {
00183         if (partial_map_expand_apply (objfile, name, real_path,
00184                                       pst, callback, data))
00185           return 1;
00186         continue;
00187       }
00188 
00189     /* Before we invoke realpath, which can get expensive when many
00190        files are involved, do a quick comparison of the basenames.  */
00191     if (! basenames_may_differ
00192         && FILENAME_CMP (name_basename, lbasename (pst->filename)) != 0)
00193       continue;
00194 
00195     if (compare_filenames_for_search (psymtab_to_fullname (pst), name))
00196       {
00197         if (partial_map_expand_apply (objfile, name, real_path,
00198                                       pst, callback, data))
00199           return 1;
00200         continue;
00201       }
00202 
00203     /* If the user gave us an absolute path, try to find the file in
00204        this symtab and use its absolute path.  */
00205     if (real_path != NULL)
00206       {
00207         gdb_assert (IS_ABSOLUTE_PATH (real_path));
00208         gdb_assert (IS_ABSOLUTE_PATH (name));
00209         if (filename_cmp (psymtab_to_fullname (pst), real_path) == 0)
00210           {
00211             if (partial_map_expand_apply (objfile, name, real_path,
00212                                           pst, callback, data))
00213               return 1;
00214             continue;
00215           }
00216       }
00217   }
00218 
00219   return 0;
00220 }
00221 
00222 /* Find which partial symtab contains PC and SECTION starting at psymtab PST.
00223    We may find a different psymtab than PST.  See FIND_PC_SECT_PSYMTAB.  */
00224 
00225 static struct partial_symtab *
00226 find_pc_sect_psymtab_closer (struct objfile *objfile,
00227                              CORE_ADDR pc, struct obj_section *section,
00228                              struct partial_symtab *pst,
00229                              struct minimal_symbol *msymbol)
00230 {
00231   struct partial_symtab *tpst;
00232   struct partial_symtab *best_pst = pst;
00233   CORE_ADDR best_addr = pst->textlow;
00234 
00235   gdb_assert (!pst->psymtabs_addrmap_supported);
00236 
00237   /* An objfile that has its functions reordered might have
00238      many partial symbol tables containing the PC, but
00239      we want the partial symbol table that contains the
00240      function containing the PC.  */
00241   if (!(objfile->flags & OBJF_REORDERED) &&
00242       section == 0)     /* Can't validate section this way.  */
00243     return pst;
00244 
00245   if (msymbol == NULL)
00246     return (pst);
00247 
00248   /* The code range of partial symtabs sometimes overlap, so, in
00249      the loop below, we need to check all partial symtabs and
00250      find the one that fits better for the given PC address.  We
00251      select the partial symtab that contains a symbol whose
00252      address is closest to the PC address.  By closest we mean
00253      that find_pc_sect_symbol returns the symbol with address
00254      that is closest and still less than the given PC.  */
00255   for (tpst = pst; tpst != NULL; tpst = tpst->next)
00256     {
00257       if (pc >= tpst->textlow && pc < tpst->texthigh)
00258         {
00259           struct partial_symbol *p;
00260           CORE_ADDR this_addr;
00261 
00262           /* NOTE: This assumes that every psymbol has a
00263              corresponding msymbol, which is not necessarily
00264              true; the debug info might be much richer than the
00265              object's symbol table.  */
00266           p = find_pc_sect_psymbol (objfile, tpst, pc, section);
00267           if (p != NULL
00268               && SYMBOL_VALUE_ADDRESS (p)
00269               == SYMBOL_VALUE_ADDRESS (msymbol))
00270             return tpst;
00271 
00272           /* Also accept the textlow value of a psymtab as a
00273              "symbol", to provide some support for partial
00274              symbol tables with line information but no debug
00275              symbols (e.g. those produced by an assembler).  */
00276           if (p != NULL)
00277             this_addr = SYMBOL_VALUE_ADDRESS (p);
00278           else
00279             this_addr = tpst->textlow;
00280 
00281           /* Check whether it is closer than our current
00282              BEST_ADDR.  Since this symbol address is
00283              necessarily lower or equal to PC, the symbol closer
00284              to PC is the symbol which address is the highest.
00285              This way we return the psymtab which contains such
00286              best match symbol.  This can help in cases where the
00287              symbol information/debuginfo is not complete, like
00288              for instance on IRIX6 with gcc, where no debug info
00289              is emitted for statics.  (See also the nodebug.exp
00290              testcase.)  */
00291           if (this_addr > best_addr)
00292             {
00293               best_addr = this_addr;
00294               best_pst = tpst;
00295             }
00296         }
00297     }
00298   return best_pst;
00299 }
00300 
00301 /* Find which partial symtab contains PC and SECTION.  Return 0 if
00302    none.  We return the psymtab that contains a symbol whose address
00303    exactly matches PC, or, if we cannot find an exact match, the
00304    psymtab that contains a symbol whose address is closest to PC.  */
00305 static struct partial_symtab *
00306 find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc,
00307                       struct obj_section *section,
00308                       struct minimal_symbol *msymbol)
00309 {
00310   struct partial_symtab *pst;
00311 
00312   /* Try just the PSYMTABS_ADDRMAP mapping first as it has better granularity
00313      than the later used TEXTLOW/TEXTHIGH one.  */
00314 
00315   if (objfile->psymtabs_addrmap != NULL)
00316     {
00317       pst = addrmap_find (objfile->psymtabs_addrmap, pc);
00318       if (pst != NULL)
00319         {
00320           /* FIXME: addrmaps currently do not handle overlayed sections,
00321              so fall back to the non-addrmap case if we're debugging
00322              overlays and the addrmap returned the wrong section.  */
00323           if (overlay_debugging && msymbol && section)
00324             {
00325               struct partial_symbol *p;
00326 
00327               /* NOTE: This assumes that every psymbol has a
00328                  corresponding msymbol, which is not necessarily
00329                  true; the debug info might be much richer than the
00330                  object's symbol table.  */
00331               p = find_pc_sect_psymbol (objfile, pst, pc, section);
00332               if (!p
00333                   || SYMBOL_VALUE_ADDRESS (p)
00334                   != SYMBOL_VALUE_ADDRESS (msymbol))
00335                 goto next;
00336             }
00337 
00338           /* We do not try to call FIND_PC_SECT_PSYMTAB_CLOSER as
00339              PSYMTABS_ADDRMAP we used has already the best 1-byte
00340              granularity and FIND_PC_SECT_PSYMTAB_CLOSER may mislead us into
00341              a worse chosen section due to the TEXTLOW/TEXTHIGH ranges
00342              overlap.  */
00343 
00344           return pst;
00345         }
00346     }
00347 
00348  next:
00349 
00350   /* Existing PSYMTABS_ADDRMAP mapping is present even for PARTIAL_SYMTABs
00351      which still have no corresponding full SYMTABs read.  But it is not
00352      present for non-DWARF2 debug infos not supporting PSYMTABS_ADDRMAP in GDB
00353      so far.  */
00354 
00355   /* Check even OBJFILE with non-zero PSYMTABS_ADDRMAP as only several of
00356      its CUs may be missing in PSYMTABS_ADDRMAP as they may be varying
00357      debug info type in single OBJFILE.  */
00358 
00359   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
00360     if (!pst->psymtabs_addrmap_supported
00361         && pc >= pst->textlow && pc < pst->texthigh)
00362       {
00363         struct partial_symtab *best_pst;
00364 
00365         best_pst = find_pc_sect_psymtab_closer (objfile, pc, section, pst,
00366                                                 msymbol);
00367         if (best_pst != NULL)
00368           return best_pst;
00369       }
00370 
00371   return NULL;
00372 }
00373 
00374 static struct symtab *
00375 find_pc_sect_symtab_from_partial (struct objfile *objfile,
00376                                   struct minimal_symbol *msymbol,
00377                                   CORE_ADDR pc, struct obj_section *section,
00378                                   int warn_if_readin)
00379 {
00380   struct partial_symtab *ps = find_pc_sect_psymtab (objfile, pc, section,
00381                                                     msymbol);
00382   if (ps)
00383     {
00384       if (warn_if_readin && ps->readin)
00385         /* Might want to error() here (in case symtab is corrupt and
00386            will cause a core dump), but maybe we can successfully
00387            continue, so let's not.  */
00388         warning (_("\
00389 (Internal error: pc %s in read in psymtab, but not in symtab.)\n"),
00390                  paddress (get_objfile_arch (objfile), pc));
00391       psymtab_to_symtab (objfile, ps);
00392       return ps->symtab;
00393     }
00394   return NULL;
00395 }
00396 
00397 /* Find which partial symbol within a psymtab matches PC and SECTION.
00398    Return 0 if none.  */
00399 
00400 static struct partial_symbol *
00401 find_pc_sect_psymbol (struct objfile *objfile,
00402                       struct partial_symtab *psymtab, CORE_ADDR pc,
00403                       struct obj_section *section)
00404 {
00405   struct partial_symbol *best = NULL, *p, **pp;
00406   CORE_ADDR best_pc;
00407 
00408   gdb_assert (psymtab != NULL);
00409 
00410   /* Cope with programs that start at address 0.  */
00411   best_pc = (psymtab->textlow != 0) ? psymtab->textlow - 1 : 0;
00412 
00413   /* Search the global symbols as well as the static symbols, so that
00414      find_pc_partial_function doesn't use a minimal symbol and thus
00415      cache a bad endaddr.  */
00416   for (pp = objfile->global_psymbols.list + psymtab->globals_offset;
00417     (pp - (objfile->global_psymbols.list + psymtab->globals_offset)
00418      < psymtab->n_global_syms);
00419        pp++)
00420     {
00421       p = *pp;
00422       if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
00423           && PSYMBOL_CLASS (p) == LOC_BLOCK
00424           && pc >= SYMBOL_VALUE_ADDRESS (p)
00425           && (SYMBOL_VALUE_ADDRESS (p) > best_pc
00426               || (psymtab->textlow == 0
00427                   && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
00428         {
00429           if (section)          /* Match on a specific section.  */
00430             {
00431               fixup_psymbol_section (p, objfile);
00432               if (!matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, p),
00433                                           section))
00434                 continue;
00435             }
00436           best_pc = SYMBOL_VALUE_ADDRESS (p);
00437           best = p;
00438         }
00439     }
00440 
00441   for (pp = objfile->static_psymbols.list + psymtab->statics_offset;
00442     (pp - (objfile->static_psymbols.list + psymtab->statics_offset)
00443      < psymtab->n_static_syms);
00444        pp++)
00445     {
00446       p = *pp;
00447       if (SYMBOL_DOMAIN (p) == VAR_DOMAIN
00448           && PSYMBOL_CLASS (p) == LOC_BLOCK
00449           && pc >= SYMBOL_VALUE_ADDRESS (p)
00450           && (SYMBOL_VALUE_ADDRESS (p) > best_pc
00451               || (psymtab->textlow == 0
00452                   && best_pc == 0 && SYMBOL_VALUE_ADDRESS (p) == 0)))
00453         {
00454           if (section)          /* Match on a specific section.  */
00455             {
00456               fixup_psymbol_section (p, objfile);
00457               if (!matching_obj_sections (SYMBOL_OBJ_SECTION (objfile, p),
00458                                           section))
00459                 continue;
00460             }
00461           best_pc = SYMBOL_VALUE_ADDRESS (p);
00462           best = p;
00463         }
00464     }
00465 
00466   return best;
00467 }
00468 
00469 static void
00470 fixup_psymbol_section (struct partial_symbol *psym, struct objfile *objfile)
00471 {
00472   CORE_ADDR addr;
00473 
00474   if (!psym)
00475     return;
00476 
00477   if (SYMBOL_SECTION (psym) >= 0)
00478     return;
00479 
00480   gdb_assert (objfile);
00481 
00482   switch (PSYMBOL_CLASS (psym))
00483     {
00484     case LOC_STATIC:
00485     case LOC_LABEL:
00486     case LOC_BLOCK:
00487       addr = SYMBOL_VALUE_ADDRESS (psym);
00488       break;
00489     default:
00490       /* Nothing else will be listed in the minsyms -- no use looking
00491          it up.  */
00492       return;
00493     }
00494 
00495   fixup_section (&psym->ginfo, addr, objfile);
00496 }
00497 
00498 static struct symtab *
00499 lookup_symbol_aux_psymtabs (struct objfile *objfile,
00500                             int block_index, const char *name,
00501                             const domain_enum domain)
00502 {
00503   struct partial_symtab *ps;
00504   const int psymtab_index = (block_index == GLOBAL_BLOCK ? 1 : 0);
00505   struct symtab *stab_best = NULL;
00506 
00507   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
00508   {
00509     if (!ps->readin && lookup_partial_symbol (objfile, ps, name,
00510                                               psymtab_index, domain))
00511       {
00512         struct symbol *sym = NULL;
00513         struct symtab *stab = psymtab_to_symtab (objfile, ps);
00514 
00515         /* Some caution must be observed with overloaded functions
00516            and methods, since the psymtab will not contain any overload
00517            information (but NAME might contain it).  */
00518         if (stab->primary)
00519           {
00520             struct blockvector *bv = BLOCKVECTOR (stab);
00521             struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
00522 
00523             sym = lookup_block_symbol (block, name, domain);
00524           }
00525 
00526         if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
00527           {
00528             if (!TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
00529               return stab;
00530 
00531             stab_best = stab;
00532           }
00533 
00534         /* Keep looking through other psymtabs.  */
00535       }
00536   }
00537 
00538   return stab_best;
00539 }
00540 
00541 /* Look in PST for a symbol in DOMAIN whose name matches NAME.  Search
00542    the global block of PST if GLOBAL, and otherwise the static block.
00543    MATCH is the comparison operation that returns true iff MATCH (s,
00544    NAME), where s is a SYMBOL_SEARCH_NAME.  If ORDERED_COMPARE is
00545    non-null, the symbols in the block are assumed to be ordered
00546    according to it (allowing binary search).  It must be compatible
00547    with MATCH.  Returns the symbol, if found, and otherwise NULL.  */
00548 
00549 static struct partial_symbol *
00550 match_partial_symbol (struct objfile *objfile,
00551                       struct partial_symtab *pst, int global,
00552                       const char *name, domain_enum domain,
00553                       symbol_compare_ftype *match,
00554                       symbol_compare_ftype *ordered_compare)
00555 {
00556   struct partial_symbol **start, **psym;
00557   struct partial_symbol **top, **real_top, **bottom, **center;
00558   int length = (global ? pst->n_global_syms : pst->n_static_syms);
00559   int do_linear_search = 1;
00560 
00561   if (length == 0)
00562       return NULL;
00563   start = (global ?
00564            objfile->global_psymbols.list + pst->globals_offset :
00565            objfile->static_psymbols.list + pst->statics_offset);
00566 
00567   if (global && ordered_compare)  /* Can use a binary search.  */
00568     {
00569       do_linear_search = 0;
00570 
00571       /* Binary search.  This search is guaranteed to end with center
00572          pointing at the earliest partial symbol whose name might be
00573          correct.  At that point *all* partial symbols with an
00574          appropriate name will be checked against the correct
00575          domain.  */
00576 
00577       bottom = start;
00578       top = start + length - 1;
00579       real_top = top;
00580       while (top > bottom)
00581         {
00582           center = bottom + (top - bottom) / 2;
00583           gdb_assert (center < top);
00584           if (!do_linear_search
00585               && (SYMBOL_LANGUAGE (*center) == language_java))
00586             do_linear_search = 1;
00587           if (ordered_compare (SYMBOL_SEARCH_NAME (*center), name) >= 0)
00588             top = center;
00589           else
00590             bottom = center + 1;
00591         }
00592       gdb_assert (top == bottom);
00593 
00594       while (top <= real_top
00595              && match (SYMBOL_SEARCH_NAME (*top), name) == 0)
00596         {
00597           if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
00598                                      SYMBOL_DOMAIN (*top), domain))
00599             return *top;
00600           top++;
00601         }
00602     }
00603 
00604   /* Can't use a binary search or else we found during the binary search that
00605      we should also do a linear search.  */
00606 
00607   if (do_linear_search)
00608     {
00609       for (psym = start; psym < start + length; psym++)
00610         {
00611           if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
00612                                      SYMBOL_DOMAIN (*psym), domain)
00613               && match (SYMBOL_SEARCH_NAME (*psym), name) == 0)
00614             return *psym;
00615         }
00616     }
00617 
00618   return NULL;
00619 }
00620 
00621 /* Returns the name used to search psymtabs.  Unlike symtabs, psymtabs do
00622    not contain any method/function instance information (since this would
00623    force reading type information while reading psymtabs).  Therefore,
00624    if NAME contains overload information, it must be stripped before searching
00625    psymtabs.
00626 
00627    The caller is responsible for freeing the return result.  */
00628 
00629 static char *
00630 psymtab_search_name (const char *name)
00631 {
00632   switch (current_language->la_language)
00633     {
00634     case language_cplus:
00635     case language_java:
00636       {
00637        if (strchr (name, '('))
00638          {
00639            char *ret = cp_remove_params (name);
00640 
00641            if (ret)
00642              return ret;
00643          }
00644       }
00645       break;
00646 
00647     default:
00648       break;
00649     }
00650 
00651   return xstrdup (name);
00652 }
00653 
00654 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
00655    Check the global symbols if GLOBAL, the static symbols if not.  */
00656 
00657 static struct partial_symbol *
00658 lookup_partial_symbol (struct objfile *objfile,
00659                        struct partial_symtab *pst, const char *name,
00660                        int global, domain_enum domain)
00661 {
00662   struct partial_symbol **start, **psym;
00663   struct partial_symbol **top, **real_top, **bottom, **center;
00664   int length = (global ? pst->n_global_syms : pst->n_static_syms);
00665   int do_linear_search = 1;
00666   char *search_name;
00667   struct cleanup *cleanup;
00668 
00669   if (length == 0)
00670     {
00671       return (NULL);
00672     }
00673 
00674   search_name = psymtab_search_name (name);
00675   cleanup = make_cleanup (xfree, search_name);
00676   start = (global ?
00677            objfile->global_psymbols.list + pst->globals_offset :
00678            objfile->static_psymbols.list + pst->statics_offset);
00679 
00680   if (global)                   /* This means we can use a binary search.  */
00681     {
00682       do_linear_search = 0;
00683 
00684       /* Binary search.  This search is guaranteed to end with center
00685          pointing at the earliest partial symbol whose name might be
00686          correct.  At that point *all* partial symbols with an
00687          appropriate name will be checked against the correct
00688          domain.  */
00689 
00690       bottom = start;
00691       top = start + length - 1;
00692       real_top = top;
00693       while (top > bottom)
00694         {
00695           center = bottom + (top - bottom) / 2;
00696           if (!(center < top))
00697             internal_error (__FILE__, __LINE__,
00698                             _("failed internal consistency check"));
00699           if (!do_linear_search
00700               && SYMBOL_LANGUAGE (*center) == language_java)
00701             {
00702               do_linear_search = 1;
00703             }
00704           if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center),
00705                                  search_name) >= 0)
00706             {
00707               top = center;
00708             }
00709           else
00710             {
00711               bottom = center + 1;
00712             }
00713         }
00714       if (!(top == bottom))
00715         internal_error (__FILE__, __LINE__,
00716                         _("failed internal consistency check"));
00717 
00718       /* For `case_sensitivity == case_sensitive_off' strcmp_iw_ordered will
00719          search more exactly than what matches SYMBOL_MATCHES_SEARCH_NAME.  */
00720       while (top >= start && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
00721         top--;
00722 
00723       /* Fixup to have a symbol which matches SYMBOL_MATCHES_SEARCH_NAME.  */
00724       top++;
00725 
00726       while (top <= real_top && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
00727         {
00728           if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
00729                                      SYMBOL_DOMAIN (*top), domain))
00730             {
00731               do_cleanups (cleanup);
00732               return (*top);
00733             }
00734           top++;
00735         }
00736     }
00737 
00738   /* Can't use a binary search or else we found during the binary search that
00739      we should also do a linear search.  */
00740 
00741   if (do_linear_search)
00742     {
00743       for (psym = start; psym < start + length; psym++)
00744         {
00745           if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
00746                                      SYMBOL_DOMAIN (*psym), domain)
00747               && SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name))
00748             {
00749               do_cleanups (cleanup);
00750               return (*psym);
00751             }
00752         }
00753     }
00754 
00755   do_cleanups (cleanup);
00756   return (NULL);
00757 }
00758 
00759 /* Get the symbol table that corresponds to a partial_symtab.
00760    This is fast after the first time you do it.  */
00761 
00762 static struct symtab *
00763 psymtab_to_symtab (struct objfile *objfile, struct partial_symtab *pst)
00764 {
00765   /* If it is a shared psymtab, find an unshared psymtab that includes
00766      it.  Any such psymtab will do.  */
00767   while (pst->user != NULL)
00768     pst = pst->user;
00769 
00770   /* If it's been looked up before, return it.  */
00771   if (pst->symtab)
00772     return pst->symtab;
00773 
00774   /* If it has not yet been read in, read it.  */
00775   if (!pst->readin)
00776     {
00777       struct cleanup *back_to = increment_reading_symtab ();
00778 
00779       (*pst->read_symtab) (pst, objfile);
00780       do_cleanups (back_to);
00781     }
00782 
00783   return pst->symtab;
00784 }
00785 
00786 static void
00787 relocate_psymtabs (struct objfile *objfile,
00788                    const struct section_offsets *new_offsets,
00789                    const struct section_offsets *delta)
00790 {
00791   struct partial_symbol **psym;
00792   struct partial_symtab *p;
00793 
00794   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
00795     {
00796       p->textlow += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
00797       p->texthigh += ANOFFSET (delta, SECT_OFF_TEXT (objfile));
00798     }
00799 
00800   for (psym = objfile->global_psymbols.list;
00801        psym < objfile->global_psymbols.next;
00802        psym++)
00803     {
00804       fixup_psymbol_section (*psym, objfile);
00805       if (SYMBOL_SECTION (*psym) >= 0)
00806         SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
00807                                                   SYMBOL_SECTION (*psym));
00808     }
00809   for (psym = objfile->static_psymbols.list;
00810        psym < objfile->static_psymbols.next;
00811        psym++)
00812     {
00813       fixup_psymbol_section (*psym, objfile);
00814       if (SYMBOL_SECTION (*psym) >= 0)
00815         SYMBOL_VALUE_ADDRESS (*psym) += ANOFFSET (delta,
00816                                                   SYMBOL_SECTION (*psym));
00817     }
00818 }
00819 
00820 static struct symtab *
00821 find_last_source_symtab_from_partial (struct objfile *ofp)
00822 {
00823   struct partial_symtab *ps;
00824   struct partial_symtab *cs_pst = 0;
00825 
00826   ALL_OBJFILE_PSYMTABS_REQUIRED (ofp, ps)
00827     {
00828       const char *name = ps->filename;
00829       int len = strlen (name);
00830 
00831       if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
00832                         || strcmp (name, "<<C++-namespaces>>") == 0)))
00833         cs_pst = ps;
00834     }
00835 
00836   if (cs_pst)
00837     {
00838       if (cs_pst->readin)
00839         {
00840           internal_error (__FILE__, __LINE__,
00841                           _("select_source_symtab: "
00842                           "readin pst found and no symtabs."));
00843         }
00844       else
00845         return psymtab_to_symtab (ofp, cs_pst);
00846     }
00847   return NULL;
00848 }
00849 
00850 static void
00851 forget_cached_source_info_partial (struct objfile *objfile)
00852 {
00853   struct partial_symtab *pst;
00854 
00855   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, pst)
00856     {
00857       if (pst->fullname != NULL)
00858         {
00859           xfree (pst->fullname);
00860           pst->fullname = NULL;
00861         }
00862     }
00863 }
00864 
00865 static void
00866 print_partial_symbols (struct gdbarch *gdbarch,
00867                        struct partial_symbol **p, int count, char *what,
00868                        struct ui_file *outfile)
00869 {
00870   fprintf_filtered (outfile, "  %s partial symbols:\n", what);
00871   while (count-- > 0)
00872     {
00873       QUIT;
00874       fprintf_filtered (outfile, "    `%s'", SYMBOL_LINKAGE_NAME (*p));
00875       if (SYMBOL_DEMANGLED_NAME (*p) != NULL)
00876         {
00877           fprintf_filtered (outfile, "  `%s'", SYMBOL_DEMANGLED_NAME (*p));
00878         }
00879       fputs_filtered (", ", outfile);
00880       switch (SYMBOL_DOMAIN (*p))
00881         {
00882         case UNDEF_DOMAIN:
00883           fputs_filtered ("undefined domain, ", outfile);
00884           break;
00885         case VAR_DOMAIN:
00886           /* This is the usual thing -- don't print it.  */
00887           break;
00888         case STRUCT_DOMAIN:
00889           fputs_filtered ("struct domain, ", outfile);
00890           break;
00891         case LABEL_DOMAIN:
00892           fputs_filtered ("label domain, ", outfile);
00893           break;
00894         default:
00895           fputs_filtered ("<invalid domain>, ", outfile);
00896           break;
00897         }
00898       switch (PSYMBOL_CLASS (*p))
00899         {
00900         case LOC_UNDEF:
00901           fputs_filtered ("undefined", outfile);
00902           break;
00903         case LOC_CONST:
00904           fputs_filtered ("constant int", outfile);
00905           break;
00906         case LOC_STATIC:
00907           fputs_filtered ("static", outfile);
00908           break;
00909         case LOC_REGISTER:
00910           fputs_filtered ("register", outfile);
00911           break;
00912         case LOC_ARG:
00913           fputs_filtered ("pass by value", outfile);
00914           break;
00915         case LOC_REF_ARG:
00916           fputs_filtered ("pass by reference", outfile);
00917           break;
00918         case LOC_REGPARM_ADDR:
00919           fputs_filtered ("register address parameter", outfile);
00920           break;
00921         case LOC_LOCAL:
00922           fputs_filtered ("stack parameter", outfile);
00923           break;
00924         case LOC_TYPEDEF:
00925           fputs_filtered ("type", outfile);
00926           break;
00927         case LOC_LABEL:
00928           fputs_filtered ("label", outfile);
00929           break;
00930         case LOC_BLOCK:
00931           fputs_filtered ("function", outfile);
00932           break;
00933         case LOC_CONST_BYTES:
00934           fputs_filtered ("constant bytes", outfile);
00935           break;
00936         case LOC_UNRESOLVED:
00937           fputs_filtered ("unresolved", outfile);
00938           break;
00939         case LOC_OPTIMIZED_OUT:
00940           fputs_filtered ("optimized out", outfile);
00941           break;
00942         case LOC_COMPUTED:
00943           fputs_filtered ("computed at runtime", outfile);
00944           break;
00945         default:
00946           fputs_filtered ("<invalid location>", outfile);
00947           break;
00948         }
00949       fputs_filtered (", ", outfile);
00950       fputs_filtered (paddress (gdbarch, SYMBOL_VALUE_ADDRESS (*p)), outfile);
00951       fprintf_filtered (outfile, "\n");
00952       p++;
00953     }
00954 }
00955 
00956 static void
00957 dump_psymtab (struct objfile *objfile, struct partial_symtab *psymtab,
00958               struct ui_file *outfile)
00959 {
00960   struct gdbarch *gdbarch = get_objfile_arch (objfile);
00961   int i;
00962 
00963   if (psymtab->anonymous)
00964     {
00965       fprintf_filtered (outfile, "\nAnonymous partial symtab (%s) ",
00966                         psymtab->filename);
00967     }
00968   else
00969     {
00970       fprintf_filtered (outfile, "\nPartial symtab for source file %s ",
00971                         psymtab->filename);
00972     }
00973   fprintf_filtered (outfile, "(object ");
00974   gdb_print_host_address (psymtab, outfile);
00975   fprintf_filtered (outfile, ")\n\n");
00976   fprintf_unfiltered (outfile, "  Read from object file %s (",
00977                       objfile_name (objfile));
00978   gdb_print_host_address (objfile, outfile);
00979   fprintf_unfiltered (outfile, ")\n");
00980 
00981   if (psymtab->readin)
00982     {
00983       fprintf_filtered (outfile,
00984                         "  Full symtab was read (at ");
00985       gdb_print_host_address (psymtab->symtab, outfile);
00986       fprintf_filtered (outfile, " by function at ");
00987       gdb_print_host_address (psymtab->read_symtab, outfile);
00988       fprintf_filtered (outfile, ")\n");
00989     }
00990 
00991   fprintf_filtered (outfile, "  Relocate symbols by ");
00992   for (i = 0; i < objfile->num_sections; ++i)
00993     {
00994       if (i != 0)
00995         fprintf_filtered (outfile, ", ");
00996       wrap_here ("    ");
00997       fputs_filtered (paddress (gdbarch,
00998                                 ANOFFSET (psymtab->section_offsets, i)),
00999                       outfile);
01000     }
01001   fprintf_filtered (outfile, "\n");
01002 
01003   fprintf_filtered (outfile, "  Symbols cover text addresses ");
01004   fputs_filtered (paddress (gdbarch, psymtab->textlow), outfile);
01005   fprintf_filtered (outfile, "-");
01006   fputs_filtered (paddress (gdbarch, psymtab->texthigh), outfile);
01007   fprintf_filtered (outfile, "\n");
01008   fprintf_filtered (outfile, "  Address map supported - %s.\n",
01009                     psymtab->psymtabs_addrmap_supported ? "yes" : "no");
01010   fprintf_filtered (outfile, "  Depends on %d other partial symtabs.\n",
01011                     psymtab->number_of_dependencies);
01012   for (i = 0; i < psymtab->number_of_dependencies; i++)
01013     {
01014       fprintf_filtered (outfile, "    %d ", i);
01015       gdb_print_host_address (psymtab->dependencies[i], outfile);
01016       fprintf_filtered (outfile, " %s\n",
01017                         psymtab->dependencies[i]->filename);
01018     }
01019   if (psymtab->user != NULL)
01020     {
01021       fprintf_filtered (outfile, "  Shared partial symtab with user ");
01022       gdb_print_host_address (psymtab->user, outfile);
01023       fprintf_filtered (outfile, "\n");
01024     }
01025   if (psymtab->n_global_syms > 0)
01026     {
01027       print_partial_symbols (gdbarch,
01028                              objfile->global_psymbols.list
01029                              + psymtab->globals_offset,
01030                              psymtab->n_global_syms, "Global", outfile);
01031     }
01032   if (psymtab->n_static_syms > 0)
01033     {
01034       print_partial_symbols (gdbarch,
01035                              objfile->static_psymbols.list
01036                              + psymtab->statics_offset,
01037                              psymtab->n_static_syms, "Static", outfile);
01038     }
01039   fprintf_filtered (outfile, "\n");
01040 }
01041 
01042 static void
01043 print_psymtab_stats_for_objfile (struct objfile *objfile)
01044 {
01045   int i;
01046   struct partial_symtab *ps;
01047 
01048   i = 0;
01049   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
01050     {
01051       if (ps->readin == 0)
01052         i++;
01053     }
01054   printf_filtered (_("  Number of psym tables (not yet expanded): %d\n"), i);
01055 }
01056 
01057 static void
01058 dump_psymtabs_for_objfile (struct objfile *objfile)
01059 {
01060   struct partial_symtab *psymtab;
01061 
01062   if (objfile->psymtabs)
01063     {
01064       printf_filtered ("Psymtabs:\n");
01065       for (psymtab = objfile->psymtabs;
01066            psymtab != NULL;
01067            psymtab = psymtab->next)
01068         {
01069           printf_filtered ("%s at ",
01070                            psymtab->filename);
01071           gdb_print_host_address (psymtab, gdb_stdout);
01072           printf_filtered (", ");
01073           wrap_here ("  ");
01074         }
01075       printf_filtered ("\n\n");
01076     }
01077 }
01078 
01079 /* Look through the partial symtabs for all symbols which begin
01080    by matching FUNC_NAME.  Make sure we read that symbol table in.  */
01081 
01082 static void
01083 read_symtabs_for_function (struct objfile *objfile, const char *func_name)
01084 {
01085   struct partial_symtab *ps;
01086 
01087   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
01088   {
01089     if (ps->readin)
01090       continue;
01091 
01092     if ((lookup_partial_symbol (objfile, ps, func_name, 1, VAR_DOMAIN)
01093          != NULL)
01094         || (lookup_partial_symbol (objfile, ps, func_name, 0, VAR_DOMAIN)
01095             != NULL))
01096       psymtab_to_symtab (objfile, ps);
01097   }
01098 }
01099 
01100 static void
01101 expand_partial_symbol_tables (struct objfile *objfile)
01102 {
01103   struct partial_symtab *psymtab;
01104 
01105   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab)
01106     {
01107       psymtab_to_symtab (objfile, psymtab);
01108     }
01109 }
01110 
01111 static void
01112 read_psymtabs_with_fullname (struct objfile *objfile, const char *fullname)
01113 {
01114   struct partial_symtab *p;
01115 
01116   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, p)
01117     {
01118       /* Anonymous psymtabs don't have a name of a source file.  */
01119       if (p->anonymous)
01120         continue;
01121 
01122       /* psymtab_to_fullname tries to open the file which is slow.
01123          Don't call it if we know the basenames don't match.  */
01124       if ((basenames_may_differ
01125            || filename_cmp (lbasename (fullname), lbasename (p->filename)) == 0)
01126           && filename_cmp (fullname, psymtab_to_fullname (p)) == 0)
01127         psymtab_to_symtab (objfile, p);
01128     }
01129 }
01130 
01131 static void
01132 map_symbol_filenames_psymtab (struct objfile *objfile,
01133                               symbol_filename_ftype *fun, void *data,
01134                               int need_fullname)
01135 {
01136   struct partial_symtab *ps;
01137 
01138   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
01139     {
01140       const char *fullname;
01141 
01142       if (ps->readin)
01143         continue;
01144 
01145       /* We can skip shared psymtabs here, because any file name will be
01146          attached to the unshared psymtab.  */
01147       if (ps->user != NULL)
01148         continue;
01149 
01150       /* Anonymous psymtabs don't have a file name.  */
01151       if (ps->anonymous)
01152         continue;
01153 
01154       QUIT;
01155       if (need_fullname)
01156         fullname = psymtab_to_fullname (ps);
01157       else
01158         fullname = NULL;
01159       (*fun) (ps->filename, fullname, data);
01160     }
01161 }
01162 
01163 /* Finds the fullname that a partial_symtab represents.
01164 
01165    If this functions finds the fullname, it will save it in ps->fullname
01166    and it will also return the value.
01167 
01168    If this function fails to find the file that this partial_symtab represents,
01169    NULL will be returned and ps->fullname will be set to NULL.  */
01170 
01171 static const char *
01172 psymtab_to_fullname (struct partial_symtab *ps)
01173 {
01174   gdb_assert (!ps->anonymous);
01175 
01176   /* Use cached copy if we have it.
01177      We rely on forget_cached_source_info being called appropriately
01178      to handle cases like the file being moved.  */
01179   if (ps->fullname == NULL)
01180     {
01181       int fd = find_and_open_source (ps->filename, ps->dirname, &ps->fullname);
01182 
01183       if (fd >= 0)
01184         close (fd);
01185       else
01186         {
01187           char *fullname;
01188           struct cleanup *back_to;
01189 
01190           /* rewrite_source_path would be applied by find_and_open_source, we
01191              should report the pathname where GDB tried to find the file.  */
01192 
01193           if (ps->dirname == NULL || IS_ABSOLUTE_PATH (ps->filename))
01194             fullname = xstrdup (ps->filename);
01195           else
01196             fullname = concat (ps->dirname, SLASH_STRING, ps->filename, NULL);
01197 
01198           back_to = make_cleanup (xfree, fullname);
01199           ps->fullname = rewrite_source_path (fullname);
01200           if (ps->fullname == NULL)
01201             ps->fullname = xstrdup (fullname);
01202           do_cleanups (back_to);
01203         }
01204     } 
01205 
01206   return ps->fullname;
01207 }
01208 
01209 /*  For all symbols, s, in BLOCK that are in NAMESPACE and match NAME
01210     according to the function MATCH, call CALLBACK(BLOCK, s, DATA).
01211     BLOCK is assumed to come from OBJFILE.  Returns 1 iff CALLBACK
01212     ever returns non-zero, and otherwise returns 0.  */
01213 
01214 static int
01215 map_block (const char *name, domain_enum namespace, struct objfile *objfile,
01216            struct block *block,
01217            int (*callback) (struct block *, struct symbol *, void *),
01218            void *data, symbol_compare_ftype *match)
01219 {
01220   struct block_iterator iter;
01221   struct symbol *sym;
01222 
01223   for (sym = block_iter_match_first (block, name, match, &iter);
01224        sym != NULL; sym = block_iter_match_next (name, match, &iter))
01225     {
01226       if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), 
01227                                  SYMBOL_DOMAIN (sym), namespace))
01228         {
01229           if (callback (block, sym, data))
01230             return 1;
01231         }
01232     }
01233 
01234   return 0;
01235 }
01236 
01237 /*  Psymtab version of map_matching_symbols.  See its definition in
01238     the definition of quick_symbol_functions in symfile.h.  */
01239 
01240 static void
01241 map_matching_symbols_psymtab (struct objfile *objfile,
01242                               const char *name, domain_enum namespace,
01243                               int global,
01244                               int (*callback) (struct block *,
01245                                                struct symbol *, void *),
01246                               void *data,
01247                               symbol_compare_ftype *match,
01248                               symbol_compare_ftype *ordered_compare)
01249 {
01250   const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
01251   struct partial_symtab *ps;
01252 
01253   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
01254     {
01255       QUIT;
01256       if (ps->readin
01257           || match_partial_symbol (objfile, ps, global, name, namespace, match,
01258                                    ordered_compare))
01259         {
01260           struct symtab *s = psymtab_to_symtab (objfile, ps);
01261           struct block *block;
01262 
01263           if (s == NULL || !s->primary)
01264             continue;
01265           block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind);
01266           if (map_block (name, namespace, objfile, block,
01267                          callback, data, match))
01268             return;
01269           if (callback (block, NULL, data))
01270             return;
01271         }
01272     }
01273 }           
01274 
01275 /* A helper for expand_symtabs_matching_via_partial that handles
01276    searching included psymtabs.  This returns 1 if a symbol is found,
01277    and zero otherwise.  It also updates the 'searched_flag' on the
01278    various psymtabs that it searches.  */
01279 
01280 static int
01281 recursively_search_psymtabs (struct partial_symtab *ps,
01282                              struct objfile *objfile,
01283                              enum search_domain kind,
01284                              int (*name_matcher) (const char *, void *),
01285                              void *data)
01286 {
01287   struct partial_symbol **psym;
01288   struct partial_symbol **bound, **gbound, **sbound;
01289   int keep_going = 1;
01290   int result = PST_SEARCHED_AND_NOT_FOUND;
01291   int i;
01292 
01293   if (ps->searched_flag != PST_NOT_SEARCHED)
01294     return ps->searched_flag == PST_SEARCHED_AND_FOUND;
01295 
01296   /* Recurse into shared psymtabs first, because they may have already
01297      been searched, and this could save some time.  */
01298   for (i = 0; i < ps->number_of_dependencies; ++i)
01299     {
01300       int r;
01301 
01302       /* Skip non-shared dependencies, these are handled elsewhere.  */
01303       if (ps->dependencies[i]->user == NULL)
01304         continue;
01305 
01306       r = recursively_search_psymtabs (ps->dependencies[i],
01307                                        objfile, kind, name_matcher, data);
01308       if (r != 0)
01309         {
01310           ps->searched_flag = PST_SEARCHED_AND_FOUND;
01311           return 1;
01312         }
01313     }
01314 
01315   gbound = (objfile->global_psymbols.list
01316             + ps->globals_offset + ps->n_global_syms);
01317   sbound = (objfile->static_psymbols.list
01318             + ps->statics_offset + ps->n_static_syms);
01319   bound = gbound;
01320 
01321   /* Go through all of the symbols stored in a partial
01322      symtab in one loop.  */
01323   psym = objfile->global_psymbols.list + ps->globals_offset;
01324   while (keep_going)
01325     {
01326       if (psym >= bound)
01327         {
01328           if (bound == gbound && ps->n_static_syms != 0)
01329             {
01330               psym = objfile->static_psymbols.list + ps->statics_offset;
01331               bound = sbound;
01332             }
01333           else
01334             keep_going = 0;
01335           continue;
01336         }
01337       else
01338         {
01339           QUIT;
01340 
01341           if ((kind == ALL_DOMAIN
01342                || (kind == VARIABLES_DOMAIN
01343                    && PSYMBOL_CLASS (*psym) != LOC_TYPEDEF
01344                    && PSYMBOL_CLASS (*psym) != LOC_BLOCK)
01345                || (kind == FUNCTIONS_DOMAIN
01346                    && PSYMBOL_CLASS (*psym) == LOC_BLOCK)
01347                || (kind == TYPES_DOMAIN
01348                    && PSYMBOL_CLASS (*psym) == LOC_TYPEDEF))
01349               && (*name_matcher) (SYMBOL_SEARCH_NAME (*psym), data))
01350             {
01351               /* Found a match, so notify our caller.  */
01352               result = PST_SEARCHED_AND_FOUND;
01353               keep_going = 0;
01354             }
01355         }
01356       psym++;
01357     }
01358 
01359   ps->searched_flag = result;
01360   return result == PST_SEARCHED_AND_FOUND;
01361 }
01362 
01363 static void
01364 expand_symtabs_matching_via_partial
01365   (struct objfile *objfile,
01366    int (*file_matcher) (const char *, void *, int basenames),
01367    int (*name_matcher) (const char *, void *),
01368    enum search_domain kind,
01369    void *data)
01370 {
01371   struct partial_symtab *ps;
01372 
01373   /* Clear the search flags.  */
01374   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
01375     {
01376       ps->searched_flag = PST_NOT_SEARCHED;
01377     }
01378 
01379   ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, ps)
01380     {
01381       if (ps->readin)
01382         continue;
01383 
01384       /* We skip shared psymtabs because file-matching doesn't apply
01385          to them; but we search them later in the loop.  */
01386       if (ps->user != NULL)
01387         continue;
01388 
01389       if (file_matcher)
01390         {
01391           int match;
01392 
01393           if (ps->anonymous)
01394             continue;
01395 
01396           match = (*file_matcher) (ps->filename, data, 0);
01397           if (!match)
01398             {
01399               /* Before we invoke realpath, which can get expensive when many
01400                  files are involved, do a quick comparison of the basenames.  */
01401               if (basenames_may_differ
01402                   || (*file_matcher) (lbasename (ps->filename), data, 1))
01403                 match = (*file_matcher) (psymtab_to_fullname (ps), data, 0);
01404             }
01405           if (!match)
01406             continue;
01407         }
01408 
01409       if (recursively_search_psymtabs (ps, objfile, kind, name_matcher, data))
01410         psymtab_to_symtab (objfile, ps);
01411     }
01412 }
01413 
01414 static int
01415 objfile_has_psyms (struct objfile *objfile)
01416 {
01417   return objfile->psymtabs != NULL;
01418 }
01419 
01420 const struct quick_symbol_functions psym_functions =
01421 {
01422   objfile_has_psyms,
01423   find_last_source_symtab_from_partial,
01424   forget_cached_source_info_partial,
01425   partial_map_symtabs_matching_filename,
01426   lookup_symbol_aux_psymtabs,
01427   print_psymtab_stats_for_objfile,
01428   dump_psymtabs_for_objfile,
01429   relocate_psymtabs,
01430   read_symtabs_for_function,
01431   expand_partial_symbol_tables,
01432   read_psymtabs_with_fullname,
01433   map_matching_symbols_psymtab,
01434   expand_symtabs_matching_via_partial,
01435   find_pc_sect_symtab_from_partial,
01436   map_symbol_filenames_psymtab
01437 };
01438 
01439 
01440 
01441 /* This compares two partial symbols by names, using strcmp_iw_ordered
01442    for the comparison.  */
01443 
01444 static int
01445 compare_psymbols (const void *s1p, const void *s2p)
01446 {
01447   struct partial_symbol *const *s1 = s1p;
01448   struct partial_symbol *const *s2 = s2p;
01449 
01450   return strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*s1),
01451                             SYMBOL_SEARCH_NAME (*s2));
01452 }
01453 
01454 void
01455 sort_pst_symbols (struct objfile *objfile, struct partial_symtab *pst)
01456 {
01457   /* Sort the global list; don't sort the static list.  */
01458 
01459   qsort (objfile->global_psymbols.list + pst->globals_offset,
01460          pst->n_global_syms, sizeof (struct partial_symbol *),
01461          compare_psymbols);
01462 }
01463 
01464 /* Allocate and partially fill a partial symtab.  It will be
01465    completely filled at the end of the symbol list.
01466 
01467    FILENAME is the name of the symbol-file we are reading from.  */
01468 
01469 struct partial_symtab *
01470 start_psymtab_common (struct objfile *objfile,
01471                       struct section_offsets *section_offsets,
01472                       const char *filename,
01473                       CORE_ADDR textlow, struct partial_symbol **global_syms,
01474                       struct partial_symbol **static_syms)
01475 {
01476   struct partial_symtab *psymtab;
01477 
01478   psymtab = allocate_psymtab (filename, objfile);
01479   psymtab->section_offsets = section_offsets;
01480   psymtab->textlow = textlow;
01481   psymtab->texthigh = psymtab->textlow;         /* default */
01482   psymtab->globals_offset = global_syms - objfile->global_psymbols.list;
01483   psymtab->statics_offset = static_syms - objfile->static_psymbols.list;
01484   return (psymtab);
01485 }
01486 
01487 /* Calculate a hash code for the given partial symbol.  The hash is
01488    calculated using the symbol's value, language, domain, class
01489    and name.  These are the values which are set by
01490    add_psymbol_to_bcache.  */
01491 
01492 static unsigned long
01493 psymbol_hash (const void *addr, int length)
01494 {
01495   unsigned long h = 0;
01496   struct partial_symbol *psymbol = (struct partial_symbol *) addr;
01497   unsigned int lang = psymbol->ginfo.language;
01498   unsigned int domain = PSYMBOL_DOMAIN (psymbol);
01499   unsigned int class = PSYMBOL_CLASS (psymbol);
01500 
01501   h = hash_continue (&psymbol->ginfo.value, sizeof (psymbol->ginfo.value), h);
01502   h = hash_continue (&lang, sizeof (unsigned int), h);
01503   h = hash_continue (&domain, sizeof (unsigned int), h);
01504   h = hash_continue (&class, sizeof (unsigned int), h);
01505   h = hash_continue (psymbol->ginfo.name, strlen (psymbol->ginfo.name), h);
01506 
01507   return h;
01508 }
01509 
01510 /* Returns true if the symbol at addr1 equals the symbol at addr2.
01511    For the comparison this function uses a symbols value,
01512    language, domain, class and name.  */
01513 
01514 static int
01515 psymbol_compare (const void *addr1, const void *addr2, int length)
01516 {
01517   struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
01518   struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
01519 
01520   return (memcmp (&sym1->ginfo.value, &sym1->ginfo.value,
01521                   sizeof (sym1->ginfo.value)) == 0
01522           && sym1->ginfo.language == sym2->ginfo.language
01523           && PSYMBOL_DOMAIN (sym1) == PSYMBOL_DOMAIN (sym2)
01524           && PSYMBOL_CLASS (sym1) == PSYMBOL_CLASS (sym2)
01525           && sym1->ginfo.name == sym2->ginfo.name);
01526 }
01527 
01528 /* Initialize a partial symbol bcache.  */
01529 
01530 struct psymbol_bcache *
01531 psymbol_bcache_init (void)
01532 {
01533   struct psymbol_bcache *bcache = XCALLOC (1, struct psymbol_bcache);
01534   bcache->bcache = bcache_xmalloc (psymbol_hash, psymbol_compare);
01535   return bcache;
01536 }
01537 
01538 /* Free a partial symbol bcache.  */
01539 void
01540 psymbol_bcache_free (struct psymbol_bcache *bcache)
01541 {
01542   if (bcache == NULL)
01543     return;
01544 
01545   bcache_xfree (bcache->bcache);
01546   xfree (bcache);
01547 }
01548 
01549 /* Return the internal bcache of the psymbol_bcache BCACHE.  */
01550 
01551 struct bcache *
01552 psymbol_bcache_get_bcache (struct psymbol_bcache *bcache)
01553 {
01554   return bcache->bcache;
01555 }
01556 
01557 /* Find a copy of the SYM in BCACHE.  If BCACHE has never seen this
01558    symbol before, add a copy to BCACHE.  In either case, return a pointer
01559    to BCACHE's copy of the symbol.  If optional ADDED is not NULL, return
01560    1 in case of new entry or 0 if returning an old entry.  */
01561 
01562 static const struct partial_symbol *
01563 psymbol_bcache_full (struct partial_symbol *sym,
01564                      struct psymbol_bcache *bcache,
01565                      int *added)
01566 {
01567   return bcache_full (sym,
01568                       sizeof (struct partial_symbol),
01569                       bcache->bcache,
01570                       added);
01571 }
01572 
01573 /* Helper function, initialises partial symbol structure and stashes 
01574    it into objfile's bcache.  Note that our caching mechanism will
01575    use all fields of struct partial_symbol to determine hash value of the
01576    structure.  In other words, having two symbols with the same name but
01577    different domain (or address) is possible and correct.  */
01578 
01579 static const struct partial_symbol *
01580 add_psymbol_to_bcache (const char *name, int namelength, int copy_name,
01581                        domain_enum domain,
01582                        enum address_class class,
01583                        long val,        /* Value as a long */
01584                        CORE_ADDR coreaddr,      /* Value as a CORE_ADDR */
01585                        enum language language, struct objfile *objfile,
01586                        int *added)
01587 {
01588   struct partial_symbol psymbol;
01589 
01590   /* We must ensure that the entire struct has been zeroed before
01591      assigning to it, because an assignment may not touch some of the
01592      holes.  */
01593   memset (&psymbol, 0, sizeof (psymbol));
01594 
01595   /* val and coreaddr are mutually exclusive, one of them *will* be zero.  */
01596   if (val != 0)
01597     {
01598       SYMBOL_VALUE (&psymbol) = val;
01599     }
01600   else
01601     {
01602       SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
01603     }
01604   SYMBOL_SECTION (&psymbol) = -1;
01605   SYMBOL_SET_LANGUAGE (&psymbol, language, &objfile->objfile_obstack);
01606   PSYMBOL_DOMAIN (&psymbol) = domain;
01607   PSYMBOL_CLASS (&psymbol) = class;
01608 
01609   SYMBOL_SET_NAMES (&psymbol, name, namelength, copy_name, objfile);
01610 
01611   /* Stash the partial symbol away in the cache.  */
01612   return psymbol_bcache_full (&psymbol,
01613                               objfile->psymbol_cache,
01614                               added);
01615 }
01616 
01617 /* Increase the space allocated for LISTP, which is probably
01618    global_psymbols or static_psymbols.  This space will eventually
01619    be freed in free_objfile().  */
01620 
01621 static void
01622 extend_psymbol_list (struct psymbol_allocation_list *listp,
01623                      struct objfile *objfile)
01624 {
01625   int new_size;
01626 
01627   if (listp->size == 0)
01628     {
01629       new_size = 255;
01630       listp->list = (struct partial_symbol **)
01631         xmalloc (new_size * sizeof (struct partial_symbol *));
01632     }
01633   else
01634     {
01635       new_size = listp->size * 2;
01636       listp->list = (struct partial_symbol **)
01637         xrealloc ((char *) listp->list,
01638                   new_size * sizeof (struct partial_symbol *));
01639     }
01640   /* Next assumes we only went one over.  Should be good if
01641      program works correctly.  */
01642   listp->next = listp->list + listp->size;
01643   listp->size = new_size;
01644 }
01645 
01646 /* Helper function, adds partial symbol to the given partial symbol
01647    list.  */
01648 
01649 static void
01650 append_psymbol_to_list (struct psymbol_allocation_list *list,
01651                         const struct partial_symbol *psym,
01652                         struct objfile *objfile)
01653 {
01654   if (list->next >= list->list + list->size)
01655     extend_psymbol_list (list, objfile);
01656   *list->next++ = (struct partial_symbol *) psym;
01657   OBJSTAT (objfile, n_psyms++);
01658 }
01659 
01660 /* Add a symbol with a long value to a psymtab.
01661    Since one arg is a struct, we pass in a ptr and deref it (sigh).
01662    Return the partial symbol that has been added.  */
01663 
01664 void
01665 add_psymbol_to_list (const char *name, int namelength, int copy_name,
01666                      domain_enum domain,
01667                      enum address_class class,
01668                      struct psymbol_allocation_list *list, 
01669                      long val,  /* Value as a long */
01670                      CORE_ADDR coreaddr,        /* Value as a CORE_ADDR */
01671                      enum language language, struct objfile *objfile)
01672 {
01673   const struct partial_symbol *psym;
01674 
01675   int added;
01676 
01677   /* Stash the partial symbol away in the cache.  */
01678   psym = add_psymbol_to_bcache (name, namelength, copy_name, domain, class,
01679                                 val, coreaddr, language, objfile, &added);
01680 
01681   /* Do not duplicate global partial symbols.  */
01682   if (list == &objfile->global_psymbols
01683       && !added)
01684     return;
01685 
01686   /* Save pointer to partial symbol in psymtab, growing symtab if needed.  */
01687   append_psymbol_to_list (list, psym, objfile);
01688 }
01689 
01690 /* Initialize storage for partial symbols.  */
01691 
01692 void
01693 init_psymbol_list (struct objfile *objfile, int total_symbols)
01694 {
01695   /* Free any previously allocated psymbol lists.  */
01696 
01697   if (objfile->global_psymbols.list)
01698     {
01699       xfree (objfile->global_psymbols.list);
01700     }
01701   if (objfile->static_psymbols.list)
01702     {
01703       xfree (objfile->static_psymbols.list);
01704     }
01705 
01706   /* Current best guess is that approximately a twentieth
01707      of the total symbols (in a debugging file) are global or static
01708      oriented symbols, then multiply that by slop factor of two.  */
01709 
01710   objfile->global_psymbols.size = total_symbols / 10;
01711   objfile->static_psymbols.size = total_symbols / 10;
01712 
01713   if (objfile->global_psymbols.size > 0)
01714     {
01715       objfile->global_psymbols.next =
01716         objfile->global_psymbols.list = (struct partial_symbol **)
01717         xmalloc ((objfile->global_psymbols.size
01718                   * sizeof (struct partial_symbol *)));
01719     }
01720   if (objfile->static_psymbols.size > 0)
01721     {
01722       objfile->static_psymbols.next =
01723         objfile->static_psymbols.list = (struct partial_symbol **)
01724         xmalloc ((objfile->static_psymbols.size
01725                   * sizeof (struct partial_symbol *)));
01726     }
01727 }
01728 
01729 struct partial_symtab *
01730 allocate_psymtab (const char *filename, struct objfile *objfile)
01731 {
01732   struct partial_symtab *psymtab;
01733 
01734   if (objfile->free_psymtabs)
01735     {
01736       psymtab = objfile->free_psymtabs;
01737       objfile->free_psymtabs = psymtab->next;
01738     }
01739   else
01740     psymtab = (struct partial_symtab *)
01741       obstack_alloc (&objfile->objfile_obstack,
01742                      sizeof (struct partial_symtab));
01743 
01744   memset (psymtab, 0, sizeof (struct partial_symtab));
01745   psymtab->filename = obstack_copy0 (&objfile->objfile_obstack,
01746                                      filename, strlen (filename));
01747   psymtab->symtab = NULL;
01748 
01749   /* Prepend it to the psymtab list for the objfile it belongs to.
01750      Psymtabs are searched in most recent inserted -> least recent
01751      inserted order.  */
01752 
01753   psymtab->next = objfile->psymtabs;
01754   objfile->psymtabs = psymtab;
01755 
01756   if (symtab_create_debug)
01757     {
01758       /* Be a bit clever with debugging messages, and don't print objfile
01759          every time, only when it changes.  */
01760       static char *last_objfile_name = NULL;
01761 
01762       if (last_objfile_name == NULL
01763           || strcmp (last_objfile_name, objfile_name (objfile)) != 0)
01764         {
01765           xfree (last_objfile_name);
01766           last_objfile_name = xstrdup (objfile_name (objfile));
01767           fprintf_unfiltered (gdb_stdlog,
01768                               "Creating one or more psymtabs for objfile %s ...\n",
01769                               last_objfile_name);
01770         }
01771       fprintf_unfiltered (gdb_stdlog,
01772                           "Created psymtab %s for module %s.\n",
01773                           host_address_to_string (psymtab), filename);
01774     }
01775 
01776   return (psymtab);
01777 }
01778 
01779 void
01780 discard_psymtab (struct objfile *objfile, struct partial_symtab *pst)
01781 {
01782   struct partial_symtab **prev_pst;
01783 
01784   /* From dbxread.c:
01785      Empty psymtabs happen as a result of header files which don't
01786      have any symbols in them.  There can be a lot of them.  But this
01787      check is wrong, in that a psymtab with N_SLINE entries but
01788      nothing else is not empty, but we don't realize that.  Fixing
01789      that without slowing things down might be tricky.  */
01790 
01791   /* First, snip it out of the psymtab chain.  */
01792 
01793   prev_pst = &(objfile->psymtabs);
01794   while ((*prev_pst) != pst)
01795     prev_pst = &((*prev_pst)->next);
01796   (*prev_pst) = pst->next;
01797 
01798   /* Next, put it on a free list for recycling.  */
01799 
01800   pst->next = objfile->free_psymtabs;
01801   objfile->free_psymtabs = pst;
01802 }
01803 
01804 /* An object of this type is passed to discard_psymtabs_upto.  */
01805 
01806 struct psymtab_state
01807 {
01808   /* The objfile where psymtabs are discarded.  */
01809 
01810   struct objfile *objfile;
01811 
01812   /* The first psymtab to save.  */
01813 
01814   struct partial_symtab *save;
01815 };
01816 
01817 /* A cleanup function used by make_cleanup_discard_psymtabs.  */
01818 
01819 static void
01820 discard_psymtabs_upto (void *arg)
01821 {
01822   struct psymtab_state *state = arg;
01823 
01824   while (state->objfile->psymtabs != state->save)
01825     discard_psymtab (state->objfile, state->objfile->psymtabs);
01826 }
01827 
01828 /* Return a new cleanup that discards all psymtabs created in OBJFILE
01829    after this function is called.  */
01830 
01831 struct cleanup *
01832 make_cleanup_discard_psymtabs (struct objfile *objfile)
01833 {
01834   struct psymtab_state *state = XNEW (struct psymtab_state);
01835 
01836   state->objfile = objfile;
01837   state->save = objfile->psymtabs;
01838 
01839   return make_cleanup_dtor (discard_psymtabs_upto, state, xfree);
01840 }
01841 
01842 
01843 
01844 static void
01845 maintenance_print_psymbols (char *args, int from_tty)
01846 {
01847   char **argv;
01848   struct ui_file *outfile;
01849   struct cleanup *cleanups;
01850   char *symname = NULL;
01851   char *filename = DEV_TTY;
01852   struct objfile *objfile;
01853   struct partial_symtab *ps;
01854 
01855   dont_repeat ();
01856 
01857   if (args == NULL)
01858     {
01859       error (_("\
01860 print-psymbols takes an output file name and optional symbol file name"));
01861     }
01862   argv = gdb_buildargv (args);
01863   cleanups = make_cleanup_freeargv (argv);
01864 
01865   if (argv[0] != NULL)
01866     {
01867       filename = argv[0];
01868       /* If a second arg is supplied, it is a source file name to match on.  */
01869       if (argv[1] != NULL)
01870         {
01871           symname = argv[1];
01872         }
01873     }
01874 
01875   filename = tilde_expand (filename);
01876   make_cleanup (xfree, filename);
01877 
01878   outfile = gdb_fopen (filename, FOPEN_WT);
01879   if (outfile == 0)
01880     perror_with_name (filename);
01881   make_cleanup_ui_file_delete (outfile);
01882 
01883   ALL_PSYMTABS (objfile, ps)
01884     {
01885       QUIT;
01886       if (symname == NULL || filename_cmp (symname, ps->filename) == 0)
01887         dump_psymtab (objfile, ps, outfile);
01888     }
01889   do_cleanups (cleanups);
01890 }
01891 
01892 /* List all the partial symbol tables whose names match REGEXP (optional).  */
01893 static void
01894 maintenance_info_psymtabs (char *regexp, int from_tty)
01895 {
01896   struct program_space *pspace;
01897   struct objfile *objfile;
01898 
01899   if (regexp)
01900     re_comp (regexp);
01901 
01902   ALL_PSPACES (pspace)
01903     ALL_PSPACE_OBJFILES (pspace, objfile)
01904     {
01905       struct gdbarch *gdbarch = get_objfile_arch (objfile);
01906       struct partial_symtab *psymtab;
01907 
01908       /* We don't want to print anything for this objfile until we
01909          actually find a symtab whose name matches.  */
01910       int printed_objfile_start = 0;
01911 
01912       ALL_OBJFILE_PSYMTABS_REQUIRED (objfile, psymtab)
01913         {
01914           QUIT;
01915 
01916           if (! regexp
01917               || re_exec (psymtab->filename))
01918             {
01919               if (! printed_objfile_start)
01920                 {
01921                   printf_filtered ("{ objfile %s ", objfile_name (objfile));
01922                   wrap_here ("  ");
01923                   printf_filtered ("((struct objfile *) %s)\n", 
01924                                    host_address_to_string (objfile));
01925                   printed_objfile_start = 1;
01926                 }
01927 
01928               printf_filtered ("  { psymtab %s ", psymtab->filename);
01929               wrap_here ("    ");
01930               printf_filtered ("((struct partial_symtab *) %s)\n", 
01931                                host_address_to_string (psymtab));
01932 
01933               printf_filtered ("    readin %s\n",
01934                                psymtab->readin ? "yes" : "no");
01935               printf_filtered ("    fullname %s\n",
01936                                psymtab->fullname
01937                                ? psymtab->fullname : "(null)");
01938               printf_filtered ("    text addresses ");
01939               fputs_filtered (paddress (gdbarch, psymtab->textlow),
01940                               gdb_stdout);
01941               printf_filtered (" -- ");
01942               fputs_filtered (paddress (gdbarch, psymtab->texthigh),
01943                               gdb_stdout);
01944               printf_filtered ("\n");
01945               printf_filtered ("    psymtabs_addrmap_supported %s\n",
01946                                (psymtab->psymtabs_addrmap_supported
01947                                 ? "yes" : "no"));
01948               printf_filtered ("    globals ");
01949               if (psymtab->n_global_syms)
01950                 {
01951                   printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n",
01952                                    host_address_to_string (objfile->global_psymbols.list
01953                                     + psymtab->globals_offset),
01954                                    psymtab->n_global_syms);
01955                 }
01956               else
01957                 printf_filtered ("(none)\n");
01958               printf_filtered ("    statics ");
01959               if (psymtab->n_static_syms)
01960                 {
01961                   printf_filtered ("(* (struct partial_symbol **) %s @ %d)\n",
01962                                    host_address_to_string (objfile->static_psymbols.list
01963                                     + psymtab->statics_offset),
01964                                    psymtab->n_static_syms);
01965                 }
01966               else
01967                 printf_filtered ("(none)\n");
01968               printf_filtered ("    dependencies ");
01969               if (psymtab->number_of_dependencies)
01970                 {
01971                   int i;
01972 
01973                   printf_filtered ("{\n");
01974                   for (i = 0; i < psymtab->number_of_dependencies; i++)
01975                     {
01976                       struct partial_symtab *dep = psymtab->dependencies[i];
01977 
01978                       /* Note the string concatenation there --- no comma.  */
01979                       printf_filtered ("      psymtab %s "
01980                                        "((struct partial_symtab *) %s)\n",
01981                                        dep->filename, 
01982                                        host_address_to_string (dep));
01983                     }
01984                   printf_filtered ("    }\n");
01985                 }
01986               else
01987                 printf_filtered ("(none)\n");
01988               printf_filtered ("  }\n");
01989             }
01990         }
01991 
01992       if (printed_objfile_start)
01993         printf_filtered ("}\n");
01994     }
01995 }
01996 
01997 /* Check consistency of currently expanded psymtabs vs symtabs.  */
01998 
01999 static void
02000 maintenance_check_psymtabs (char *ignore, int from_tty)
02001 {
02002   struct symbol *sym;
02003   struct partial_symbol **psym;
02004   struct symtab *s = NULL;
02005   struct partial_symtab *ps;
02006   struct blockvector *bv;
02007   struct objfile *objfile;
02008   struct block *b;
02009   int length;
02010 
02011   ALL_PSYMTABS (objfile, ps)
02012   {
02013     struct gdbarch *gdbarch = get_objfile_arch (objfile);
02014 
02015     /* We don't call psymtab_to_symtab here because that may cause symtab
02016        expansion.  When debugging a problem it helps if checkers leave
02017        things unchanged.  */
02018     s = ps->symtab;
02019 
02020     /* First do some checks that don't require the associated symtab.  */
02021     if (ps->texthigh < ps->textlow)
02022       {
02023         printf_filtered ("Psymtab ");
02024         puts_filtered (ps->filename);
02025         printf_filtered (" covers bad range ");
02026         fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout);
02027         printf_filtered (" - ");
02028         fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout);
02029         printf_filtered ("\n");
02030         continue;
02031       }
02032 
02033     /* Now do checks requiring the associated symtab.  */
02034     if (s == NULL)
02035       continue;
02036     bv = BLOCKVECTOR (s);
02037     b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
02038     psym = objfile->static_psymbols.list + ps->statics_offset;
02039     length = ps->n_static_syms;
02040     while (length--)
02041       {
02042         sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
02043                                    SYMBOL_DOMAIN (*psym));
02044         if (!sym)
02045           {
02046             printf_filtered ("Static symbol `");
02047             puts_filtered (SYMBOL_LINKAGE_NAME (*psym));
02048             printf_filtered ("' only found in ");
02049             puts_filtered (ps->filename);
02050             printf_filtered (" psymtab\n");
02051           }
02052         psym++;
02053       }
02054     b = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
02055     psym = objfile->global_psymbols.list + ps->globals_offset;
02056     length = ps->n_global_syms;
02057     while (length--)
02058       {
02059         sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
02060                                    SYMBOL_DOMAIN (*psym));
02061         if (!sym)
02062           {
02063             printf_filtered ("Global symbol `");
02064             puts_filtered (SYMBOL_LINKAGE_NAME (*psym));
02065             printf_filtered ("' only found in ");
02066             puts_filtered (ps->filename);
02067             printf_filtered (" psymtab\n");
02068           }
02069         psym++;
02070       }
02071     if (ps->texthigh != 0
02072         && (ps->textlow < BLOCK_START (b) || ps->texthigh > BLOCK_END (b)))
02073       {
02074         printf_filtered ("Psymtab ");
02075         puts_filtered (ps->filename);
02076         printf_filtered (" covers ");
02077         fputs_filtered (paddress (gdbarch, ps->textlow), gdb_stdout);
02078         printf_filtered (" - ");
02079         fputs_filtered (paddress (gdbarch, ps->texthigh), gdb_stdout);
02080         printf_filtered (" but symtab covers only ");
02081         fputs_filtered (paddress (gdbarch, BLOCK_START (b)), gdb_stdout);
02082         printf_filtered (" - ");
02083         fputs_filtered (paddress (gdbarch, BLOCK_END (b)), gdb_stdout);
02084         printf_filtered ("\n");
02085       }
02086   }
02087 }
02088 
02089 
02090 
02091 void
02092 expand_partial_symbol_names (int (*fun) (const char *, void *),
02093                              void *data)
02094 {
02095   struct objfile *objfile;
02096 
02097   ALL_OBJFILES (objfile)
02098   {
02099     if (objfile->sf)
02100       objfile->sf->qf->expand_symtabs_matching (objfile, NULL, fun,
02101                                                 ALL_DOMAIN, data);
02102   }
02103 }
02104 
02105 void
02106 map_partial_symbol_filenames (symbol_filename_ftype *fun, void *data,
02107                               int need_fullname)
02108 {
02109   struct objfile *objfile;
02110 
02111   ALL_OBJFILES (objfile)
02112   {
02113     if (objfile->sf)
02114       objfile->sf->qf->map_symbol_filenames (objfile, fun, data,
02115                                              need_fullname);
02116   }
02117 }
02118 
02119 extern initialize_file_ftype _initialize_psymtab;
02120 
02121 void
02122 _initialize_psymtab (void)
02123 {
02124   add_cmd ("psymbols", class_maintenance, maintenance_print_psymbols, _("\
02125 Print dump of current partial symbol definitions.\n\
02126 Entries in the partial symbol table are dumped to file OUTFILE.\n\
02127 If a SOURCE file is specified, dump only that file's partial symbols."),
02128            &maintenanceprintlist);
02129 
02130   add_cmd ("psymtabs", class_maintenance, maintenance_info_psymtabs, _("\
02131 List the partial symbol tables for all object files.\n\
02132 This does not include information about individual partial symbols,\n\
02133 just the symbol table structures themselves."),
02134            &maintenanceinfolist);
02135 
02136   add_cmd ("check-psymtabs", class_maintenance, maintenance_check_psymtabs,
02137            _("\
02138 Check consistency of currently expanded psymtabs versus symtabs."),
02139            &maintenancelist);
02140 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines