Fix prologue analysis for moxie.
[deliverable/binutils-gdb.git] / gdb / minsyms.c
index f1a6c486b4451601cd2b061b3b49a7975d88d933..1a1a37fa6dfb764c2a38856af481a79ff4fba4f8 100644 (file)
@@ -1,6 +1,6 @@
 /* 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 Free Software Foundation, Inc.
    Contributed by Cygnus Support, using pieces from other GDB modules.
 
    This file is part of GDB.
@@ -47,6 +47,9 @@
 #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
@@ -125,7 +128,8 @@ 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)) % 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;
     }
@@ -185,6 +189,9 @@ 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)
     {
       char *p = strrchr (sfile, '/');
@@ -192,6 +199,18 @@ lookup_minimal_symbol (const char *name, const char *sfile,
        sfile = p + 1;
     }
 
+  /* For C++, canonicalize the input name. */
+  modified_name = name;
+  if (current_language->la_language == language_cplus)
+    {
+      char *cname = cp_canonicalize_string (name);
+      if (cname)
+       {
+         modified_name = cname;
+         needtofreename = 1;
+       }
+    }
+
   for (objfile = object_files;
        objfile != NULL && found_symbol == NULL;
        objfile = objfile->next)
@@ -213,15 +232,20 @@ lookup_minimal_symbol (const char *name, const char *sfile,
 
             while (msymbol != NULL && found_symbol == NULL)
                {
-                 /* 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))
+                 int match;
+
+                 if (pass == 1)
+                   {
+                     match = strcmp (SYMBOL_LINKAGE_NAME (msymbol),
+                                     modified_name) == 0;
+                   }
+                 else
+                   {
+                     match = SYMBOL_MATCHES_SEARCH_NAME (msymbol,
+                                                         modified_name);
+                   }
+
+                 if (match)
                    {
                     switch (MSYMBOL_TYPE (msymbol))
                       {
@@ -259,6 +283,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;
@@ -330,6 +358,41 @@ 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.  */
+
+struct minimal_symbol *
+lookup_minimal_symbol_by_pc_name (CORE_ADDR pc, const char *name,
+                                 struct objfile *objf)
+{
+  struct objfile *objfile;
+  struct minimal_symbol *msymbol;
+
+  unsigned int hash = msymbol_hash (name) % MINIMAL_SYMBOL_HASH_SIZE;
+
+  for (objfile = object_files;
+       objfile != NULL;
+       objfile = objfile->next)
+    {
+      if (objf == NULL || objf == objfile
+         || objf->separate_debug_objfile == objfile)
+       {
+         for (msymbol = objfile->msymbol_hash[hash];
+              msymbol != NULL;
+              msymbol = msymbol->hash_next)
+           {
+             if (SYMBOL_VALUE_ADDRESS (msymbol) == pc
+                 && strcmp (SYMBOL_LINKAGE_NAME (msymbol), name) == 0)
+               return msymbol;
+           }
+       }
+    }
+
+  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
@@ -384,7 +447,8 @@ lookup_minimal_symbol_solib_trampoline (const char *name,
    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;
@@ -495,7 +559,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;
@@ -507,9 +571,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;
@@ -526,8 +590,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;
@@ -614,7 +678,7 @@ 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)
 {
   return lookup_minimal_symbol_by_pc_section_1 (pc, section, 0);
 }
@@ -631,7 +695,7 @@ lookup_minimal_symbol_by_pc (CORE_ADDR pc)
   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, section);
 }
 \f
 
@@ -689,7 +753,7 @@ 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
@@ -698,10 +762,11 @@ prim_record_minimal_symbol (const char *name, CORE_ADDR address,
 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,
+                                    int section,
                                     asection *bfd_section,
                                     struct objfile *objfile)
 {
+  struct obj_section *obj_section;
   struct msym_bunch *new;
   struct minimal_symbol *msymbol;
 
@@ -725,7 +790,7 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
 
   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;
@@ -737,11 +802,22 @@ prim_record_minimal_symbol_and_info (const char *name, CORE_ADDR address,
 
   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,
@@ -1013,7 +1089,8 @@ install_minimal_symbols (struct objfile *objfile)
 
       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);
@@ -1077,8 +1154,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;
@@ -1110,6 +1186,22 @@ find_solib_trampoline_target (struct frame_info *frame, CORE_ADDR pc)
            && strcmp (SYMBOL_LINKAGE_NAME (msymbol),
                       SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
          return SYMBOL_VALUE_ADDRESS (msymbol);
+
+       /* Also handle minimal symbols pointing to function descriptors.  */
+       if (MSYMBOL_TYPE (msymbol) == mst_data
+           && strcmp (SYMBOL_LINKAGE_NAME (msymbol),
+                      SYMBOL_LINKAGE_NAME (tsymbol)) == 0)
+         {
+           CORE_ADDR func;
+           func = gdbarch_convert_from_func_ptr_addr
+                   (get_objfile_arch (objfile),
+                    SYMBOL_VALUE_ADDRESS (msymbol),
+                    &current_target);
+
+           /* Ignore data symbols that are not function descriptors.  */
+           if (func != SYMBOL_VALUE_ADDRESS (msymbol))
+             return func;
+         }
       }
     }
   return 0;
This page took 0.027277 seconds and 4 git commands to generate.