PR ld/12549
[binutils-gdb.git] / gdb / dbxread.c
index 0a92764d873c5a50d44833c569506d227ca5c593..09b46a024a05f65b623a8b9acdfa4fc6c5d1a51a 100644 (file)
@@ -1,5 +1,5 @@
 /* Read dbx symbol tables and convert to internal format, for GDB.
-   Copyright (C) 1986-2004, 2008-2012 Free Software Foundation, Inc.
+   Copyright (C) 1986-2013 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -55,6 +55,7 @@
 #include "cp-abi.h"
 #include "cp-support.h"
 #include "psympriv.h"
+#include "block.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -259,11 +260,12 @@ static int bincls_allocated;
 
 extern void _initialize_dbxread (void);
 
-static void read_ofile_symtab (struct partial_symtab *);
+static void read_ofile_symtab (struct objfile *, struct partial_symtab *);
 
-static void dbx_psymtab_to_symtab (struct partial_symtab *);
+static void dbx_read_symtab (struct partial_symtab *self,
+                            struct objfile *objfile);
 
-static void dbx_psymtab_to_symtab_1 (struct partial_symtab *);
+static void dbx_psymtab_to_symtab_1 (struct objfile *, struct partial_symtab *);
 
 static void read_dbx_dynamic_symtab (struct objfile *objfile);
 
@@ -1254,7 +1256,7 @@ read_dbx_symtab (struct objfile *objfile)
   init_bincl_list (20, objfile);
   back_to = make_cleanup_free_bincl_list (objfile);
 
-  last_source_file = NULL;
+  set_last_source_file (NULL);
 
   lowest_text_address = (CORE_ADDR) -1;
 
@@ -1388,8 +1390,8 @@ read_dbx_symtab (struct objfile *objfile)
                     which are not the address.  */
                  && nlist.n_value >= pst->textlow)
                {
-                 end_psymtab (pst, psymtab_include_list, includes_used,
-                              symnum * symbol_size,
+                 end_psymtab (objfile, pst, psymtab_include_list,
+                              includes_used, symnum * symbol_size,
                               nlist.n_value > pst->texthigh
                               ? nlist.n_value : pst->texthigh,
                               dependency_list, dependencies_used,
@@ -1507,8 +1509,8 @@ read_dbx_symtab (struct objfile *objfile)
 
                if (pst)
                  {
-                   end_psymtab (pst, psymtab_include_list, includes_used,
-                                symnum * symbol_size,
+                   end_psymtab (objfile, pst, psymtab_include_list,
+                                includes_used, symnum * symbol_size,
                                 valu > pst->texthigh ? valu : pst->texthigh,
                                 dependency_list, dependencies_used,
                                 prev_textlow_not_set);
@@ -1705,8 +1707,8 @@ read_dbx_symtab (struct objfile *objfile)
              if (new_name != NULL)
                {
                  sym_len = strlen (new_name);
-                 sym_name = obsavestring (new_name, sym_len,
-                                          &objfile->objfile_obstack);
+                 sym_name = obstack_copy0 (&objfile->objfile_obstack,
+                                           new_name, sym_len);
                  xfree (new_name);
                }
               xfree (name);
@@ -2118,7 +2120,7 @@ read_dbx_symtab (struct objfile *objfile)
             follows this module.  */
          if (pst && gdbarch_sofun_address_maybe_missing (gdbarch))
            {
-             end_psymtab (pst, psymtab_include_list, includes_used,
+             end_psymtab (objfile, pst, psymtab_include_list, includes_used,
                           symnum * symbol_size,
                           (CORE_ADDR) 0, dependency_list,
                           dependencies_used, textlow_not_set);
@@ -2181,7 +2183,7 @@ read_dbx_symtab (struct objfile *objfile)
         : lowest_text_address)
        + text_size;
 
-      end_psymtab (pst, psymtab_include_list, includes_used,
+      end_psymtab (objfile, pst, psymtab_include_list, includes_used,
                   symnum * symbol_size,
                   text_end > pst->texthigh ? text_end : pst->texthigh,
                   dependency_list, dependencies_used, textlow_not_set);
@@ -2209,7 +2211,7 @@ start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
   result->read_symtab_private = obstack_alloc (&objfile->objfile_obstack,
                                               sizeof (struct symloc));
   LDSYMOFF (result) = ldsymoff;
-  result->read_symtab = dbx_psymtab_to_symtab;
+  result->read_symtab = dbx_read_symtab;
   SYMBOL_SIZE (result) = symbol_size;
   SYMBOL_OFFSET (result) = symbol_table_offset;
   STRING_OFFSET (result) = string_table_offset;
@@ -2235,14 +2237,13 @@ start_psymtab (struct objfile *objfile, char *filename, CORE_ADDR textlow,
    FIXME:  List variables and peculiarities of same.  */
 
 struct partial_symtab *
-end_psymtab (struct partial_symtab *pst,
+end_psymtab (struct objfile *objfile, struct partial_symtab *pst,
             const char **include_list, int num_includes,
             int capping_symbol_offset, CORE_ADDR capping_text,
             struct partial_symtab **dependency_list, int number_dependencies,
             int textlow_not_set)
 {
   int i;
-  struct objfile *objfile = pst->objfile;
   struct gdbarch *gdbarch = get_objfile_arch (objfile);
 
   if (capping_symbol_offset != -1)
@@ -2377,7 +2378,7 @@ end_psymtab (struct partial_symtab *pst,
       subpst->read_symtab = pst->read_symtab;
     }
 
-  sort_pst_symbols (pst);
+  sort_pst_symbols (objfile, pst);
 
   if (num_includes == 0
       && number_dependencies == 0
@@ -2393,7 +2394,7 @@ end_psymtab (struct partial_symtab *pst,
          is not empty, but we don't realize that.  Fixing that without slowing
          things down might be tricky.  */
 
-      discard_psymtab (pst);
+      discard_psymtab (objfile, pst);
 
       /* Indicate that psymtab was thrown away.  */
       pst = (struct partial_symtab *) NULL;
@@ -2402,14 +2403,11 @@ end_psymtab (struct partial_symtab *pst,
 }
 \f
 static void
-dbx_psymtab_to_symtab_1 (struct partial_symtab *pst)
+dbx_psymtab_to_symtab_1 (struct objfile *objfile, struct partial_symtab *pst)
 {
   struct cleanup *old_chain;
   int i;
 
-  if (!pst)
-    return;
-
   if (pst->readin)
     {
       fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in.  "
@@ -2433,7 +2431,7 @@ dbx_psymtab_to_symtab_1 (struct partial_symtab *pst)
            wrap_here ("");     /* Flush output.  */
            gdb_flush (gdb_stdout);
          }
-       dbx_psymtab_to_symtab_1 (pst->dependencies[i]);
+       dbx_psymtab_to_symtab_1 (objfile, pst->dependencies[i]);
       }
 
   if (LDSYMLEN (pst))          /* Otherwise it's a dummy.  */
@@ -2446,8 +2444,8 @@ dbx_psymtab_to_symtab_1 (struct partial_symtab *pst)
       symbol_size = SYMBOL_SIZE (pst);
 
       /* Read in this file's symbols.  */
-      bfd_seek (pst->objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET);
-      read_ofile_symtab (pst);
+      bfd_seek (objfile->obfd, SYMBOL_OFFSET (pst), SEEK_SET);
+      read_ofile_symtab (objfile, pst);
 
       do_cleanups (old_chain);
     }
@@ -2456,44 +2454,41 @@ dbx_psymtab_to_symtab_1 (struct partial_symtab *pst)
 }
 
 /* Read in all of the symbols for a given psymtab for real.
-   Be verbose about it if the user wants that.  */
+   Be verbose about it if the user wants that.  SELF is not NULL.  */
 
 static void
-dbx_psymtab_to_symtab (struct partial_symtab *pst)
+dbx_read_symtab (struct partial_symtab *self, struct objfile *objfile)
 {
   bfd *sym_bfd;
   struct cleanup *back_to = NULL;
 
-  if (!pst)
-    return;
-
-  if (pst->readin)
+  if (self->readin)
     {
       fprintf_unfiltered (gdb_stderr, "Psymtab for %s already read in.  "
                          "Shouldn't happen.\n",
-                         pst->filename);
+                         self->filename);
       return;
     }
 
-  if (LDSYMLEN (pst) || pst->number_of_dependencies)
+  if (LDSYMLEN (self) || self->number_of_dependencies)
     {
       /* Print the message now, before reading the string table,
          to avoid disconcerting pauses.  */
       if (info_verbose)
        {
-         printf_filtered ("Reading in symbols for %s...", pst->filename);
+         printf_filtered ("Reading in symbols for %s...", self->filename);
          gdb_flush (gdb_stdout);
        }
 
-      sym_bfd = pst->objfile->obfd;
+      sym_bfd = objfile->obfd;
 
       next_symbol_text_func = dbx_next_symbol_text;
 
-      if (DBX_STAB_SECTION (pst->objfile))
+      if (DBX_STAB_SECTION (objfile))
        {
          stabs_data
-           = symfile_relocate_debug_section (pst->objfile,
-                                             DBX_STAB_SECTION (pst->objfile),
+           = symfile_relocate_debug_section (objfile,
+                                             DBX_STAB_SECTION (objfile),
                                              NULL);
 
          if (stabs_data)
@@ -2501,14 +2496,14 @@ dbx_psymtab_to_symtab (struct partial_symtab *pst)
                                    (void *) &stabs_data);
        }
 
-      dbx_psymtab_to_symtab_1 (pst);
+      dbx_psymtab_to_symtab_1 (objfile, self);
 
       if (back_to)
        do_cleanups (back_to);
 
       /* Match with global symbols.  This only needs to be done once,
          after all of the symtabs and dependencies have been read in.   */
-      scan_file_globals (pst->objfile);
+      scan_file_globals (objfile);
 
       /* Finish up the debug error message.  */
       if (info_verbose)
@@ -2519,7 +2514,7 @@ dbx_psymtab_to_symtab (struct partial_symtab *pst)
 /* Read in a defined section of a specific object file's symbols.  */
 
 static void
-read_ofile_symtab (struct partial_symtab *pst)
+read_ofile_symtab (struct objfile *objfile, struct partial_symtab *pst)
 {
   char *namestring;
   struct external_nlist *bufp;
@@ -2527,14 +2522,12 @@ read_ofile_symtab (struct partial_symtab *pst)
   unsigned char type;
   unsigned max_symnum;
   bfd *abfd;
-  struct objfile *objfile;
   int sym_offset;              /* Offset to start of symbols to read */
   int sym_size;                        /* Size of symbols to read */
   CORE_ADDR text_offset;       /* Start of text segment for symbols */
   int text_size;               /* Size of text segment for symbols */
   struct section_offsets *section_offsets;
 
-  objfile = pst->objfile;
   sym_offset = LDSYMOFF (pst);
   sym_size = LDSYMLEN (pst);
   text_offset = pst->textlow;
@@ -2549,7 +2542,7 @@ read_ofile_symtab (struct partial_symtab *pst)
   subfile_stack = NULL;
 
   stringtab_global = DBX_STRINGTAB (objfile);
-  last_source_file = NULL;
+  set_last_source_file (NULL);
 
   abfd = objfile->obfd;
   symfile_bfd = objfile->obfd; /* Implicit param to next_text_symbol.  */
@@ -2714,6 +2707,34 @@ read_ofile_symtab (struct partial_symtab *pst)
 }
 \f
 
+/* Record the namespace that the function defined by SYMBOL was
+   defined in, if necessary.  BLOCK is the associated block; use
+   OBSTACK for allocation.  */
+
+static void
+cp_set_block_scope (const struct symbol *symbol,
+                   struct block *block,
+                   struct obstack *obstack)
+{
+  if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
+    {
+      /* Try to figure out the appropriate namespace from the
+        demangled name.  */
+
+      /* FIXME: carlton/2003-04-15: If the function in question is
+        a method of a class, the name will actually include the
+        name of the class as well.  This should be harmless, but
+        is a little unfortunate.  */
+
+      const char *name = SYMBOL_DEMANGLED_NAME (symbol);
+      unsigned int prefix_len = cp_entire_prefix_len (name);
+
+      block_set_scope (block,
+                      obstack_copy0 (obstack, name, prefix_len),
+                      obstack);
+    }
+}
+
 /* This handles a single symbol from the symbol-file, building symbols
    into a GDB symtab.  It takes these arguments and an implicit argument.
 
@@ -2773,7 +2794,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
   /* Something is wrong if we see real data before seeing a source
      file name.  */
 
-  if (last_source_file == NULL && type != (unsigned char) N_SO)
+  if (get_last_source_file () == NULL && type != (unsigned char) N_SO)
     {
       /* Ignore any symbols which appear before an N_SO symbol.
          Currently no one puts symbols there, but we should deal
@@ -2821,8 +2842,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
 
          /* For C++, set the block's scope.  */
          if (SYMBOL_LANGUAGE (new->name) == language_cplus)
-           cp_set_block_scope (new->name, block, &objfile->objfile_obstack,
-                               "", 0);
+           cp_set_block_scope (new->name, block, &objfile->objfile_obstack);
 
          /* May be switching to an assembler file which may not be using
             block relative stabs, so reset the offset.  */
@@ -2949,7 +2969,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
 
       n_opt_found = 0;
 
-      if (last_source_file)
+      if (get_last_source_file ())
        {
          /* Check if previous symbol was also an N_SO (with some
             sanity checks).  If so, that one was actually the
@@ -3182,7 +3202,8 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
                  && gdbarch_sofun_address_maybe_missing (gdbarch))
                {
                  CORE_ADDR minsym_valu = 
-                   find_stab_function_addr (name, last_source_file, objfile);
+                   find_stab_function_addr (name, get_last_source_file (),
+                                            objfile);
 
                  /* The function find_stab_function_addr will return
                     0 if the minimal symbol wasn't found.
@@ -3226,8 +3247,7 @@ process_one_symbol (int type, int desc, CORE_ADDR valu, char *name,
                  /* For C++, set the block's scope.  */
                  if (SYMBOL_LANGUAGE (new->name) == language_cplus)
                    cp_set_block_scope (new->name, block,
-                                       &objfile->objfile_obstack,
-                                       "", 0);
+                                       &objfile->objfile_obstack);
                }
 
              new = push_context (0, valu);