*** empty log message ***
[binutils-gdb.git] / gdb / psymtab.c
index 0645dd69f2f0c30a262cfa53790b15e02ff6462b..b1a7fc9581fa5d0252ed320619d420735b0d482d 100644 (file)
 #define DEV_TTY "/dev/tty"
 #endif
 
+struct psymbol_bcache
+{
+  struct bcache *bcache;
+};
+
 /* A fast way to get from a psymtab to its symtab (after the first time).  */
 #define PSYMTAB_TO_SYMTAB(pst)  \
     ((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
@@ -236,6 +241,7 @@ find_pc_sect_psymtab (struct objfile *objfile, CORE_ADDR pc,
          if (overlay_debugging && msymbol && section)
            {
              struct partial_symbol *p;
+
              /* NOTE: This assumes that every psymbol has a
                 corresponding msymbol, which is not necessarily
                 true; the debug info might be much richer than the
@@ -420,10 +426,24 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
   return NULL;
 }
 
+static struct symbol *
+expand_one_symtab_matching_psymtabs (struct objfile *objfile,
+                                    int kind, const char *name,
+                                    domain_enum domain,
+                                    struct symbol *(*matcher) (struct symtab *,
+                                                               int,
+                                                               const char *,
+                                                               domain_enum,
+                                                               void *),
+                                    void *data)
+{
+  return NULL;
+}
+
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
    Check the global symbols if GLOBAL, the static symbols if not. */
 
-struct partial_symbol *
+static struct partial_symbol *
 lookup_partial_symbol (struct partial_symtab *pst, const char *name,
                       int global, domain_enum domain)
 {
@@ -518,6 +538,7 @@ psymtab_to_symtab (struct partial_symtab *pst)
   if (!pst->readin)
     {
       struct cleanup *back_to = increment_reading_symtab ();
+
       (*pst->read_symtab) (pst);
       do_cleanups (back_to);
     }
@@ -569,6 +590,7 @@ find_last_source_symtab_from_partial (struct objfile *ofp)
     {
       const char *name = ps->filename;
       int len = strlen (name);
+
       if (!(len > 2 && (strcmp (&name[len - 2], ".h") == 0
                        || strcmp (name, "<<C++-namespaces>>") == 0)))
        cs_pst = ps;
@@ -768,6 +790,7 @@ print_psymtab_stats_for_objfile (struct objfile *objfile)
 {
   int i;
   struct partial_symtab *ps;
+
   i = 0;
   ALL_OBJFILE_PSYMTABS (objfile, ps)
     {
@@ -854,6 +877,7 @@ map_symbol_names_psymtab (struct objfile *objfile,
                          void (*fun) (const char *, void *), void *data)
 {
   struct partial_symtab *ps;
+
   ALL_OBJFILE_PSYMTABS (objfile, ps)
     {
       struct partial_symbol **psym;
@@ -900,7 +924,7 @@ map_symbol_filenames_psymtab (struct objfile *objfile,
        continue;
 
       fullname = psymtab_to_fullname (ps);
-      (*fun) (fullname, ps->filename, data);
+      (*fun) (ps->filename, fullname, data);
     }
 }
 
@@ -936,7 +960,7 @@ psymtab_to_fullname (struct partial_symtab *ps)
   return NULL;
 }
 
-static char *
+static const char *
 find_symbol_file_from_partial (struct objfile *objfile, const char *name)
 {
   struct partial_symtab *pst;
@@ -991,12 +1015,14 @@ ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name,
       if (global)
         {
           int U;
+
           i = 0;
           U = length - 1;
           while (U - i > 4)
             {
               int M = (U + i) >> 1;
               struct partial_symbol *psym = start[M];
+
               if (SYMBOL_LINKAGE_NAME (psym)[0] < name[0])
                 i = M + 1;
               else if (SYMBOL_LINKAGE_NAME (psym)[0] > name[0])
@@ -1035,12 +1061,14 @@ ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name,
       if (global)
         {
           int U;
+
           i = 0;
           U = length - 1;
           while (U - i > 4)
             {
               int M = (U + i) >> 1;
               struct partial_symbol *psym = start[M];
+
               if (SYMBOL_LINKAGE_NAME (psym)[0] < '_')
                 i = M + 1;
               else if (SYMBOL_LINKAGE_NAME (psym)[0] > '_')
@@ -1106,6 +1134,7 @@ map_ada_symtabs (struct objfile *objfile,
                                        wild_match, is_name_suffix))
        {
          struct symtab *s = PSYMTAB_TO_SYMTAB (ps);
+
          if (s == NULL || !s->primary)
            continue;
          (*callback) (objfile, s, data);
@@ -1189,6 +1218,7 @@ const struct quick_symbol_functions psym_functions =
   forget_cached_source_info_partial,
   lookup_symtab_via_partial_symtab,
   lookup_symbol_aux_psymtabs,
+  expand_one_symtab_matching_psymtabs,
   print_psymtab_stats_for_objfile,
   dump_psymtabs_for_objfile,
   relocate_psymtabs,
@@ -1251,6 +1281,92 @@ start_psymtab_common (struct objfile *objfile,
   return (psymtab);
 }
 
+/* Calculate a hash code for the given partial symbol.  The hash is
+   calculated using the symbol's value, language, domain, class
+   and name. These are the values which are set by
+   add_psymbol_to_bcache.  */
+
+static unsigned long
+psymbol_hash (const void *addr, int length)
+{
+  unsigned long h = 0;
+  struct partial_symbol *psymbol = (struct partial_symbol *) addr;
+  unsigned int lang = psymbol->ginfo.language;
+  unsigned int domain = PSYMBOL_DOMAIN (psymbol);
+  unsigned int class = PSYMBOL_CLASS (psymbol);
+
+  h = hash_continue (&psymbol->ginfo.value, sizeof (psymbol->ginfo.value), h);
+  h = hash_continue (&lang, sizeof (unsigned int), h);
+  h = hash_continue (&domain, sizeof (unsigned int), h);
+  h = hash_continue (&class, sizeof (unsigned int), h);
+  h = hash_continue (psymbol->ginfo.name, strlen (psymbol->ginfo.name), h);
+
+  return h;
+}
+
+/* Returns true if the symbol at addr1 equals the symbol at addr2.
+   For the comparison this function uses a symbols value,
+   language, domain, class and name.  */
+
+static int
+psymbol_compare (const void *addr1, const void *addr2, int length)
+{
+  struct partial_symbol *sym1 = (struct partial_symbol *) addr1;
+  struct partial_symbol *sym2 = (struct partial_symbol *) addr2;
+
+  return (memcmp (&sym1->ginfo.value, &sym1->ginfo.value,
+                  sizeof (sym1->ginfo.value)) == 0
+         && sym1->ginfo.language == sym2->ginfo.language
+          && PSYMBOL_DOMAIN (sym1) == PSYMBOL_DOMAIN (sym2)
+          && PSYMBOL_CLASS (sym1) == PSYMBOL_CLASS (sym2)
+          && sym1->ginfo.name == sym2->ginfo.name);
+}
+
+/* Initialize a partial symbol bcache.  */
+
+struct psymbol_bcache *
+psymbol_bcache_init (void)
+{
+  struct psymbol_bcache *bcache = XCALLOC (1, struct psymbol_bcache);
+  bcache->bcache = bcache_xmalloc (psymbol_hash, psymbol_compare);
+  return bcache;
+}
+
+/* Free a partial symbol bcache.  */
+void
+psymbol_bcache_free (struct psymbol_bcache *bcache)
+{
+  if (bcache == NULL)
+    return;
+
+  bcache_xfree (bcache->bcache);
+  xfree (bcache);
+}
+
+/* Return the internal bcache of the psymbol_bcache BCACHE*/
+
+struct bcache *
+psymbol_bcache_get_bcache (struct psymbol_bcache *bcache)
+{
+  return bcache->bcache;
+}
+
+/* Find a copy of the SYM in BCACHE.  If BCACHE has never seen this
+   symbol before, add a copy to BCACHE.  In either case, return a pointer
+   to BCACHE's copy of the symbol.  If optional ADDED is not NULL, return
+   1 in case of new entry or 0 if returning an old entry.  */
+
+static const struct partial_symbol *
+psymbol_bcache_full (struct partial_symbol *sym,
+                     struct psymbol_bcache *bcache,
+                     int *added)
+{
+  return bcache_full (sym,
+                      sizeof (struct partial_symbol),
+                      bcache->bcache,
+                      added);
+}
+
 /* Helper function, initialises partial symbol structure and stashes 
    it into objfile's bcache.  Note that our caching mechanism will
    use all fields of struct partial_symbol to determine hash value of the
@@ -1266,15 +1382,8 @@ add_psymbol_to_bcache (char *name, int namelength, int copy_name,
                       enum language language, struct objfile *objfile,
                       int *added)
 {
-  /* psymbol is static so that there will be no uninitialized gaps in the
-     structure which might contain random data, causing cache misses in
-     bcache. */
-  static struct partial_symbol psymbol;
-
-  /* However, we must ensure that the entire 'value' field has been
-     zeroed before assigning to it, because an assignment may not
-     write the entire field.  */
-  memset (&psymbol.ginfo.value, 0, sizeof (psymbol.ginfo.value));
+  struct partial_symbol psymbol;
+
   /* val and coreaddr are mutually exclusive, one of them *will* be zero */
   if (val != 0)
     {
@@ -1285,15 +1394,16 @@ add_psymbol_to_bcache (char *name, int namelength, int copy_name,
       SYMBOL_VALUE_ADDRESS (&psymbol) = coreaddr;
     }
   SYMBOL_SECTION (&psymbol) = 0;
-  SYMBOL_LANGUAGE (&psymbol) = language;
+  SYMBOL_SET_LANGUAGE (&psymbol, language);
   PSYMBOL_DOMAIN (&psymbol) = domain;
   PSYMBOL_CLASS (&psymbol) = class;
 
   SYMBOL_SET_NAMES (&psymbol, name, namelength, copy_name, objfile);
 
   /* Stash the partial symbol away in the cache */
-  return bcache_full (&psymbol, sizeof (struct partial_symbol),
-                     objfile->psymbol_cache, added);
+  return psymbol_bcache_full (&psymbol,
+                              objfile->psymbol_cache,
+                              added);
 }
 
 /* Helper function, adds partial symbol to the given partial symbol
@@ -1456,6 +1566,7 @@ extend_psymbol_list (struct psymbol_allocation_list *listp,
                     struct objfile *objfile)
 {
   int new_size;
+
   if (listp->size == 0)
     {
       new_size = 255;
@@ -1641,6 +1752,7 @@ maintenance_check_symtabs (char *ignore, int from_tty)
   ALL_PSYMTABS (objfile, ps)
   {
     struct gdbarch *gdbarch = get_objfile_arch (objfile);
+
     s = PSYMTAB_TO_SYMTAB (ps);
     if (s == NULL)
       continue;