2007-07-03 Paul Gilliam <pgilliam@us.ibm.com>
[deliverable/binutils-gdb.git] / gdb / minsyms.c
index 74b867d59b2f343edbe8f391d5cf3d0d98f284de..68193bbe3e61b2144011e5d35267bd109015d9fe 100644 (file)
@@ -1,7 +1,6 @@
 /* GDB routines for manipulating the minimal symbol tables.
-   Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004
-   Free Software Foundation, Inc.
+   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+   2002, 2003, 2004, 2007 Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
    This file is part of GDB.
@@ -18,8 +17,8 @@
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
 
 
 /* This file contains support routines for creating, manipulating, and
@@ -145,7 +144,15 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
    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).
+
+   It's also possible to have minimal symbols with different mangled
+   names, but identical demangled names.  For example, the GNU C++ v3
+   ABI requires the generation of two (or perhaps three) copies of
+   constructor functions --- "in-charge", "not-in-charge", and
+   "allocate" copies; destructors may be duplicated as well.
+   Obviously, there must be distinct mangled names for each of these,
+   but the demangled names are all the same: S::S or S::~S.  */
 
 struct minimal_symbol *
 lookup_minimal_symbol (const char *name, const char *sfile,
@@ -352,10 +359,9 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
   return NULL;
 }
 
-
 /* Search through the minimal symbol table for each objfile and find
    the symbol whose address is the largest address that is still less
-   than or equal to PC, and matches SECTION (if non-null).  Returns a
+   than or equal to PC, and matches SECTION (if non-NULL).  Returns a
    pointer to the minimal symbol if such a symbol is found, or NULL if
    PC is not in a suitable range.  Note that we need to look through
    ALL the minimal symbol tables before deciding on the symbol that
@@ -374,24 +380,27 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
   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.  */
+  /* 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.  */
   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;
+  /* We can not require the symbol found to be in pc_section, because
+     e.g. IRIX 6.5 mdebug relies on this code returning an absolute
+     symbol - but find_pc_section won't return an absolute section and
+     hence the code below would skip over absolute symbols.  We can
+     still take advantage of the call to find_pc_section, though - the
+     object file still must match.  In case we have separate debug
+     files, search both the file and its separate debug file.  There's
+     no telling which one will have the minimal symbols.  */
 
-  /* FIXME drow/2003-07-19: Should we also check that PC is in SECTION
-     if we were passed a non-NULL SECTION argument?  */
+  objfile = pc_section->objfile;
+  if (objfile->separate_debug_objfile)
+    objfile = objfile->separate_debug_objfile;
 
-  for (objfile = object_files;
-       objfile != NULL;
-       objfile = objfile->next)
+  for (; objfile != NULL; objfile = objfile->separate_debug_objfile_backlink)
     {
       /* If this objfile has a minimal symbol table, go search it using
          a binary search.  Note that a minimal symbol table always consists
@@ -401,6 +410,8 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
 
       if (objfile->minimal_symbol_count > 0)
        {
+         int best_zero_sized = -1;
+
           msymbol = objfile->msymbols;
          lo = 0;
          hi = objfile->minimal_symbol_count - 1;
@@ -450,34 +461,108 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
                         == SYMBOL_VALUE_ADDRESS (&msymbol[hi + 1])))
                hi++;
 
+             /* Skip various undesirable symbols.  */
+             while (hi >= 0)
+               {
+                 /* Skip any absolute symbols.  This is apparently
+                    what adb and dbx do, and is needed for the CM-5.
+                    There are two known possible problems: (1) on
+                    ELF, apparently end, edata, etc. are absolute.
+                    Not sure ignoring them here is a big deal, but if
+                    we want to use them, the fix would go in
+                    elfread.c.  (2) I think shared library entry
+                    points on the NeXT are absolute.  If we want
+                    special handling for this it probably should be
+                    triggered by a special mst_abs_or_lib or some
+                    such.  */
+
+                 if (msymbol[hi].type == mst_abs)
+                   {
+                     hi--;
+                     continue;
+                   }
+
+                 /* If SECTION was specified, skip any symbol from
+                    wrong section.  */
+                 if (section
+                     /* 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_BFD_SECTION (&msymbol[hi]) != NULL
+                     && (!matching_bfd_sections
+                         (SYMBOL_BFD_SECTION (&msymbol[hi]), section)))
+                   {
+                     hi--;
+                     continue;
+                   }
+
+                 /* If the minimal symbol has a zero size, save it
+                    but keep scanning backwards looking for one with
+                    a non-zero size.  A zero size may mean that the
+                    symbol isn't an object or function (e.g. a
+                    label), or it may just mean that the size was not
+                    specified.  */
+                 if (MSYMBOL_SIZE (&msymbol[hi]) == 0
+                     && best_zero_sized == -1)
+                   {
+                     best_zero_sized = hi;
+                     hi--;
+                     continue;
+                   }
+
+                 /* If we are past the end of the current symbol, try
+                    the previous symbol if it has a larger overlapping
+                    size.  This happens on i686-pc-linux-gnu with glibc;
+                    the nocancel variants of system calls are inside
+                    the cancellable variants, but both have sizes.  */
+                 if (hi > 0
+                     && MSYMBOL_SIZE (&msymbol[hi]) != 0
+                     && pc >= (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
+                               + MSYMBOL_SIZE (&msymbol[hi]))
+                     && pc < (SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1])
+                              + MSYMBOL_SIZE (&msymbol[hi - 1])))
+                   {
+                     hi--;
+                     continue;
+                   }
+
+                 /* Otherwise, this symbol must be as good as we're going
+                    to get.  */
+                 break;
+               }
+
+             /* If HI has a zero size, and best_zero_sized is set,
+                then we had two or more zero-sized symbols; prefer
+                the first one we found (which may have a higher
+                address).  Also, if we ran off the end, be sure
+                to back up.  */
+             if (best_zero_sized != -1
+                 && (hi < 0 || MSYMBOL_SIZE (&msymbol[hi]) == 0))
+               hi = best_zero_sized;
+
+             /* If the minimal symbol has a non-zero size, and this
+                PC appears to be outside the symbol's contents, then
+                refuse to use this symbol.  If we found a zero-sized
+                symbol with an address greater than this symbol's,
+                use that instead.  We assume that if symbols have
+                specified sizes, they do not overlap.  */
+
+             if (hi >= 0
+                 && MSYMBOL_SIZE (&msymbol[hi]) != 0
+                 && pc >= (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
+                           + MSYMBOL_SIZE (&msymbol[hi])))
+               {
+                 if (best_zero_sized != -1)
+                   hi = best_zero_sized;
+                 else
+                   /* Go on to the next object file.  */
+                   continue;
+               }
+
              /* The minimal symbol indexed by hi now is the best one in this
                 objfile's minimal symbol table.  See if it is the best one
                 overall. */
 
-             /* Skip any absolute symbols.  This is apparently what adb
-                and dbx do, and is needed for the CM-5.  There are two
-                known possible problems: (1) on ELF, apparently end, edata,
-                etc. are absolute.  Not sure ignoring them here is a big
-                deal, but if we want to use them, the fix would go in
-                elfread.c.  (2) I think shared library entry points on the
-                NeXT are absolute.  If we want special handling for this
-                it probably should be triggered by a special
-                mst_abs_or_lib or some such.  */
-             while (hi >= 0
-                    && msymbol[hi].type == mst_abs)
-               --hi;
-
-             /* If "section" specified, skip any symbol from wrong section */
-             /* This is the new code that distinguishes it from the old function */
-             if (section)
-               while (hi >= 0
-                      /* 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_BFD_SECTION (&msymbol[hi]) != NULL
-                      && SYMBOL_BFD_SECTION (&msymbol[hi]) != section)
-                 --hi;
-
              if (hi >= 0
                  && ((best_symbol == NULL) ||
                      (SYMBOL_VALUE_ADDRESS (best_symbol) <
@@ -497,7 +582,13 @@ lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
 struct minimal_symbol *
 lookup_minimal_symbol_by_pc (CORE_ADDR pc)
 {
-  return lookup_minimal_symbol_by_pc_section (pc, find_pc_mapped_section (pc));
+  /* NOTE: cagney/2004-01-27: This was using find_pc_mapped_section to
+     force the section but that (well unless you're doing overlay
+     debugging) always returns NULL making the call somewhat useless.  */
+  struct obj_section *section = find_pc_section (pc);
+  if (section == NULL)
+    return NULL;
+  return lookup_minimal_symbol_by_pc_section (pc, section->the_bfd_section);
 }
 \f
 
@@ -571,26 +662,23 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
   struct msym_bunch *new;
   struct minimal_symbol *msymbol;
 
-  if (ms_type == mst_file_text)
-    {
-      /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into
-         the minimal symbols, because if there is also another symbol
-         at the same address (e.g. the first function of the file),
-         lookup_minimal_symbol_by_pc would have no way of getting the
-         right one.  */
-      if (name[0] == 'g'
-         && (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0
-             || strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0))
-       return (NULL);
+  /* Don't put gcc_compiled, __gnu_compiled_cplus, and friends into
+     the minimal symbols, because if there is also another symbol
+     at the same address (e.g. the first function of the file),
+     lookup_minimal_symbol_by_pc would have no way of getting the
+     right one.  */
+  if (ms_type == mst_file_text && name[0] == 'g'
+      && (strcmp (name, GCC_COMPILED_FLAG_SYMBOL) == 0
+         || strcmp (name, GCC2_COMPILED_FLAG_SYMBOL) == 0))
+    return (NULL);
 
-      {
-       const char *tempstring = name;
-       if (tempstring[0] == get_symbol_leading_char (objfile->obfd))
-         ++tempstring;
-       if (strncmp (tempstring, "__gnu_compiled", 14) == 0)
-         return (NULL);
-      }
-    }
+  /* It's safe to strip the leading char here once, since the name
+     is also stored stripped in the minimal symbol table. */
+  if (name[0] == get_symbol_leading_char (objfile->obfd))
+    ++name;
+
+  if (ms_type == mst_file_text && strncmp (name, "__gnu_compiled", 14) == 0)
+    return (NULL);
 
   if (msym_bunch_index == BUNCH_SIZE)
     {
@@ -785,7 +873,7 @@ build_minimal_symbol_hash_tables (struct objfile *objfile)
       add_minsym_to_hash_table (msym, objfile->msymbol_hash);
 
       msym->demangled_hash_next = 0;
-      if (SYMBOL_DEMANGLED_NAME (msym) != NULL)
+      if (SYMBOL_SEARCH_NAME (msym) != SYMBOL_LINKAGE_NAME (msym))
        add_minsym_to_demangled_hash_table (msym,
                                             objfile->msymbol_demangled_hash);
     }
@@ -822,7 +910,6 @@ install_minimal_symbols (struct objfile *objfile)
   struct msym_bunch *bunch;
   struct minimal_symbol *msymbols;
   int alloc_count;
-  char leading_char;
 
   if (msym_count > 0)
     {
@@ -850,18 +937,11 @@ install_minimal_symbols (struct objfile *objfile)
          each bunch is full. */
 
       mcount = objfile->minimal_symbol_count;
-      leading_char = get_symbol_leading_char (objfile->obfd);
 
       for (bunch = msym_bunch; bunch != NULL; bunch = bunch->next)
        {
          for (bindex = 0; bindex < msym_bunch_index; bindex++, mcount++)
-           {
-             msymbols[mcount] = bunch->contents[bindex];
-             if (SYMBOL_LINKAGE_NAME (&msymbols[mcount])[0] == leading_char)
-               {
-                 SYMBOL_LINKAGE_NAME (&msymbols[mcount])++;
-               }
-           }
+           msymbols[mcount] = bunch->contents[bindex];
          msym_bunch_index = BUNCH_SIZE;
        }
 
@@ -967,7 +1047,7 @@ lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
    a duplicate function in case this matters someday.  */
 
 CORE_ADDR
-find_solib_trampoline_target (CORE_ADDR pc)
+find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
 {
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
This page took 0.029835 seconds and 4 git commands to generate.