import gdb-1999-05-10
[deliverable/binutils-gdb.git] / gdb / coffread.c
index ddd05117bebcb0b507155f28d1a863353057209d..ae1decaf728e374b19eee77a66de925fc16845db 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, 88, 89, 90, 91, 92, 93, 94, 96, 97, 1998
              Free Software Foundation, Inc.
    Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
 
@@ -17,17 +17,19 @@ 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"
 #include "gdbtypes.h"
+#include "demangle.h"
 #include "breakpoint.h"
 
 #include "bfd.h"
-#include <obstack.h>
+#include "obstack.h"
 
-#include <string.h>
+#include "gdb_string.h"
+#include <ctype.h>
 
 #include "coff/internal.h"     /* Internal format of COFF symbols in BFD */
 #include "libcoff.h"           /* FIXME secret internal data from BFD */
@@ -44,9 +46,10 @@ struct coff_symfile_info {
   file_ptr min_lineno_offset;          /* Where in file lowest line#s are */
   file_ptr max_lineno_offset;          /* 1+last byte of line#s in file */
 
-  asection *stabsect;          /* Section pointer for .stab section */
+  CORE_ADDR textaddr;                  /* Addr of .text section. */
+  unsigned int textsize;               /* Size of .text section. */
+  struct stab_section_list *stabsects; /* .stab sections.  */
   asection *stabstrsect;               /* Section pointer for .stab section */
-  asection *stabindexsect;     /* Section pointer for .stab.index section */
   char *stabstrdata;
 };
 
@@ -81,21 +84,6 @@ static CORE_ADDR current_source_end_addr;
 static bfd *nlist_bfd_global;
 static int nlist_nsyms_global;
 
-/* Vector of line number information.  */
-
-static struct linetable *line_vector;
-
-/* Index of next entry to go in line_vector_index.  */
-
-static int line_vector_index;
-
-/* Last line number recorded in the line vector.  */
-
-static int prev_line_number;
-
-/* Number of elements allocated for line_vector currently.  */
-
-static int line_vector_length;
 
 /* Pointers to scratch storage, used for reading raw symbols and auxents.  */
 
@@ -127,23 +115,26 @@ 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.  */
 
 static struct symbol *opaque_type_chain[HASHSIZE];
 
-#if 0
-/* The type of the function we are currently reading in.  This is
-   used by define_symbol to record the type of arguments to a function. */
-
-struct type *in_function_type;
-#endif
-
 /* 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};
 
@@ -212,6 +203,8 @@ static int init_lineno PARAMS ((bfd *, long, int));
 
 static char *getsymname PARAMS ((struct internal_syment *));
 
+static char *coff_getfilename PARAMS ((union internal_auxent *));
+
 static void free_stringtab PARAMS ((void));
 
 static int init_stringtab PARAMS ((bfd *, long));
@@ -242,9 +235,7 @@ static void coff_end_symtab PARAMS ((struct objfile *));
 
 static void complete_symtab PARAMS ((char *, CORE_ADDR, unsigned int));
 
-static void coff_start_symtab PARAMS ((void));
-
-static void coff_record_line PARAMS ((int, CORE_ADDR));
+static void coff_start_symtab PARAMS ((char *));
 
 static struct type *coff_alloc_type PARAMS ((int));
 
@@ -263,25 +254,55 @@ static void coff_locate_sections PARAMS ((bfd *, asection *, PTR));
    -kingdon).  */
 
 static void
-coff_locate_sections (ignore_abfd, sectp, csip)
-     bfd *ignore_abfd;
+coff_locate_sections (abfd, sectp, csip)
+     bfd *abfd;
      asection *sectp;
      PTR csip;
 {
   register struct coff_symfile_info *csi;
+  const char *name;
 
   csi = (struct coff_symfile_info *) csip;
-  if (STREQ (sectp->name, ".stab"))
+  name = bfd_get_section_name (abfd, sectp);
+  if (STREQ (name, ".text"))
+    {
+      csi->textaddr = bfd_section_vma (abfd, sectp);
+      csi->textsize += bfd_section_size (abfd, sectp);
+    }
+  else if (strncmp (name, ".text", sizeof ".text" - 1) == 0)
     {
-      csi->stabsect = sectp;
+      csi->textsize += bfd_section_size (abfd, sectp);
     }
-  else if (STREQ (sectp->name, ".stabstr"))
+  else if (STREQ (name, ".stabstr"))
     {
       csi->stabstrsect = sectp;
     }
-  else if (STREQ (sectp->name, ".stab.index"))
+  else if (strncmp (name, ".stab", sizeof ".stab" - 1) == 0)
     {
-      csi->stabindexsect = sectp;
+      const char *s;
+
+      /* We can have multiple .stab sections if linked with
+         --split-by-reloc.  */
+      for (s = name + sizeof ".stab" - 1; *s != '\0'; s++)
+       if (! isdigit (*s))
+         break;
+      if (*s == '\0')
+       {
+         struct stab_section_list *n, **pn;
+
+         n = ((struct stab_section_list *)
+              xmalloc (sizeof (struct stab_section_list)));
+         n->section = sectp;
+         n->next = NULL;
+         for (pn = &csi->stabsects; *pn != NULL; pn = &(*pn)->next)
+           ;
+         *pn = n;
+
+         /* This will be run after coffstab_build_psymtabs is called
+             in coff_symfile_read, at which point we no longer need
+             the information.  */
+         make_cleanup (free, n);
+       }
     }
 }
 
@@ -290,7 +311,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 *));
@@ -302,15 +323,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.  */
@@ -319,14 +332,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. 
@@ -377,59 +423,26 @@ coff_alloc_type (index)
   return type;
 }
 \f
-/* Record a line number entry for line LINE at address PC.
-   FIXME:  Use record_line instead.  */
-
-static void
-coff_record_line (line, pc)
-     int line;
-     CORE_ADDR pc;
-{
-  struct linetable_entry *e;
-  /* Make sure line vector is big enough.  */
-
-  if (line_vector_index + 2 >= line_vector_length)
-    {
-      line_vector_length *= 2;
-      line_vector = (struct linetable *)
-       xrealloc ((char *) line_vector, sizeof (struct linetable)
-                 + (line_vector_length
-                    * sizeof (struct linetable_entry)));
-    }
-
-  e = line_vector->item + line_vector_index++;
-  e->line = line; e->pc = pc;
-}
-\f
 /* Start a new symtab for a new source file.
    This is called when a COFF ".file" symbol is seen;
    it indicates the start of data for one original source file.  */
 
 static void
-coff_start_symtab ()
+coff_start_symtab (name)
+    char *name;
 {
   start_symtab (
                /* We fill in the filename later.  start_symtab puts
                   this pointer into last_source_file and we put it in
                   subfiles->name, which end_symtab frees; that's why
                   it must be malloc'd.  */
-               savestring ("", 0),
+               savestring (name, strlen(name)),
                /* We never know the directory name for COFF.  */
                NULL,
                /* The start address is irrelevant, since we set
                   last_source_start_addr in coff_end_symtab.  */
                0);
-
-  /* Initialize the source file line number information for this file.  */
-
-  if (line_vector)             /* Unlikely, but maybe possible? */
-    free ((PTR)line_vector);
-  line_vector_index = 0;
-  line_vector_length = 1000;
-  prev_line_number = -2;       /* Force first line number to be explicit */
-  line_vector = (struct linetable *)
-    xmalloc (sizeof (struct linetable)
-            + line_vector_length * sizeof (struct linetable_entry));
+  record_debugformat ("COFF");
 }
 
 /* Save the vital information from when starting to read a file,
@@ -470,29 +483,12 @@ coff_end_symtab (objfile)
 
   last_source_start_addr = current_source_start_addr;
 
-  /* For no good reason, this file stores the number of entries in a
-     separate variable instead of in line_vector->nitems.  Fix it.  */
-  if (line_vector)
-    line_vector->nitems = line_vector_index;
-
-  /* For COFF, we only have one subfile, so we can just look at
-     subfiles and not worry about there being other elements in the
-     chain.  We fill in various fields now because we didn't know them
-     before (or because doing it now is simply an artifact of how this
-     file used to be written).  */
-  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);
 
   /* Reinitialize for beginning of new file. */
-  line_vector = 0;
-  line_vector_length = -1;
   last_source_file = NULL;
 }
 \f
@@ -506,10 +502,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 ()
@@ -529,20 +522,23 @@ static void
 coff_symfile_init (objfile)
      struct objfile *objfile;
 {
-  bfd *abfd = objfile->obfd;
-
   /* Allocate struct to keep track of stab reading. */
-  objfile->sym_stab_info = (PTR)
-    xmmalloc (objfile -> md, sizeof (struct dbx_symfile_info));
+  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));
 
   /* Allocate struct to keep track of the symfile */
-  objfile -> sym_private = xmmalloc (objfile -> md,
-                                    sizeof (struct coff_symfile_info));
+  objfile->sym_private = xmmalloc (objfile->md,
+                                  sizeof (struct coff_symfile_info));
 
   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);
 }
 
@@ -607,10 +603,10 @@ coff_symfile_read (objfile, section_offsets, mainline)
   int symtab_offset;
   int stringtab_offset;
   struct cleanup *back_to;
-  int stabsize, stabstrsize;
+  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!  */
@@ -621,7 +617,6 @@ coff_symfile_read (objfile, section_offsets, mainline)
 
   /* Set a few file-statics that give us specific information about
      the particular COFF file format we're reading.  */
-  local_linesz   = cdata->local_linesz;
   local_n_btmask = cdata->local_n_btmask;
   local_n_btshft = cdata->local_n_btshft;
   local_n_tmask  = cdata->local_n_tmask;
@@ -635,7 +630,15 @@ coff_symfile_read (objfile, section_offsets, mainline)
   temp_sym = (char *) xmalloc
         (cdata->local_symesz + cdata->local_auxesz);
   temp_aux = temp_sym + cdata->local_symesz;
-  back_to = make_cleanup (free_current_contents, &temp_sym);
+  back_to = make_cleanup ((make_cleanup_func) 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.  */
@@ -643,7 +646,7 @@ coff_symfile_read (objfile, section_offsets, mainline)
   info->max_lineno_offset = 0;
   bfd_map_over_sections (abfd, find_linenos, (PTR) info);
 
-  make_cleanup (free_linetab, 0);
+  make_cleanup ((make_cleanup_func) free_linetab, 0);
   val = init_lineno (abfd, info->min_lineno_offset, 
                     info->max_lineno_offset - info->min_lineno_offset);
   if (val < 0)
@@ -651,13 +654,13 @@ coff_symfile_read (objfile, section_offsets, mainline)
 
   /* Now read the string table, all at once.  */
 
-  make_cleanup (free_stringtab, 0);
+  make_cleanup ((make_cleanup_func) free_stringtab, 0);
   val = init_stringtab (abfd, stringtab_offset);
   if (val < 0)
     error ("\"%s\": can't get string table", name);
 
   init_minimal_symbol_collection ();
-  make_cleanup (discard_minimal_symbols, 0);
+  make_cleanup ((make_cleanup_func) discard_minimal_symbols, 0);
 
   /* Now that the executable file is positioned at symbol table,
      process it and define symbols accordingly.  */
@@ -681,19 +684,30 @@ coff_symfile_read (objfile, section_offsets, mainline)
 
   bfd_map_over_sections (abfd, coff_locate_sections, (PTR) info);
 
-  if (info->stabsect)
+  if (info->stabsects)
     {
+      if (! info->stabstrsect)
+       {
+         error_begin ();
+         fprintf_filtered
+           (gdb_stderr,
+            ("The debugging information in `%s' is corrupted.\n"
+             "The file has a `.stabs' section, but no `.stabstr' section.\n"),
+            name);
+         return_to_top_level (RETURN_ERROR);
+       }
+
       /* FIXME: dubious.  Why can't we use something normal like
         bfd_get_section_contents?  */
       bfd_seek (abfd, abfd->where, 0);
 
-      stabsize = bfd_section_size (abfd, info->stabsect);
       stabstrsize = bfd_section_size (abfd, info->stabstrsect);
 
       coffstab_build_psymtabs (objfile,
                               section_offsets,
                               mainline,
-                              info->stabsect->filepos, stabsize,
+                              info->textaddr, info->textsize,
+                              info->stabsects,
                               info->stabstrsect->filepos, stabstrsize);
     }
 
@@ -750,6 +764,7 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
   char *filestring = "";
   int depth = 0;
   int fcn_first_line = 0;
+  CORE_ADDR fcn_first_line_addr;
   int fcn_last_line = 0;
   int fcn_start_addr = 0;
   long fcn_line_ptr = 0;
@@ -790,7 +805,7 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
     xmalloc (type_vector_length * sizeof (struct type *));
   memset (type_vector, 0, type_vector_length * sizeof (struct type *));
 
-  coff_start_symtab ();
+  coff_start_symtab ("");
 
   symnum = 0;
   while (symnum < nsyms)
@@ -799,19 +814,12 @@ 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)
            coff_end_symtab (objfile);
 
-         coff_start_symtab ();
+         coff_start_symtab ("_globals_");
          complete_symtab ("_globals_", 0, 0);
          /* done with all files, everything from here on out is globals */
        }
@@ -862,12 +870,23 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
            if (last_source_file)
              {
                coff_end_symtab (objfile);
-               coff_start_symtab ();
+               coff_start_symtab (filestring);
              }
            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:
+           /* However, labels within a function can make weird backtraces,
+              so filter them out (from phdm@macqel.be). */
+           if (within_function)
+             break;
           case C_STAT:
+         case C_THUMBLABEL:
+         case C_THUMBSTAT:
+         case C_THUMBSTATFUNC:
            if (cs->c_name[0] == '.')
              {
                if (STREQ (cs->c_name, ".text")) {
@@ -899,6 +918,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
@@ -922,38 +943,71 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
                      break;
                    }
                  tmpaddr = reladdr;
-                 sec = SECT_OFF_BSS;
+                 /* The address has already been relocated; make sure that
+                    objfile_relocate doesn't relocate it again.  */
+                 sec = -2;
+                 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)
+                   {
+                   case SECT_OFF_TEXT:
+                   case SECT_OFF_RODATA:
+                     ms_type =
+                       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_EXT || cs->c_sclass == C_THUMBEXT ?
+                         mst_data : mst_file_data;
+                     break;
+                   case SECT_OFF_BSS:
+                     ms_type =
+                       cs->c_sclass == C_EXT || cs->c_sclass == C_THUMBEXT ?
+                         mst_data : mst_file_data;
+                     break;
+                   default:
+                     ms_type = mst_unknown;
+                     break;
+                   }
                }
 
-             switch (sec)
+             if (cs->c_name[0] != '@' /* Skip tdesc symbols */)
+               {
+                 struct minimal_symbol *msym;
+
+                 msym = prim_record_minimal_symbol_and_info
+                 (cs->c_name, tmpaddr, ms_type, (char *)cs->c_sclass, sec,
+                  NULL, objfile);
+#ifdef COFF_MAKE_MSYMBOL_SPECIAL
+                 if(msym)
+                   COFF_MAKE_MSYMBOL_SPECIAL(cs->c_sclass, msym);              
+#endif
+               }
+             if (SDB_TYPE (cs->c_type))
                {
-               case SECT_OFF_TEXT:
-               case SECT_OFF_RODATA:
-                 ms_type = cs->c_sclass == C_STAT ? mst_file_text : mst_text;
-                 break;
-               case SECT_OFF_DATA:
-                 ms_type = cs->c_sclass == C_STAT ? mst_file_data : mst_data;
-                 break;
-               case SECT_OFF_BSS:
-                 ms_type = cs->c_sclass == C_STAT ? mst_file_bss : mst_bss;
-                 break;
-               default:
-                 ms_type = mst_unknown;
-                 break;
+                 struct symbol *sym;
+                 sym = process_coff_symbol
+                   (cs, &main_aux, section_offsets, objfile);
+                 SYMBOL_VALUE (sym) = tmpaddr;
+                 SYMBOL_SECTION (sym) = sec;
                }
-
-             record_minimal_symbol (cs->c_name, tmpaddr, ms_type, objfile);
            }
-
-           if (SDB_TYPE (cs->c_type))
-             process_coff_symbol (cs, &main_aux, section_offsets, objfile);
            break;
 
          case C_FCN:
@@ -967,6 +1021,7 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
                if (cs->c_naux != 1)
                  complain (&bf_no_aux_complaint, cs->c_symnum);
                fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
+               fcn_first_line_addr = cs->c_value;
 
                /* Might want to check that locals are 0 and
                   context_stack_depth is zero, and complain if not.  */
@@ -984,6 +1039,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)
@@ -1001,8 +1064,18 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
                  {
                    fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
                  }
-               enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line,
-                              section_offsets);
+               /* fcn_first_line is the line number of the opening '{'.
+                  Do not record it - because it would affect gdb's idea
+                  of the line number of the first statement of the function -
+                  except for one-line functions, for which it is also the line
+                  number of all the statements and of the closing '}', and
+                  for which we do not have any other statement-line-number. */
+               if (fcn_last_line == 1)
+                 record_line (current_subfile, fcn_first_line,
+                              fcn_first_line_addr);
+               else
+                 enter_linenos (fcn_line_ptr, fcn_first_line, fcn_last_line,
+                                section_offsets);
 
                finish_block (new->name, &local_symbols, new->old_blocks,
                              new->start_addr,
@@ -1037,6 +1110,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)
                  {
@@ -1109,7 +1188,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 */
@@ -1137,7 +1249,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)
@@ -1191,7 +1303,7 @@ getsymname (symbol_entry)
    only the last component of the name.  Result is in static storage and
    is only good for temporary use.  */
 
-char *
+static char *
 coff_getfilename (aux_entry)
     union internal_auxent *aux_entry;
 {
@@ -1280,6 +1392,8 @@ enter_linenos (file_offset, first_line, last_line, section_offsets)
   register char *rawptr;
   struct internal_lineno lptr;
 
+  if (!linetab)
+    return ;
   if (file_offset < linetab_offset)
     {
       complain (&lineno_complaint, file_offset);
@@ -1300,7 +1414,7 @@ enter_linenos (file_offset, first_line, last_line, section_offsets)
     rawptr += local_linesz;
     /* The next function, or the sentinel, will have L_LNNO32 zero; we exit. */
     if (L_LNNO32 (&lptr) && L_LNNO32 (&lptr) <= last_line)
-      coff_record_line (first_line + L_LNNO32 (&lptr),
+      record_line (current_subfile, first_line + L_LNNO32 (&lptr),
                        lptr.l_addr.l_paddr
                        + ANOFFSET (section_offsets, SECT_OFF_TEXT));
     else
@@ -1411,8 +1525,10 @@ 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);
+  SYMBOL_LANGUAGE (sym) = language_auto;
+  SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
 
   /* default assumptions */
   SYMBOL_VALUE (sym) = cs->c_value;
@@ -1422,27 +1538,15 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
   if (ISFCN (cs->c_type))
     {
       SYMBOL_VALUE (sym) += ANOFFSET (section_offsets, SECT_OFF_TEXT);
-#if 0
-       /* FIXME:  This has NOT been tested.  The DBX version has.. */
-       /* Generate a template for the type of this function.  The 
-         types of the arguments will be added as we read the symbol 
-         table. */
-       struct type *new = (struct type *)
-                   obstack_alloc (&objfile->symbol_obstack, sizeof (struct type));
-       
-       memcpy (new, lookup_function_type (decode_function_type (cs, cs->c_type, aux)),
-                     sizeof(struct type));
-       SYMBOL_TYPE (sym) = new;
-       in_function_type = SYMBOL_TYPE(sym);
-#else
        SYMBOL_TYPE(sym) = 
         lookup_function_type (decode_function_type (cs, cs->c_type, aux));
-#endif
 
       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
@@ -1458,6 +1562,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;
@@ -1465,6 +1571,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;
@@ -1488,16 +1596,12 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
            add_symbol_to_list (sym, &local_symbols);
            break;
 
+         case C_THUMBLABEL:
          case C_LABEL:
            break;
 
          case C_ARG:
            SYMBOL_CLASS (sym) = LOC_ARG;
-#if 0
-           /* FIXME:  This has not been tested. */
-           /* Add parameter to function.  */
-           add_param_to_type(&in_function_type,sym);
-#endif
            add_symbol_to_list (sym, &local_symbols);
 #if !defined (BELIEVE_PCC_PROMOTION)
            if (TARGET_BYTE_ORDER == BIG_ENDIAN)
@@ -1766,7 +1870,11 @@ decode_base_type (cs, c_type, aux)
        return lookup_fundamental_type (current_objfile, FT_INTEGER);
 
       case T_LONG:
-       return lookup_fundamental_type (current_objfile, FT_LONG);
+       if (cs->c_sclass == C_FIELD
+           && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
+         return lookup_fundamental_type (current_objfile, FT_LONG_LONG);
+       else
+         return lookup_fundamental_type (current_objfile, FT_LONG);
 
       case T_FLOAT:
        return lookup_fundamental_type (current_objfile, FT_FLOAT);
@@ -1774,6 +1882,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)
          {
@@ -1859,7 +1970,11 @@ decode_base_type (cs, c_type, aux)
        return lookup_fundamental_type (current_objfile, FT_UNSIGNED_INTEGER);
 
       case T_ULONG:
-       return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
+       if (cs->c_sclass == C_FIELD
+           && aux->x_sym.x_misc.x_lnsz.x_size > TARGET_LONG_BIT)
+         return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG_LONG);
+       else
+         return lookup_fundamental_type (current_objfile, FT_UNSIGNED_LONG);
     }
   complain (&unexpected_type_complaint, cs->c_name);
   return lookup_fundamental_type (current_objfile, FT_VOID);
@@ -1920,9 +2035,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;
 
@@ -1938,9 +2053,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;
 
@@ -1987,6 +2102,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)
@@ -2059,35 +2175,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;
-}
+  if (unsigned_enum)
+    TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
 
-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-1));
-
-  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. */
@@ -2099,7 +2199,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.034299 seconds and 4 git commands to generate.