* mips-tdep.c (init_extra_frame_info): Use frame relative stack
[deliverable/binutils-gdb.git] / gdb / buildsym.c
index a25190a6168054fd9b1e698bb85e84cf23984ce5..58eb157e6116da5de0185a7115a0f11844df2963 100644 (file)
@@ -31,6 +31,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "symtab.h"
 #include "symfile.h"           /* Needed for "struct complaint" */
 #include "objfiles.h"
+#include "complaints.h"
 #include <string.h>
 
 /* Ask buildsym.h to define the vars it normally declares `extern'.  */
@@ -38,6 +39,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "buildsym.h"          /* Our own declarations */
 #undef EXTERN
 
+/* For cleanup_undefined_types and finish_global_stabs (somewhat
+   questionable--see comment where we call them).  */
+#include "stabsread.h"
+
 static int
 compare_line_numbers PARAMS ((const void *, const void *));
 
@@ -61,7 +66,7 @@ struct complaint innerblock_anon_complaint =
   {"inner block not inside outer block", 0, 0};
 
 struct complaint blockvector_complaint = 
-  {"block at 0x%x out of order", 0, 0};
+  {"block at 0x%lx out of order", 0, 0};
 
 \f
 /* maintain the lists of symbols and blocks */
@@ -97,7 +102,8 @@ add_symbol_to_list (symbol, listhead)
   (*listhead)->symbol[(*listhead)->nsyms++] = symbol;
 }
 
-/* Find a symbol on a pending list.  */
+/* Find a symbol named NAME on a LIST.  NAME need not be '\0'-terminated;
+   LENGTH is the length of the name.  */
 
 struct symbol *
 find_symbol_in_list (list, name, length)
@@ -256,11 +262,12 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
            {
              if (symbol)
                {
-                 complain (&innerblock_complaint, SYMBOL_NAME (symbol));
+                 complain (&innerblock_complaint,
+                           SYMBOL_SOURCE_NAME (symbol));
                }
              else
                {
-                 complain (&innerblock_anon_complaint, 0);
+                 complain (&innerblock_anon_complaint);
                }
              BLOCK_START (pblock->block) = BLOCK_START (block);
              BLOCK_END   (pblock->block) = BLOCK_END   (block);
@@ -295,7 +302,7 @@ finish_block (symbol, listhead, old_blocks, start, end, objfile)
 
 static struct blockvector *
 make_blockvector (objfile)
-      struct objfile *objfile;
+     struct objfile *objfile;
 {
   register struct pending_block *next;
   register struct blockvector *blockvector;
@@ -345,7 +352,7 @@ make_blockvector (objfile)
              > BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)))
            {
              complain (&blockvector_complaint, 
-                       (char *) BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)));
+                       (unsigned long) BLOCK_START(BLOCKVECTOR_BLOCK (blockvector, i)));
            }
        }
     }
@@ -356,7 +363,9 @@ make_blockvector (objfile)
 
 \f
 /* Start recording information about source code that came from an included
-   (or otherwise merged-in) source file with a different name.  */
+   (or otherwise merged-in) source file with a different name.  NAME is
+   the name of the file (cannot be NULL), DIRNAME is the directory in which
+   it resides (or NULL if not known).  */
 
 void
 start_subfile (name, dirname)
@@ -370,7 +379,7 @@ start_subfile (name, dirname)
 
   for (subfile = subfiles; subfile; subfile = subfile->next)
     {
-      if (!strcmp (subfile->name, name))
+      if (STREQ (subfile->name, name))
        {
          current_subfile = subfile;
          return;
@@ -387,11 +396,57 @@ start_subfile (name, dirname)
   current_subfile = subfile;
 
   /* Save its name and compilation directory name */
-  subfile->name = strdup (name);
+  subfile->name = (name == NULL)? NULL : strdup (name);
   subfile->dirname = (dirname == NULL) ? NULL : strdup (dirname);
   
   /* Initialize line-number recording for this subfile.  */
   subfile->line_vector = NULL;
+
+  /* Default the source language to whatever can be deduced from
+     the filename.  If nothing can be deduced (such as for a C/C++
+     include file with a ".h" extension), then inherit whatever
+     language the previous subfile had.  This kludgery is necessary
+     because there is no standard way in some object formats to
+     record the source language.  Also, when symtabs are allocated
+     we try to deduce a language then as well, but it is too late
+     for us to use that information while reading symbols, since
+     symtabs aren't allocated until after all the symbols have
+     been processed for a given source file. */
+
+  subfile->language = deduce_language_from_filename (subfile->name);
+  if (subfile->language == language_unknown &&
+      subfile->next != NULL)
+    {
+      subfile->language = subfile->next->language;
+    }
+
+  /* cfront output is a C program, so in most ways it looks like a C
+     program.  But to demangle we need to set the language to C++.  We
+     can distinguish cfront code by the fact that it has #line
+     directives which specify a file name ending in .C.
+
+     So if the filename of this subfile ends in .C, then change the language
+     of any pending subfiles from C to C++.  We also accept any other C++
+     suffixes accepted by deduce_language_from_filename (in particular,
+     some people use .cxx with cfront).  */
+
+  if (subfile->name)
+    {
+      struct subfile *s;
+
+      if (deduce_language_from_filename (subfile->name) == language_cplus)
+       for (s = subfiles; s != NULL; s = s->next)
+         if (s->language == language_c)
+           s->language = language_cplus;
+    }
+
+  /* And patch up this file if necessary.  */
+  if (subfile->language == language_c
+      && subfile->next != NULL
+      && subfile->next->language == language_cplus)
+    {
+      subfile->language = language_cplus;
+    }
 }
 
 /* For stabs readers, the first N_SO symbol is assumed to be the source
@@ -416,6 +471,24 @@ patch_subfile_names (subfile, name)
     {
       subfile->dirname = subfile->name;
       subfile->name = strdup (name);
+
+      /* Default the source language to whatever can be deduced from
+        the filename.  If nothing can be deduced (such as for a C/C++
+        include file with a ".h" extension), then inherit whatever
+        language the previous subfile had.  This kludgery is necessary
+        because there is no standard way in some object formats to
+        record the source language.  Also, when symtabs are allocated
+        we try to deduce a language then as well, but it is too late
+        for us to use that information while reading symbols, since
+        symtabs aren't allocated until after all the symbols have
+        been processed for a given source file. */
+
+      subfile->language = deduce_language_from_filename (subfile->name);
+      if (subfile->language == language_unknown &&
+         subfile->next != NULL)
+       {
+         subfile->language = subfile->next->language;
+       }
     }
 }
 
@@ -457,7 +530,8 @@ pop_subfile ()
 }
 
 \f
-/* Manage the vector of line numbers for each subfile.  */
+/* Add a linetable entry for line number LINE and address PC to the line
+   vector for SUBFILE.  */
 
 void
 record_line (subfile, line, pc)
@@ -503,8 +577,20 @@ compare_line_numbers (ln1p, ln2p)
      const PTR ln1p;
      const PTR ln2p;
 {
-  return (((struct linetable_entry *) ln1p) -> line -
-         ((struct linetable_entry *) ln2p) -> line);
+  struct linetable_entry *ln1 = (struct linetable_entry *) ln1p;
+  struct linetable_entry *ln2 = (struct linetable_entry *) ln2p;
+
+  /* Note: this code does not assume that CORE_ADDRs can fit in ints.
+     Please keep it that way.  */
+  if (ln1->pc < ln2->pc)
+    return -1;
+
+  if (ln1->pc > ln2->pc)
+    return 1;
+
+  /* If pc equal, sort by line.  I'm not sure whether this is optimum
+     behavior (see comment at struct linetable in symtab.h).  */
+  return ln1->line - ln2->line;
 }
 
 \f
@@ -550,6 +636,8 @@ start_symtab (name, dirname, start_addr)
    for that file and put it in the list of all such.
 
    END_ADDR is the address of the end of the file's text.
+   SECTION is the section number (in objfile->section_offsets) of
+   the blockvector and linetable.
 
    Note that it is possible for end_symtab() to return NULL.  In particular,
    for the DWARF case at least, it will return NULL when it finds a
@@ -559,13 +647,14 @@ start_symtab (name, dirname, start_addr)
    because then gdb will never know about this empty file (FIXME). */
 
 struct symtab *
-end_symtab (end_addr, sort_pending, sort_linevec, objfile)
+end_symtab (end_addr, sort_pending, sort_linevec, objfile, section)
      CORE_ADDR end_addr;
      int sort_pending;
      int sort_linevec;
      struct objfile *objfile;
+     int section;
 {
-  register struct symtab *symtab;
+  register struct symtab *symtab = NULL;
   register struct blockvector *blockvector;
   register struct subfile *subfile;
   register struct context_stack *cstk;
@@ -582,11 +671,16 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
       finish_block (cstk->name, &local_symbols, cstk->old_blocks,
                    cstk->start_addr, end_addr, objfile);
 
-      /* Debug: if context stack still has something in it,
-        we are in trouble.  */
       if (context_stack_depth > 0)
        {
-         abort ();
+         /* This is said to happen with SCO.  The old coffread.c code
+            simply emptied the context stack, so we do the 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);
+         context_stack_depth = 0;
        }
     }
 
@@ -627,7 +721,13 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
   /* Cleanup any undefined types that have been left hanging around
      (this needs to be done before the finish_blocks so that
      file_symbols is still good).
-     FIXME:  Stabs specific. */
+
+     Both cleanup_undefined_types and finish_global_stabs are stabs
+     specific, but harmless for other symbol readers, since on gdb
+     startup or when finished reading stabs, the state is set so these
+     are no-ops.  FIXME: Is this handled right in case of QUIT?  Can
+     we make this cleaner?  */
+
   cleanup_undefined_types ();
   finish_global_stabs (objfile);
 
@@ -657,7 +757,7 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
 
   for (subfile = subfiles; subfile; subfile = nextsub)
     {
-      int linetablesize;
+      int linetablesize = 0;
       /* If we have blocks of symbols, make a symtab.
         Otherwise, just ignore this file and any line number info in it.  */
       symtab = NULL;
@@ -665,11 +765,20 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
        {
          if (subfile->line_vector)
            {
-             /* First, shrink the linetable to make more memory.  */
              linetablesize = sizeof (struct linetable) +
                subfile->line_vector->nitems * sizeof (struct linetable_entry);
+#if 0
+             /* I think this is artifact from before it went on the obstack.
+                I doubt we'll need the memory between now and when we
+                free it later in this function.  */
+             /* First, shrink the linetable to make more memory.  */
              subfile->line_vector = (struct linetable *)
                xrealloc ((char *) subfile->line_vector, linetablesize);
+#endif
+             /* If sort_linevec is false, we might want just check to make
+                sure they are sorted and complain() if not, as a way of
+                tracking down compilers/symbol readers which don't get
+                them sorted right.  */
 
              if (sort_linevec)
                qsort (subfile->line_vector->item,
@@ -693,6 +802,7 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
            {
              symtab->linetable = NULL;
            }
+         symtab->block_line_section = section;
          if (subfile->dirname)
            {
              /* Reallocate the dirname on the symbol obstack */
@@ -708,14 +818,18 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
          symtab->free_code = free_linetable;
          symtab->free_ptr = NULL;
 
-#ifdef IBM6000_TARGET
-         /* In case we need to duplicate symbol tables (to represent include
-            files), and in case our system needs relocation, we want to
-            relocate the main symbol table node only (for the main file,
-            not for the include files). */
+         /* Use whatever language we have been using for this subfile,
+            not the one that was deduced in allocate_symtab from the
+            filename.  We already did our own deducing when we created
+            the subfile, and we may have altered our opinion of what
+            language it is from things we found in the symbols. */
+         symtab->language = subfile->language;
 
-         symtab->nonreloc = TRUE;
-#endif
+         /* All symtabs for the main file and the subfiles share a
+            blockvector, so we need to clear primary for everything but
+            the main file.  */
+
+         symtab->primary = 0;
        }
       if (subfile->name != NULL)
        {
@@ -734,14 +848,11 @@ end_symtab (end_addr, sort_pending, sort_linevec, objfile)
       free ((PTR)subfile);
     }
 
-#ifdef IBM6000_TARGET
-  /* all include symbol tables are non-relocatable, except the main source
-     file's. */
+  /* Set this for the main source file.  */
   if (symtab)
     {
-      symtab->nonreloc = FALSE;
+      symtab->primary = 1;
     }
-#endif
 
   last_source_file = NULL;
   current_subfile = NULL;
@@ -780,6 +891,37 @@ push_context (desc, valu)
   return (new);
 }
 
+\f
+/* Compute a small integer hash code for the given name. */
+
+int
+hashname (name)
+     char *name;
+{
+  register char *p = name;
+  register int total = p[0];
+  register int c;
+
+  c = p[1];
+  total += c << 2;
+  if (c)
+    {
+      c = p[2];
+      total += c << 4;
+      if (c)
+       {
+         total += p[3] << 6;
+       }
+    }
+
+  /* Ensure result is positive.  */
+  if (total < 0)
+    {
+      total += (1000 << 6);
+    }
+  return (total % HASHSIZE);
+}
+
 \f
 /* Initialize anything that needs initializing when starting to read
    a fresh piece of a symbol file, e.g. reading in the stuff corresponding
This page took 0.027658 seconds and 4 git commands to generate.