]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gdb/dbxread.c
This commit was generated by cvs2svn to track changes on a CVS vendor
[thirdparty/binutils-gdb.git] / gdb / dbxread.c
index 6463f27209fee96dcfddc1a6c3aec1ade5711a2d..0749412cc35d23ca7f358170a932984a11d0c500 100644 (file)
@@ -1,5 +1,5 @@
 /* Read dbx symbol tables and convert to internal format, for GDB.
-   Copyright 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+   Copyright 1986, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 1998
    Free Software Foundation, Inc.
 
 This file is part of GDB.
@@ -62,6 +62,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "aout/stab_gnu.h"     /* We always use GNU stabs, not native, now */
 
 \f
+/* This macro returns the size field of a minimal symbol, which is normally
+   stored in the "info" field.  The macro can be overridden for specific
+   targets (e.g. MIPS16) that use the info field for other purposes.  */
+#ifndef MSYMBOL_SIZE
+#define MSYMBOL_SIZE(msym) ((long) MSYMBOL_INFO (msym))
+#endif
+
+
 /* We put a pointer to this structure in the read_symtab_private field
    of the psymtab.  */
 
@@ -101,18 +109,12 @@ struct symloc {
 #define FILE_STRING_OFFSET(p) (SYMLOC(p)->file_string_offset)
 
 \f
-/* Macro to determine which symbols to ignore when reading the first symbol
-   of a file.  Some machines override this definition. */
-#ifndef IGNORE_SYMBOL
-/* This code is used on Ultrix systems.  Ignore it */
-#define IGNORE_SYMBOL(type)  (type == (int)N_NSYMS)
-#endif
-
 /* Remember what we deduced to be the source language of this psymtab. */
 
 static enum language psymtab_language = language_unknown;
 
 /* Nonzero means give verbose info on gdb action.  From main.c.  */
+
 extern int info_verbose;
 
 /* The BFD for this file -- implicit parameter to next_symbol_text.  */
@@ -125,28 +127,31 @@ static bfd *symfile_bfd;
 
 static unsigned symbol_size;
 
-/* This is the offset of the symbol table in the executable file */
+/* This is the offset of the symbol table in the executable file. */
+
 static unsigned symbol_table_offset;
 
-/* This is the offset of the string table in the executable file */
+/* This is the offset of the string table in the executable file. */
+
 static unsigned string_table_offset;
 
 /* For elf+stab executables, the n_strx field is not a simple index
-   into the string table.  Instead, each .o file has a base offset
-   in the string table, and the associated symbols contain offsets
-   from this base.  The following two variables contain the base
-   offset for the current and next .o files. */
+   into the string table.  Instead, each .o file has a base offset in
+   the string table, and the associated symbols contain offsets from
+   this base.  The following two variables contain the base offset for
+   the current and next .o files. */
+
 static unsigned int file_string_table_offset;
 static unsigned int next_file_string_table_offset;
 
-/* .o and NLM files contain unrelocated addresses which are based at 0.  When
-   non-zero, this flag disables some of the special cases for Solaris elf+stab
-   text addresses at location 0. */
+/* .o and NLM files contain unrelocated addresses which are based at
+   0.  When non-zero, this flag disables some of the special cases for
+   Solaris elf+stab text addresses at location 0. */
 
 static int symfile_relocatable = 0;
 
-  /* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are relative
-     to the function start address.  */
+/* If this is nonzero, N_LBRAC, N_RBRAC, and N_SLINE entries are
+   relative to the function start address.  */
 
 static int block_address_function_relative = 0;
 \f
@@ -155,8 +160,14 @@ static int block_address_function_relative = 0;
    what address the program is actually going to be loaded at, so we
    need to make guesses based on the symbols (which *are* relocated to
    reflect the address it will be loaded at).  */
+
 static CORE_ADDR lowest_text_address;
 
+/* Non-zero if there is any line number info in the objfile.  Prevents
+   end_psymtab from discarding an otherwise empty psymtab.  */
+
+static int has_line_numbers;
+
 /* Complaints about the symbols we have encountered.  */
 
 struct complaint lbrac_complaint = 
@@ -561,10 +572,10 @@ dbx_symfile_read (objfile, section_offsets, mainline)
   symbol_table_offset = DBX_SYMTAB_OFFSET (objfile);
 
   free_pending_blocks ();
-  back_to = make_cleanup (really_free_pendings, 0);
+  back_to = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
 
   init_minimal_symbol_collection ();
-  make_cleanup (discard_minimal_symbols, 0);
+  make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
 
   /* Now that the symbol table data of the executable file are all in core,
      process them and define symbols accordingly.  */
@@ -625,7 +636,7 @@ dbx_symfile_init (objfile)
   unsigned char size_temp[DBX_STRINGTAB_SIZE_SIZE];
 
   /* Allocate struct to keep track of the symfile */
-  objfile->sym_stab_info = (PTR)
+  objfile->sym_stab_info = (struct dbx_symfile_info *)
     xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info));
   memset ((PTR) objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
 
@@ -773,7 +784,7 @@ struct cont_elem
     int sym_idx;
     int sym_end;
     int symnum;
-    int (*func) (struct objfile *, struct symbol *, char *);
+    int (*func) PARAMS ((struct objfile *, struct symbol *, char *));
     /* other state dependancies include:
        (assumption is that these will not change since process_now FIXME!!)
         stringtab_global
@@ -786,21 +797,29 @@ static struct cont_elem *cont_list = 0;
 static int cont_limit = 0;
 static int cont_count = 0;
 
+/* Arrange for function F to be called with arguments SYM and P later
+   in the stabs reading process.  */
 void 
 process_later (sym, p, f)
-  struct symbol * sym;
-  char * p;
-  int (*f) (struct objfile *, struct symbol *, char *);
+  struct symbol *sym;
+  char *p;
+  int (*f) PARAMS ((struct objfile *, struct symbol *, char *));
 {
+
+  /* Allocate more space for the deferred list.  */
   if (cont_count >= cont_limit - 1)
     {
       cont_limit += 32;        /* chunk size */
-      cont_list = (struct cont_elem *) realloc (cont_list, 
-                                       cont_limit * sizeof (struct cont_elem));
+
+      cont_list
+       = (struct cont_elem *) xrealloc (cont_list, 
+                                         (cont_limit
+                                          * sizeof (struct cont_elem)));
       if (!cont_list)
         error ("Virtual memory exhausted\n");
     }
-  /* save state so we can process these stabs later */
+
+  /* Save state variables so we can process these stabs later.  */
   cont_list[cont_count].sym_idx = symbuf_idx;
   cont_list[cont_count].sym_end = symbuf_end;
   cont_list[cont_count].symnum = symnum;
@@ -810,40 +829,49 @@ process_later (sym, p, f)
   cont_count++;
 }
 
+/* Call deferred funtions in CONT_LIST.  */
+
 static void 
 process_now (objfile) 
-  struct objfile * objfile;
+  struct objfile *objfile;
 {
   int i;
-  /* save original state */
-  int save_symbuf_idx = symbuf_idx;
-  int save_symbuf_end = symbuf_end;
-  int save_symnum = symnum;
+  int save_symbuf_idx;
+  int save_symbuf_end;
+  int save_symnum;
   struct symbol *sym;
   char *stabs;
   int err;
-  int (*func) (struct objfile *, struct symbol *, char *);
+  int (*func) PARAMS ((struct objfile *, struct symbol *, char *));
 
-  for (i=0; i<cont_count; i++) 
+  /* Save the state of our caller, we'll want to restore it before
+     returning.  */
+  save_symbuf_idx = symbuf_idx;
+  save_symbuf_end = symbuf_end;
+  save_symnum = symnum;
+
+  /* Iterate over all the deferred stabs.  */
+  for (i = 0; i < cont_count; i++)
     {
-      /* Set state as if we were parsing stabs strings 
-         for this symbol */
-      symbuf_idx = cont_list[i].sym_idx;   /* statics used by gdb */
+      /* Restore the state for this deferred stab.  */
+      symbuf_idx = cont_list[i].sym_idx;
       symbuf_end = cont_list[i].sym_end;  
       symnum = cont_list[i].symnum;  
       sym = cont_list[i].sym;
       stabs = cont_list[i].stabs;
       func = cont_list[i].func;
 
+      /* Call the function to handle this deferrd stab.  */
       err = (*func) (objfile, sym, stabs);
       if (err)
        error ("Internal error: unable to resolve stab.\n");
     }
-  /* restore original state */
+
+  /* Restore our caller's state.  */
   symbuf_idx = save_symbuf_idx;
   symbuf_end = save_symbuf_end;
   symnum = save_symnum;
-  cont_count=0;  /* reset for next run */
+  cont_count = 0;
 }
 
 
@@ -1224,7 +1252,7 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
 
   /* Init bincl list */
   init_bincl_list (20, objfile);
-  back_to = make_cleanup (free_bincl_list, objfile);
+  back_to = make_cleanup ((make_cleanup_func) free_bincl_list, objfile);
 
   last_source_file = NULL;
 
@@ -1235,6 +1263,7 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
   symbuf_end = symbuf_idx = 0;
   next_symbol_text_func = dbx_next_symbol_text;
   textlow_not_set = 1;
+  has_line_numbers = 0;
 
   for (symnum = 0; symnum < DBX_SYMCOUNT (objfile); symnum++)
     {
@@ -1248,7 +1277,10 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
        * Special case to speed up readin.
        */
       if (bfd_h_get_8 (abfd, bufp->e_type) == N_SLINE)
-       continue;
+       {
+         has_line_numbers = 1;
+         continue;
+       }
 
       INTERNALIZE_SYMBOL (nlist, bufp, abfd);
       OBJSTAT (objfile, n_stabs++);
@@ -1304,12 +1336,16 @@ read_dbx_symtab (section_offsets, objfile, text_addr, text_size)
 
   if (pst)
     {
+      /* Don't set pst->texthigh lower than it already is.  */
+      CORE_ADDR text_end =
+       (lowest_text_address == (CORE_ADDR)-1
+        ? (text_addr + section_offsets->offsets[SECT_OFF_TEXT])
+        : lowest_text_address)
+       + text_size;
+
       end_psymtab (pst, psymtab_include_list, includes_used,
                   symnum * symbol_size,
-                  (lowest_text_address == (CORE_ADDR)-1
-                   ? (text_addr + section_offsets->offsets[SECT_OFF_TEXT])
-                   : lowest_text_address)
-                  + text_size,
+                  text_end > pst->texthigh ? text_end : pst->texthigh,
                   dependency_list, dependencies_used, textlow_not_set);
     }
 
@@ -1410,15 +1446,23 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
       if (p == NULL)
        p = last_function_name;
       n = p - last_function_name;
-      p = alloca (n + 1);
+      p = alloca (n + 2);
       strncpy (p, last_function_name, n);
       p[n] = 0;
     
       minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+      if (minsym == NULL)
+       {
+         /* Sun Fortran appends an underscore to the minimal symbol name,
+            try again with an appended underscore if the minimal symbol
+            was not found.  */
+         p[n] = '_';
+         p[n + 1] = 0;
+         minsym = lookup_minimal_symbol (p, pst->filename, objfile);
+       }
 
       if (minsym)
-       pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym)
-         + (long) MSYMBOL_INFO (minsym);
+       pst->texthigh = SYMBOL_VALUE_ADDRESS (minsym) + MSYMBOL_SIZE (minsym);
 
       last_function_name = NULL;
     }
@@ -1510,7 +1554,8 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
   if (num_includes == 0
       && number_dependencies == 0
       && pst->n_global_syms == 0
-      && pst->n_static_syms == 0)
+      && pst->n_static_syms == 0
+      && has_line_numbers == 0)
     {
       /* Throw away this psymtab, it's empty.  We can't deallocate it, since
         it is on the obstack, but we can forget to chain it on the list.  */
@@ -1519,21 +1564,8 @@ end_psymtab (pst, include_list, num_includes, capping_symbol_offset,
         is wrong, in that a psymtab with N_SLINE entries but nothing else
         is not empty, but we don't realize that.  Fixing that without slowing
         things down might be tricky.  */
-      struct partial_symtab *prev_pst;
-
-      /* First, snip it out of the psymtab chain */
-
-      if (pst->objfile->psymtabs == pst)
-       pst->objfile->psymtabs = pst->next;
-      else
-       for (prev_pst = pst->objfile->psymtabs; prev_pst; prev_pst = pst->next)
-         if (prev_pst->next == pst)
-           prev_pst->next = pst->next;
 
-      /* Next, put it on a free list for recycling */
-
-      pst->next = pst->objfile->free_psymtabs;
-      pst->objfile->free_psymtabs = pst;
+      discard_psymtab (pst);
 
       /* Indicate that psymtab was thrown away.  */
       pst = (struct partial_symtab *)NULL;
@@ -1581,7 +1613,7 @@ dbx_psymtab_to_symtab_1 (pst)
       /* Init stuff necessary for reading in symbols */
       stabsread_init ();
       buildsym_init ();
-      old_chain = make_cleanup (really_free_pendings, 0);
+      old_chain = make_cleanup ((make_cleanup_func) really_free_pendings, 0);
       file_string_table_offset = FILE_STRING_OFFSET (pst);
       symbol_size = SYMBOL_SIZE (pst);
 
@@ -1808,7 +1840,7 @@ read_ofile_symtab (pst)
   pst->symtab = end_symtab (text_offset + text_size, objfile, SECT_OFF_TEXT);
 
   /* Process items which we had to "process_later" due to dependancies 
-     on other stabs. */
+     on other stabs.  */
   process_now (objfile);       
 
   end_stabs ();
@@ -1874,9 +1906,9 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
 
   if (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 gracefully with the
-        case.  A complain()t might be in order (if !IGNORE_SYMBOL (type)),
+      /* Ignore any symbols which appear before an N_SO symbol.
+        Currently no one puts symbols there, but we should deal
+        gracefully with the case.  A complain()t might be in order,
         but this should not be an error ().  */
       return;
     }
@@ -1897,11 +1929,20 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
          finish_block (new->name, &local_symbols, new->old_blocks,
                        new->start_addr, new->start_addr + valu,
                        objfile);
+
+         /* May be switching to an assembler file which may not be using
+            block relative stabs, so reset the offset.  */
+         if (block_address_function_relative)
+           function_start_offset = 0;
+
          break;
        }
 
       /* Relocate for dynamic loading */
       valu += ANOFFSET (section_offsets, SECT_OFF_TEXT);
+#ifdef SMASH_TEXT_ADDRESS
+      SMASH_TEXT_ADDRESS (valu);
+#endif
       goto define_a_symbol;
 
     case N_LBRAC:
@@ -1912,10 +1953,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
       if (n_opt_found && desc == 1)
        break;
 
-#if defined(BLOCK_ADDRESS_ABSOLUTE)
-      /* Relocate for dynamic loading (?).  */
-      valu += function_start_offset;
-#else
       if (block_address_function_relative)
        /* Relocate for Sun ELF acc fn-relative syms.  */
        valu += function_start_offset;
@@ -1923,7 +1960,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
        /* On most machines, the block addresses are relative to the
           N_SO, the linker did not relocate them (sigh).  */
        valu += last_source_start_addr;
-#endif
 
 #ifdef SUN_FIXED_LBRAC_BUG
       if (!SUN_FIXED_LBRAC_BUG && valu < last_pc_address) {
@@ -1943,10 +1979,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
       if (n_opt_found && desc == 1)
        break;
 
-#if defined(BLOCK_ADDRESS_ABSOLUTE)
-      /* Relocate for dynamic loading (?).  */
-      valu += function_start_offset;
-#else
       if (block_address_function_relative)
        /* Relocate for Sun ELF acc fn-relative syms.  */
        valu += function_start_offset;
@@ -1954,7 +1986,6 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
        /* On most machines, the block addresses are relative to the
           N_SO, the linker did not relocate them (sigh).  */
        valu += last_source_start_addr;
-#endif
 
       new = pop_context();
       if (desc != new->depth)
@@ -2060,6 +2091,9 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
       if (*name == '\000')
        break;
 
+      if (block_address_function_relative)
+        function_start_offset = 0;
+
       start_stabs ();
       start_symtab (name, NULL, valu);
       record_debugformat ("stabs");
@@ -2093,8 +2127,10 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
       /* This type of "symbol" really just records
         one line-number -- core-address correspondence.
         Enter it in the line list for this symbol table.  */
+
       /* Relocate for dynamic loading and for ELF acc fn-relative syms.  */
       valu += function_start_offset;
+
 #ifdef SUN_FIXED_LBRAC_BUG
       last_pc_address = valu;  /* Save for SunOS bug circumcision */
 #endif
@@ -2239,12 +2275,22 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
                  if (p == NULL)
                    p = name;
                  n = p - name;
-                 p = alloca (n + 1);
+                 p = alloca (n + 2);
                  strncpy (p, name, n);
                  p[n] = 0;
 
                  msym = lookup_minimal_symbol (p, last_source_file,
                                                objfile);
+                 if (msym == NULL)
+                   {
+                     /* Sun Fortran appends an underscore to the minimal
+                        symbol name, try again with an appended underscore
+                        if the minimal symbol was not found.  */
+                     p[n] = '_';
+                     p[n + 1] = 0;
+                     msym = lookup_minimal_symbol (p, last_source_file,
+                                                   objfile);
+                   }
                  if (msym)
                    valu = SYMBOL_VALUE_ADDRESS (msym);
                }
@@ -2360,29 +2406,34 @@ process_one_symbol (type, desc, valu, name, section_offsets, objfile)
                    file's symbols at once.  */
     case N_ENDM:               /* Solaris 2:  End of module */
     case N_MAIN:               /* Name of main routine.  */
+    case N_ALIAS:              /* SunPro F77: alias name, ignore for now.  */
       break;
     }
 
-  /* Special GNU C extension for referencing names.  */
+  /* '#' is a GNU C extension to allow one symbol to refer to another
+     related symbol.
+
+     Generally this is used so that an alias can refer to its main
+     symbol.  */  
   if (name[0] == '#')
     {
       /* Initialize symbol reference names and determine if this is 
          a definition.  If symbol reference is being defined, go 
          ahead and add it.  Otherwise, just return sym. */
-      char *s;
+
+      char *s = name;
       int refnum;
-      extern int symbol_reference_defined (char **);
-      extern void ref_add (int, struct symbol *, char *, CORE_ADDR);
-      extern struct symbol * ref_search (int);
-
-      /* If defined, store away a pointer to the symbol;
-        we'll use it later when we resolve references in
-        "resolve_symbol_reference". */
-      s = name;
-      if (refnum = symbol_reference_defined (&s), refnum)
+
+      /* If this stab defines a new reference ID that is not on the
+        reference list, then put it on the reference list.
+
+        We go ahead and advance NAME past the reference, even though
+        it is not strictly necessary at this time.  */
+      refnum = symbol_reference_defined (&s);
+      if (refnum >= 0)
        if (!ref_search (refnum))
          ref_add (refnum, 0, name, valu);
-      name = s;                /* Advance past refid. */
+      name = s;
     }
 
 
@@ -2623,7 +2674,8 @@ stabsect_build_psymtabs (objfile, section_offsets, mainline, stab_name,
     error ("stabsect_build_psymtabs:  Found stabs (%s), but not string section (%s)",
           stab_name, stabstr_name);
 
-  objfile->sym_stab_info = (PTR) xmalloc (sizeof (struct dbx_symfile_info));
+  objfile->sym_stab_info = (struct dbx_symfile_info *)
+    xmalloc (sizeof (struct dbx_symfile_info));
   memset (objfile->sym_stab_info, 0, sizeof (struct dbx_symfile_info));
 
   text_sect = bfd_get_section_by_name (sym_bfd, text_name);