2003-11-07 Andrew Cagney <cagney@redhat.com>
[deliverable/binutils-gdb.git] / gdb / minsyms.c
index 36d695acaab0c68ff25e8430f4eed25882ed38c9..afa36b10e2e690c40134c84770cce9bdb73f2ad1 100644 (file)
@@ -1,5 +1,6 @@
 /* GDB routines for manipulating the minimal symbol tables.
-   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+   2002, 2003
    Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
@@ -75,16 +76,6 @@ static int msym_bunch_index;
 
 static int msym_count;
 
-/* Prototypes for local functions. */
-
-static int compare_minimal_symbols (const PTR, const PTR);
-
-static int
-compact_minimal_symbols (struct minimal_symbol *, int, struct objfile *);
-
-static void add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
-                                               struct minimal_symbol **table);
-
 /* Compute a hash code based using the same criteria as `strcmp_iw'.  */
 
 unsigned int
@@ -101,7 +92,7 @@ msymbol_hash_iw (const char *string)
          ++string;
        }
     }
-  return hash % MINIMAL_SYMBOL_HASH_SIZE;
+  return hash;
 }
 
 /* Compute a hash code for a string.  */
@@ -112,7 +103,7 @@ msymbol_hash (const char *string)
   unsigned int hash = 0;
   for (; *string; ++string)
     hash = hash * 67 + *string - 113;
-  return hash % MINIMAL_SYMBOL_HASH_SIZE;
+  return hash;
 }
 
 /* Add the minimal symbol SYM to an objfile's minsym hash table, TABLE.  */
@@ -122,7 +113,8 @@ add_minsym_to_hash_table (struct minimal_symbol *sym,
 {
   if (sym->hash_next == NULL)
     {
-      unsigned int hash = msymbol_hash (SYMBOL_NAME (sym));
+      unsigned int hash
+       = msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
       sym->hash_next = table[hash];
       table[hash] = sym;
     }
@@ -136,7 +128,7 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
 {
   if (sym->demangled_hash_next == NULL)
     {
-      unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym));
+      unsigned int hash = msymbol_hash_iw (SYMBOL_DEMANGLED_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
       sym->demangled_hash_next = table[hash];
       table[hash] = sym;
     }
@@ -145,17 +137,18 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
 
 /* Look through all the current minimal symbol tables and find the
    first minimal symbol that matches NAME.  If OBJF is non-NULL, limit
-   the search to that objfile.  If SFILE is non-NULL, limit the search
-   to that source file.  Returns a pointer to the minimal symbol that
+   the search to that objfile.  If SFILE is non-NULL, the only file-scope
+   symbols considered will be from that source file (global symbols are
+   still preferred).  Returns a pointer to the minimal symbol that
    matches, or NULL if no match is found.
 
    Note:  One instance where there may be duplicate minimal symbols with
    the same name is when the symbol tables for a shared library and the
    symbol tables for an executable contain global symbols with the same
-   names (the dynamic linker deals with the duplication). */
+   names (the dynamic linker deals with the duplication).  */
 
 struct minimal_symbol *
-lookup_minimal_symbol (register const char *name, const char *sfile,
+lookup_minimal_symbol (const char *name, const char *sfile,
                       struct objfile *objf)
 {
   struct objfile *objfile;
@@ -164,8 +157,8 @@ lookup_minimal_symbol (register const char *name, const char *sfile,
   struct minimal_symbol *found_file_symbol = NULL;
   struct minimal_symbol *trampoline_symbol = NULL;
 
-  unsigned int hash = msymbol_hash (name);
-  unsigned int dem_hash = msymbol_hash_iw (name);
+  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+  unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
 
 #ifdef SOFUN_ADDRESS_MAYBE_MISSING
   if (sfile != NULL)
@@ -196,7 +189,15 @@ lookup_minimal_symbol (register const char *name, const char *sfile,
 
             while (msymbol != NULL && found_symbol == NULL)
                {
-                if (SYMBOL_MATCHES_NAME (msymbol, name))
+                 /* FIXME: carlton/2003-02-27: This is an unholy
+                    mixture of linkage names and natural names.  If
+                    you want to test the linkage names with strcmp,
+                    do that.  If you want to test the natural names
+                    with strcmp_iw, use SYMBOL_MATCHES_NATURAL_NAME.  */
+                 if (strcmp (DEPRECATED_SYMBOL_NAME (msymbol), (name)) == 0
+                     || (SYMBOL_DEMANGLED_NAME (msymbol) != NULL
+                         && strcmp_iw (SYMBOL_DEMANGLED_NAME (msymbol),
+                                       (name)) == 0))
                    {
                     switch (MSYMBOL_TYPE (msymbol))
                       {
@@ -204,7 +205,8 @@ lookup_minimal_symbol (register const char *name, const char *sfile,
                       case mst_file_data:
                       case mst_file_bss:
 #ifdef SOFUN_ADDRESS_MAYBE_MISSING
-                        if (sfile == NULL || STREQ (msymbol->filename, sfile))
+                        if (sfile == NULL
+                           || strcmp (msymbol->filename, sfile) == 0)
                           found_file_symbol = msymbol;
 #else
                         /* We have neither the ability nor the need to
@@ -258,30 +260,21 @@ lookup_minimal_symbol (register const char *name, const char *sfile,
 }
 
 /* Look through all the current minimal symbol tables and find the
-   first minimal symbol that matches NAME and of text type.  
-   If OBJF is non-NULL, limit
-   the search to that objfile.  If SFILE is non-NULL, limit the search
-   to that source file.  Returns a pointer to the minimal symbol that
-   matches, or NULL if no match is found.
- */
+   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.
+
+   This function only searches the mangled (linkage) names.  */
 
 struct minimal_symbol *
-lookup_minimal_symbol_text (register const char *name, const char *sfile,
-                           struct objfile *objf)
+lookup_minimal_symbol_text (const char *name, struct objfile *objf)
 {
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
   struct minimal_symbol *found_symbol = NULL;
   struct minimal_symbol *found_file_symbol = NULL;
 
-#ifdef SOFUN_ADDRESS_MAYBE_MISSING
-  if (sfile != NULL)
-    {
-      char *p = strrchr (sfile, '/');
-      if (p != NULL)
-       sfile = p + 1;
-    }
-#endif
+  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
 
   for (objfile = object_files;
        objfile != NULL && found_symbol == NULL;
@@ -289,29 +282,18 @@ lookup_minimal_symbol_text (register const char *name, const char *sfile,
     {
       if (objf == NULL || objf == objfile)
        {
-         for (msymbol = objfile->msymbols;
-              msymbol != NULL && SYMBOL_NAME (msymbol) != NULL &&
-              found_symbol == NULL;
-              msymbol++)
+         for (msymbol = objfile->msymbol_hash[hash];
+              msymbol != NULL && found_symbol == NULL;
+              msymbol = msymbol->hash_next)
            {
-             if (SYMBOL_MATCHES_NAME (msymbol, name) &&
+             if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
                  (MSYMBOL_TYPE (msymbol) == mst_text ||
                   MSYMBOL_TYPE (msymbol) == mst_file_text))
                {
                  switch (MSYMBOL_TYPE (msymbol))
                    {
                    case mst_file_text:
-#ifdef SOFUN_ADDRESS_MAYBE_MISSING
-                     if (sfile == NULL || STREQ (msymbol->filename, sfile))
-                       found_file_symbol = msymbol;
-#else
-                     /* We have neither the ability nor the need to
-                        deal with the SFILE parameter.  If we find
-                        more than one symbol, just return the latest
-                        one (the user can't expect useful behavior in
-                        that case).  */
                      found_file_symbol = msymbol;
-#endif
                      break;
                    default:
                      found_symbol = msymbol;
@@ -333,29 +315,22 @@ lookup_minimal_symbol_text (register const char *name, const char *sfile,
 }
 
 /* Look through all the current minimal symbol tables and find the
-   first minimal symbol that matches NAME and of solib trampoline type.  
-   If OBJF is non-NULL, limit
-   the search to that objfile.  If SFILE is non-NULL, limit the search
-   to that source file.  Returns a pointer to the minimal symbol that
-   matches, or NULL if no match is found.
- */
+   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.  */
 
 struct minimal_symbol *
-lookup_minimal_symbol_solib_trampoline (register const char *name,
-                                       const char *sfile, struct objfile *objf)
+lookup_minimal_symbol_solib_trampoline (const char *name,
+                                       struct objfile *objf)
 {
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
   struct minimal_symbol *found_symbol = NULL;
 
-#ifdef SOFUN_ADDRESS_MAYBE_MISSING
-  if (sfile != NULL)
-    {
-      char *p = strrchr (sfile, '/');
-      if (p != NULL)
-       sfile = p + 1;
-    }
-#endif
+  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
 
   for (objfile = object_files;
        objfile != NULL && found_symbol == NULL;
@@ -363,12 +338,11 @@ lookup_minimal_symbol_solib_trampoline (register const char *name,
     {
       if (objf == NULL || objf == objfile)
        {
-         for (msymbol = objfile->msymbols;
-              msymbol != NULL && SYMBOL_NAME (msymbol) != NULL &&
-              found_symbol == NULL;
-              msymbol++)
+         for (msymbol = objfile->msymbol_hash[hash];
+              msymbol != NULL && found_symbol == NULL;
+              msymbol = msymbol->hash_next)
            {
-             if (SYMBOL_MATCHES_NAME (msymbol, name) &&
+             if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
                  MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
                return msymbol;
            }
@@ -398,13 +372,23 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
   struct minimal_symbol *best_symbol = NULL;
+  struct obj_section *pc_section;
 
   /* pc has to be in a known section. This ensures that anything beyond
      the end of the last segment doesn't appear to be part of the last
      function in the last segment.  */
-  if (find_pc_section (pc) == NULL)
+  pc_section = find_pc_section (pc);
+  if (pc_section == NULL)
     return NULL;
 
+  /* If no section was specified, then just make sure that the PC is in
+     the same section as the minimal symbol we find.  */
+  if (section == NULL)
+    section = pc_section->the_bfd_section;
+
+  /* FIXME drow/2003-07-19: Should we also check that PC is in SECTION
+     if we were passed a non-NULL SECTION argument?  */
+
   for (objfile = object_files;
        objfile != NULL;
        objfile = objfile->next)
@@ -415,8 +399,9 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
          "null symbol".  If there are no real symbols, then there is no
          minimal symbol table at all. */
 
-      if ((msymbol = objfile->msymbols) != NULL)
+      if (objfile->minimal_symbol_count > 0)
        {
+          msymbol = objfile->msymbols;
          lo = 0;
          hi = objfile->minimal_symbol_count - 1;
 
@@ -514,52 +499,6 @@ lookup_minimal_symbol_by_pc (CORE_ADDR pc)
 {
   return lookup_minimal_symbol_by_pc_section (pc, find_pc_mapped_section (pc));
 }
-
-#ifdef SOFUN_ADDRESS_MAYBE_MISSING
-CORE_ADDR
-find_stab_function_addr (char *namestring, char *filename,
-                        struct objfile *objfile)
-{
-  struct minimal_symbol *msym;
-  char *p;
-  int n;
-
-  p = strchr (namestring, ':');
-  if (p == NULL)
-    p = namestring;
-  n = p - namestring;
-  p = alloca (n + 2);
-  strncpy (p, namestring, n);
-  p[n] = 0;
-
-  msym = lookup_minimal_symbol (p, filename, objfile);
-  if (msym == NULL)
-    {
-      /* Sun Fortran appends an underscore to the minimal symbol name,
-         try again with an appended underscore if the minimal symbol
-         was not found.  */
-      p[n] = '_';
-      p[n + 1] = 0;
-      msym = lookup_minimal_symbol (p, filename, objfile);
-    }
-
-  if (msym == NULL && filename != NULL)
-    {
-      /* Try again without the filename. */
-      p[n] = 0;
-      msym = lookup_minimal_symbol (p, NULL, objfile);
-    }
-  if (msym == NULL && filename != NULL)
-    {
-      /* And try again for Sun Fortran, but without the filename. */
-      p[n] = '_';
-      p[n + 1] = 0;
-      msym = lookup_minimal_symbol (p, NULL, objfile);
-    }
-
-  return msym == NULL ? 0 : SYMBOL_VALUE_ADDRESS (msym);
-}
-#endif /* SOFUN_ADDRESS_MAYBE_MISSING */
 \f
 
 /* Return leading symbol character for a BFD. If BFD is NULL,
@@ -629,8 +568,8 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
                                     asection *bfd_section,
                                     struct objfile *objfile)
 {
-  register struct msym_bunch *new;
-  register struct minimal_symbol *msymbol;
+  struct msym_bunch *new;
+  struct minimal_symbol *msymbol;
 
   if (ms_type == mst_file_text)
     {
@@ -648,7 +587,7 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
        const char *tempstring = name;
        if (tempstring[0] == get_symbol_leading_char (objfile->obfd))
          ++tempstring;
-       if (STREQN (tempstring, "__gnu_compiled", 14))
+       if (strncmp (tempstring, "__gnu_compiled", 14) == 0)
          return (NULL);
       }
     }
@@ -661,9 +600,10 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
       msym_bunch = new;
     }
   msymbol = &msym_bunch->contents[msym_bunch_index];
-  SYMBOL_NAME (msymbol) = obsavestring ((char *) name, strlen (name),
-                                       &objfile->symbol_obstack);
   SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown);
+  SYMBOL_LANGUAGE (msymbol) = language_auto;
+  SYMBOL_SET_NAMES (msymbol, (char *)name, strlen (name), objfile);
+
   SYMBOL_VALUE_ADDRESS (msymbol) = address;
   SYMBOL_SECTION (msymbol) = section;
   SYMBOL_BFD_SECTION (msymbol) = bfd_section;
@@ -688,10 +628,10 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
    Within groups with the same address, sort by name.  */
 
 static int
-compare_minimal_symbols (const PTR fn1p, const PTR fn2p)
+compare_minimal_symbols (const void *fn1p, const void *fn2p)
 {
-  register const struct minimal_symbol *fn1;
-  register const struct minimal_symbol *fn2;
+  const struct minimal_symbol *fn1;
+  const struct minimal_symbol *fn2;
 
   fn1 = (const struct minimal_symbol *) fn1p;
   fn2 = (const struct minimal_symbol *) fn2p;
@@ -707,8 +647,8 @@ compare_minimal_symbols (const PTR fn1p, const PTR fn2p)
   else
     /* addrs are equal: sort by name */
     {
-      char *name1 = SYMBOL_NAME (fn1);
-      char *name2 = SYMBOL_NAME (fn2);
+      char *name1 = SYMBOL_LINKAGE_NAME (fn1);
+      char *name2 = SYMBOL_LINKAGE_NAME (fn2);
 
       if (name1 && name2)      /* both have names */
        return strcmp (name1, name2);
@@ -732,7 +672,7 @@ compare_minimal_symbols (const PTR fn1p, const PTR fn2p)
 static void
 do_discard_minimal_symbols_cleanup (void *arg)
 {
-  register struct msym_bunch *next;
+  struct msym_bunch *next;
 
   while (msym_bunch != NULL)
     {
@@ -798,9 +738,10 @@ compact_minimal_symbols (struct minimal_symbol *msymbol, int mcount,
       copyfrom = copyto = msymbol;
       while (copyfrom < msymbol + mcount - 1)
        {
-         if (SYMBOL_VALUE_ADDRESS (copyfrom) ==
-             SYMBOL_VALUE_ADDRESS ((copyfrom + 1)) &&
-             (STREQ (SYMBOL_NAME (copyfrom), SYMBOL_NAME ((copyfrom + 1)))))
+         if (SYMBOL_VALUE_ADDRESS (copyfrom)
+             == SYMBOL_VALUE_ADDRESS ((copyfrom + 1))
+             && strcmp (SYMBOL_LINKAGE_NAME (copyfrom),
+                        SYMBOL_LINKAGE_NAME ((copyfrom + 1))) == 0)
            {
              if (MSYMBOL_TYPE ((copyfrom + 1)) == mst_unknown)
                {
@@ -875,12 +816,12 @@ build_minimal_symbol_hash_tables (struct objfile *objfile)
 void
 install_minimal_symbols (struct objfile *objfile)
 {
-  register int bindex;
-  register int mcount;
-  register struct msym_bunch *bunch;
-  register struct minimal_symbol *msymbols;
+  int bindex;
+  int mcount;
+  struct msym_bunch *bunch;
+  struct minimal_symbol *msymbols;
   int alloc_count;
-  register char leading_char;
+  char leading_char;
 
   if (msym_count > 0)
     {
@@ -915,10 +856,9 @@ install_minimal_symbols (struct objfile *objfile)
          for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++)
            {
              msymbols[mcount] = bunch->contents[bindex];
-             SYMBOL_LANGUAGE (&msymbols[mcount]) = language_auto;
-             if (SYMBOL_NAME (&msymbols[mcount])[0] == leading_char)
+             if (SYMBOL_LINKAGE_NAME (&msymbols[mcount])[0] == leading_char)
                {
-                 SYMBOL_NAME (&msymbols[mcount])++;
+                 SYMBOL_LINKAGE_NAME (&msymbols[mcount])++;
                }
            }
          msym_bunch_index = BUNCH_SIZE;
@@ -947,7 +887,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_NAME (&msymbols[mcount]) = NULL;
+      SYMBOL_LINKAGE_NAME (&msymbols[mcount]) = NULL;
       SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0;
       MSYMBOL_INFO (&msymbols[mcount]) = NULL;
       MSYMBOL_TYPE (&msymbols[mcount]) = mst_unknown;
@@ -967,19 +907,20 @@ install_minimal_symbols (struct objfile *objfile)
 
        for (i = 0; i < mcount; i++)
          {
-           const char *name = SYMBOL_NAME (&objfile->msymbols[i]);
-           if (name[0] == '_' && name[1] == 'Z')
+           /* 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)
              {
-               switch_to_cp_abi ("gnu-v3");
+               set_cp_abi_as_auto_default ("gnu-v3");
                break;
              }
          }
       }
-      
-      /* Now walk through all the minimal symbols, selecting the newly added
-         ones and attempting to cache their C++ demangled names. */
-      for (; mcount-- > 0; msymbols++)
-       SYMBOL_INIT_DEMANGLED_NAME (msymbols, &objfile->symbol_obstack);
 
       /* Now build the hash tables; we can't do this incrementally
          at an earlier point since we weren't finished with the obstack
@@ -1035,7 +976,8 @@ find_solib_trampoline_target (CORE_ADDR pc)
       ALL_MSYMBOLS (objfile, msymbol)
       {
        if (MSYMBOL_TYPE (msymbol) == mst_text
-           && STREQ (SYMBOL_NAME (msymbol), SYMBOL_NAME (tsymbol)))
+           && strcmp (SYMBOL_LINKAGE_NAME (msymbol),
+                      SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
          return SYMBOL_VALUE_ADDRESS (msymbol);
       }
     }
This page took 0.035626 seconds and 4 git commands to generate.