import gdb-1999-05-10
[deliverable/binutils-gdb.git] / gdb / coffread.c
index c2a96a8f7b27e112e5449c9288dfadf26fd99a8e..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, 1996
+   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).
 
@@ -22,6 +22,7 @@ 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"
@@ -83,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.  */
 
@@ -129,6 +115,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.  */
 
@@ -245,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));
 
@@ -323,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 *));
@@ -335,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.  */
@@ -352,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 = §
   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 = §
+  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. 
@@ -410,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,
@@ -503,27 +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;
-
   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
@@ -537,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 ()
@@ -561,7 +523,7 @@ coff_symfile_init (objfile)
      struct objfile *objfile;
 {
   /* Allocate struct to keep track of stab reading. */
-  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));
@@ -644,7 +606,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!  */
@@ -655,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;
@@ -669,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.  */
@@ -677,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)
@@ -685,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.  */
@@ -717,6 +686,17 @@ coff_symfile_read (objfile, section_offsets, mainline)
 
   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);
@@ -784,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;
@@ -824,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)
@@ -833,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 */
        }
@@ -896,7 +870,7 @@ 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;
@@ -905,7 +879,14 @@ coff_symtab_read (symtab_offset, nsyms, section_offsets, objfile)
             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")) {
@@ -937,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
@@ -963,13 +946,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)
@@ -977,15 +963,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;
@@ -994,15 +988,17 @@ 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);
-
+               {
+                 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))
                {
                  struct symbol *sym;
@@ -1025,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.  */
@@ -1067,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,
@@ -1181,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 */
@@ -1374,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
@@ -1485,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;
@@ -1500,9 +1542,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
@@ -1518,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;
@@ -1525,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;
@@ -1548,6 +1596,7 @@ process_coff_symbol (cs, aux, section_offsets, objfile)
            add_symbol_to_list (sym, &local_symbols);
            break;
 
+         case C_THUMBLABEL:
          case C_LABEL:
            break;
 
@@ -1821,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);
@@ -1917,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);
@@ -1978,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;
 
@@ -1996,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;
 
@@ -2045,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)
@@ -2117,14 +2175,18 @@ 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;
     }
 
+  if (unsigned_enum)
+    TYPE_FLAGS (type) |= TYPE_FLAG_UNSIGNED;
+
   return type;
 }
 
This page took 0.031778 seconds and 4 git commands to generate.