binutils/
[external/binutils.git] / gdb / minsyms.c
index 34bbbb9..70871cd 100644 (file)
@@ -1,6 +1,7 @@
 /* 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 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2007, 2008, 2009, 2010, 2011
+   Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
    This file is part of GDB.
@@ -34,7 +35,7 @@
    Even when a file contains enough debugging information to build a full
    symbol table, these minimal symbols are still useful for quickly mapping
    between names and addresses, and vice versa.  They are also sometimes used
-   to figure out what full symbol table entries need to be read in. */
+   to figure out what full symbol table entries need to be read in.  */
 
 
 #include "defs.h"
 #include "gdb_string.h"
 #include "symtab.h"
 #include "bfd.h"
+#include "filenames.h"
 #include "symfile.h"
 #include "objfiles.h"
 #include "demangle.h"
 #include "value.h"
 #include "cp-abi.h"
 #include "target.h"
+#include "cp-support.h"
+#include "language.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
@@ -80,13 +84,14 @@ unsigned int
 msymbol_hash_iw (const char *string)
 {
   unsigned int hash = 0;
+
   while (*string && *string != '(')
     {
       while (isspace (*string))
        ++string;
       if (*string && *string != '(')
        {
-         hash = hash * 67 + *string - 113;
+         hash = SYMBOL_HASH_NEXT (hash, *string);
          ++string;
        }
     }
@@ -99,8 +104,9 @@ unsigned int
 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;
 }
 
@@ -113,6 +119,7 @@ add_minsym_to_hash_table (struct minimal_symbol *sym,
     {
       unsigned int hash
        = msymbol_hash (SYMBOL_LINKAGE_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
+
       sym->hash_next = table[hash];
       table[hash] = sym;
     }
@@ -126,8 +133,9 @@ add_minsym_to_demangled_hash_table (struct minimal_symbol *sym,
 {
   if (sym->demangled_hash_next == NULL)
     {
-      unsigned int hash
-       = msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym)) % MINIMAL_SYMBOL_HASH_SIZE;
+      unsigned int hash = msymbol_hash_iw (SYMBOL_SEARCH_NAME (sym))
+       % MINIMAL_SYMBOL_HASH_SIZE;
+
       sym->demangled_hash_next = table[hash];
       table[hash] = sym;
     }
@@ -187,11 +195,23 @@ lookup_minimal_symbol (const char *name, const char *sfile,
   unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
   unsigned int dem_hash = msymbol_hash_iw (name) % MINIMAL_SYMBOL_HASH_SIZE;
 
+  int needtofreename = 0;
+  const char *modified_name;
+
   if (sfile != NULL)
+    sfile = lbasename (sfile);
+
+  /* For C++, canonicalize the input name.  */
+  modified_name = name;
+  if (current_language->la_language == language_cplus)
     {
-      char *p = strrchr (sfile, '/');
-      if (p != NULL)
-       sfile = p + 1;
+      char *cname = cp_canonicalize_string (name);
+
+      if (cname)
+       {
+         modified_name = cname;
+         needtofreename = 1;
+       }
     }
 
   for (objfile = object_files;
@@ -199,7 +219,7 @@ lookup_minimal_symbol (const char *name, const char *sfile,
        objfile = objfile->next)
     {
       if (objf == NULL || objf == objfile
-         || objf->separate_debug_objfile == objfile)
+         || objf == objfile->separate_debug_objfile_backlink)
        {
          /* Do two passes: the first over the ordinary hash table,
             and the second over the demangled hash table.  */
@@ -218,9 +238,21 @@ lookup_minimal_symbol (const char *name, const char *sfile,
                  int match;
 
                  if (pass == 1)
-                   match = strcmp (SYMBOL_LINKAGE_NAME (msymbol), 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
-                   match = SYMBOL_MATCHES_SEARCH_NAME (msymbol, name);
+                   {
+                     /* The function respects CASE_SENSITIVITY.  */
+                     match = SYMBOL_MATCHES_SEARCH_NAME (msymbol,
+                                                         modified_name);
+                   }
+
                  if (match)
                    {
                     switch (MSYMBOL_TYPE (msymbol))
@@ -229,16 +261,16 @@ lookup_minimal_symbol (const char *name, const char *sfile,
                       case mst_file_data:
                       case mst_file_bss:
                         if (sfile == NULL
-                           || strcmp (msymbol->filename, sfile) == 0)
+                           || filename_cmp (msymbol->filename, sfile) == 0)
                           found_file_symbol = msymbol;
                         break;
 
                       case mst_solib_trampoline:
 
                         /* If a trampoline symbol is found, we prefer to
-                           keep looking for the *real* symbol. If the
+                           keep looking for the *real* symbol.  If the
                            actual symbol is not found, then we'll use the
-                           trampoline entry. */
+                           trampoline entry.  */
                         if (trampoline_symbol == NULL)
                           trampoline_symbol = msymbol;
                         break;
@@ -259,6 +291,10 @@ lookup_minimal_symbol (const char *name, const char *sfile,
            }
        }
     }
+
+  if (needtofreename)
+    xfree ((void *) modified_name);
+
   /* External symbols are best.  */
   if (found_symbol)
     return found_symbol;
@@ -296,15 +332,16 @@ lookup_minimal_symbol_text (const char *name, struct objfile *objf)
        objfile = objfile->next)
     {
       if (objf == NULL || objf == objfile
-         || objf->separate_debug_objfile == objfile)
+         || objf == objfile->separate_debug_objfile_backlink)
        {
          for (msymbol = objfile->msymbol_hash[hash];
               msymbol != NULL && found_symbol == NULL;
               msymbol = msymbol->hash_next)
            {
              if (strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0 &&
-                 (MSYMBOL_TYPE (msymbol) == mst_text ||
-                  MSYMBOL_TYPE (msymbol) == mst_file_text))
+                 (MSYMBOL_TYPE (msymbol) == mst_text
+                  || MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc
+                  || MSYMBOL_TYPE (msymbol) == mst_file_text))
                {
                  switch (MSYMBOL_TYPE (msymbol))
                    {
@@ -349,7 +386,7 @@ lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
        objfile = objfile->next)
     {
       if (objf == NULL || objf == objfile
-         || objf->separate_debug_objfile == objfile)
+         || objf == objfile->separate_debug_objfile_backlink)
        {
          for (msymbol = objfile->msymbol_hash[hash];
               msymbol != NULL;
@@ -388,7 +425,7 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
        objfile = objfile->next)
     {
       if (objf == NULL || objf == objfile
-         || objf->separate_debug_objfile == objfile)
+         || objf == objfile->separate_debug_objfile_backlink)
        {
          for (msymbol = objfile->msymbol_hash[hash];
               msymbol != NULL && found_symbol == NULL;
@@ -406,20 +443,22 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
 
 /* 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
-   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
-   comes closest to the specified PC.  This is because objfiles can
-   overlap, for example objfile A has .text at 0x100 and .data at
-   0x40000 and objfile B has .text at 0x234 and .data at 0x40048.
+   than or equal to PC, and matches SECTION (which is not 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 comes closest to the specified PC.
+   This is because objfiles can overlap, for example objfile A has .text
+   at 0x100 and .data at 0x40000 and objfile B has .text at 0x234 and
+   .data at 0x40048.
 
    If WANT_TRAMPOLINE is set, prefer mst_solib_trampoline symbols when
    there are text and trampoline symbols at the same address.
    Otherwise prefer mst_text symbols.  */
 
 static struct minimal_symbol *
-lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
+lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc,
+                                      struct obj_section *section,
                                       int want_trampoline)
 {
   int lo;
@@ -428,20 +467,12 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
   struct objfile *objfile;
   struct minimal_symbol *msymbol;
   struct minimal_symbol *best_symbol = NULL;
-  struct obj_section *pc_section;
   enum minimal_symbol_type want_type, other_type;
 
   want_type = want_trampoline ? mst_solib_trampoline : mst_text;
   other_type = want_trampoline ? mst_text : mst_solib_trampoline;
-  
-  /* 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;
 
-  /* We can not require the symbol found to be in pc_section, because
+  /* We can not require the symbol found to be in 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
@@ -450,17 +481,17 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
      files, search both the file and its separate debug file.  There's
      no telling which one will have the minimal symbols.  */
 
-  objfile = pc_section->objfile;
-  if (objfile->separate_debug_objfile)
-    objfile = objfile->separate_debug_objfile;
+  gdb_assert (section != NULL);
 
-  for (; objfile != NULL; objfile = objfile->separate_debug_objfile_backlink)
+  for (objfile = section->objfile;
+       objfile != NULL;
+       objfile = objfile_separate_debug_iterate (section->objfile, objfile))
     {
       /* If this objfile has a minimal symbol table, go search it using
          a binary search.  Note that a minimal symbol table always consists
          of at least two symbols, a "real" symbol and the terminating
          "null symbol".  If there are no real symbols, then there is no
-         minimal symbol table at all. */
+         minimal symbol table at all.  */
 
       if (objfile->minimal_symbol_count > 0)
        {
@@ -486,15 +517,15 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
             terminates.  In essence, we are iterating the test interval
             down until the pc value is pushed out of it from the high end.
 
-            Warning: this code is trickier than it would appear at first. */
+            Warning: this code is trickier than it would appear at first.  */
 
-         /* Should also require that pc is <= end of objfile.  FIXME! */
+         /* Should also require that pc is <= end of objfile.  FIXME!  */
          if (pc >= SYMBOL_VALUE_ADDRESS (&msymbol[lo]))
            {
              while (SYMBOL_VALUE_ADDRESS (&msymbol[hi]) > pc)
                {
-                 /* pc is still strictly less than highest address */
-                 /* Note "new" will always be >= lo */
+                 /* pc is still strictly less than highest address */
+                 /* Note "new" will always be >= lo */
                  new = (lo + hi) / 2;
                  if ((SYMBOL_VALUE_ADDRESS (&msymbol[new]) >= pc) ||
                      (lo == new))
@@ -530,7 +561,7 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
                     triggered by a special mst_abs_or_lib or some
                     such.  */
 
-                 if (msymbol[hi].type == mst_abs)
+                 if (MSYMBOL_TYPE (&msymbol[hi]) == mst_abs)
                    {
                      hi--;
                      continue;
@@ -542,9 +573,9 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *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)))
+                     && SYMBOL_OBJ_SECTION (&msymbol[hi]) != NULL
+                     && (!matching_obj_sections
+                         (SYMBOL_OBJ_SECTION (&msymbol[hi]), section)))
                    {
                      hi--;
                      continue;
@@ -552,7 +583,7 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
 
                  /* 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
@@ -561,8 +592,8 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
                          == MSYMBOL_SIZE (&msymbol[hi - 1]))
                      && (SYMBOL_VALUE_ADDRESS (&msymbol[hi])
                          == SYMBOL_VALUE_ADDRESS (&msymbol[hi - 1]))
-                     && (SYMBOL_BFD_SECTION (&msymbol[hi])
-                         == SYMBOL_BFD_SECTION (&msymbol[hi - 1])))
+                     && (SYMBOL_OBJ_SECTION (&msymbol[hi])
+                         == SYMBOL_OBJ_SECTION (&msymbol[hi - 1])))
                    {
                      hi--;
                      continue;
@@ -633,7 +664,7 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
 
              /* 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. */
+                overall.  */
 
              if (hi >= 0
                  && ((best_symbol == NULL) ||
@@ -649,28 +680,125 @@ lookup_minimal_symbol_by_pc_section_1 (CORE_ADDR pc, asection *section,
 }
 
 struct minimal_symbol *
-lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, asection *section)
+lookup_minimal_symbol_by_pc_section (CORE_ADDR pc, struct obj_section *section)
 {
+  if (section == NULL)
+    {
+      /* 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.  */
+      section = find_pc_section (pc);
+      if (section == NULL)
+       return NULL;
+    }
   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) */
+   for a matching PC (no section given) */
 
 struct minimal_symbol *
 lookup_minimal_symbol_by_pc (CORE_ADDR 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);
+  return lookup_minimal_symbol_by_pc_section (pc, NULL);
+}
+
+/* Return non-zero iff PC is in an STT_GNU_IFUNC function resolver.  */
+
+int
+in_gnu_ifunc_stub (CORE_ADDR pc)
+{
+  struct minimal_symbol *msymbol = lookup_minimal_symbol_by_pc (pc);
+
+  return msymbol && MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc;
+}
+
+/* See elf_gnu_ifunc_resolve_addr for its real implementation.  */
+
+static CORE_ADDR
+stub_gnu_ifunc_resolve_addr (struct gdbarch *gdbarch, CORE_ADDR pc)
+{
+  error (_("GDB cannot resolve STT_GNU_IFUNC symbol at address %s without "
+          "the ELF support compiled in."),
+        paddress (gdbarch, pc));
+}
+
+/* See elf_gnu_ifunc_resolve_name for its real implementation.  */
+
+static int
+stub_gnu_ifunc_resolve_name (const char *function_name,
+                            CORE_ADDR *function_address_p)
+{
+  error (_("GDB cannot resolve STT_GNU_IFUNC symbol \"%s\" without "
+          "the ELF support compiled in."),
+        function_name);
+}
+
+/* See elf_gnu_ifunc_resolver_stop for its real implementation.  */
+
+static void
+stub_gnu_ifunc_resolver_stop (struct breakpoint *b)
+{
+  internal_error (__FILE__, __LINE__,
+                 _("elf_gnu_ifunc_resolver_stop cannot be reached."));
+}
+
+/* See elf_gnu_ifunc_resolver_return_stop for its real implementation.  */
+
+static void
+stub_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
+{
+  internal_error (__FILE__, __LINE__,
+                 _("elf_gnu_ifunc_resolver_return_stop cannot be reached."));
+}
+
+/* See elf_gnu_ifunc_fns for its real implementation.  */
+
+static const struct gnu_ifunc_fns stub_gnu_ifunc_fns =
+{
+  stub_gnu_ifunc_resolve_addr,
+  stub_gnu_ifunc_resolve_name,
+  stub_gnu_ifunc_resolver_stop,
+  stub_gnu_ifunc_resolver_return_stop,
+};
+
+/* A placeholder for &elf_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.  */
+
+struct minimal_symbol *
+lookup_minimal_symbol_and_objfile (const char *name,
+                                  struct objfile **objfile_p)
+{
+  struct objfile *objfile;
+  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+
+  ALL_OBJFILES (objfile)
+    {
+      struct minimal_symbol *msym;
+
+      for (msym = objfile->msymbol_hash[hash];
+          msym != NULL;
+          msym = msym->hash_next)
+       {
+         if (strcmp (SYMBOL_LINKAGE_NAME (msym), name) == 0)
+           {
+             *objfile_p = objfile;
+             return msym;
+           }
+       }
+    }
+
+  return 0;
 }
 \f
 
-/* Return leading symbol character for a BFD. If BFD is NULL,
+/* Return leading symbol character for a BFD.  If BFD is NULL,
    return the leading symbol character from the main objfile.  */
 
 static int get_symbol_leading_char (bfd *);
@@ -687,7 +815,7 @@ get_symbol_leading_char (bfd *abfd)
 
 /* 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. */
+   symbol to allocate the memory for the first bunch.  */
 
 void
 init_minimal_symbol_collection (void)
@@ -707,6 +835,7 @@ prim_record_minimal_symbol (const char *name, CORE_ADDR address,
   switch (ms_type)
     {
     case mst_text:
+    case mst_text_gnu_ifunc:
     case mst_file_text:
     case mst_solib_trampoline:
       section = SECT_OFF_TEXT (objfile);
@@ -724,19 +853,21 @@ prim_record_minimal_symbol (const char *name, CORE_ADDR address,
     }
 
   prim_record_minimal_symbol_and_info (name, address, ms_type,
-                                      NULL, section, NULL, objfile);
+                                      section, NULL, objfile);
 }
 
 /* Record a minimal symbol in the msym bunches.  Returns the symbol
    newly created.  */
 
 struct minimal_symbol *
-prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
-                                    enum minimal_symbol_type ms_type,
-                                    char *info, int section,
-                                    asection *bfd_section,
-                                    struct objfile *objfile)
+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;
   struct msym_bunch *new;
   struct minimal_symbol *msymbol;
 
@@ -751,36 +882,49 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
     return (NULL);
 
   /* It's safe to strip the leading char here once, since the name
-     is also stored stripped in the minimal symbol table. */
+     is also stored stripped in the minimal symbol table.  */
   if (name[0] == get_symbol_leading_char (objfile->obfd))
-    ++name;
+    {
+      ++name;
+      --name_len;
+    }
 
   if (ms_type == mst_file_text && strncmp (name, "__gnu_compiled", 14) == 0)
     return (NULL);
 
   if (msym_bunch_index == BUNCH_SIZE)
     {
-      new = (struct msym_bunch *) xmalloc (sizeof (struct msym_bunch));
+      new = XCALLOC (1, struct msym_bunch);
       msym_bunch_index = 0;
       new->next = msym_bunch;
       msym_bunch = new;
     }
   msymbol = &msym_bunch->contents[msym_bunch_index];
-  SYMBOL_INIT_LANGUAGE_SPECIFIC (msymbol, language_unknown);
-  SYMBOL_LANGUAGE (msymbol) = language_auto;
-  SYMBOL_SET_NAMES (msymbol, (char *)name, strlen (name), objfile);
+  SYMBOL_SET_LANGUAGE (msymbol, language_auto);
+  SYMBOL_SET_NAMES (msymbol, name, name_len, copy_name, objfile);
 
   SYMBOL_VALUE_ADDRESS (msymbol) = address;
   SYMBOL_SECTION (msymbol) = section;
-  SYMBOL_BFD_SECTION (msymbol) = bfd_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;
-  /* FIXME:  This info, if it remains, needs its own field.  */
-  MSYMBOL_INFO (msymbol) = info;       /* FIXME! */
+  MSYMBOL_TARGET_FLAG_1 (msymbol) = 0;
+  MSYMBOL_TARGET_FLAG_2 (msymbol) = 0;
   MSYMBOL_SIZE (msymbol) = 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. */
+     add_minsym_to_hash_table will NOT add this msymbol to the hash table.  */
   msymbol->hash_next = NULL;
   msymbol->demangled_hash_next = NULL;
 
@@ -790,8 +934,23 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
   return msymbol;
 }
 
+/* Record a minimal symbol in the msym bunches.  Returns the symbol
+   newly created.  */
+
+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);
+}
+
 /* Compare two minimal symbols by address and return a signed result based
-   on unsigned comparisons, so that we sort into unsigned numeric order.  
+   on unsigned comparisons, so that we sort into unsigned numeric order.
    Within groups with the same address, sort by name.  */
 
 static int
@@ -805,11 +964,11 @@ compare_minimal_symbols (const void *fn1p, const void *fn2p)
 
   if (SYMBOL_VALUE_ADDRESS (fn1) < SYMBOL_VALUE_ADDRESS (fn2))
     {
-      return (-1);             /* addr 1 is less than addr 2 */
+      return (-1);             /* addr 1 is less than addr 2 */
     }
   else if (SYMBOL_VALUE_ADDRESS (fn1) > SYMBOL_VALUE_ADDRESS (fn2))
     {
-      return (1);              /* addr 1 is greater than addr 2 */
+      return (1);              /* addr 1 is greater than addr 2 */
     }
   else
     /* addrs are equal: sort by name */
@@ -820,11 +979,11 @@ compare_minimal_symbols (const void *fn1p, const void *fn2p)
       if (name1 && name2)      /* both have names */
        return strcmp (name1, name2);
       else if (name2)
-       return 1;               /* fn1 has no name, so it is "less" */
-      else if (name1)          /* fn2 has no name, so it is "less" */
+       return 1;               /* fn1 has no name, so it is "less" */
+      else if (name1)          /* fn2 has no name, so it is "less" */
        return -1;
       else
-       return (0);             /* neither has a name, so they're equal. */
+       return (0);             /* Neither has a name, so they're equal.  */
     }
 }
 
@@ -834,7 +993,7 @@ compare_minimal_symbols (const void *fn1p, const void *fn2p)
 
    FIXME:  We could allocate the minimal symbol bunches on their own
    obstack and then simply blow the obstack away when we are done with
-   it.  Is it worth the extra trouble though? */
+   it.  Is it worth the extra trouble though?  */
 
 static void
 do_discard_minimal_symbols_cleanup (void *arg)
@@ -927,7 +1086,7 @@ compact_minimal_symbols (struct minimal_symbol *msymbol, int mcount,
 
 /* Build (or rebuild) the minimal symbol hash tables.  This is necessary
    after compacting or sorting the table since the entries move around
-   thus causing the internal minimal_symbol pointers to become jumbled. */
+   thus causing the internal minimal_symbol pointers to become jumbled.  */
   
 static void
 build_minimal_symbol_hash_tables (struct objfile *objfile)
@@ -935,14 +1094,14 @@ build_minimal_symbol_hash_tables (struct objfile *objfile)
   int i;
   struct minimal_symbol *msym;
 
-  /* Clear the hash tables. */
+  /* Clear the hash tables.  */
   for (i = 0; i < MINIMAL_SYMBOL_HASH_SIZE; i++)
     {
       objfile->msymbol_hash[i] = 0;
       objfile->msymbol_demangled_hash[i] = 0;
     }
 
-  /* Now, (re)insert the actual entries. */
+  /* Now, (re)insert the actual entries.  */
   for (i = objfile->minimal_symbol_count, msym = objfile->msymbols;
        i > 0;
        i--, msym++)
@@ -978,7 +1137,7 @@ build_minimal_symbol_hash_tables (struct objfile *objfile)
    to demangle it, and if successful, record it as a language_cplus symbol
    and cache the demangled form on the symbol obstack.  Symbols which don't
    demangle are marked as language_unknown symbols, which inhibits future
-   attempts to demangle them if we later add more minimal symbols. */
+   attempts to demangle them if we later add more minimal symbols.  */
 
 void
 install_minimal_symbols (struct objfile *objfile)
@@ -1012,7 +1171,7 @@ install_minimal_symbols (struct objfile *objfile)
          to the new contiguous array of symbols.  Note that we start with the
          current, possibly partially filled bunch (thus we use the current
          msym_bunch_index for the first bunch we copy over), and thereafter
-         each bunch is full. */
+         each bunch is full.  */
 
       mcount = objfile->minimal_symbol_count;
 
@@ -1044,14 +1203,15 @@ install_minimal_symbols (struct objfile *objfile)
          to some symbol in the middle of it.  Zero out the fields in the
          "null symbol" allocated at the end of the array.  Note that the
          symbol count does *not* include this null symbol, which is why it
-         is indexed by mcount and not mcount-1. */
+         is indexed by mcount and not mcount-1.  */
 
       SYMBOL_LINKAGE_NAME (&msymbols[mcount]) = NULL;
       SYMBOL_VALUE_ADDRESS (&msymbols[mcount]) = 0;
-      MSYMBOL_INFO (&msymbols[mcount]) = NULL;
+      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_INIT_LANGUAGE_SPECIFIC (&msymbols[mcount], language_unknown);
+      SYMBOL_SET_LANGUAGE (&msymbols[mcount], language_unknown);
 
       /* Attach the minimal symbol table to the specified objfile.
          The strings themselves are also located in the objfile_obstack
@@ -1073,6 +1233,7 @@ install_minimal_symbols (struct objfile *objfile)
               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)
              {
@@ -1085,7 +1246,7 @@ install_minimal_symbols (struct objfile *objfile)
       /* 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
-        pointers to other msymbols need to be adjusted.) */
+        pointers to other msymbols need to be adjusted.)  */
       build_minimal_symbol_hash_tables (objfile);
     }
 }
@@ -1112,8 +1273,7 @@ lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
 
   if (section == NULL)
     return NULL;
-  msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section->the_bfd_section,
-                                                  1);
+  msymbol = lookup_minimal_symbol_by_pc_section_1 (pc, section, 1);
 
   if (msymbol != NULL && MSYMBOL_TYPE (msymbol) == mst_solib_trampoline)
     return msymbol;
@@ -1127,7 +1287,7 @@ lookup_solib_trampoline_symbol_by_pc (CORE_ADDR pc)
 
    We may fail to find the right function if a function with the
    same name is defined in more than one shared library, but this
-   is considered bad programming style. We could return 0 if we find
+   is considered bad programming style.  We could return 0 if we find
    a duplicate function in case this matters someday.  */
 
 CORE_ADDR
@@ -1141,7 +1301,8 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
     {
       ALL_MSYMBOLS (objfile, msymbol)
       {
-       if (MSYMBOL_TYPE (msymbol) == mst_text
+       if ((MSYMBOL_TYPE (msymbol) == mst_text
+           || MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc)
            && strcmp (SYMBOL_LINKAGE_NAME (msymbol),
                       SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
          return SYMBOL_VALUE_ADDRESS (msymbol);
@@ -1152,6 +1313,7 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
                       SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
          {
            CORE_ADDR func;
+
            func = gdbarch_convert_from_func_ptr_addr
                    (get_objfile_arch (objfile),
                     SYMBOL_VALUE_ADDRESS (msymbol),