* gdb.base/help.exp: Allow Win32 child process.
[deliverable/binutils-gdb.git] / gdb / coffread.c
index 52b36c88c34307b53e70f58d7e41588fd0c33a04..0f36b9509d1838c5cc92ea21aed10688b48cbfc6 100644 (file)
@@ -1,6 +1,6 @@
 /* Read coff symbol tables and convert to internal format, for GDB.
    Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996,
-   1997, 1998, 1999, 2000, 2001, 2002
+   1997, 1998, 1999, 2000, 2001, 2002, 2003
    Free Software Foundation, Inc.
    Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
 
@@ -44,6 +44,9 @@
 #include "complaints.h"
 #include "target.h"
 #include "gdb_assert.h"
+#include "block.h"
+
+#include "coff-pe-read.h"
 
 extern void _initialize_coffread (void);
 
@@ -122,41 +125,6 @@ static int pe_file;
 
 static struct symbol *opaque_type_chain[HASHSIZE];
 
-/* Complaints about various problems in the file being read  */
-
-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};
-
-struct complaint ef_no_aux_complaint =
-{"`.ef' symbol %d has no aux entry", 0, 0};
-
-struct complaint lineno_complaint =
-{"Line number pointer %d lower than start of line numbers", 0, 0};
-
-struct complaint unexpected_type_complaint =
-{"Unexpected type for symbol %s", 0, 0};
-
-struct complaint bad_sclass_complaint =
-{"Bad n_sclass for symbol %s", 0, 0};
-
-struct complaint misordered_blocks_complaint =
-{"Blocks out of order at address %x", 0, 0};
-
-struct complaint tagndx_bad_complaint =
-{"Symbol table entry for %s has bad tagndx value", 0, 0};
-
-struct complaint eb_complaint =
-{"Mismatched .eb symbol ignored starting at symnum %d", 0, 0};
-
 /* Simplified internal version of coff symbol table information */
 
 struct coff_symbol
@@ -550,7 +518,7 @@ coff_symfile_read (struct objfile *objfile, int mainline)
   unsigned int num_symbols;
   int symtab_offset;
   int stringtab_offset;
-  struct cleanup *back_to;
+  struct cleanup *back_to, *cleanup_minimal_symbols;
   int stabstrsize;
   int len;
   char * target;
@@ -593,16 +561,34 @@ coff_symfile_read (struct objfile *objfile, int mainline)
 
 /* End of warning */
 
-  /* Read the line number table, all at once.  */
   info->min_lineno_offset = 0;
   info->max_lineno_offset = 0;
-  bfd_map_over_sections (abfd, find_linenos, (void *) info);
 
-  make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
-  val = init_lineno (abfd, info->min_lineno_offset,
-                    info->max_lineno_offset - info->min_lineno_offset);
-  if (val < 0)
-    error ("\"%s\": error reading line numbers\n", name);
+  /* Only read line number information if we have symbols.
+
+     On Windows NT, some of the system's DLL's have sections with
+     PointerToLinenumbers fields that are non-zero, but point at
+     random places within the image file.  (In the case I found,
+     KERNEL32.DLL's .text section has a line number info pointer that
+     points into the middle of the string `lib\\i386\kernel32.dll'.)
+
+     However, these DLL's also have no symbols.  The line number
+     tables are meaningless without symbols.  And in fact, GDB never
+     uses the line number information unless there are symbols.  So we
+     can avoid spurious error messages (and maybe run a little
+     faster!) by not even reading the line number table unless we have
+     symbols.  */
+  if (num_symbols > 0)
+    {
+      /* Read the line number table, all at once.  */
+      bfd_map_over_sections (abfd, find_linenos, (void *) info);
+
+      make_cleanup (free_linetab_cleanup, 0 /*ignore*/);
+      val = init_lineno (abfd, info->min_lineno_offset,
+                         info->max_lineno_offset - info->min_lineno_offset);
+      if (val < 0)
+        error ("\"%s\": error reading line numbers\n", name);
+    }
 
   /* Now read the string table, all at once.  */
 
@@ -612,7 +598,7 @@ coff_symfile_read (struct objfile *objfile, int mainline)
     error ("\"%s\": can't get string table", name);
 
   init_minimal_symbol_collection ();
-  make_cleanup_discard_minimal_symbols ();
+  cleanup_minimal_symbols = make_cleanup_discard_minimal_symbols ();
 
   /* Now that the executable file is positioned at symbol table,
      process it and define symbols accordingly.  */
@@ -633,6 +619,9 @@ coff_symfile_read (struct objfile *objfile, int mainline)
 
   install_minimal_symbols (objfile);
 
+  /* Free the installed minimal symbol data.  */
+  do_cleanups (cleanup_minimal_symbols);
+
   bfd_map_over_sections (abfd, coff_locate_sections, (void *) info);
 
   if (info->stabsects)
@@ -803,7 +792,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
        case C_LINE:
        case C_ALIAS:
        case C_HIDDEN:
-         complain (&bad_sclass_complaint, cs->c_name);
+         complaint (&symfile_complaints, "Bad n_sclass for symbol %s",
+                    cs->c_name);
          break;
 
        case C_FILE:
@@ -969,7 +959,8 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
              /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
                 contains line number of '{' } */
              if (cs->c_naux != 1)
-               complain (&bf_no_aux_complaint, cs->c_symnum);
+               complaint (&symfile_complaints,
+                          "`.bf' symbol %d has no aux entry", cs->c_symnum);
              fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
              fcn_first_line_addr = cs->c_value;
 
@@ -993,7 +984,9 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
 
              if (context_stack_depth <= 0)
                {               /* We attempted to pop an empty context stack */
-                 complain (&ef_stack_complaint, cs->c_symnum);
+                 complaint (&symfile_complaints,
+                            "`.ef' symbol without matching `.bf' symbol ignored starting at symnum %d",
+                            cs->c_symnum);
                  within_function = 0;
                  break;
                }
@@ -1002,13 +995,16 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
              /* Stack must be empty now.  */
              if (context_stack_depth > 0 || new == NULL)
                {
-                 complain (&ef_complaint, cs->c_symnum);
+                 complaint (&symfile_complaints,
+                            "Unmatched .ef symbol(s) ignored starting at symnum %d",
+                            cs->c_symnum);
                  within_function = 0;
                  break;
                }
              if (cs->c_naux != 1)
                {
-                 complain (&ef_no_aux_complaint, cs->c_symnum);
+                 complaint (&symfile_complaints,
+                            "`.ef' symbol %d has no aux entry", cs->c_symnum);
                  fcn_last_line = 0x7FFFFFFF;
                }
              else
@@ -1063,14 +1059,18 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
            {
              if (context_stack_depth <= 0)
                {               /* We attempted to pop an empty context stack */
-                 complain (&eb_stack_complaint, cs->c_symnum);
+                 complaint (&symfile_complaints,
+                            "`.eb' symbol without matching `.bb' symbol ignored starting at symnum %d",
+                            cs->c_symnum);
                  break;
                }
 
              new = pop_context ();
              if (depth-- != new->depth)
                {
-                 complain (&eb_complaint, symnum);
+                 complaint (&symfile_complaints,
+                            "Mismatched .eb symbol ignored starting at symnum %d",
+                            symnum);
                  break;
                }
              if (local_symbols && context_stack_depth > 0)
@@ -1092,6 +1092,13 @@ coff_symtab_read (long symtab_offset, unsigned int nsyms,
        }
     }
 
+  if ((nsyms == 0) && (pe_file))
+    {
+      /* We've got no debugging symbols, but it's is a portable
+        executable, so try to read the export table */
+      read_pe_exported_syms (objfile);
+    }
+
   if (last_source_file)
     coff_end_symtab (objfile);
 
@@ -1349,7 +1356,9 @@ enter_linenos (long file_offset, register int first_line,
     return;
   if (file_offset < linetab_offset)
     {
-      complain (&lineno_complaint, file_offset);
+      complaint (&symfile_complaints,
+                "Line number pointer %ld lower than start of line numbers",
+                file_offset);
       if (file_offset > linetab_size)  /* Too big to be an offset? */
        return;
       file_offset += linetab_offset;   /* Try reading at that linetab offset */
@@ -1420,15 +1429,15 @@ patch_opaque_types (struct symtab *s)
          TYPE_CODE (SYMBOL_TYPE (real_sym)) == TYPE_CODE_PTR &&
          TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (real_sym))) != 0)
        {
-         register char *name = SYMBOL_NAME (real_sym);
+         register char *name = DEPRECATED_SYMBOL_NAME (real_sym);
          register int hash = hashname (name);
          register struct symbol *sym, *prev;
 
          prev = 0;
          for (sym = opaque_type_chain[hash]; sym;)
            {
-             if (name[0] == SYMBOL_NAME (sym)[0] &&
-                 STREQ (name + 1, SYMBOL_NAME (sym) + 1))
+             if (name[0] == DEPRECATED_SYMBOL_NAME (sym)[0] &&
+                 STREQ (name + 1, DEPRECATED_SYMBOL_NAME (sym) + 1))
                {
                  if (prev)
                    {
@@ -1473,10 +1482,8 @@ process_coff_symbol (register struct coff_symbol *cs,
   memset (sym, 0, sizeof (struct symbol));
   name = cs->c_name;
   name = EXTERNAL_NAME (name, objfile->obfd);
-  SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
-                                   &objfile->symbol_obstack);
   SYMBOL_LANGUAGE (sym) = language_auto;
-  SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
+  SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
   /* default assumptions */
   SYMBOL_VALUE (sym) = cs->c_value;
@@ -1632,7 +1639,7 @@ process_coff_symbol (register struct coff_symbol *cs,
                }
              else
                TYPE_NAME (SYMBOL_TYPE (sym)) =
-                 concat (SYMBOL_NAME (sym), NULL);
+                 concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
            }
 #ifdef CXUX_TARGET
          /* Ignore vendor section for Harris CX/UX targets. */
@@ -1650,7 +1657,7 @@ process_coff_symbol (register struct coff_symbol *cs,
              TYPE_CODE (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
              TYPE_CODE_UNDEF)
            {
-             register int i = hashname (SYMBOL_NAME (sym));
+             register int i = hashname (DEPRECATED_SYMBOL_NAME (sym));
 
              SYMBOL_VALUE_CHAIN (sym) = opaque_type_chain[i];
              opaque_type_chain[i] = sym;
@@ -1668,11 +1675,11 @@ process_coff_symbol (register struct coff_symbol *cs,
             names for anonymous enums, structures, and unions, like
             "~0fake" or ".0fake".  Thanks, but no thanks... */
          if (TYPE_TAG_NAME (SYMBOL_TYPE (sym)) == 0)
-           if (SYMBOL_NAME (sym) != NULL
-               && *SYMBOL_NAME (sym) != '~'
-               && *SYMBOL_NAME (sym) != '.')
+           if (DEPRECATED_SYMBOL_NAME (sym) != NULL
+               && *DEPRECATED_SYMBOL_NAME (sym) != '~'
+               && *DEPRECATED_SYMBOL_NAME (sym) != '.')
              TYPE_TAG_NAME (SYMBOL_TYPE (sym)) =
-               concat (SYMBOL_NAME (sym), NULL);
+               concat (DEPRECATED_SYMBOL_NAME (sym), NULL);
 
          add_symbol_to_list (sym, &file_symbols);
          break;
@@ -1754,7 +1761,9 @@ decode_type (register struct coff_symbol *cs, unsigned int c_type,
        }
       else
        {
-         complain (&tagndx_bad_complaint, cs->c_name);
+         complaint (&symfile_complaints,
+                    "Symbol table entry for %s has bad tagndx value",
+                    cs->c_name);
          /* And fall through to decode_base_type... */
        }
     }
@@ -1920,7 +1929,7 @@ decode_base_type (register struct coff_symbol *cs, unsigned int c_type,
       else
        return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
     }
-  complain (&unexpected_type_complaint, cs->c_name);
+  complaint (&symfile_complaints, "Unexpected type for symbol %s", cs->c_name);
   return lookup_fundamental_type (current_objfile, FT_VOID);
 }
 \f
@@ -1979,6 +1988,7 @@ coff_read_struct_type (int index, int length, int lastsym)
          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;
+         FIELD_STATIC_KIND (list->field) = 0;
          nfields++;
          break;
 
@@ -1997,6 +2007,7 @@ coff_read_struct_type (int index, int length, int lastsym)
          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;
+         FIELD_STATIC_KIND (list->field) = 0;
          nfields++;
          break;
 
@@ -2064,7 +2075,7 @@ coff_read_enum_type (int index, int length, int lastsym)
             sizeof (struct symbol));
          memset (sym, 0, sizeof (struct symbol));
 
-         SYMBOL_NAME (sym) =
+         DEPRECATED_SYMBOL_NAME (sym) =
            obsavestring (name, strlen (name),
                          &current_objfile->symbol_obstack);
          SYMBOL_CLASS (sym) = LOC_CONST;
@@ -2112,11 +2123,12 @@ coff_read_enum_type (int index, int length, int lastsym)
        {
          struct symbol *xsym = syms->symbol[j];
          SYMBOL_TYPE (xsym) = type;
-         TYPE_FIELD_NAME (type, n) = SYMBOL_NAME (xsym);
+         TYPE_FIELD_NAME (type, n) = DEPRECATED_SYMBOL_NAME (xsym);
          TYPE_FIELD_BITPOS (type, n) = SYMBOL_VALUE (xsym);
          if (SYMBOL_VALUE (xsym) < 0)
            unsigned_enum = 0;
          TYPE_FIELD_BITSIZE (type, n) = 0;
+         TYPE_FIELD_STATIC_KIND (type, n) = 0;
        }
       if (syms == osyms)
        break;
This page took 0.036539 seconds and 4 git commands to generate.