PR c++/15176:
[deliverable/binutils-gdb.git] / gdb / minsyms.c
index b054e3ff9874ee7a6b9dda953b4cfd815b7bbe06..89e538af0ec50333eda1fffeaf827ea60a997c8f 100644 (file)
@@ -1,7 +1,5 @@
 /* GDB routines for manipulating the minimal symbol tables.
-   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 1992-2013 Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
    This file is part of GDB.
@@ -52,6 +50,7 @@
 #include "target.h"
 #include "cp-support.h"
 #include "language.h"
+#include "cli/cli-utils.h"
 
 /* Accumulate the minimal symbols for each objfile in bunches of BUNCH_SIZE.
    At the end, copy them all into one newly allocated location on an objfile's
@@ -78,7 +77,7 @@ static int msym_bunch_index;
 
 static int msym_count;
 
-/* Compute a hash code based using the same criteria as `strcmp_iw'.  */
+/* See minsyms.h.  */
 
 unsigned int
 msymbol_hash_iw (const char *string)
@@ -87,18 +86,17 @@ msymbol_hash_iw (const char *string)
 
   while (*string && *string != '(')
     {
-      while (isspace (*string))
-       ++string;
+      string = skip_spaces_const (string);
       if (*string && *string != '(')
        {
-         hash = hash * 67 + *string - 113;
+         hash = SYMBOL_HASH_NEXT (hash, *string);
          ++string;
        }
     }
   return hash;
 }
 
-/* Compute a hash code for a string.  */
+/* See minsyms.h.  */
 
 unsigned int
 msymbol_hash (const char *string)
@@ -106,12 +104,12 @@ msymbol_hash (const char *string)
   unsigned int hash = 0;
 
   for (; *string; ++string)
-    hash = hash * 67 + *string - 113;
+    hash = SYMBOL_HASH_NEXT (hash, *string);
   return hash;
 }
 
 /* Add the minimal symbol SYM to an objfile's minsym hash table, TABLE.  */
-void
+static void
 add_minsym_to_hash_table (struct minimal_symbol *sym,
                          struct minimal_symbol **table)
 {
@@ -141,8 +139,8 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
     }
 }
 
+/* See minsyms.h.  */
 
-/* Return OBJFILE where minimal symbol SYM is defined.  */
 struct objfile *
 msymbol_objfile (struct minimal_symbol *sym)
 {
@@ -239,11 +237,16 @@ lookup_minimal_symbol (const char *name, const char *sfile,
 
                  if (pass == 1)
                    {
-                     match = strcmp (SYMBOL_LINKAGE_NAME (msymbol),
-                                     modified_name) == 0;
+                     int (*cmp) (const char *, const char *);
+
+                     cmp = (case_sensitivity == case_sensitive_on
+                            ? strcmp : strcasecmp);
+                     match = cmp (SYMBOL_LINKAGE_NAME (msymbol),
+                                  modified_name) == 0;
                    }
                  else
                    {
+                     /* The function respects CASE_SENSITIVITY.  */
                      match = SYMBOL_MATCHES_SEARCH_NAME (msymbol,
                                                          modified_name);
                    }
@@ -305,12 +308,41 @@ lookup_minimal_symbol (const char *name, const char *sfile,
   return NULL;
 }
 
-/* Look through all the current minimal symbol tables and find the
-   first minimal symbol that matches NAME and has text type.  If OBJF
-   is non-NULL, limit the search to that objfile.  Returns a pointer
-   to the minimal symbol that matches, or NULL if no match is found.
+/* See minsyms.h.  */
 
-   This function only searches the mangled (linkage) names.  */
+void
+iterate_over_minimal_symbols (struct objfile *objf, const char *name,
+                             void (*callback) (struct minimal_symbol *,
+                                               void *),
+                             void *user_data)
+{
+  unsigned int hash;
+  struct minimal_symbol *iter;
+  int (*cmp) (const char *, const char *);
+
+  /* The first pass is over the ordinary hash table.  */
+  hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+  iter = objf->msymbol_hash[hash];
+  cmp = (case_sensitivity == case_sensitive_on ? strcmp : strcasecmp);
+  while (iter)
+    {
+      if (cmp (SYMBOL_LINKAGE_NAME (iter), name) == 0)
+       (*callback) (iter, user_data);
+      iter = iter->hash_next;
+    }
+
+  /* The second pass is over the demangled table.  */
+  hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
+  iter = objf->msymbol_demangled_hash[hash];
+  while (iter)
+    {
+      if (SYMBOL_MATCHES_SEARCH_NAME (iter, name))
+       (*callback) (iter, user_data);
+      iter = iter->demangled_hash_next;
+    }
+}
+
+/* See minsyms.h.  */
 
 struct minimal_symbol *
 lookup_minimal_symbol_text (const char *name, struct objfile *objf)
@@ -362,10 +394,7 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
   return NULL;
 }
 
-/* Look through all the current minimal symbol tables and find the
-   first minimal symbol that matches NAME and PC.  If OBJF is non-NULL,
-   limit the search to that objfile.  Returns a pointer to the minimal
-   symbol that matches, or NULL if no match is found.  */
+/* See minsyms.h.  */
 
 struct minimal_symbol *
 lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
@@ -397,13 +426,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
   return NULL;
 }
 
-/* Look through all the current minimal symbol tables and find the
-   first minimal symbol that matches NAME and is a solib trampoline.
-   If OBJF is non-NULL, limit the search to that objfile.  Returns a
-   pointer to the minimal symbol that matches, or NULL if no match is
-   found.
-
-   This function only searches the mangled (linkage) names.  */
+/* See minsyms.h.  */
 
 struct minimal_symbol *
 lookup_minimal_symbol_solib_trampoline (const char *name,
@@ -451,7 +474,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
    there are text and trampoline symbols at the same address.
    Otherwise prefer mst_text symbols.  */
 
-static struct minimal_symbol *
+static struct bound_minimal_symbol
 lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
                                       struct obj_section *section,
                                       int want_trampoline)
@@ -462,6 +485,8 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
   struct minimal_symbol *best_symbol = NULL;
+  struct objfile *best_objfile = NULL;
+  struct bound_minimal_symbol result;
   enum minimal_symbol_type want_type, other_type;
 
   want_type = want_trampoline ? mst_solib_trampoline : mst_text;
@@ -568,9 +593,10 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
                      /* Some types of debug info, such as COFF,
                         don't fill the bfd_section member, so don't
                         throw away symbols on those platforms.  */
-                     && SYMBOL_OBJ_SECTION (&msymbol[hi]) != NULL
+                     && SYMBOL_OBJ_SECTION (objfile, &msymbol[hi]) != NULL
                      && (!matching_obj_sections
-                         (SYMBOL_OBJ_SECTION (&msymbol[hi]), section)))
+                         (SYMBOL_OBJ_SECTION (objfile, &msymbol[hi]),
+                          section)))
                    {
                      hi--;
                      continue;
@@ -578,7 +604,7 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
 
                  /* If we are looking for a trampoline and this is a
                     text symbol, or the other way around, check the
-                    preceeding symbol too.  If they are otherwise
+                    preceding symbol too.  If they are otherwise
                     identical prefer that one.  */
                  if (hi > 0
                      && MSYMBOL_TYPE (&msymbol[hi]) == other_type
@@ -587,8 +613,8 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
                          == MSYMBOL_SIZE (&msymbol[hi - 1]))
                      && (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
                          == SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1]))
-                     && (SYMBOL_OBJ_SECTION (&msymbol[hi])
-                         == SYMBOL_OBJ_SECTION (&msymbol[hi - 1])))
+                     && (SYMBOL_OBJ_SECTION (objfile, &msymbol[hi])
+                         == SYMBOL_OBJ_SECTION (objfile, &msymbol[hi - 1])))
                    {
                      hi--;
                      continue;
@@ -667,14 +693,18 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
                       SYMBOL_VALUE_ADDRESS (&msymbol[hi]))))
                {
                  best_symbol = &msymbol[hi];
+                 best_objfile = objfile;
                }
            }
        }
     }
-  return (best_symbol);
+
+  result.minsym = best_symbol;
+  result.objfile = best_objfile;
+  return result;
 }
 
-struct minimal_symbol *
+struct bound_minimal_symbol
 lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, struct obj_section *section)
 {
   if (section == NULL)
@@ -684,18 +714,31 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, struct obj_section *section)
         debugging) always returns NULL making the call somewhat useless.  */
       section = find_pc_section (pc);
       if (section == NULL)
-       return NULL;
+       {
+         struct bound_minimal_symbol result;
+
+         memset (&result, 0, sizeof (result));
+         return result;
+       }
     }
   return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0);
 }
 
-/* Backward compatibility: search through the minimal symbol table 
-   for a matching PC (no section given).  */
+/* See minsyms.h.  */
 
-struct minimal_symbol *
+struct bound_minimal_symbol
 lookup_minimal_symbol_by_pc (CORE_ADDR pc)
 {
-  return lookup_minimal_symbol_by_pc_section (pc, NULL);
+  struct obj_section *section = find_pc_section (pc);
+
+  if (section == NULL)
+    {
+      struct bound_minimal_symbol result;
+
+      memset (&result, 0, sizeof (result));
+      return result;
+    }
+  return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0);
 }
 
 /* Return non-zero iff PC is in an STT_GNU_IFUNC function resolver.  */
@@ -703,9 +746,9 @@ lookup_minimal_symbol_by_pc (CORE_ADDR pc)
 int
 in_gnu_ifunc_stub (CORE_ADDR pc)
 {
-  struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
+  struct bound_minimal_symbol msymbol = lookup_minimal_symbol_by_pc (pc);
 
-  return msymbol && MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc;
+  return msymbol.minsym && MSYMBOL_TYPE (msymbol.minsym) == mst_text_gnu_ifunc;
 }
 
 /* See elf_gnu_ifunc_resolve_addr for its real implementation.  */
@@ -761,15 +804,12 @@ static const struct gnu_ifunc_fns stub_gnu_ifunc_fns =
 
 const struct gnu_ifunc_fns *gnu_ifunc_fns_p = &stub_gnu_ifunc_fns;
 
-/* Find the minimal symbol named NAME, and return both the minsym
-   struct and its objfile.  This only checks the linkage name.  Sets
-   *OBJFILE_P and returns the minimal symbol, if it is found.  If it
-   is not found, returns NULL.  */
+/* See minsyms.h.  */
 
-struct minimal_symbol *
-lookup_minimal_symbol_and_objfile (const char *name,
-                                  struct objfile **objfile_p)
+struct bound_minimal_symbol
+lookup_minimal_symbol_and_objfile (const char *name)
 {
+  struct bound_minimal_symbol result;
   struct objfile *objfile;
   unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
 
@@ -783,13 +823,15 @@ lookup_minimal_symbol_and_objfile (const char *name,
        {
          if (strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0)
            {
-             *objfile_p = objfile;
-             return msym;
+             result.minsym = msym;
+             result.objfile = objfile;
+             return result;
            }
        }
     }
 
-  return 0;
+  memset (&result, 0, sizeof (result));
+  return result;
 }
 \f
 
@@ -808,18 +850,21 @@ get_symbol_leading_char (bfd *abfd)
   return 0;
 }
 
-/* Prepare to start collecting minimal symbols.  Note that presetting
-   msym_bunch_index to BUNCH_SIZE causes the first call to save a minimal
-   symbol to allocate the memory for the first bunch.  */
+/* See minsyms.h.  */
 
 void
 init_minimal_symbol_collection (void)
 {
   msym_count = 0;
   msym_bunch = NULL;
+  /* Note that presetting msym_bunch_index to BUNCH_SIZE causes the
+     first call to save a minimal symbol to allocate the memory for
+     the first bunch.  */
   msym_bunch_index = BUNCH_SIZE;
 }
 
+/* See minsyms.h.  */
+
 void
 prim_record_minimal_symbol (const char *name, CORE_ADDR address,
                            enum minimal_symbol_type ms_type,
@@ -848,18 +893,16 @@ prim_record_minimal_symbol (const char *name, CORE_ADDR address,
     }
 
   prim_record_minimal_symbol_and_info (name, address, ms_type,
-                                      section, NULL, objfile);
+                                      section, objfile);
 }
 
-/* Record a minimal symbol in the msym bunches.  Returns the symbol
-   newly created.  */
+/* See minsyms.h.  */
 
 struct minimal_symbol *
 prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name,
                                 CORE_ADDR address,
                                 enum minimal_symbol_type ms_type,
                                 int section,
-                                asection *bfd_section,
                                 struct objfile *objfile)
 {
   struct obj_section *obj_section;
@@ -895,28 +938,18 @@ prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name,
       msym_bunch = new;
     }
   msymbol = &msym_bunch->contents[msym_bunch_index];
-  SYMBOL_SET_LANGUAGE (msymbol, language_auto);
+  SYMBOL_SET_LANGUAGE (msymbol, language_auto, &objfile->objfile_obstack);
   SYMBOL_SET_NAMES (msymbol, name, name_len, copy_name, objfile);
 
   SYMBOL_VALUE_ADDRESS (msymbol) = address;
   SYMBOL_SECTION (msymbol) = section;
-  SYMBOL_OBJ_SECTION (msymbol) = NULL;
-
-  /* Find obj_section corresponding to bfd_section.  */
-  if (bfd_section)
-    ALL_OBJFILE_OSECTIONS (objfile, obj_section)
-      {
-       if (obj_section->the_bfd_section == bfd_section)
-         {
-           SYMBOL_OBJ_SECTION (msymbol) = obj_section;
-           break;
-         }
-      }
 
   MSYMBOL_TYPE (msymbol) = ms_type;
   MSYMBOL_TARGET_FLAG_1 (msymbol) = 0;
   MSYMBOL_TARGET_FLAG_2 (msymbol) = 0;
-  MSYMBOL_SIZE (msymbol) = 0;
+  /* Do not use the SET_MSYMBOL_SIZE macro to initialize the size,
+     as it would also set the has_size flag.  */
+  msymbol->size = 0;
 
   /* The hash pointers must be cleared! If they're not,
      add_minsym_to_hash_table will NOT add this msymbol to the hash table.  */
@@ -929,19 +962,17 @@ prim_record_minimal_symbol_full (const char *name, int name_len, int copy_name,
   return msymbol;
 }
 
-/* Record a minimal symbol in the msym bunches.  Returns the symbol
-   newly created.  */
+/* See minsyms.h.  */
 
 struct minimal_symbol *
 prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
                                     enum minimal_symbol_type ms_type,
                                     int section,
-                                    asection *bfd_section,
                                     struct objfile *objfile)
 {
   return prim_record_minimal_symbol_full (name, strlen (name), 1,
-                                         address, ms_type, section,
-                                         bfd_section, objfile);
+                                         address, ms_type,
+                                         section, objfile);
 }
 
 /* Compare two minimal symbols by address and return a signed result based
@@ -968,8 +999,8 @@ compare_minimal_symbols (const void *fn1p, const void *fn2p)
   else
     /* addrs are equal: sort by name */
     {
-      char *name1 = SYMBOL_LINKAGE_NAME (fn1);
-      char *name2 = SYMBOL_LINKAGE_NAME (fn2);
+      const char *name1 = SYMBOL_LINKAGE_NAME (fn1);
+      const char *name2 = SYMBOL_LINKAGE_NAME (fn2);
 
       if (name1 && name2)      /* both have names */
        return strcmp (name1, name2);
@@ -1003,6 +1034,8 @@ do_discard_minimal_symbols_cleanup (void *arg)
     }
 }
 
+/* See minsyms.h.  */
+
 struct cleanup *
 make_cleanup_discard_minimal_symbols (void)
 {
@@ -1145,6 +1178,13 @@ install_minimal_symbols (struct objfile *objfile)
 
   if (msym_count > 0)
     {
+      if (symtab_create_debug)
+       {
+         fprintf_unfiltered (gdb_stdlog,
+                             "Installing %d minimal symbols of objfile %s.\n",
+                             msym_count, objfile->name);
+       }
+
       /* Allocate enough space in the obstack, into which we will gather the
          bunches of new and existing minimal symbols, sort them, and then
          compact out the duplicate entries.  Once we have a final table,
@@ -1200,13 +1240,7 @@ install_minimal_symbols (struct objfile *objfile)
          symbol count does *not* include this null symbol, which is why it
          is indexed by mcount and not mcount-1.  */
 
-      SYMBOL_LINKAGE_NAME (&msymbols[mcount]) = NULL;
-      SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0;
-      MSYMBOL_TARGET_FLAG_1 (&msymbols[mcount]) = 0;
-      MSYMBOL_TARGET_FLAG_2 (&msymbols[mcount]) = 0;
-      MSYMBOL_SIZE (&msymbols[mcount]) = 0;
-      MSYMBOL_TYPE (&msymbols[mcount]) = mst_unknown;
-      SYMBOL_SET_LANGUAGE (&msymbols[mcount], language_unknown);
+      memset (&msymbols[mcount], 0, sizeof (struct minimal_symbol));
 
       /* Attach the minimal symbol table to the specified objfile.
          The strings themselves are also located in the objfile_obstack
@@ -1215,29 +1249,6 @@ install_minimal_symbols (struct objfile *objfile)
       objfile->minimal_symbol_count = mcount;
       objfile->msymbols = msymbols;
 
-      /* Try to guess the appropriate C++ ABI by looking at the names 
-        of the minimal symbols in the table.  */
-      {
-       int i;
-
-       for (i = 0; i < mcount; i++)
-         {
-           /* If a symbol's name starts with _Z and was successfully
-              demangled, then we can assume we've found a GNU v3 symbol.
-              For now we set the C++ ABI globally; if the user is
-              mixing ABIs then the user will need to "set cp-abi"
-              manually.  */
-           const char *name = SYMBOL_LINKAGE_NAME (&objfile->msymbols[i]);
-
-           if (name[0] == '_' && name[1] == 'Z'
-               && SYMBOL_DEMANGLED_NAME (&objfile->msymbols[i]) != NULL)
-             {
-               set_cp_abi_as_auto_default ("gnu-v3");
-               break;
-             }
-         }
-      }
-
       /* Now build the hash tables; we can't do this incrementally
          at an earlier point since we weren't finished with the obstack
         yet.  (And if the msymbol obstack gets moved, all the internal
@@ -1246,6 +1257,27 @@ install_minimal_symbols (struct objfile *objfile)
     }
 }
 
+/* See minsyms.h.  */
+
+void
+terminate_minimal_symbol_table (struct objfile *objfile)
+{
+  if (! objfile->msymbols)
+    objfile->msymbols = ((struct minimal_symbol *)
+                         obstack_alloc (&objfile->objfile_obstack,
+                                        sizeof (objfile->msymbols[0])));
+
+  {
+    struct minimal_symbol *m
+      = &objfile->msymbols[objfile->minimal_symbol_count];
+
+    memset (m, 0, sizeof (*m));
+    /* Don't rely on these enumeration values being 0's.  */
+    MSYMBOL_TYPE (m) = mst_unknown;
+    SYMBOL_SET_LANGUAGE (m, language_unknown, &objfile->objfile_obstack);
+  }
+}
+
 /* Sort all the minimal symbols in OBJFILE.  */
 
 void
@@ -1260,18 +1292,19 @@ msymbols_sort (struct objfile *objfile)
    Return minimal symbol for the trampoline entry or NULL if PC is not
    in a trampoline code stub.  */
 
-struct minimal_symbol *
+static struct minimal_symbol *
 lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
 {
   struct obj_section *section = find_pc_section (pc);
-  struct minimal_symbol *msymbol;
+  struct bound_minimal_symbol msymbol;
 
   if (section == NULL)
     return NULL;
   msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section, 1);
 
-  if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
-    return msymbol;
+  if (msymbol.minsym != NULL
+      && MSYMBOL_TYPE (msymbol.minsym) == mst_solib_trampoline)
+    return msymbol.minsym;
   return NULL;
 }
 
This page took 0.032711 seconds and 4 git commands to generate.