* i386b-nat.c: Comment changes.
[deliverable/binutils-gdb.git] / gdb / dwarfread.c
index 6844813fb0486aeff15e35fbdd7b80f0e8c22556..2b13ad6d334bf0d67035c987575dab3c2b823977 100644 (file)
@@ -41,10 +41,6 @@ other things to work on, if you get bored. :-)
 */
 
 #include "defs.h"
 */
 
 #include "defs.h"
-#include <varargs.h>
-#include <fcntl.h>
-#include <string.h>
-
 #include "bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
 #include "bfd.h"
 #include "symtab.h"
 #include "gdbtypes.h"
@@ -55,6 +51,18 @@ other things to work on, if you get bored. :-)
 #include "buildsym.h"
 #include "demangle.h"
 
 #include "buildsym.h"
 #include "demangle.h"
 
+#include <varargs.h>
+#include <fcntl.h>
+#include <string.h>
+#ifndef        NO_SYS_FILE
+#include <sys/file.h>
+#endif
+
+/* FIXME -- convert this to SEEK_SET a la POSIX, move to config files.  */
+#ifndef L_SET
+#define L_SET 0
+#endif
+
 #ifdef MAINTENANCE     /* Define to 1 to compile in some maintenance stuff */
 #define SQUAWK(stuff) dwarfwarn stuff
 #else
 #ifdef MAINTENANCE     /* Define to 1 to compile in some maintenance stuff */
 #define SQUAWK(stuff) dwarfwarn stuff
 #else
@@ -212,6 +220,7 @@ static int diecount;        /* Approximate count of dies for compilation unit */
 static struct dieinfo *curdie; /* For warnings and such */
 
 static char *dbbase;   /* Base pointer to dwarf info */
 static struct dieinfo *curdie; /* For warnings and such */
 
 static char *dbbase;   /* Base pointer to dwarf info */
+static int dbsize;     /* Size of dwarf info in bytes */
 static int dbroff;     /* Relative offset from start of .debug section */
 static char *lnbase;   /* Base pointer to line section */
 static int isreg;      /* Kludge to identify register variables */
 static int dbroff;     /* Relative offset from start of .debug section */
 static char *lnbase;   /* Base pointer to line section */
 static int isreg;      /* Kludge to identify register variables */
@@ -252,10 +261,10 @@ static struct section_offsets *base_section_offsets;
  */
 
 struct dwfinfo {
  */
 
 struct dwfinfo {
-  int dbfoff;          /* Absolute file offset to start of .debug section */
+  file_ptr dbfoff;     /* Absolute file offset to start of .debug section */
   int dbroff;          /* Relative offset from start of .debug section */
   int dblength;                /* Size of the chunk of DIE's being examined */
   int dbroff;          /* Relative offset from start of .debug section */
   int dblength;                /* Size of the chunk of DIE's being examined */
-  int lnfoff;          /* Absolute file offset to line table fragment */
+  file_ptr lnfoff;     /* Absolute file offset to line table fragment */
 };
 
 #define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff)
 };
 
 #define DBFOFF(p) (((struct dwfinfo *)((p)->read_symtab_private))->dbfoff)
@@ -300,6 +309,15 @@ struct pending **list_in_scope = &file_symbols;
 static struct type **utypes;   /* Pointer to array of user type pointers */
 static int numutypes;          /* Max number of user type pointers */
 
 static struct type **utypes;   /* Pointer to array of user type pointers */
 static int numutypes;          /* Max number of user type pointers */
 
+/* Record the language for the compilation unit which is currently being
+   processed.  We know it once we have seen the TAG_compile_unit DIE,
+   and we need it while processing the DIE's for that compilation unit.
+   It is eventually saved in the symtab structure, but we don't finalize
+   the symtab struct until we have processed all the DIE's for the
+   compilation unit. */
+
+static enum language cu_language;
+
 /* Forward declarations of static functions so we don't have to worry
    about ordering within this file.  */
 
 /* Forward declarations of static functions so we don't have to worry
    about ordering within this file.  */
 
@@ -332,8 +350,8 @@ static void
 scan_partial_symbols PARAMS ((char *, char *, struct objfile *));
 
 static void
 scan_partial_symbols PARAMS ((char *, char *, struct objfile *));
 
 static void
-scan_compilation_units PARAMS ((char *, char *, char *, unsigned int,
-                               unsigned int, struct objfile *));
+scan_compilation_units PARAMS ((char *, char *, file_ptr,
+                               file_ptr, struct objfile *));
 
 static void
 add_partial_symbol PARAMS ((struct dieinfo *, struct objfile *));
 
 static void
 add_partial_symbol PARAMS ((struct dieinfo *, struct objfile *));
@@ -417,6 +435,10 @@ alloc_utype PARAMS ((DIE_REF, struct type *));
 static struct symbol *
 new_symbol PARAMS ((struct dieinfo *, struct objfile *));
 
 static struct symbol *
 new_symbol PARAMS ((struct dieinfo *, struct objfile *));
 
+static void
+synthesize_typedef PARAMS ((struct dieinfo *, struct objfile *,
+                           struct type *));
+
 static int
 locval PARAMS ((char *));
 
 static int
 locval PARAMS ((char *));
 
@@ -424,6 +446,58 @@ static void
 record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type,
                               struct objfile *));
 
 record_minimal_symbol PARAMS ((char *, CORE_ADDR, enum minimal_symbol_type,
                               struct objfile *));
 
+static void
+set_cu_language PARAMS ((struct dieinfo *));
+
+/*
+
+LOCAL FUNCTION
+
+       set_cu_language -- set local copy of language for compilation unit
+
+SYNOPSIS
+
+       void
+       set_cu_language (struct dieinfo *dip)
+
+DESCRIPTION
+
+       Decode the language attribute for a compilation unit DIE and
+       remember what the language was.  We use this at various times
+       when processing DIE's for a given compilation unit.
+
+RETURNS
+
+       No return value.
+
+ */
+
+static void
+set_cu_language (dip)
+     struct dieinfo *dip;
+{
+  switch (dip -> at_language)
+    {
+      case LANG_C89:
+      case LANG_C:
+        cu_language = language_c;
+       break;
+      case LANG_C_PLUS_PLUS:
+       cu_language = language_cplus;
+       break;
+      case LANG_ADA83:
+      case LANG_COBOL74:
+      case LANG_COBOL85:
+      case LANG_FORTRAN77:
+      case LANG_FORTRAN90:
+      case LANG_PASCAL83:
+      case LANG_MODULA2:
+      default:
+       cu_language = language_unknown;
+       break;
+    }
+}
+
 /*
 
 GLOBAL FUNCTION
 /*
 
 GLOBAL FUNCTION
@@ -432,18 +506,17 @@ GLOBAL FUNCTION
 
 SYNOPSIS
 
 
 SYNOPSIS
 
-       void dwarf_build_psymtabs (int desc, char *filename, 
+       void dwarf_build_psymtabs (struct objfile *objfile,
             struct section_offsets *section_offsets,
             struct section_offsets *section_offsets,
-            int mainline, unsigned int dbfoff, unsigned int dbsize,
-            unsigned int lnoffset, unsigned int lnsize,
-            struct objfile *objfile)
+            int mainline, file_ptr dbfoff, unsigned int dbfsize,
+            file_ptr lnoffset, unsigned int lnsize)
 
 DESCRIPTION
 
        This function is called upon to build partial symtabs from files
        containing DIE's (Dwarf Information Entries) and DWARF line numbers.
 
 
 DESCRIPTION
 
        This function is called upon to build partial symtabs from files
        containing DIE's (Dwarf Information Entries) and DWARF line numbers.
 
-       It is passed a file descriptor for an open file containing the DIES
+       It is passed a bfd* containing the DIES
        and line number information, the corresponding filename for that
        file, a base address for relocating the symbols, a flag indicating
        whether or not this debugging information is from a "main symbol
        and line number information, the corresponding filename for that
        file, a base address for relocating the symbols, a flag indicating
        whether or not this debugging information is from a "main symbol
@@ -458,28 +531,28 @@ RETURNS
  */
 
 void
  */
 
 void
-dwarf_build_psymtabs (desc, filename, section_offsets, mainline, dbfoff, dbsize,
-                     lnoffset, lnsize, objfile)
-     int desc;
-     char *filename;
+dwarf_build_psymtabs (objfile, section_offsets, mainline, dbfoff, dbfsize,
+                     lnoffset, lnsize)
+     struct objfile *objfile;
      struct section_offsets *section_offsets;
      int mainline;
      struct section_offsets *section_offsets;
      int mainline;
-     unsigned int dbfoff;
-     unsigned int dbsize;
-     unsigned int lnoffset;
+     file_ptr dbfoff;
+     unsigned int dbfsize;
+     file_ptr lnoffset;
      unsigned int lnsize;
      unsigned int lnsize;
-     struct objfile *objfile;
 {
 {
+  bfd *abfd = objfile->obfd;
   struct cleanup *back_to;
   
   current_objfile = objfile;
   struct cleanup *back_to;
   
   current_objfile = objfile;
+  dbsize = dbfsize;
   dbbase = xmalloc (dbsize);
   dbroff = 0;
   dbbase = xmalloc (dbsize);
   dbroff = 0;
-  if ((lseek (desc, dbfoff, 0) != dbfoff) ||
-      (read (desc, dbbase, dbsize) != dbsize))
+  if ((bfd_seek (abfd, dbfoff, L_SET) != 0) ||
+      (bfd_read (dbbase, dbsize, 1, abfd) != dbsize))
     {
       free (dbbase);
     {
       free (dbbase);
-      error ("can't read DWARF data from '%s'", filename);
+      error ("can't read DWARF data from '%s'", bfd_get_filename (abfd));
     }
   back_to = make_cleanup (free, dbbase);
   
     }
   back_to = make_cleanup (free, dbbase);
   
@@ -502,8 +575,7 @@ dwarf_build_psymtabs (desc, filename, section_offsets, mainline, dbfoff, dbsize,
      table entry for each one.  Save enough information about each compilation
      unit to locate the full DWARF information later. */
   
      table entry for each one.  Save enough information about each compilation
      unit to locate the full DWARF information later. */
   
-  scan_compilation_units (filename, dbbase, dbbase + dbsize,
-                         dbfoff, lnoffset, objfile);
+  scan_compilation_units (dbbase, dbbase + dbsize, dbfoff, lnoffset, objfile);
   
   do_cleanups (back_to);
   current_objfile = NULL;
   
   do_cleanups (back_to);
   current_objfile = NULL;
@@ -818,6 +890,10 @@ struct_type (dip, thisdie, enddie, objfile)
   INIT_CPLUS_SPECIFIC(type);
   switch (dip -> die_tag)
     {
   INIT_CPLUS_SPECIFIC(type);
   switch (dip -> die_tag)
     {
+      case TAG_class_type:
+        TYPE_CODE (type) = TYPE_CODE_CLASS;
+       tpart1 = "class";
+       break;
       case TAG_structure_type:
         TYPE_CODE (type) = TYPE_CODE_STRUCT;
        tpart1 = "struct";
       case TAG_structure_type:
         TYPE_CODE (type) = TYPE_CODE_STRUCT;
        tpart1 = "struct";
@@ -830,7 +906,7 @@ struct_type (dip, thisdie, enddie, objfile)
        /* Should never happen */
        TYPE_CODE (type) = TYPE_CODE_UNDEF;
        tpart1 = "???";
        /* Should never happen */
        TYPE_CODE (type) = TYPE_CODE_UNDEF;
        tpart1 = "???";
-       SQUAWK (("missing structure or union tag"));
+       SQUAWK (("missing class, structure, or union tag"));
        break;
     }
   /* Some compilers try to be helpful by inventing "fake" names for
        break;
     }
   /* Some compilers try to be helpful by inventing "fake" names for
@@ -935,8 +1011,7 @@ struct_type (dip, thisdie, enddie, objfile)
     {
       TYPE_NFIELDS (type) = nfields;
       TYPE_FIELDS (type) = (struct field *)
     {
       TYPE_NFIELDS (type) = nfields;
       TYPE_FIELDS (type) = (struct field *)
-       obstack_alloc (&objfile -> type_obstack,
-                      sizeof (struct field) * nfields);
+       TYPE_ALLOC (type, sizeof (struct field) * nfields);
       /* Copy the saved-up fields into the field vector.  */
       for (n = nfields; list; list = list -> next)
        {
       /* Copy the saved-up fields into the field vector.  */
       for (n = nfields; list; list = list -> next)
        {
@@ -993,9 +1068,14 @@ read_structure_scope (dip, thisdie, enddie, objfile)
   type = struct_type (dip, thisdie, enddie, objfile);
   if (!(TYPE_FLAGS (type) & TYPE_FLAG_STUB))
     {
   type = struct_type (dip, thisdie, enddie, objfile);
   if (!(TYPE_FLAGS (type) & TYPE_FLAG_STUB))
     {
-      if ((sym = new_symbol (dip, objfile)) != NULL)
+      sym = new_symbol (dip, objfile);
+      if (sym != NULL)
        {
          SYMBOL_TYPE (sym) = type;
        {
          SYMBOL_TYPE (sym) = type;
+         if (cu_language == language_cplus)
+           {
+             synthesize_typedef (dip, objfile, type);
+           }
        }
     }
 }
        }
     }
 }
@@ -1372,9 +1452,14 @@ read_enumeration (dip, thisdie, enddie, objfile)
   struct symbol *sym;
   
   type = enum_type (dip, objfile);
   struct symbol *sym;
   
   type = enum_type (dip, objfile);
-  if ((sym = new_symbol (dip, objfile)) != NULL)
+  sym = new_symbol (dip, objfile);
+  if (sym != NULL)
     {
       SYMBOL_TYPE (sym) = type;
     {
       SYMBOL_TYPE (sym) = type;
+      if (cu_language == language_cplus)
+       {
+         synthesize_typedef (dip, objfile, type);
+       }
     }
 }
 
     }
 }
 
@@ -1650,6 +1735,7 @@ read_file_scope (dip, thisdie, enddie, objfile)
       objfile -> ei.entry_file_lowpc = dip -> at_low_pc;
       objfile -> ei.entry_file_highpc = dip -> at_high_pc;
     }
       objfile -> ei.entry_file_lowpc = dip -> at_low_pc;
       objfile -> ei.entry_file_highpc = dip -> at_high_pc;
     }
+  set_cu_language (dip);
   if (dip -> at_producer != NULL)
     {
       handle_producer (dip -> at_producer);
   if (dip -> at_producer != NULL)
     {
       handle_producer (dip -> at_producer);
@@ -1664,19 +1750,7 @@ read_file_scope (dip, thisdie, enddie, objfile)
   symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile);
   if (symtab != NULL)
     {
   symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile);
   if (symtab != NULL)
     {
-      /* FIXME:  The following may need to be expanded for other languages */
-      switch (dip -> at_language)
-       {
-         case LANG_C89:
-         case LANG_C:
-           symtab -> language = language_c;
-           break;
-         case LANG_C_PLUS_PLUS:
-           symtab -> language = language_cplus;
-           break;
-         default:
-           ;
-       }
+      symtab -> language = cu_language;
     }      
   do_cleanups (back_to);
   utypes = NULL;
     }      
   do_cleanups (back_to);
   utypes = NULL;
@@ -1746,6 +1820,7 @@ process_dies (thisdie, enddie, objfile)
            case TAG_lexical_block:
              read_lexical_block_scope (&di, thisdie, nextdie, objfile);
              break;
            case TAG_lexical_block:
              read_lexical_block_scope (&di, thisdie, nextdie, objfile);
              break;
+           case TAG_class_type:
            case TAG_structure_type:
            case TAG_union_type:
              read_structure_scope (&di, thisdie, nextdie, objfile);
            case TAG_structure_type:
            case TAG_union_type:
              read_structure_scope (&di, thisdie, nextdie, objfile);
@@ -2013,7 +2088,7 @@ read_ofile_symtab (pst)
 {
   struct cleanup *back_to;
   unsigned long lnsize;
 {
   struct cleanup *back_to;
   unsigned long lnsize;
-  int foffset;
+  file_ptr foffset;
   bfd *abfd;
   char lnsizedata[SIZEOF_LINETBL_LENGTH];
 
   bfd *abfd;
   char lnsizedata[SIZEOF_LINETBL_LENGTH];
 
@@ -2024,13 +2099,14 @@ read_ofile_symtab (pst)
      unit, seek to the location in the file, and read in all the DIE's. */
 
   diecount = 0;
      unit, seek to the location in the file, and read in all the DIE's. */
 
   diecount = 0;
-  dbbase = xmalloc (DBLENGTH(pst));
+  dbsize = DBLENGTH (pst);
+  dbbase = xmalloc (dbsize);
   dbroff = DBROFF(pst);
   foffset = DBFOFF(pst) + dbroff;
   base_section_offsets = pst->section_offsets;
   baseaddr = ANOFFSET (pst->section_offsets, 0);
   dbroff = DBROFF(pst);
   foffset = DBFOFF(pst) + dbroff;
   base_section_offsets = pst->section_offsets;
   baseaddr = ANOFFSET (pst->section_offsets, 0);
-  if (bfd_seek (abfd, foffset, 0) ||
-      (bfd_read (dbbase, DBLENGTH(pst), 1, abfd) != DBLENGTH(pst)))
+  if (bfd_seek (abfd, foffset, L_SET) ||
+      (bfd_read (dbbase, dbsize, 1, abfd) != dbsize))
     {
       free (dbbase);
       error ("can't read DWARF data");
     {
       free (dbbase);
       error ("can't read DWARF data");
@@ -2045,7 +2121,7 @@ read_ofile_symtab (pst)
   lnbase = NULL;
   if (LNFOFF (pst))
     {
   lnbase = NULL;
   if (LNFOFF (pst))
     {
-      if (bfd_seek (abfd, LNFOFF (pst), 0) ||
+      if (bfd_seek (abfd, LNFOFF (pst), L_SET) ||
          (bfd_read ((PTR) lnsizedata, sizeof (lnsizedata), 1, abfd) !=
           sizeof (lnsizedata)))
        {
          (bfd_read ((PTR) lnsizedata, sizeof (lnsizedata), 1, abfd) !=
           sizeof (lnsizedata)))
        {
@@ -2054,7 +2130,7 @@ read_ofile_symtab (pst)
       lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH,
                               GET_UNSIGNED, pst -> objfile);
       lnbase = xmalloc (lnsize);
       lnsize = target_to_host (lnsizedata, SIZEOF_LINETBL_LENGTH,
                               GET_UNSIGNED, pst -> objfile);
       lnbase = xmalloc (lnsize);
-      if (bfd_seek (abfd, LNFOFF (pst), 0) ||
+      if (bfd_seek (abfd, LNFOFF (pst), L_SET) ||
          (bfd_read (lnbase, lnsize, 1, abfd) != lnsize))
        {
          free (lnbase);
          (bfd_read (lnbase, lnsize, 1, abfd) != lnsize))
        {
          free (lnbase);
@@ -2063,7 +2139,7 @@ read_ofile_symtab (pst)
       make_cleanup (free, lnbase);
     }
 
       make_cleanup (free, lnbase);
     }
 
-  process_dies (dbbase, dbbase + DBLENGTH(pst), pst -> objfile);
+  process_dies (dbbase, dbbase + dbsize, pst -> objfile);
   do_cleanups (back_to);
   current_objfile = NULL;
   return (pst -> objfile -> symtabs);
   do_cleanups (back_to);
   current_objfile = NULL;
   return (pst -> objfile -> symtabs);
@@ -2312,6 +2388,9 @@ DESCRIPTION
        add to a partial symbol table, finish filling in the die info
        and then add a partial symbol table entry for it.
 
        add to a partial symbol table, finish filling in the die info
        and then add a partial symbol table entry for it.
 
+NOTES
+
+       The caller must ensure that the DIE has a valid name attribute.
 */
 
 static void
 */
 
 static void
@@ -2355,22 +2434,22 @@ add_partial_symbol (dip, objfile)
                           objfile -> static_psymbols,
                           0);
       break;
                           objfile -> static_psymbols,
                           0);
       break;
+    case TAG_class_type:
     case TAG_structure_type:
     case TAG_union_type:
     case TAG_structure_type:
     case TAG_union_type:
+    case TAG_enumeration_type:
       ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
                           STRUCT_NAMESPACE, LOC_TYPEDEF,
                           objfile -> static_psymbols,
                           0);
       ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
                           STRUCT_NAMESPACE, LOC_TYPEDEF,
                           objfile -> static_psymbols,
                           0);
-      break;
-    case TAG_enumeration_type:
-      if (dip -> at_name)
+      if (cu_language == language_cplus)
        {
        {
+         /* For C++, these implicitly act as typedefs as well. */
          ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
          ADD_PSYMBOL_TO_LIST (dip -> at_name, strlen (dip -> at_name),
-                              STRUCT_NAMESPACE, LOC_TYPEDEF,
+                              VAR_NAMESPACE, LOC_TYPEDEF,
                               objfile -> static_psymbols,
                               0);
        }
                               objfile -> static_psymbols,
                               0);
        }
-      add_enum_psymbol (dip, objfile);
       break;
     }
 }
       break;
     }
 }
@@ -2496,6 +2575,7 @@ scan_partial_symbols (thisdie, enddie, objfile)
                }
              break;
            case TAG_typedef:
                }
              break;
            case TAG_typedef:
+           case TAG_class_type:
            case TAG_structure_type:
            case TAG_union_type:
              completedieinfo (&di, objfile);
            case TAG_structure_type:
            case TAG_union_type:
              completedieinfo (&di, objfile);
@@ -2506,7 +2586,11 @@ scan_partial_symbols (thisdie, enddie, objfile)
              break;
            case TAG_enumeration_type:
              completedieinfo (&di, objfile);
              break;
            case TAG_enumeration_type:
              completedieinfo (&di, objfile);
-             add_partial_symbol (&di, objfile);
+             if (di.at_name)
+               {
+                 add_partial_symbol (&di, objfile);
+               }
+             add_enum_psymbol (&di, objfile);
              break;
            }
        }
              break;
            }
        }
@@ -2558,12 +2642,11 @@ RETURNS
  */
 
 static void
  */
 
 static void
-scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile)
-     char *filename;
+scan_compilation_units (thisdie, enddie, dbfoff, lnoffset, objfile)
      char *thisdie;
      char *enddie;
      char *thisdie;
      char *enddie;
-     unsigned int dbfoff;
-     unsigned int lnoffset;
+     file_ptr dbfoff;
+     file_ptr lnoffset;
      struct objfile *objfile;
 {
   char *nextdie;
      struct objfile *objfile;
 {
   char *nextdie;
@@ -2571,7 +2654,7 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile)
   struct partial_symtab *pst;
   int culength;
   int curoff;
   struct partial_symtab *pst;
   int culength;
   int curoff;
-  int curlnoffset;
+  file_ptr curlnoffset;
 
   while (thisdie < enddie)
     {
 
   while (thisdie < enddie)
     {
@@ -2587,6 +2670,7 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile)
       else
        {
          completedieinfo (&di, objfile);
       else
        {
          completedieinfo (&di, objfile);
+         set_cu_language (&di);
          if (di.at_sibling != 0)
            {
              nextdie = dbbase + di.at_sibling - dbroff;
          if (di.at_sibling != 0)
            {
              nextdie = dbbase + di.at_sibling - dbroff;
@@ -2601,8 +2685,8 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile)
 
          /* First allocate a new partial symbol table structure */
 
 
          /* First allocate a new partial symbol table structure */
 
-         pst = start_psymtab_common (objfile, base_section_offsets, di.at_name,
-                                     di.at_low_pc,
+         pst = start_psymtab_common (objfile, base_section_offsets,
+                                     di.at_name, di.at_low_pc,
                                      objfile -> global_psymbols.next,
                                      objfile -> static_psymbols.next);
 
                                      objfile -> global_psymbols.next,
                                      objfile -> static_psymbols.next);
 
@@ -2664,7 +2748,8 @@ new_symbol (dip, objfile)
       sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack,
                                             sizeof (struct symbol));
       memset (sym, 0, sizeof (struct symbol));
       sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack,
                                             sizeof (struct symbol));
       memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = create_name (dip -> at_name, &objfile->symbol_obstack);
+      SYMBOL_NAME (sym) = create_name (dip -> at_name,
+                                      &objfile->symbol_obstack);
       /* default assumptions */
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       SYMBOL_CLASS (sym) = LOC_STATIC;
       /* default assumptions */
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
       SYMBOL_CLASS (sym) = LOC_STATIC;
@@ -2737,6 +2822,7 @@ new_symbol (dip, objfile)
          /* From varargs functions; gdb doesn't seem to have any interest in
             this information, so just ignore it for now. (FIXME?) */
          break;
          /* From varargs functions; gdb doesn't seem to have any interest in
             this information, so just ignore it for now. (FIXME?) */
          break;
+       case TAG_class_type:
        case TAG_structure_type:
        case TAG_union_type:
        case TAG_enumeration_type:
        case TAG_structure_type:
        case TAG_union_type:
        case TAG_enumeration_type:
@@ -2761,6 +2847,50 @@ new_symbol (dip, objfile)
 
 /*
 
 
 /*
 
+LOCAL FUNCTION
+
+       synthesize_typedef -- make a symbol table entry for a "fake" typedef
+
+SYNOPSIS
+
+       static void synthesize_typedef (struct dieinfo *dip,
+                                       struct objfile *objfile,
+                                       struct type *type);
+
+DESCRIPTION
+
+       Given a pointer to a DWARF information entry, synthesize a typedef
+       for the name in the DIE, using the specified type.
+
+       This is used for C++ class, structs, unions, and enumerations to
+       set up the tag name as a type.
+
+ */
+
+static void
+synthesize_typedef (dip, objfile, type)
+     struct dieinfo *dip;
+     struct objfile *objfile;
+     struct type *type;
+{
+  struct symbol *sym = NULL;
+  
+  if (dip -> at_name != NULL)
+    {
+      sym = (struct symbol *)
+       obstack_alloc (&objfile -> symbol_obstack, sizeof (struct symbol));
+      memset (sym, 0, sizeof (struct symbol));
+      SYMBOL_NAME (sym) = create_name (dip -> at_name,
+                                      &objfile->symbol_obstack);
+      SYMBOL_TYPE (sym) = type;
+      SYMBOL_CLASS (sym) = LOC_TYPEDEF;
+      SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
+      add_symbol_to_list (sym, list_in_scope);
+    }
+}
+
+/*
+
 LOCAL FUNCTION
 
        decode_mod_fund_type -- decode a modified fundamental type
 LOCAL FUNCTION
 
        decode_mod_fund_type -- decode a modified fundamental type
@@ -3171,6 +3301,12 @@ NOTES
        that if a padding DIE is used for alignment and the amount needed is
        less than SIZEOF_DIE_LENGTH, then the padding DIE has to be big
        enough to align to the next alignment boundry.
        that if a padding DIE is used for alignment and the amount needed is
        less than SIZEOF_DIE_LENGTH, then the padding DIE has to be big
        enough to align to the next alignment boundry.
+
+       We do some basic sanity checking here, such as verifying that the
+       length of the die would not cause it to overrun the recorded end of
+       the buffer holding the DIE info.  If we find a DIE that is either
+       too small or too large, we force it's length to zero which should
+       cause the caller to take appropriate action.
  */
 
 static void
  */
 
 static void
@@ -3185,9 +3321,11 @@ basicdieinfo (dip, diep, objfile)
   dip -> die_ref = dbroff + (diep - dbbase);
   dip -> die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED,
                                      objfile);
   dip -> die_ref = dbroff + (diep - dbbase);
   dip -> die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED,
                                      objfile);
-  if (dip -> die_length < SIZEOF_DIE_LENGTH)
+  if ((dip -> die_length < SIZEOF_DIE_LENGTH) ||
+      ((diep + dip -> die_length) > (dbbase + dbsize)))
     {
       dwarfwarn ("malformed DIE, bad length (%d bytes)", dip -> die_length);
     {
       dwarfwarn ("malformed DIE, bad length (%d bytes)", dip -> die_length);
+      dip -> die_length = 0;
     }
   else if (dip -> die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG))
     {
     }
   else if (dip -> die_length < (SIZEOF_DIE_LENGTH + SIZEOF_DIE_TAG))
     {
This page took 0.031188 seconds and 4 git commands to generate.