* bfd.c (union tdata): Add nlm_obj_data;
[deliverable/binutils-gdb.git] / gdb / coffread.c
index f61d806b5e882ee5c1ada050d2caffe4bb0dac6a..d4e6db80d7fffbe071b0eab525de6834d79e3e6f 100644 (file)
@@ -1,6 +1,7 @@
 /* Read coff symbol tables and convert to internal format, for GDB.
    Contributed by David D. Johnson, Brown University (ddj@cs.brown.edu).
-   Copyright 1987, 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
+   Copyright 1987, 1988, 1989, 1990, 1991, 1992, 1993
+   Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -17,7 +18,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.  */
-\f
+
 #include "defs.h"
 #include "symtab.h"
 #include "gdbtypes.h"
@@ -26,13 +27,19 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "symfile.h"
 #include "objfiles.h"
 #include "buildsym.h"
+#include "complaints.h"
 #include <obstack.h>
 
 #include <string.h>
 
+#include "libbfd.h"            /* FIXME secret internal data from BFD */
 #include "coff/internal.h"     /* Internal format of COFF symbols in BFD */
 #include "libcoff.h"           /* FIXME secret internal data from BFD */
 
+/* Translate an external name string into a user-visible name.  */
+#define        EXTERNAL_NAME(string, abfd) \
+       (string[0] == bfd_get_symbol_leading_char(abfd)? string+1: string)
+
 /* To be an sdb debug type, type must have at least a basic or primary
    derived type.  Using this rather than checking against T_NULL is
    said to prevent core dumps if we try to operate on Michael Bloom
@@ -130,9 +137,9 @@ struct coff_pending
 
 struct coff_pending *coff_file_symbols;        /* static at top level, and types */
 
-struct coff_pending *coff_global_symbols;      /* global functions and variables */
+struct coff_pending *coff_global_symbols;  /* global functions and variables */
 
-struct coff_pending *coff_local_symbols;       /* everything local to lexical context */
+struct coff_pending *coff_local_symbols;  /* everything local to lexical context */
 
 /* List of unclosed lexical contexts
    (that will become blocks, eventually).  */
@@ -183,6 +190,15 @@ struct complaint unexpected_type_complaint =
 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 {
@@ -220,8 +236,8 @@ static struct symbol *
 process_coff_symbol PARAMS ((struct coff_symbol *, union internal_auxent *,
                             struct objfile *));
 
-static PTR
-patch_opaque_types PARAMS ((struct objfile *, struct symtab *, PTR, PTR, PTR));
+static void
+patch_opaque_types PARAMS ((struct symtab *));
 
 static void
 patch_type PARAMS ((struct type *, struct type *));
@@ -249,7 +265,7 @@ read_one_sym PARAMS ((struct coff_symbol *, struct internal_syment *,
                      union internal_auxent *));
 
 static void
-read_coff_symtab PARAMS ((int, int, struct objfile *));
+read_coff_symtab PARAMS ((long, int, struct objfile *));
 
 static void
 find_linenos PARAMS ((bfd *, sec_ptr, PTR));
@@ -261,13 +277,13 @@ static void
 coff_new_init PARAMS ((struct objfile *));
 
 static void
-coff_symfile_read PARAMS ((struct objfile *, CORE_ADDR, int));
+coff_symfile_read PARAMS ((struct objfile *, struct section_offsets *, int));
 
 static void
 coff_symfile_finish PARAMS ((struct objfile *));
 
 static void
-record_minimal_symbol PARAMS ((char *, CORE_ADDR));
+record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type));
 
 static void
 coff_end_symtab PARAMS ((struct objfile *));
@@ -312,13 +328,13 @@ coff_lookup_type (index)
       int old_vector_length = type_vector_length;
 
       type_vector_length *= 2;
-      if (type_vector_length < index) {
+      if (index /* is still */ >= type_vector_length) {
        type_vector_length = index * 2;
       }
       type_vector = (struct type **)
        xrealloc ((char *) type_vector,
                  type_vector_length * sizeof (struct type *));
-      bzero (&type_vector[old_vector_length],
+      memset (&type_vector[old_vector_length], 0,
             (type_vector_length - old_vector_length) * sizeof(struct type *));
     }
   return &type_vector[index];
@@ -411,7 +427,7 @@ coff_finish_block (symbol, listhead, old_blocks, start, end, objfile)
   for (next = *listhead; next; next = next1)
     {
       next1 = next->next;
-      free (next);
+      free ((PTR)next);
     }
   *listhead = 0;
 
@@ -475,7 +491,7 @@ make_blockvector (objfile)
   for (next = pending_blocks; next; next = next1)
     {
       next1 = next->next;
-      free (next);
+      free ((PTR)next);
     }
   pending_blocks = 0;
 
@@ -516,12 +532,12 @@ coff_start_symtab ()
   coff_global_symbols = 0;
   coff_context_stack = 0;
   within_function = 0;
-  last_source_file = 0;
+  last_source_file = NULL;
 
   /* Initialize the source file line number information for this file.  */
 
   if (line_vector)             /* Unlikely, but maybe possible? */
-    free (line_vector);
+    free ((PTR)line_vector);
   line_vector_index = 0;
   line_vector_length = 1000;
   prev_line_number = -2;       /* Force first line number to be explicit */
@@ -576,19 +592,49 @@ coff_end_symtab (objfile)
       /* Make a block for the local symbols within.  */
       coff_finish_block (cstk->name, &coff_local_symbols, cstk->old_blocks,
                    cstk->start_addr, cur_src_end_addr, objfile);
-      free (cstk);
+      free ((PTR)cstk);
     }
 
   /* Ignore a file that has no functions with real debugging info.  */
   if (pending_blocks == 0 && coff_file_symbols == 0 && coff_global_symbols == 0)
     {
-      free (line_vector);
+      free ((PTR)line_vector);
       line_vector = 0;
       line_vector_length = -1;
-      last_source_file = 0;
+      last_source_file = NULL;
       return;
     }
 
+  /* It is unfortunate that in amdcoff, pending blocks might not be ordered
+     in this stage. Especially, blocks for static functions will show up at
+     the end.  We need to sort them, so tools like `find_pc_function' and
+     `find_pc_block' can work reliably. */
+  if (pending_blocks) {
+    /* FIXME!  Remove this horrid bubble sort and use qsort!!! */
+    int swapped;
+    do {
+      struct pending_block *pb, *pbnext;
+
+      pb = pending_blocks, pbnext = pb->next;
+      swapped = 0;
+
+      while ( pbnext ) {
+
+         /* swap blocks if unordered! */
+
+         if (BLOCK_START(pb->block) < BLOCK_START(pbnext->block)) {
+           struct block *tmp = pb->block;
+           complain (&misordered_blocks_complaint, BLOCK_START (pb->block));
+           pb->block = pbnext->block;
+           pbnext->block = tmp;
+           swapped = 1;
+         }
+         pb = pbnext;
+         pbnext = pbnext->next;
+      }
+    } while (swapped);
+  }
+
   /* Create the two top-level blocks for this file (STATIC_BLOCK and
      GLOBAL_BLOCK).  */
   coff_finish_block (0, &coff_file_symbols, 0, cur_src_start_addr, cur_src_end_addr, objfile);
@@ -617,13 +663,14 @@ coff_end_symtab (objfile)
   /* Reinitialize for beginning of new file. */
   line_vector = 0;
   line_vector_length = -1;
-  last_source_file = 0;
+  last_source_file = NULL;
 }
 \f
 static void
-record_minimal_symbol (name, address)
+record_minimal_symbol (name, address, type)
      char *name;
      CORE_ADDR address;
+     enum minimal_symbol_type type;
 {
   /* We don't want TDESC entry points in the minimal symbol table */
   if (name[0] == '@') return;
@@ -632,7 +679,7 @@ record_minimal_symbol (name, address)
      is, so this guess is more useful than mst_unknown.  */
   prim_record_minimal_symbol (savestring (name, strlen (name)),
                             address,
-                            (int)mst_text);
+                            type);
 }
 \f
 /* coff_symfile_init ()
@@ -669,7 +716,8 @@ coff_symfile_init (objfile)
   init_entry_point_info (objfile);
 
   /* Save the section number for the text section */
-  if (section = bfd_get_section_by_name(abfd,".text"))
+  section = bfd_get_section_by_name(abfd,".text");
+  if (section)
     text_bfd_scnum = section->index;
   else
     text_bfd_scnum = -1; 
@@ -723,9 +771,9 @@ static bfd *symfile_bfd;
 
 /* ARGSUSED */
 static void
-coff_symfile_read (objfile, addr, mainline)
+coff_symfile_read (objfile, section_offsets, mainline)
      struct objfile *objfile;
-     CORE_ADDR addr;
+     struct section_offsets *section_offsets;
      int mainline;
 {
   struct coff_symfile_info *info;
@@ -770,7 +818,7 @@ coff_symfile_read (objfile, addr, mainline)
   /* 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, info);
+  bfd_map_over_sections (abfd, find_linenos, (PTR)info);
 
   val = init_lineno (desc, info->min_lineno_offset, 
                     info->max_lineno_offset - info->min_lineno_offset);
@@ -784,21 +832,13 @@ coff_symfile_read (objfile, addr, mainline)
     error ("\"%s\": can't get string table", name);
   make_cleanup (free_stringtab, 0);
 
-  /* Position to read the symbol table.  Do not read it all at once. */
-  val = lseek (desc, (long)symtab_offset, 0);
-  if (val < 0)
-    perror_with_name (name);
-
   init_minimal_symbol_collection ();
   make_cleanup (discard_minimal_symbols, 0);
 
   /* Now that the executable file is positioned at symbol table,
      process it and define symbols accordingly.  */
 
-  read_coff_symtab (desc, num_symbols, objfile);
-
-  iterate_over_symtabs (patch_opaque_types, (PTR) NULL, (PTR) NULL,
-                       (PTR) NULL);
+  read_coff_symtab ((long)symtab_offset, num_symbols, objfile);
 
   /* Sort symbols alphabetically within each block.  */
 
@@ -811,8 +851,8 @@ coff_symfile_read (objfile, addr, mainline)
 }
 
 static void
-coff_new_init (objfile)
-     struct objfile *objfile;
+coff_new_init (ignore)
+     struct objfile *ignore;
 {
        /* Nothin' to do */
 }
@@ -839,12 +879,11 @@ coff_symfile_finish (objfile)
    We read them one at a time using read_one_sym ().  */
 
 static void
-read_coff_symtab (desc, nsyms, objfile)
-     int desc;
+read_coff_symtab (symtab_offset, nsyms, objfile)
+     long symtab_offset;
      int nsyms;
      struct objfile *objfile;
 {
-  int newfd;                   /* Avoid multiple closes on same desc */
   FILE *stream; 
   register struct coff_context_stack *new;
   struct coff_symbol coff_symbol;
@@ -854,7 +893,8 @@ read_coff_symtab (desc, nsyms, objfile)
   struct coff_symbol fcn_cs_saved;
   static struct internal_syment fcn_sym_saved;
   static union internal_auxent fcn_aux_saved;
-
+  struct symtab *s;
+  
   /* A .file is open.  */
   int in_source_file = 0;
   int num_object_files = 0;
@@ -862,35 +902,54 @@ read_coff_symtab (desc, nsyms, objfile)
 
   /* Name of the current file.  */
   char *filestring = "";
-  int depth;
-  int fcn_first_line;
-  int fcn_last_line;
-  int fcn_start_addr;
-  long fcn_line_ptr;
+  int depth = 0;
+  int fcn_first_line = 0;
+  int fcn_last_line = 0;
+  int fcn_start_addr = 0;
+  long fcn_line_ptr = 0;
   struct cleanup *old_chain;
+  int val;
+
+  stream = bfd_cache_lookup(objfile->obfd);
+  if (!stream)
+   perror_with_name(objfile->name);
 
+  /* Work around a stdio bug in SunOS4.1.1 (this makes me nervous....
+     it's hard to know I've really worked around it.  The fix should be
+     harmless, anyway).  The symptom of the bug is that the first
+     fread (in read_one_sym), will (in my example) actually get data
+     from file offset 268, when the fseek was to 264 (and ftell shows
+     264).  This causes all hell to break loose.  I was unable to
+     reproduce this on a short test program which operated on the same
+     file, performing (I think) the same sequence of operations.
 
-  newfd = dup (desc);
-  if (newfd == -1)
-    fatal ("Too many open files");
-  stream = fdopen (newfd, "r");
+     It stopped happening when I put in this rewind().
+
+     FIXME: Find out if this has been reported to Sun, whether it has
+     been fixed in a later release, etc.  */
+
+  rewind (stream);
+
+  /* Position to read the symbol table. */
+  val = fseek (stream, (long)symtab_offset, 0);
+  if (val < 0)
+    perror_with_name (objfile->name);
 
-  /* These cleanups will be discarded below if we succeed.  */
+  /* This cleanup will be discarded below if we succeed.  */
   old_chain = make_cleanup (free_objfile, objfile);
-  make_cleanup (fclose, stream);
 
   current_objfile = objfile;
   nlist_stream_global = stream;
   nlist_nsyms_global = nsyms;
-  last_source_file = 0;
-  bzero (opaque_type_chain, sizeof opaque_type_chain);
+  last_source_file = NULL;
+  memset (opaque_type_chain, 0, sizeof opaque_type_chain);
 
   if (type_vector)                     /* Get rid of previous one */
-    free (type_vector);
+    free ((PTR)type_vector);
   type_vector_length = 160;
   type_vector = (struct type **)
                xmalloc (type_vector_length * sizeof (struct type *));
-  bzero (type_vector, type_vector_length * sizeof (struct type *));
+  memset (type_vector, 0, type_vector_length * sizeof (struct type *));
 
   coff_start_symtab ();
 
@@ -928,7 +987,7 @@ read_coff_symtab (desc, nsyms, objfile)
          /* record as a minimal symbol.  if we get '.bf' next,
           * then we undo this step
           */
-         record_minimal_symbol (cs->c_name, cs->c_value);
+         record_minimal_symbol (cs->c_name, cs->c_value, mst_text);
 
          fcn_line_ptr = main_aux.x_sym.x_fcnary.x_fcn.x_lnnoptr;
          fcn_start_addr = cs->c_value;
@@ -971,7 +1030,7 @@ read_coff_symtab (desc, nsyms, objfile)
 
           case C_STAT:
            if (cs->c_name[0] == '.') {
-                   if (strcmp (cs->c_name, ".text") == 0) {
+                   if (STREQ (cs->c_name, ".text")) {
                            /* FIXME:  don't wire in ".text" as section name
                                       or symbol name! */
                            if (++num_object_files == 1) {
@@ -1013,17 +1072,20 @@ read_coff_symtab (desc, nsyms, objfile)
                record this symbol as a function in the minimal symbol table.
                But why are absolute syms recorded as functions, anyway?  */
                    if (cs->c_secnum <= text_bfd_scnum+1) {/* text or abs */
-                           record_minimal_symbol (cs->c_name, cs->c_value);
+                           record_minimal_symbol (cs->c_name, cs->c_value,
+                                                  mst_text);
                            break;
                    } else {
-                           cs->c_type = T_INT;
+                           record_minimal_symbol (cs->c_name, cs->c_value,
+                                                  mst_data);
+                           break;
                    }
            }
-           (void) process_coff_symbol (cs, &main_aux, objfile);
+           process_coff_symbol (cs, &main_aux, objfile);
            break;
 
          case C_FCN:
-           if (strcmp (cs->c_name, ".bf") == 0)
+           if (STREQ (cs->c_name, ".bf"))
              {
                within_function = 1;
 
@@ -1031,7 +1093,7 @@ read_coff_symtab (desc, nsyms, objfile)
                /* main_aux.x_sym.x_misc.x_lnsz.x_lnno
                            contains line number of '{' } */
                if (cs->c_naux != 1)
-                 complain (&bf_no_aux_complaint, (char *) cs->c_symnum);
+                 complain (&bf_no_aux_complaint, cs->c_symnum);
                fcn_first_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
 
                new = (struct coff_context_stack *)
@@ -1046,7 +1108,7 @@ read_coff_symtab (desc, nsyms, objfile)
                new->name = process_coff_symbol (&fcn_cs_saved,
                                                 &fcn_aux_saved, objfile);
              }
-           else if (strcmp (cs->c_name, ".ef") == 0)
+           else if (STREQ (cs->c_name, ".ef"))
              {
                      /* the value of .ef is the address of epilogue code;
                       * not useful for gdb
@@ -1056,12 +1118,12 @@ read_coff_symtab (desc, nsyms, objfile)
                new = coff_context_stack;
                if (new == 0)
                  {
-                   complain (&ef_complaint, (char *) cs->c_symnum);
+                   complain (&ef_complaint, cs->c_symnum);
                    within_function = 0;
                    break;
                  }
                if (cs->c_naux != 1) {
-                 complain (&ef_no_aux_complaint, (char *) cs->c_symnum);
+                 complain (&ef_no_aux_complaint, cs->c_symnum);
                  fcn_last_line = 0x7FFFFFFF;
                } else {
                  fcn_last_line = main_aux.x_sym.x_misc.x_lnsz.x_lnno;
@@ -1087,12 +1149,12 @@ read_coff_symtab (desc, nsyms, objfile)
                              );
                coff_context_stack = 0;
                within_function = 0;
-               free (new);
+               free ((PTR)new);
              }
            break;
 
          case C_BLOCK:
-           if (strcmp (cs->c_name, ".bb") == 0)
+           if (STREQ (cs->c_name, ".bb"))
              {
                new = (struct coff_context_stack *)
                            xmalloc (sizeof (struct coff_context_stack));
@@ -1106,12 +1168,14 @@ read_coff_symtab (desc, nsyms, objfile)
                new->name = 0;
                coff_local_symbols = 0;
              }
-           else if (strcmp (cs->c_name, ".eb") == 0)
+           else if (STREQ (cs->c_name, ".eb"))
              {
                new = coff_context_stack;
                if (new == 0 || depth != new->depth)
-                 error ("Invalid symbol data: .bb/.eb symbol mismatch at symbol %d.",
-                        symnum);
+                 {
+                   complain (&eb_complaint, (char *)symnum);
+                   break;
+                 }
                if (coff_local_symbols && coff_context_stack->next)
                  {
                    /* Make a block for the local symbols within.  */
@@ -1121,12 +1185,12 @@ read_coff_symtab (desc, nsyms, objfile)
                depth--;
                coff_local_symbols = new->locals;
                coff_context_stack = new->next;
-               free (new);
+               free ((PTR)new);
              }
            break;
 
          default:
-           (void) process_coff_symbol (cs, &main_aux, objfile);
+           process_coff_symbol (cs, &main_aux, objfile);
            break;
        }
     }
@@ -1134,6 +1198,12 @@ read_coff_symtab (desc, nsyms, objfile)
   if (last_source_file)
     coff_end_symtab (objfile);
   fclose (stream);
+
+  /* Patch up any opaque types (references to types that are not defined
+     in the file where they are referenced, e.g. "struct foo *bar").  */
+  ALL_OBJFILE_SYMTABS (objfile, s)
+    patch_opaque_types (s);
+
   discard_cleanups (old_chain);
   current_objfile = NULL;
 }
@@ -1274,7 +1344,7 @@ init_stringtab (chan, offset)
   if (stringtab == NULL)
     return -1;
 
-  bcopy (&length, stringtab, sizeof length);
+  memcpy (stringtab, &length, sizeof length);
   if (length == sizeof length)         /* Empty table -- just the count */
     return 0;
 
@@ -1313,6 +1383,10 @@ getsymname (symbol_entry)
   return result;
 }
 
+/* Extract the file name from the aux entry of a C_FILE symbol.  Return
+   only the last component of the name.  Result is in static storage and
+   is only good for temporary use.  */
+
 static char *
 getfilename (aux_entry)
     union internal_auxent *aux_entry;
@@ -1321,24 +1395,11 @@ getfilename (aux_entry)
   register char *temp;
   char *result;
 
-#ifndef COFF_NO_LONG_FILE_NAMES
-#if defined (x_zeroes)
-  /* Data General.  */
-  if (aux_entry->x_zeroes == 0)
-    strcpy (buffer, stringtab + aux_entry->x_offset);
-#else /* no x_zeroes */
   if (aux_entry->x_file.x_n.x_zeroes == 0)
     strcpy (buffer, stringtab + aux_entry->x_file.x_n.x_offset);
-#endif /* no x_zeroes */
   else
-#endif /* COFF_NO_LONG_FILE_NAMES */
     {
-#if defined (x_name)
-      /* Data General.  */
-      strncpy (buffer, aux_entry->x_name, FILNMLEN);
-#else
       strncpy (buffer, aux_entry->x_file.x_fname, FILNMLEN);
-#endif
       buffer[FILNMLEN] = '\0';
     }
   result = buffer;
@@ -1381,7 +1442,7 @@ init_lineno (chan, offset, size)
     return -1;
 
   /* Terminate it with an all-zero sentinel record */
-  bzero (linetab + size, local_linesz);
+  memset (linetab + size, 0, local_linesz);
 
   make_cleanup (free, linetab);                /* Be sure it gets de-allocated. */
   return 0;
@@ -1402,7 +1463,7 @@ enter_linenos (file_offset, first_line, last_line)
 
   if (file_offset < linetab_offset)
     {
-      complain (&lineno_complaint, (char *) file_offset);
+      complain (&lineno_complaint, file_offset);
       if (file_offset > linetab_size)  /* Too big to be an offset? */
        return;
       file_offset += linetab_offset;  /* Try reading at that linetab offset */
@@ -1437,10 +1498,9 @@ patch_type (type, real_type)
 
   TYPE_LENGTH (target) = TYPE_LENGTH (real_target);
   TYPE_NFIELDS (target) = TYPE_NFIELDS (real_target);
-  TYPE_FIELDS (target) = (struct field *)
-    obstack_alloc (&current_objfile -> type_obstack, field_size);
+  TYPE_FIELDS (target) = (struct field *) TYPE_ALLOC (target, field_size);
 
-  bcopy (TYPE_FIELDS (real_target), TYPE_FIELDS (target), field_size);
+  memcpy (TYPE_FIELDS (target), TYPE_FIELDS (real_target), field_size);
 
   if (TYPE_NAME (real_target))
     {
@@ -1451,20 +1511,11 @@ patch_type (type, real_type)
 }
 
 /* Patch up all appropriate typedef symbols in the opaque_type_chains
-   so that they can be used to print out opaque data structures properly.
-
-   This is called via iterate_over_symtabs, and thus simply returns NULL
-   for each time it is called, to indicate that the iteration should
-   continue. */
+   so that they can be used to print out opaque data structures properly.  */
 
-/* ARGSUSED */
-static PTR
-patch_opaque_types (objfile, s, arg1, arg2, arg3)
-     struct objfile *objfile;
+static void
+patch_opaque_types (s)
      struct symtab *s;
-     PTR arg1;
-     PTR arg2;
-     PTR arg3;
 {
   register struct block *b;
   register int i;
@@ -1492,7 +1543,7 @@ patch_opaque_types (objfile, s, arg1, arg2, arg3)
          for (sym = opaque_type_chain[hash]; sym;)
            {
              if (name[0] == SYMBOL_NAME (sym)[0] &&
-                 !strcmp (name + 1, SYMBOL_NAME (sym) + 1))
+                 STREQ (name + 1, SYMBOL_NAME (sym) + 1))
                {
                  if (prev)
                    {
@@ -1522,7 +1573,6 @@ patch_opaque_types (objfile, s, arg1, arg2, arg3)
            }
        }
     }
-  return (NULL);
 }
 \f
 static struct symbol *
@@ -1532,19 +1582,16 @@ process_coff_symbol (cs, aux, objfile)
      struct objfile *objfile;
 {
   register struct symbol *sym
-    = (struct symbol *) obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+    = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
+                                      sizeof (struct symbol));
   char *name;
-#ifdef NAMES_HAVE_UNDERSCORE
-  int offset = 1;
-#else
-  int offset = 0;
-#endif
   struct type *temptype;
 
-  bzero (sym, sizeof (struct symbol));
+  memset (sym, 0, sizeof (struct symbol));
   name = cs->c_name;
-  name = (name[0] == '_' ? name + offset : name);
-  SYMBOL_NAME (sym) = obstack_copy0 (&objfile->symbol_obstack, name, strlen (name));
+  name = EXTERNAL_NAME (name, objfile->obfd);
+  SYMBOL_NAME (sym) = obstack_copy0 (&objfile->symbol_obstack, name,
+                                    strlen (name));
 
   /* default assumptions */
   SYMBOL_VALUE (sym) = cs->c_value;
@@ -1560,8 +1607,8 @@ process_coff_symbol (cs, aux, objfile)
        struct type *new = (struct type *)
                    obstack_alloc (&objfile->symbol_obstack, sizeof (struct type));
        
-       bcopy(lookup_function_type (decode_function_type (cs, cs->c_type, aux)),
-            new, 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
@@ -1627,17 +1674,17 @@ process_coff_symbol (cs, aux, objfile)
            add_param_to_type(&in_function_type,sym);
 #endif
            coff_add_symbol_to_list (sym, &coff_local_symbols);
-#if !defined (BELIEVE_PCC_PROMOTION)
+#if !defined (BELIEVE_PCC_PROMOTION) && (TARGET_BYTE_ORDER == BIG_ENDIAN)
            /* If PCC says a parameter is a short or a char,
-              it is really an int.  */
+              aligned on an int boundary, realign it to the "little end"
+              of the int.  */
            temptype = lookup_fundamental_type (current_objfile, FT_INTEGER);
            if (TYPE_LENGTH (SYMBOL_TYPE (sym)) < TYPE_LENGTH (temptype)
-               && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT)
+               && TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_INT
+               && 0 == SYMBOL_VALUE (sym) % TYPE_LENGTH (temptype))
                {
-                   SYMBOL_TYPE (sym) = TYPE_UNSIGNED (SYMBOL_TYPE (sym))
-                       ? lookup_fundamental_type (current_objfile,
-                                                  FT_UNSIGNED_INTEGER)
-                           : temptype;
+                   SYMBOL_VALUE (sym) += TYPE_LENGTH (temptype)
+                                       - TYPE_LENGTH (SYMBOL_TYPE (sym));
                }
 #endif
            break;
@@ -1647,6 +1694,8 @@ process_coff_symbol (cs, aux, objfile)
            SYMBOL_VALUE (sym) = SDB_REG_TO_REGNUM(cs->c_value);
            coff_add_symbol_to_list (sym, &coff_local_symbols);
 #if !defined (BELIEVE_PCC_PROMOTION)
+       /* FIXME:  This should retain the current type, since it's just
+          a register value.  gnu@adobe, 26Feb93 */
            /* If PCC says a parameter is a short or a char,
               it is really an int.  */
            temptype = lookup_fundamental_type (current_objfile, FT_INTEGER);
@@ -1670,9 +1719,14 @@ process_coff_symbol (cs, aux, objfile)
              TYPE_NAME (SYMBOL_TYPE (sym)) = concat (SYMBOL_NAME (sym), NULL);
 
            /* Keep track of any type which points to empty structured type,
-               so it can be filled from a definition from another file */
+               so it can be filled from a definition from another file.  A
+               simple forward reference (TYPE_CODE_UNDEF) is not an
+               empty structured type, though; the forward references
+               work themselves out via the magic of coff_lookup_type.  */
            if (TYPE_CODE (SYMBOL_TYPE (sym)) == TYPE_CODE_PTR &&
-               TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0)
+               TYPE_LENGTH (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) == 0 &&
+               TYPE_CODE   (TYPE_TARGET_TYPE (SYMBOL_TYPE (sym))) !=
+                                               TYPE_CODE_UNDEF)
              {
                register int i = hashname (SYMBOL_NAME (sym));
 
@@ -1735,7 +1789,7 @@ decode_type (cs, c_type, aux)
        {
          int i, n;
          register unsigned short *dim;
-         struct type *base_type;
+         struct type *base_type, *index_type, *range_type;
 
          /* Define an array type.  */
          /* auxent refers to array, not base type */
@@ -1750,26 +1804,36 @@ decode_type (cs, c_type, aux)
            *dim = *(dim + 1);
          *dim = 0;
 
-         type = (struct type *)
-           obstack_alloc (&current_objfile -> type_obstack,
-                          sizeof (struct type));
-         bzero (type, sizeof (struct type));
-         TYPE_OBJFILE (type) = current_objfile;
-
          base_type = decode_type (cs, new_c_type, aux);
-
-         TYPE_CODE (type) = TYPE_CODE_ARRAY;
-         TYPE_TARGET_TYPE (type) = base_type;
-         TYPE_LENGTH (type) = n * TYPE_LENGTH (base_type);
+         index_type = lookup_fundamental_type (current_objfile, FT_INTEGER);
+         range_type =
+           create_range_type ((struct type *) NULL, index_type, 0, n - 1);
+         type =
+           create_array_type ((struct type *) NULL, base_type, range_type);
        }
       return type;
     }
 
-  /* Reference to existing type */
+  /* Reference to existing type.  This only occurs with the
+     struct, union, and enum types.  EPI a29k coff
+     fakes us out by producing aux entries with a nonzero
+     x_tagndx for definitions of structs, unions, and enums, so we
+     have to check the c_sclass field.  SCO 3.2v4 cc gets confused
+     with pointers to pointers to defined structs, and generates
+     negative x_tagndx fields.  */
   if (cs->c_naux > 0 && aux->x_sym.x_tagndx.l != 0)
     {
-      type = coff_alloc_type (aux->x_sym.x_tagndx.l);
-      return type;
+      if (cs->c_sclass != C_STRTAG
+         && cs->c_sclass != C_UNTAG
+         && cs->c_sclass != C_ENTAG
+         && aux->x_sym.x_tagndx.l >= 0)
+       {
+         type = coff_alloc_type (aux->x_sym.x_tagndx.l);
+         return type;
+       } else {
+         complain (&tagndx_bad_complaint, cs->c_name);
+         /* And fall through to decode_base_type... */
+       }
     }
 
   return decode_base_type (cs, BTYPE (c_type), aux);
@@ -1930,11 +1994,6 @@ coff_read_struct_type (index, length, lastsym)
   int nfields = 0;
   register int n;
   char *name;
-#ifdef NAMES_HAVE_UNDERSCORE
-  int offset = 1;
-#else
-  int offset = 0;
-#endif
   struct coff_symbol member_sym;
   register struct coff_symbol *ms = &member_sym;
   struct internal_syment sub_sym;
@@ -1950,7 +2009,7 @@ coff_read_struct_type (index, length, lastsym)
     {
       read_one_sym (ms, &sub_sym, &sub_aux);
       name = ms->c_name;
-      name = (name[0] == '_' ? name + offset : name);
+      name = EXTERNAL_NAME (name, current_objfile->obfd);
 
       switch (ms->c_sclass)
        {
@@ -1994,8 +2053,7 @@ coff_read_struct_type (index, length, lastsym)
 
   TYPE_NFIELDS (type) = nfields;
   TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&current_objfile -> type_obstack,
-                  sizeof (struct field) * nfields);
+    TYPE_ALLOC (type, sizeof (struct field) * nfields);
 
   /* Copy the saved-up fields into the field vector.  */
 
@@ -2008,7 +2066,6 @@ coff_read_struct_type (index, length, lastsym)
 /* Read a definition of an enumeration type,
    and create and return a suitable type object.
    Also defines the symbols that represent the values of the type.  */
-/* Currently assumes it's sizeof (int) and doesn't use length.  */
 
 /* ARGSUSED */
 static struct type *
@@ -2029,11 +2086,6 @@ coff_read_enum_type (index, length, lastsym)
   struct coff_pending *osyms, *syms;
   register int n;
   char *name;
-#ifdef NAMES_HAVE_UNDERSCORE
-  int offset = 1;
-#else
-  int offset = 0;
-#endif
 
   type = coff_alloc_type (index);
   if (within_function)
@@ -2046,13 +2098,13 @@ coff_read_enum_type (index, length, lastsym)
     {
       read_one_sym (ms, &sub_sym, &sub_aux);
       name = ms->c_name;
-      name = (name[0] == '_' ? name + offset : name);
+      name = EXTERNAL_NAME (name, current_objfile->obfd);
 
       switch (ms->c_sclass)
        {
          case C_MOE:
            sym = (struct symbol *) xmalloc (sizeof (struct symbol));
-           bzero (sym, sizeof (struct symbol));
+           memset (sym, 0, sizeof (struct symbol));
 
            SYMBOL_NAME (sym) = savestring (name, strlen (name));
            SYMBOL_CLASS (sym) = LOC_CONST;
@@ -2073,12 +2125,14 @@ coff_read_enum_type (index, length, lastsym)
 
   /* Now fill in the fields of the type-structure.  */
 
-  TYPE_LENGTH (type) =  TARGET_INT_BIT / TARGET_CHAR_BIT;
+  if (length > 0)
+    TYPE_LENGTH (type) =  length;
+  else
+    TYPE_LENGTH (type) =  TARGET_INT_BIT / TARGET_CHAR_BIT;    /* Assume ints */
   TYPE_CODE (type) = TYPE_CODE_ENUM;
   TYPE_NFIELDS (type) = nsyms;
   TYPE_FIELDS (type) = (struct field *)
-    obstack_alloc (&current_objfile -> type_obstack,
-                  sizeof (struct field) * nsyms);
+    TYPE_ALLOC (type, sizeof (struct field) * nsyms);
 
   /* Find the symbols for the values and put them into the type.
      The symbols can be found in the symlist that we put them on
@@ -2095,14 +2149,26 @@ coff_read_enum_type (index, length, lastsym)
     }
   /* Is this Modula-2's BOOLEAN type?  Flag it as such if so. */
   if(TYPE_NFIELDS(type) == 2 &&
-     ((!strcmp(TYPE_FIELD_NAME(type,0),"TRUE") &&
-       !strcmp(TYPE_FIELD_NAME(type,1),"FALSE")) ||
-      (!strcmp(TYPE_FIELD_NAME(type,1),"TRUE") &&
-       !strcmp(TYPE_FIELD_NAME(type,0),"FALSE"))))
+     ((STREQ(TYPE_FIELD_NAME(type,0),"TRUE") &&
+       STREQ(TYPE_FIELD_NAME(type,1),"FALSE")) ||
+      (STREQ(TYPE_FIELD_NAME(type,1),"TRUE") &&
+       STREQ(TYPE_FIELD_NAME(type,0),"FALSE"))))
      TYPE_CODE(type) = TYPE_CODE_BOOL;
   return type;
 }
 
+/* Fake up support for relocating symbol addresses.  FIXME.  */
+
+struct section_offsets coff_symfile_faker = {0};
+
+struct section_offsets *
+coff_symfile_offsets (objfile, addr)
+     struct objfile *objfile;
+     CORE_ADDR addr;
+{
+  return &coff_symfile_faker;
+}
+
 /* Register our ability to parse symbols for coff BFD files */
 
 static struct sym_fns coff_sym_fns =
@@ -2113,6 +2179,7 @@ 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 */
   NULL                 /* next: pointer to next struct sym_fns */
 };
 
This page took 0.035988 seconds and 4 git commands to generate.