* Makefile.in (VERSION): Bump to 4.6.2.
[deliverable/binutils-gdb.git] / gdb / dwarfread.c
index 8a9cebd29491dd01bd6fcce3dd958ed0e889a93d..9e39f4ff95cfc4fa2099f2ce68b1b4922e9b8c61 100644 (file)
@@ -53,6 +53,7 @@ other things to work on, if you get bored. :-)
 #include "libbfd.h"    /* FIXME Secret Internal BFD stuff (bfd_read) */
 #include "elf/dwarf.h"
 #include "buildsym.h"
+#include "demangle.h"
 
 #ifdef MAINTENANCE     /* Define to 1 to compile in some maintenance stuff */
 #define SQUAWK(stuff) dwarfwarn stuff
@@ -70,6 +71,18 @@ typedef unsigned int DIE_REF;        /* Reference to a DIE */
 #define GCC_PRODUCER "GNU C "
 #endif
 
+#ifndef GPLUS_PRODUCER
+#define GPLUS_PRODUCER "GNU C++ "
+#endif
+
+#ifndef LCC_PRODUCER
+#define LCC_PRODUCER "NCR C/C++ "
+#endif
+
+#ifndef CFRONT_PRODUCER
+#define CFRONT_PRODUCER "CFRONT "      /* A wild a** guess... */
+#endif
+
 #define STREQ(a,b)             (strcmp(a,b)==0)
 #define STREQN(a,b,n)          (strncmp(a,b,n)==0)
 
@@ -206,8 +219,14 @@ static char *lnbase;       /* Base pointer to line section */
 static int isreg;      /* Kludge to identify register variables */
 static int offreg;     /* Kludge to identify basereg references */
 
+/* This value is added to each symbol value.  FIXME:  Generalize to 
+   the section_offsets structure used by dbxread.  */
 static CORE_ADDR baseaddr;     /* Add to each symbol value */
 
+/* The section offsets used in the current psymtab or symtab.  FIXME,
+   only used to pass one value (baseaddr) at the moment.  */
+static struct section_offsets *base_section_offsets;
+
 /* Each partial symbol table entry contains a pointer to private data for the
    read_symtab() function to use when expanding a partial symbol table entry
    to a full symbol table entry.  For DWARF debugging info, this data is
@@ -295,6 +314,9 @@ target_to_host PARAMS ((char *, int, int, struct objfile *));
 static void
 add_enum_psymbol PARAMS ((struct dieinfo *, struct objfile *));
 
+static void
+handle_producer PARAMS ((char *));
+
 static void
 read_file_scope PARAMS ((struct dieinfo *, char *, char *, struct objfile *));
 
@@ -380,7 +402,7 @@ static struct type *
 decode_mod_u_d_type PARAMS ((char *));
 
 static struct type *
-decode_modified_type PARAMS ((unsigned char *, unsigned int, int));
+decode_modified_type PARAMS ((char *, unsigned int, int));
 
 static struct type *
 decode_fund_type PARAMS ((unsigned int));
@@ -412,7 +434,8 @@ GLOBAL FUNCTION
 
 SYNOPSIS
 
-       void dwarf_build_psymtabs (int desc, char *filename, CORE_ADDR addr,
+       void dwarf_build_psymtabs (int desc, char *filename, 
+            struct section_offsets *section_offsets,
             int mainline, unsigned int dbfoff, unsigned int dbsize,
             unsigned int lnoffset, unsigned int lnsize,
             struct objfile *objfile)
@@ -437,11 +460,11 @@ RETURNS
  */
 
 void
-dwarf_build_psymtabs (desc, filename, addr, mainline, dbfoff, dbsize,
+dwarf_build_psymtabs (desc, filename, section_offsets, mainline, dbfoff, dbsize,
                      lnoffset, lnsize, objfile)
      int desc;
      char *filename;
-     CORE_ADDR addr;
+     struct section_offsets *section_offsets;
      int mainline;
      unsigned int dbfoff;
      unsigned int dbsize;
@@ -474,7 +497,8 @@ dwarf_build_psymtabs (desc, filename, addr, mainline, dbfoff, dbsize,
   
   /* Save the relocation factor where everybody can see it.  */
 
-  baseaddr = addr;
+  base_section_offsets = section_offsets;
+  baseaddr = ANOFFSET (section_offsets, 0);
 
   /* Follow the compilation unit sibling chain, building a partial symbol
      table entry for each one.  Save enough information about each compilation
@@ -596,7 +620,7 @@ read_lexical_block_scope (dip, thisdie, enddie, objfile)
 {
   register struct context_stack *new;
 
-  (void) push_context (0, dip -> at_low_pc);
+  push_context (0, dip -> at_low_pc);
   process_dies (thisdie + dip -> die_length, enddie, objfile);
   new = pop_context ();
   if (local_symbols != NULL)
@@ -691,11 +715,7 @@ alloc_utype (die_ref, utypep)
     {
       if (utypep == NULL)
        {
-         utypep = (struct type *)
-           obstack_alloc (&current_objfile -> type_obstack,
-                          sizeof (struct type));
-         (void) memset (utypep, 0, sizeof (struct type));
-         TYPE_OBJFILE (utypep) = current_objfile;
+         utypep = alloc_type (current_objfile);
        }
       *typep = utypep;
     }
@@ -853,7 +873,9 @@ struct_type (dip, thisdie, enddie, objfile)
          new -> next = list;
          list = new;
          /* Save the data.  */
-         list -> field.name = savestring (mbr.at_name, strlen (mbr.at_name));
+         list -> field.name =
+             obsavestring (mbr.at_name, strlen (mbr.at_name),
+                           &objfile -> type_obstack);
          list -> field.type = decode_die_type (&mbr);
          list -> field.bitpos = 8 * locval (mbr.at_location);
          /* Handle bit fields. */
@@ -1107,11 +1129,7 @@ decode_subscr_data (scan, end)
          nexttype = decode_subscr_data (scan, end);
          if (nexttype != NULL)
            {
-             typep = (struct type *)
-               obstack_alloc (&current_objfile -> type_obstack,
-                              sizeof (struct type));
-             (void) memset (typep, 0, sizeof (struct type));
-             TYPE_OBJFILE (typep) = current_objfile;
+             typep = alloc_type (current_objfile);
              TYPE_CODE (typep) = TYPE_CODE_ARRAY;
              TYPE_LENGTH (typep) = TYPE_LENGTH (nexttype);
              TYPE_LENGTH (typep) *= (highbound - lowbound) + 1;
@@ -1189,7 +1207,7 @@ dwarf_read_array_type (dip)
        {
          if ((utype = lookup_utype (dip -> die_ref)) == NULL)
            {
-             (void) alloc_utype (dip -> die_ref, type);
+             alloc_utype (dip -> die_ref, type);
            }
          else
            {
@@ -1228,7 +1246,7 @@ read_tag_pointer_type (dip)
   if ((utype = lookup_utype (dip -> die_ref)) == NULL)
     {
       utype = lookup_pointer_type (type);
-      (void) alloc_utype (dip -> die_ref, utype);
+      alloc_utype (dip -> die_ref, utype);
     }
   else
     {
@@ -1292,7 +1310,7 @@ read_subroutine_type (dip, thisdie, enddie)
       /* This is the first reference to one of these types.  Make
         a new one and place it in the user defined types. */
       ftype = lookup_function_type (type);
-      (void) alloc_utype (dip -> die_ref, ftype);
+      alloc_utype (dip -> die_ref, ftype);
     }
   else
     {
@@ -1440,13 +1458,14 @@ enum_type (dip, objfile)
            target_to_host (scan, TARGET_FT_LONG_SIZE (objfile), GET_SIGNED,
                            objfile);
          scan += TARGET_FT_LONG_SIZE (objfile);
-         list -> field.name = savestring (scan, strlen (scan));
+         list -> field.name = obsavestring (scan, strlen (scan),
+                                            &objfile -> type_obstack);
          scan += strlen (scan) + 1;
          nfields++;
          /* Handcraft a new symbol for this enum member. */
          sym = (struct symbol *) obstack_alloc (&objfile->symbol_obstack,
                                                 sizeof (struct symbol));
-         (void) memset (sym, 0, sizeof (struct symbol));
+         memset (sym, 0, sizeof (struct symbol));
          SYMBOL_NAME (sym) = create_name (list -> field.name,
                                           &objfile->symbol_obstack);
          SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
@@ -1456,7 +1475,7 @@ enum_type (dip, objfile)
          add_symbol_to_list (sym, list_in_scope);
        }
       /* Now create the vector of fields, and record how big it is. This is
-        where we reverse the order, by pulling the members of the list in
+        where we reverse the order, by pulling the members off the list in
         reverse order from how they were inserted.  If we have no fields
         (this is apparently possible in C++) then skip building a field
         vector. */
@@ -1527,6 +1546,57 @@ read_func_scope (dip, thisdie, enddie, objfile)
   list_in_scope = &file_symbols;
 }
 
+
+/*
+
+LOCAL FUNCTION
+
+       handle_producer -- process the AT_producer attribute
+
+DESCRIPTION
+
+       Perform any operations that depend on finding a particular
+       AT_producer attribute.
+
+ */
+
+static void
+handle_producer (producer)
+     char *producer;
+{
+
+  /* If this compilation unit was compiled with g++ or gcc, then set the
+     processing_gcc_compilation flag. */
+
+  processing_gcc_compilation =
+    STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER))
+      || STREQN (producer, GCC_PRODUCER, strlen (GCC_PRODUCER));
+
+  /* Select a demangling style if we can identify the producer and if
+     the current style is auto.  We leave the current style alone if it
+     is not auto.  We also leave the demangling style alone if we find a
+     gcc (cc1) producer, as opposed to a g++ (cc1plus) producer. */
+
+#if 1 /* Works, but is experimental.  -fnf */
+  if (current_demangling_style == auto_demangling)
+    {
+      if (STREQN (producer, GPLUS_PRODUCER, strlen (GPLUS_PRODUCER)))
+       {
+         set_demangling_style (GNU_DEMANGLING_STYLE_STRING);
+       }
+      else if (STREQN (producer, LCC_PRODUCER, strlen (LCC_PRODUCER)))
+       {
+         set_demangling_style (LUCID_DEMANGLING_STYLE_STRING);
+       }
+      else if (STREQN (producer, CFRONT_PRODUCER, strlen (CFRONT_PRODUCER)))
+       {
+         set_demangling_style (CFRONT_DEMANGLING_STYLE_STRING);
+       }
+    }
+#endif
+}
+
+
 /*
 
 LOCAL FUNCTION
@@ -1567,14 +1637,13 @@ read_file_scope (dip, thisdie, enddie, objfile)
     }
   if (dip -> at_producer != NULL)
     {
-      processing_gcc_compilation =
-       STREQN (dip -> at_producer, GCC_PRODUCER, strlen (GCC_PRODUCER));
+      handle_producer (dip -> at_producer);
     }
   numutypes = (enddie - thisdie) / 4;
   utypes = (struct type **) xmalloc (numutypes * sizeof (struct type *));
   back_to = make_cleanup (free, utypes);
-  (void) memset (utypes, 0, numutypes * sizeof (struct type *));
-  start_symtab (dip -> at_name, NULL, dip -> at_low_pc);
+  memset (utypes, 0, numutypes * sizeof (struct type *));
+  start_symtab (dip -> at_name, dip -> at_comp_dir, dip -> at_low_pc);
   decode_line_numbers (lnbase);
   process_dies (thisdie + dip -> die_length, enddie, objfile);
   symtab = end_symtab (dip -> at_high_pc, 0, 0, objfile);
@@ -1676,7 +1745,7 @@ process_dies (thisdie, enddie, objfile)
              read_tag_pointer_type (&di);
              break;
            default:
-             (void) new_symbol (&di, objfile);
+             new_symbol (&di, objfile);
              break;
            }
        }
@@ -1940,7 +2009,8 @@ read_ofile_symtab (pst)
   dbbase = xmalloc (DBLENGTH(pst));
   dbroff = DBROFF(pst);
   foffset = DBFOFF(pst) + dbroff;
-  baseaddr = pst -> addr;
+  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)))
     {
@@ -2003,6 +2073,7 @@ psymtab_to_symtab_1 (pst)
      struct partial_symtab *pst;
 {
   int i;
+  struct cleanup *old_chain;
   
   if (pst != NULL)
     {
@@ -2035,6 +2106,8 @@ psymtab_to_symtab_1 (pst)
            }     
          if (DBLENGTH (pst))           /* Otherwise it's a dummy */
            {
+             buildsym_init ();
+             old_chain = make_cleanup (really_free_pendings, 0);
              pst -> symtab = read_ofile_symtab (pst);
              if (info_verbose)
                {
@@ -2043,6 +2116,7 @@ psymtab_to_symtab_1 (pst)
                  fflush (stdout);
                }
              sort_symtab_syms (pst -> symtab);
+             do_cleanups (old_chain);
            }
          pst -> readin = 1;
        }
@@ -2451,7 +2525,7 @@ scan_compilation_units (filename, thisdie, enddie, dbfoff, lnoffset, objfile)
 
          /* First allocate a new partial symbol table structure */
 
-         pst = start_psymtab_common (objfile, baseaddr, di.at_name,
+         pst = start_psymtab_common (objfile, base_section_offsets, di.at_name,
                                      di.at_low_pc,
                                      objfile -> global_psymbols.next,
                                      objfile -> static_psymbols.next);
@@ -2513,7 +2587,7 @@ new_symbol (dip, objfile)
     {
       sym = (struct symbol *) obstack_alloc (&objfile -> symbol_obstack,
                                             sizeof (struct symbol));
-      (void) memset (sym, 0, sizeof (struct symbol));
+      memset (sym, 0, sizeof (struct symbol));
       SYMBOL_NAME (sym) = create_name (dip -> at_name, &objfile->symbol_obstack);
       /* default assumptions */
       SYMBOL_NAMESPACE (sym) = VAR_NAMESPACE;
@@ -2711,7 +2785,7 @@ LOCAL FUNCTION
 
 SYNOPSIS
 
-       static struct type *decode_modified_type (unsigned char *modifiers,
+       static struct type *decode_modified_type (char *modifiers,
            unsigned short modcount, int mtype)
 
 DESCRIPTION
@@ -2745,14 +2819,14 @@ BUGS
 
 static struct type *
 decode_modified_type (modifiers, modcount, mtype)
-     unsigned char *modifiers;
+     char *modifiers;
      unsigned int modcount;
      int mtype;
 {
   struct type *typep = NULL;
   unsigned short fundtype;
   DIE_REF die_ref;
-  unsigned char modifier;
+  char modifier;
   int nbytes;
   
   if (modcount == 0)
@@ -2799,9 +2873,11 @@ decode_modified_type (modifiers, modcount, mtype)
            SQUAWK (("type modifier 'volatile' ignored"));      /* FIXME */
            break;
          default:
-           if (!(MOD_lo_user <= modifier && modifier <= MOD_hi_user))
+           if (!(MOD_lo_user <= (unsigned char) modifier
+                 && (unsigned char) modifier <= MOD_hi_user))
              {
-               SQUAWK (("unknown type modifier %u", modifier));
+               SQUAWK (("unknown type modifier %u",
+                        (unsigned char) modifier));
              }
            break;
        }
@@ -2969,7 +3045,7 @@ create_name (name, obstackp)
 
   length = strlen (name) + 1;
   newname = (char *) obstack_alloc (obstackp, length);
-  (void) strcpy (newname, name);
+  strcpy (newname, name);
   return (newname);
 }
 
@@ -3028,7 +3104,7 @@ basicdieinfo (dip, diep, objfile)
      struct objfile *objfile;
 {
   curdie = dip;
-  (void) memset (dip, 0, sizeof (struct dieinfo));
+  memset (dip, 0, sizeof (struct dieinfo));
   dip -> die = diep;
   dip -> die_ref = dbroff + (diep - dbbase);
   dip -> die_length = target_to_host (diep, SIZEOF_DIE_LENGTH, GET_UNSIGNED,
@@ -3202,7 +3278,17 @@ completedieinfo (dip, objfile)
          dip -> at_name = diep;
          break;
        case AT_comp_dir:
-         dip -> at_comp_dir = diep;
+         /* For now, ignore any "hostname:" portion, since gdb doesn't
+            know how to deal with it.  (FIXME). */
+         dip -> at_comp_dir = strrchr (diep, ':');
+         if (dip -> at_comp_dir != NULL)
+           {
+             dip -> at_comp_dir++;
+           }
+         else
+           {
+             dip -> at_comp_dir = diep;
+           }
          break;
        case AT_producer:
          dip -> at_producer = diep;
This page took 0.029407 seconds and 4 git commands to generate.