2002-12-20 David Carlton <carlton@math.stanford.edu>
[deliverable/binutils-gdb.git] / gdb / buildsym.c
index 70105be01579dedcdfd641959f171912268bab82..8fdba5e28e0609137ffcd3ffbc2118dcbf56a260 100644 (file)
@@ -1,5 +1,6 @@
 /* Support routines for building symbol tables in GDB's internal format.
-   Copyright 1986-2000 Free Software Foundation, Inc.
+   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
+   1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 
 #include "defs.h"
 #include "bfd.h"
-#include "obstack.h"
+#include "gdb_obstack.h"
 #include "symtab.h"
-#include "symfile.h"           /* Needed for "struct complaint" */
+#include "symfile.h"
 #include "objfiles.h"
 #include "gdbtypes.h"
+#include "gdb_assert.h"
 #include "complaints.h"
 #include "gdb_string.h"
 #include "expression.h"                /* For "enum exp_opcode" used by... */
-#include "language.h"          /* For "longest_local_hex_string_custom" */
+#include "language.h"          /* For "local_hex_string" */
 #include "bcache.h"
+#include "filenames.h"         /* For DOSish file names */
+#include "macrotab.h"
+#include "demangle.h"          /* Needed by SYMBOL_INIT_DEMANGLED_NAME.  */
 /* Ask buildsym.h to define the vars it normally declares `extern'.  */
 #define        EXTERN
 /**/
@@ -68,23 +73,6 @@ static int compare_line_numbers (const void *ln1p, const void *ln2p);
 #define        INITIAL_LINE_VECTOR_LENGTH      1000
 \f
 
-/* Complaints about the symbols we have encountered.  */
-
-struct complaint block_end_complaint =
-{"block end address less than block start address in %s (patched it)", 0, 0};
-
-struct complaint anon_block_end_complaint =
-{"block end address 0x%lx less than block start address 0x%lx (patched it)", 0, 0};
-
-struct complaint innerblock_complaint =
-{"inner block not inside outer block in %s", 0, 0};
-
-struct complaint innerblock_anon_complaint =
-{"inner block (0x%lx-0x%lx) not inside outer block (0x%lx-0x%lx)", 0, 0};
-
-struct complaint blockvector_complaint =
-{"block at %s out of order", 0, 0};
-\f
 /* maintain the lists of symbols and blocks */
 
 /* Add a pending list to free_pendings. */
@@ -171,7 +159,7 @@ really_free_pendings (PTR dummy)
   for (next = free_pendings; next; next = next1)
     {
       next1 = next->next;
-      free ((void *) next);
+      xfree ((void *) next);
     }
   free_pendings = NULL;
 
@@ -180,16 +168,19 @@ really_free_pendings (PTR dummy)
   for (next = file_symbols; next != NULL; next = next1)
     {
       next1 = next->next;
-      free ((void *) next);
+      xfree ((void *) next);
     }
   file_symbols = NULL;
 
   for (next = global_symbols; next != NULL; next = next1)
     {
       next1 = next->next;
-      free ((void *) next);
+      xfree ((void *) next);
     }
   global_symbols = NULL;
+
+  if (pending_macros)
+    free_macro_table (pending_macros);
 }
 
 /* This function is called to discard any pending blocks. */
@@ -205,7 +196,7 @@ free_pending_blocks (void)
   for (bnext = pending_blocks; bnext; bnext = bnext1)
     {
       bnext1 = bnext->next;
-      free ((void *) bnext);
+      xfree ((void *) bnext);
     }
 #endif
   pending_blocks = NULL;
@@ -237,17 +228,49 @@ finish_block (struct symbol *symbol, struct pending **listhead,
       /* EMPTY */ ;
     }
 
-  block = (struct block *) obstack_alloc (&objfile->symbol_obstack,
-           (sizeof (struct block) + ((i - 1) * sizeof (struct symbol *))));
-
   /* Copy the symbols into the block.  */
 
-  BLOCK_NSYMS (block) = i;
-  for (next = *listhead; next; next = next->next)
+  if (symbol)
+    {
+      block = (struct block *) 
+       obstack_alloc (&objfile->symbol_obstack,
+                      (sizeof (struct block) + 
+                       ((i - 1) * sizeof (struct symbol *))));
+      BLOCK_NSYMS (block) = i;
+      for (next = *listhead; next; next = next->next)
+       for (j = next->nsyms - 1; j >= 0; j--)
+         {
+           BLOCK_SYM (block, --i) = next->symbol[j];
+         }
+    }
+  else
     {
-      for (j = next->nsyms - 1; j >= 0; j--)
+      int htab_size = BLOCK_HASHTABLE_SIZE (i);
+
+      block = (struct block *) 
+       obstack_alloc (&objfile->symbol_obstack,
+                      (sizeof (struct block) + 
+                       ((htab_size - 1) * sizeof (struct symbol *))));
+      for (j = 0; j < htab_size; j++)
+       {
+         BLOCK_BUCKET (block, j) = 0;
+       }
+      BLOCK_BUCKETS (block) = htab_size;
+      for (next = *listhead; next; next = next->next)
        {
-         BLOCK_SYM (block, --i) = next->symbol[j];
+         for (j = next->nsyms - 1; j >= 0; j--)
+           {
+             struct symbol *sym;
+             unsigned int hash_index;
+             const char *name = SYMBOL_DEMANGLED_NAME (next->symbol[j]);
+             if (name == NULL)
+               name = SYMBOL_NAME (next->symbol[j]);
+             hash_index = msymbol_hash_iw (name);
+             hash_index = hash_index % BLOCK_BUCKETS (block);
+             sym = BLOCK_BUCKET (block, hash_index);
+             BLOCK_BUCKET (block, hash_index) = next->symbol[j];
+             next->symbol[j]->hash_next = sym;
+           }
        }
     }
 
@@ -265,6 +288,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
       struct type *ftype = SYMBOL_TYPE (symbol);
       SYMBOL_BLOCK_VALUE (symbol) = block;
       BLOCK_FUNCTION (block) = symbol;
+      BLOCK_HASHTABLE (block) = 0;
 
       if (TYPE_NFIELDS (ftype) <= 0)
        {
@@ -273,9 +297,8 @@ finish_block (struct symbol *symbol, struct pending **listhead,
             parameter symbols. */
          int nparams = 0, iparams;
          struct symbol *sym;
-         for (i = 0; i < BLOCK_NSYMS (block); i++)
+         ALL_BLOCK_SYMBOLS (block, i, sym)
            {
-             sym = BLOCK_SYM (block, i);
              switch (SYMBOL_CLASS (sym))
                {
                case LOC_ARG:
@@ -321,6 +344,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
                    case LOC_BASEREG_ARG:
                    case LOC_LOCAL_ARG:
                      TYPE_FIELD_TYPE (ftype, iparams) = SYMBOL_TYPE (sym);
+                     TYPE_FIELD_ARTIFICIAL (ftype, iparams) = 0;
                      iparams++;
                      break;
                    case LOC_UNDEF:
@@ -346,6 +370,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
   else
     {
       BLOCK_FUNCTION (block) = NULL;
+      BLOCK_HASHTABLE (block) = 1;
     }
 
   /* Now "free" the links of the list, and empty the list.  */
@@ -366,11 +391,15 @@ finish_block (struct symbol *symbol, struct pending **listhead,
     {
       if (symbol)
        {
-         complain (&block_end_complaint, SYMBOL_SOURCE_NAME (symbol));
+         complaint (&symfile_complaints,
+                    "block end address less than block start address in %s (patched it)",
+                    SYMBOL_SOURCE_NAME (symbol));
        }
       else
        {
-         complain (&anon_block_end_complaint, BLOCK_END (block), BLOCK_START (block));
+         complaint (&symfile_complaints,
+                    "block end address 0x%s less than block start address 0x%s (patched it)",
+                    paddr_nz (BLOCK_END (block)), paddr_nz (BLOCK_START (block)));
        }
       /* Better than nothing */
       BLOCK_END (block) = BLOCK_START (block);
@@ -381,7 +410,9 @@ finish_block (struct symbol *symbol, struct pending **listhead,
      start of this scope that don't have superblocks yet.  */
 
   opblock = NULL;
-  for (pblock = pending_blocks; pblock != old_blocks; pblock = pblock->next)
+  for (pblock = pending_blocks; 
+       pblock && pblock != old_blocks; 
+       pblock = pblock->next)
     {
       if (BLOCK_SUPERBLOCK (pblock->block) == NULL)
        {
@@ -394,14 +425,18 @@ finish_block (struct symbol *symbol, struct pending **listhead,
            {
              if (symbol)
                {
-                 complain (&innerblock_complaint,
-                           SYMBOL_SOURCE_NAME (symbol));
+                 complaint (&symfile_complaints,
+                            "inner block not inside outer block in %s",
+                            SYMBOL_SOURCE_NAME (symbol));
                }
              else
                {
-                 complain (&innerblock_anon_complaint, BLOCK_START (pblock->block),
-                           BLOCK_END (pblock->block), BLOCK_START (block),
-                           BLOCK_END (block));
+                 complaint (&symfile_complaints,
+                            "inner block (0x%s-0x%s) not inside outer block (0x%s-0x%s)",
+                            paddr_nz (BLOCK_START (pblock->block)),
+                            paddr_nz (BLOCK_END (pblock->block)),
+                            paddr_nz (BLOCK_START (block)),
+                            paddr_nz (BLOCK_END (block)));
                }
              if (BLOCK_START (pblock->block) < BLOCK_START (block))
                BLOCK_START (pblock->block) = BLOCK_START (block);
@@ -445,11 +480,11 @@ record_pending_block (struct objfile *objfile, struct block *block,
     }
 }
 
-/* Note that this is only used in this file and in dstread.c, which
-   should be fixed to not need direct access to this function.  When
-   that is done, it can be made static again. */
+/* OBSOLETE Note that this is only used in this file and in dstread.c, which */
+/* OBSOLETE should be fixed to not need direct access to this function.  When */
+/* OBSOLETE that is done, it can be made static again. */
 
-struct blockvector *
+static struct blockvector *
 make_blockvector (struct objfile *objfile)
 {
   register struct pending_block *next;
@@ -486,7 +521,7 @@ make_blockvector (struct objfile *objfile)
   for (next = pending_blocks; next; next = next1)
     {
       next1 = next->next;
-      free (next);
+      xfree (next);
     }
 #endif
   pending_blocks = NULL;
@@ -506,8 +541,8 @@ make_blockvector (struct objfile *objfile)
              CORE_ADDR start
                = BLOCK_START (BLOCKVECTOR_BLOCK (blockvector, i));
 
-             complain (&blockvector_complaint,
-                       longest_local_hex_string ((LONGEST) start));
+             complaint (&symfile_complaints, "block at %s out of order",
+                        local_hex_string ((LONGEST) start));
            }
        }
     }
@@ -531,7 +566,7 @@ start_subfile (char *name, char *dirname)
 
   for (subfile = subfiles; subfile; subfile = subfile->next)
     {
-      if (STREQ (subfile->name, name))
+      if (FILENAME_CMP (subfile->name, name) == 0)
        {
          current_subfile = subfile;
          return;
@@ -667,7 +702,7 @@ push_subfile (void)
   subfile_stack = tem;
   if (current_subfile == NULL || current_subfile->name == NULL)
     {
-      abort ();
+      internal_error (__FILE__, __LINE__, "failed internal consistency check");
     }
   tem->name = current_subfile->name;
 }
@@ -680,11 +715,11 @@ pop_subfile (void)
 
   if (link == NULL)
     {
-      abort ();
+      internal_error (__FILE__, __LINE__, "failed internal consistency check");
     }
   name = link->name;
   subfile_stack = link->next;
-  free ((void *) link);
+  xfree ((void *) link);
   return (name);
 }
 \f
@@ -725,7 +760,7 @@ record_line (register struct subfile *subfile, int line, CORE_ADDR pc)
 
   e = subfile->line_vector->item + subfile->line_vector->nitems++;
   e->line = line;
-  e->pc = pc;
+  e->pc = ADDR_BITS_REMOVE(pc);
 }
 
 /* Needed in order to sort line tables from IBM xcoff files.  Sigh!  */
@@ -826,9 +861,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
             same.  FIXME: Find out why it is happening.  This is not
             believed to happen in most cases (even for coffread.c);
             it used to be an abort().  */
-         static struct complaint msg =
-         {"Context stack not empty in end_symtab", 0, 0};
-         complain (&msg);
+         complaint (&symfile_complaints,
+                    "Context stack not empty in end_symtab");
          context_stack_depth = 0;
        }
     }
@@ -881,7 +915,8 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
   if (pending_blocks == NULL
       && file_symbols == NULL
       && global_symbols == NULL
-      && have_line_numbers == 0)
+      && have_line_numbers == 0
+      && pending_macros == NULL)
     {
       /* Ignore symtabs that have no functions with real debugging
          info.  */
@@ -942,6 +977,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
 
          /* Fill in its components.  */
          symtab->blockvector = blockvector;
+          symtab->macro_table = pending_macros;
          if (subfile->line_vector)
            {
              /* Reallocate the line table on the symbol obstack */
@@ -993,23 +1029,23 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
        }
       if (subfile->name != NULL)
        {
-         free ((void *) subfile->name);
+         xfree ((void *) subfile->name);
        }
       if (subfile->dirname != NULL)
        {
-         free ((void *) subfile->dirname);
+         xfree ((void *) subfile->dirname);
        }
       if (subfile->line_vector != NULL)
        {
-         free ((void *) subfile->line_vector);
+         xfree ((void *) subfile->line_vector);
        }
       if (subfile->debugformat != NULL)
        {
-         free ((void *) subfile->debugformat);
+         xfree ((void *) subfile->debugformat);
        }
 
       nextsub = subfile->next;
-      free ((void *) subfile);
+      xfree ((void *) subfile);
     }
 
   /* Set this for the main source file.  */
@@ -1020,6 +1056,7 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
 
   last_source_file = NULL;
   current_subfile = NULL;
+  pending_macros = NULL;
 
   return symtab;
 }
@@ -1054,6 +1091,17 @@ push_context (int desc, CORE_ADDR valu)
 
   return new;
 }
+
+/* Pop a context block.  Returns the address of the context block just
+   popped. */
+
+struct context_stack *
+pop_context (void)
+{
+  gdb_assert (context_stack_depth > 0);
+  return (&context_stack[--context_stack_depth]);
+}
+
 \f
 
 /* Compute a small integer hash code for the given name. */
@@ -1104,12 +1152,13 @@ merge_symbol_lists (struct pending **srclist, struct pending **targetlist)
    corresponding to a psymtab.  */
 
 void
-buildsym_init ()
+buildsym_init (void)
 {
   free_pendings = NULL;
   file_symbols = NULL;
   global_symbols = NULL;
   pending_blocks = NULL;
+  pending_macros = NULL;
 }
 
 /* Initialize anything that needs initializing when a completely new
@@ -1117,7 +1166,7 @@ buildsym_init ()
    file, e.g. a shared library).  */
 
 void
-buildsym_new_init ()
+buildsym_new_init (void)
 {
   buildsym_init ();
 }
This page took 0.055616 seconds and 4 git commands to generate.