Removed superflous code.
[deliverable/binutils-gdb.git] / gdb / coffread.c
index ec7aef24346fffc284931d464a5593d57bb2944e..cb2661b60915168d11e334c90467f687360f417f 100644 (file)
@@ -1,5 +1,5 @@
 /* Read coff symbol tables and convert to internal format, for GDB.
-   Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994
+   Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997
              Free Software Foundation, Inc.
    Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
 
@@ -17,7 +17,7 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include "defs.h"
 #include "symtab.h"
@@ -25,7 +25,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "breakpoint.h"
 
 #include "bfd.h"
-#include <obstack.h>
+#include "obstack.h"
 
 #include "gdb_string.h"
 #include <ctype.h>
@@ -129,6 +129,10 @@ static unsigned    local_linesz;
 static unsigned        local_symesz;
 static unsigned        local_auxesz;
 
+/* This is set if this is a PE format file.  */
+
+static int pe_file;
+
 /* Chain of typedefs of pointers to empty struct/union types.
    They are chained thru the SYMBOL_VALUE_CHAIN.  */
 
@@ -139,6 +143,12 @@ static struct symbol *opaque_type_chain[HASHSIZE];
 struct complaint ef_complaint = 
   {"Unmatched .ef symbol(s) ignored starting at symnum %d", 0, 0};
 
+struct complaint ef_stack_complaint = 
+  {"`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d", 0, 0};
+
+struct complaint eb_stack_complaint = 
+  {"`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d", 0, 0};
+
 struct complaint bf_no_aux_complaint =
   {"`.bf' symbol %d has no aux entry", 0, 0};
 
@@ -317,7 +327,7 @@ static int cs_to_section PARAMS ((struct coff_symbol *, struct objfile *));
 
 struct find_targ_sec_arg {
   int targ_index;
-  int *resultp;
+  asection **resultp;
 };
 
 static void find_targ_sec PARAMS ((bfd *, asection *, void *));
@@ -329,15 +339,7 @@ static void find_targ_sec (abfd, sect, obj)
 {
   struct find_targ_sec_arg *args = (struct find_targ_sec_arg *)obj;
   if (sect->target_index == args->targ_index)
-    {
-      /* This is the section.  Figure out what SECT_OFF_* code it is.  */
-      if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
-       *args->resultp = SECT_OFF_TEXT;
-      else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
-       *args->resultp = SECT_OFF_DATA;
-      else
-       *args->resultp = SECT_OFF_BSS;
-    }
+    *args->resultp = sect;
 }
 
 /* Return the section number (SECT_OFF_*) that CS points to.  */
@@ -346,14 +348,47 @@ cs_to_section (cs, objfile)
      struct coff_symbol *cs;
      struct objfile *objfile;
 {
-  int off = SECT_OFF_TEXT;
+  asection *sect = NULL;
   struct find_targ_sec_arg args;
+  int off = SECT_OFF_TEXT;
+
   args.targ_index = cs->c_secnum;
-  args.resultp = &off;
+  args.resultp = &sect;
   bfd_map_over_sections (objfile->obfd, find_targ_sec, &args);
+  if (sect != NULL)
+    {
+      /* This is the section.  Figure out what SECT_OFF_* code it is.  */
+      if (bfd_get_section_flags (abfd, sect) & SEC_CODE)
+       off = SECT_OFF_TEXT;
+      else if (bfd_get_section_flags (abfd, sect) & SEC_LOAD)
+       off = SECT_OFF_DATA;
+      else
+       off = SECT_OFF_BSS;
+    }
   return off;
 }
 
+/* Return the address of the section of a COFF symbol.  */
+
+static CORE_ADDR cs_section_address PARAMS ((struct coff_symbol *, bfd *));
+
+static CORE_ADDR
+cs_section_address (cs, abfd)
+     struct coff_symbol *cs;
+     bfd *abfd;
+{
+  asection *sect = NULL;
+  struct find_targ_sec_arg args;
+  CORE_ADDR addr = 0;
+
+  args.targ_index = cs->c_secnum;
+  args.resultp = &sect;
+  bfd_map_over_sections (abfd, find_targ_sec, &args);
+  if (sect != NULL)
+    addr = bfd_get_section_vma (objfile->obfd, sect);
+  return addr;
+}
+
 /* Look up a coff type-number index.  Return the address of the slot
    where the type for that index is stored.
    The type-number is in INDEX. 
@@ -446,6 +481,7 @@ coff_start_symtab ()
                /* The start address is irrelevant, since we set
                   last_source_start_addr in coff_end_symtab.  */
                0);
+  record_debugformat ("COFF");
 
   /* Initialize the source file line number information for this file.  */
 
@@ -510,9 +546,7 @@ coff_end_symtab (objfile)
   subfiles->line_vector = line_vector;
   subfiles->name = last_source_file;
 
-  /* sort_pending is needed for amdcoff, at least.
-     sort_linevec is needed for the SCO compiler.  */
-  symtab = end_symtab (current_source_end_addr, 1, 1, objfile, 0);
+  symtab = end_symtab (current_source_end_addr, objfile, 0);
 
   if (symtab != NULL)
     free_named_symtabs (symtab->filename);
@@ -533,10 +567,7 @@ record_minimal_symbol (name, address, type, objfile)
   /* We don't want TDESC entry points in the minimal symbol table */
   if (name[0] == '@') return;
 
-  prim_record_minimal_symbol
-    (obsavestring (name, strlen (name), &objfile->symbol_obstack),
-     address, type,
-     objfile);
+  prim_record_minimal_symbol (name, address, type, objfile);
 }
 \f
 /* coff_symfile_init ()
@@ -568,6 +599,11 @@ coff_symfile_init (objfile)
 
   memset (objfile->sym_private, 0, sizeof (struct coff_symfile_info));
 
+  /* COFF objects may be reordered, so set OBJF_REORDERED.  If we
+     find this causes a significant slowdown in gdb then we could
+     set it in the debug symbol readers only when necessary.  */
+  objfile->flags |= OBJF_REORDERED;
+
   init_entry_point_info (objfile);
 }
 
@@ -635,7 +671,7 @@ coff_symfile_read (objfile, section_offsets, mainline)
   int stabstrsize;
 
   info = (struct coff_symfile_info *) objfile -> sym_private;
-  dbxinfo = (struct dbx_symfile_info *) objfile->sym_stab_info;
+  dbxinfo = objfile->sym_stab_info;
   symfile_bfd = abfd;                  /* Kludge for swap routines */
 
 /* WARNING WILL ROBINSON!  ACCESSING BFD-PRIVATE DATA HERE!  FIXME!  */
@@ -661,6 +697,14 @@ coff_symfile_read (objfile, section_offsets, mainline)
         (cdata->local_symesz + cdata->local_auxesz);
   temp_aux = temp_sym + cdata->local_symesz;
   back_to = make_cleanup (free_current_contents, &temp_sym);
+
+  /* We need to know whether this is a PE file, because in PE files,
+     unlike standard COFF files, symbol values are stored as offsets
+     from the section address, rather than as absolute addresses.
+     FIXME: We should use BFD to read the symbol table, and thus avoid
+     this problem.  */
+  pe_file = strncmp (bfd_get_target (objfile->obfd), "pe", 2) == 0;
+
 /* End of warning */
 
   /* Read the line number table, all at once.  */
@@ -824,13 +868,6 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
 
       read_one_sym (cs, &main_sym, &main_aux);
 
-#ifdef SEM
-      temp_sem_val = cs->c_name[0] << 24 | cs->c_name[1] << 16 |
-                     cs->c_name[2] << 8 | cs->c_name[3];
-      if (int_sem_val == temp_sem_val)
-        last_coffsem = (int) strtol (cs->c_name+4, (char **) NULL, 10);
-#endif
-
       if (cs->c_symnum == next_file_symnum && cs->c_sclass != C_FILE)
        {
          if (last_source_file)
@@ -892,7 +929,14 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
            in_source_file = 1;
            break;
 
+         /* C_LABEL is used for labels and static functions.  Including
+            it here allows gdb to see static functions when no debug
+            info is available.  */
+         case C_LABEL:
           case C_STAT:
+         case C_THUMBLABEL:
+         case C_THUMBSTAT:
+         case C_THUMBSTATFUNC:
            if (cs->c_name[0] == '.')
              {
                if (STREQ (cs->c_name, ".text")) {
@@ -924,6 +968,8 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
                 that look like this.  Ignore them.  */
              break;
            /* fall in for static symbols that don't start with '.' */
+         case C_THUMBEXT:
+         case C_THUMBEXTFUNC:
          case C_EXT:
            {
              /* Record it in the minimal symbols regardless of
@@ -950,13 +996,16 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
                  /* The address has already been relocated; make sure that
                     objfile_relocate doesn't relocate it again.  */
                  sec = -2;
-                 ms_type = cs->c_sclass == C_STAT ? mst_file_bss : mst_bss;
+                 ms_type = cs->c_sclass == C_EXT
+                           || cs->c_sclass == C_THUMBEXT ?
+                              mst_bss : mst_file_bss;
                }
              else
                {
                  sec = cs_to_section (cs, objfile);
                  tmpaddr = cs->c_value;
-                 if (cs->c_sclass != C_STAT)
+                 if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
+                     || cs->c_sclass == C_THUMBEXT)
                    tmpaddr += ANOFFSET (section_offsets, sec);
 
                  switch (sec)
@@ -964,15 +1013,23 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
                    case SECT_OFF_TEXT:
                    case SECT_OFF_RODATA:
                      ms_type =
-                       cs->c_sclass == C_STAT ? mst_file_text : mst_text;
+                       cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXTFUNC
+                                       || cs->c_sclass == C_THUMBEXT ?
+                                         mst_text : mst_file_text;
+#ifdef SMASH_TEXT_ADDRESS
+                     if (tmpaddr & 1)  /* FIXME: delete this line */
+                       SMASH_TEXT_ADDRESS (tmpaddr);
+#endif
                      break;
                    case SECT_OFF_DATA:
                      ms_type =
-                       cs->c_sclass == C_STAT ? mst_file_data : mst_data;
+                       cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+                         mst_data : mst_file_data;
                      break;
                    case SECT_OFF_BSS:
                      ms_type =
-                       cs->c_sclass == C_STAT ? mst_file_bss : mst_bss;
+                       cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+                         mst_data : mst_file_data;
                      break;
                    default:
                      ms_type = mst_unknown;
@@ -982,13 +1039,8 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
 
              if (cs->c_name[0] != '@' /* Skip tdesc symbols */)
                prim_record_minimal_symbol_and_info
-                 (obsavestring (cs->c_name, strlen (cs->c_name),
-                                &objfile->symbol_obstack),
-                  tmpaddr,
-                  ms_type,
-                  NULL,
-                  sec,
-                  objfile);
+                 (cs->c_name, tmpaddr, ms_type, (char *)cs->c_sclass, sec,
+                  NULL, objfile);
 
              if (SDB_TYPE (cs->c_type))
                {
@@ -1029,6 +1081,14 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
                   not useful for gdb.  */
                /* { main_aux.x_sym.x_misc.x_lnsz.x_lnno
                            contains number of lines to '}' */
+
+               if (context_stack_depth <= 0)
+                 {             /* We attempted to pop an empty context stack */
+                   complain (&ef_stack_complaint, cs->c_symnum);
+                   within_function = 0;
+                   break;
+                 }
+
                new = pop_context ();
                /* Stack must be empty now.  */
                if (context_stack_depth > 0 || new == NULL)
@@ -1082,6 +1142,12 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
              }
            else if (STREQ (cs->c_name, ".eb"))
              {
+               if (context_stack_depth <= 0)
+                 {             /* We attempted to pop an empty context stack */
+                   complain (&eb_stack_complaint, cs->c_symnum);
+                   break;
+                 }
+
                new = pop_context ();
                if (depth-- != new->depth)
                  {
@@ -1154,7 +1220,40 @@ read_one_sym (cs, sym, aux)
   if (!SDB_TYPE (cs->c_type))
     cs->c_type = 0;
 
+#if 0
+  if (cs->c_sclass & 128)
+    printf("thumb symbol %s, class 0x%x\n", cs->c_name, cs->c_sclass);
+#endif
+
   symnum += 1 + cs->c_naux;
+
+  /* The PE file format stores symbol values as offsets within the
+     section, rather than as absolute addresses.  We correct that
+     here, if the symbol has an appropriate storage class.  FIXME: We
+     should use BFD to read the symbols, rather than duplicating the
+     work here.  */
+  if (pe_file)
+    {
+      switch (cs->c_sclass)
+       {
+       case C_EXT:
+       case C_THUMBEXT:
+       case C_THUMBEXTFUNC:
+       case C_SECTION:
+       case C_NT_WEAK:
+       case C_STAT:
+       case C_THUMBSTAT:
+       case C_THUMBSTATFUNC:
+       case C_LABEL:
+       case C_THUMBLABEL:
+       case C_BLOCK:
+       case C_FCN:
+       case C_EFCN:
+         if (cs->c_secnum != 0)
+           cs->c_value += cs_section_address (cs, symfile_bfd);
+         break;
+       }
+    }
 }
 \f
 /* Support for string table handling */
@@ -1182,7 +1281,7 @@ init_stringtab (abfd, offset)
 
   val = bfd_read ((char *)lengthbuf, sizeof lengthbuf, 1, abfd);
   length = bfd_h_get_32 (symfile_bfd, lengthbuf);
-
+       
   /* If no string table is needed, then the file may end immediately
      after the symbols.  Just return with `stringtab' set to null. */
   if (val != sizeof lengthbuf || length < sizeof lengthbuf)
@@ -1458,8 +1557,8 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
   memset (sym, 0, sizeof (struct symbol));
   name = cs->c_name;
   name = EXTERNAL_NAME (name, objfile->obfd);
-  SYMBOL_NAME (sym) = obstack_copy0 (&objfile->symbol_obstack, name,
-                                    strlen (name));
+  SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
+                                   &objfile->symbol_obstack);
 
   /* default assumptions */
   SYMBOL_VALUE (sym) = cs->c_value;
@@ -1473,9 +1572,11 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
         lookup_function_type (decode_function_type (cs, cs->c_type, aux));
 
       SYMBOL_CLASS (sym) = LOC_BLOCK;
-      if (cs->c_sclass == C_STAT)
+      if (cs->c_sclass == C_STAT || cs->c_sclass == C_THUMBSTAT
+         || cs->c_sclass == C_THUMBSTATFUNC)
        add_symbol_to_list (sym, &file_symbols);
-      else if (cs->c_sclass == C_EXT)
+      else if (cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT
+              || cs->c_sclass == C_THUMBEXTFUNC)
        add_symbol_to_list (sym, &global_symbols);
     }
   else
@@ -1491,6 +1592,8 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
            add_symbol_to_list (sym, &local_symbols);
            break;
 
+         case C_THUMBEXT:
+         case C_THUMBEXTFUNC:
          case C_EXT:
            SYMBOL_CLASS (sym) = LOC_STATIC;
            SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
@@ -1498,6 +1601,8 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
            add_symbol_to_list (sym, &global_symbols);
            break;
 
+         case C_THUMBSTAT:
+         case C_THUMBSTATFUNC:
          case C_STAT:
            SYMBOL_CLASS (sym) = LOC_STATIC;
            SYMBOL_VALUE_ADDRESS (sym) = (CORE_ADDR) cs->c_value;
@@ -1521,6 +1626,7 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
            add_symbol_to_list (sym, &local_symbols);
            break;
 
+         case C_THUMBLABEL:
          case C_LABEL:
            break;
 
@@ -1802,6 +1908,9 @@ decode_base_type (cs, c_type, aux)
       case T_DOUBLE:
        return lookup_fundamental_type (current_objfile, FT_DBL_PREC_FLOAT);
 
+      case T_LNGDBL:
+       return lookup_fundamental_type (current_objfile, FT_EXT_PREC_FLOAT);
+
       case T_STRUCT:
        if (cs->c_naux != 1)
          {
@@ -1948,9 +2057,9 @@ coff_read_struct_type (index, length, lastsym)
              obsavestring (name,
                            strlen (name),
                            &current_objfile->symbol_obstack);
-           list->field.type = decode_type (ms, ms->c_type, &sub_aux);
-           list->field.bitpos = 8 * ms->c_value;
-           list->field.bitsize = 0;
+           FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
+           FIELD_BITPOS (list->field) = 8 * ms->c_value;
+           FIELD_BITSIZE (list->field) = 0;
            nfields++;
            break;
 
@@ -1966,9 +2075,9 @@ coff_read_struct_type (index, length, lastsym)
              obsavestring (name,
                            strlen (name),
                            &current_objfile->symbol_obstack);
-           list->field.type = decode_type (ms, ms->c_type, &sub_aux);
-           list->field.bitpos = ms->c_value;
-           list->field.bitsize = sub_aux.x_sym.x_misc.x_lnsz.x_size;
+           FIELD_TYPE (list->field) = decode_type (ms, ms->c_type, &sub_aux);
+           FIELD_BITPOS (list->field) = ms->c_value;
+           FIELD_BITSIZE (list->field) = sub_aux.x_sym.x_misc.x_lnsz.x_size;
            nfields++;
            break;
 
@@ -2015,6 +2124,7 @@ coff_read_enum_type (index, length, lastsym)
   int o_nsyms;
   register int n;
   char *name;
+  int unsigned_enum = 1;
 
   type = coff_alloc_type (index);
   if (within_function)
@@ -2087,35 +2197,19 @@ coff_read_enum_type (index, length, lastsym)
          struct symbol *xsym = syms->symbol[j];
          SYMBOL_TYPE (xsym) = type;
          TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
-         TYPE_FIELD_VALUE (type, n) = 0;
          TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
+         if (SYMBOL_VALUE (xsym) < 0)
+           unsigned_enum = 0;
          TYPE_FIELD_BITSIZE (type, n) = 0;
        }
       if (syms == osyms)
        break;
     }
 
-  return type;
-}
-
-struct section_offsets *
-coff_symfile_offsets (objfile, addr)
-     struct objfile *objfile;
-     CORE_ADDR addr;
-{
-  struct section_offsets *section_offsets;
-  int i;
-
-  objfile->num_sections = SECT_OFF_MAX;
-  section_offsets = (struct section_offsets *)
-    obstack_alloc (&objfile -> psymbol_obstack,
-                  sizeof (struct section_offsets)
-                  + sizeof (section_offsets->offsets) * SECT_OFF_MAX);
+  if (unsigned_enum)
+    TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
 
-  for (i = 0; i < SECT_OFF_MAX; i++)
-    ANOFFSET (section_offsets, i) = addr;
-  
-  return section_offsets;
+  return type;
 }
 
 /* Register our ability to parse symbols for coff BFD files. */
@@ -2127,7 +2221,8 @@ static struct sym_fns coff_sym_fns =
   coff_symfile_init,   /* sym_init: read initial info, setup for sym_read() */
   coff_symfile_read,   /* sym_read: read a symbol file into symtab */
   coff_symfile_finish, /* sym_finish: finished with file, cleanup */
-  coff_symfile_offsets, /* sym_offsets:  xlate external to internal form */
+  default_symfile_offsets,
+                       /* sym_offsets:  xlate external to internal form */
   NULL                 /* next: pointer to next struct sym_fns */
 };
 
This page took 0.033156 seconds and 4 git commands to generate.