Add new devices x1122 x1132 emulation.
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 62f0fee2ed5a8f2fa9ae5b8b7b4dac6ddfa8a722..c77642d239a1a126e3e60ac3e5a657848b66442e 100644 (file)
 #include "expression.h"
 #include "filenames.h" /* for DOSish file names */
 #include "macrotab.h"
-
 #include "language.h"
 #include "complaints.h"
 #include "bcache.h"
+#include "dwarf2expr.h"
+#include "dwarf2loc.h"
+
 #include <fcntl.h>
 #include "gdb_string.h"
 #include "gdb_assert.h"
@@ -905,6 +907,11 @@ static void dwarf_decode_macros (struct line_header *, unsigned int,
 
 static int attr_form_is_block (struct attribute *);
 
+static void
+dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
+                            const struct comp_unit_head *,
+                            struct objfile *objfile);
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
@@ -978,7 +985,7 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, void *ignore_ptr)
     {
       dwarf_macinfo_offset = sectp->filepos;
       dwarf_macinfo_size = bfd_get_section_size_before_reloc (sectp);
-      dwarf_loc_section = sectp;
+      dwarf_macinfo_section = sectp;
     }
   else if (STREQ (sectp->name, STR_SECTION))
     {
@@ -1218,22 +1225,24 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
 
       if (cu_header.version != 2)
        {
-         error ("Dwarf Error: wrong version in compilation unit header.");
+         error ("Dwarf Error: wrong version in compilation unit header (is %d, should be %d) [in module %s]", cu_header.version, 2, bfd_get_filename (abfd));
          return;
        }
       if (cu_header.abbrev_offset >= dwarf_abbrev_size)
        {
-         error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6).",
+         error ("Dwarf Error: bad offset (0x%lx) in compilation unit header (offset 0x%lx + 6) [in module %s]",
                 (long) cu_header.abbrev_offset,
-                (long) (beg_of_comp_unit - dwarf_info_buffer));
+                (long) (beg_of_comp_unit - dwarf_info_buffer),
+                bfd_get_filename (abfd));
          return;
        }
       if (beg_of_comp_unit + cu_header.length + cu_header.initial_length_size
          > dwarf_info_buffer + dwarf_info_size)
        {
-         error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0).",
+         error ("Dwarf Error: bad length (0x%lx) in compilation unit header (offset 0x%lx + 0) [in module %s]",
                 (long) cu_header.length,
-                (long) (beg_of_comp_unit - dwarf_info_buffer));
+                (long) (beg_of_comp_unit - dwarf_info_buffer),
+                bfd_get_filename (abfd));
          return;
        }
       /* Complete the cu_header */
@@ -1996,6 +2005,13 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
 
   new = push_context (0, lowpc);
   new->name = new_symbol (die, die->type, objfile, cu_header);
+
+  /* If there was a location expression for DW_AT_frame_base above,
+     record it.  We still need to decode it above because not all
+     symbols use location expressions exclusively.  */
+  if (attr)
+    dwarf2_symbol_mark_computed (attr, new->name, cu_header, objfile);
+
   list_in_scope = &local_symbols;
 
   if (die->has_children)
@@ -2193,6 +2209,9 @@ dwarf2_get_pc_bounds (struct die_info *die, CORE_ADDR *lowpc,
                  return 0;
                }
 
+             range_beginning += base;
+             range_end += base;
+
              /* FIXME: This is recording everything as a low-high
                 segment of consecutive addresses.  We should have a
                 data structure for discontiguous block ranges
@@ -2908,7 +2927,7 @@ read_enumeration (struct die_info *die, struct objfile *objfile,
                                  * sizeof (struct field));
                    }
 
-                 FIELD_NAME (fields[num_fields]) = SYMBOL_NAME (sym);
+                 FIELD_NAME (fields[num_fields]) = DEPRECATED_SYMBOL_NAME (sym);
                  FIELD_TYPE (fields[num_fields]) = NULL;
                  FIELD_BITPOS (fields[num_fields]) = SYMBOL_VALUE (sym);
                  FIELD_BITSIZE (fields[num_fields]) = 0;
@@ -3787,7 +3806,8 @@ read_partial_die (struct partial_die_info *part_die, bfd *abfd,
   abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
   if (!abbrev)
     {
-      error ("Dwarf Error: Could not find abbrev number %d.", abbrev_number);
+      error ("Dwarf Error: Could not find abbrev number %d [in module %s]", abbrev_number,
+                     bfd_get_filename (abfd));
     }
   part_die->offset = info_ptr - dwarf_info_buffer;
   part_die->tag = abbrev->tag;
@@ -3931,7 +3951,8 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
   abbrev = dwarf2_lookup_abbrev (abbrev_number, cu_header);
   if (!abbrev)
     {
-      error ("Dwarf Error: could not find abbrev number %d.", abbrev_number);
+      error ("Dwarf Error: could not find abbrev number %d [in module %s]", abbrev_number, 
+                     bfd_get_filename (abfd));
     }
   die = dwarf_alloc_die ();
   die->offset = offset;
@@ -4067,8 +4088,9 @@ read_attribute_value (struct attribute *attr, unsigned form,
       info_ptr = read_attribute_value (attr, form, abfd, info_ptr, cu_header);
       break;
     default:
-      error ("Dwarf Error: Cannot handle %s in DWARF reader.",
-            dwarf_form_name (form));
+      error ("Dwarf Error: Cannot handle %s in DWARF reader [in module %s]",
+            dwarf_form_name (form),
+            bfd_get_filename (abfd));
     }
   return info_ptr;
 }
@@ -4149,7 +4171,8 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
          break;
        default:
          internal_error (__FILE__, __LINE__,
-                         "read_address: bad switch, signed");
+                         "read_address: bad switch, signed [in module %s]",
+                         bfd_get_filename (abfd));
        }
     }
   else
@@ -4167,7 +4190,8 @@ read_address (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
          break;
        default:
          internal_error (__FILE__, __LINE__,
-                         "read_address: bad switch, unsigned");
+                         "read_address: bad switch, unsigned [in module %s]",
+                         bfd_get_filename (abfd));
        }
     }
 
@@ -4282,7 +4306,8 @@ read_offset (bfd *abfd, char *buf, const struct comp_unit_head *cu_header,
       break;
     default:
       internal_error (__FILE__, __LINE__,
-                     "read_offset: bad switch");
+                     "read_offset: bad switch [in module %s]",
+                     bfd_get_filename (abfd));
     }
 
  return retval;
@@ -4324,12 +4349,14 @@ read_indirect_string (bfd *abfd, char *buf,
 
   if (dwarf_str_buffer == NULL)
     {
-      error ("DW_FORM_strp used without .debug_str section");
+      error ("DW_FORM_strp used without .debug_str section [in module %s]",
+                     bfd_get_filename (abfd));
       return NULL;
     }
   if (str_offset >= dwarf_str_size)
     {
-      error ("DW_FORM_strp pointing outside of .debug_str section");
+      error ("DW_FORM_strp pointing outside of .debug_str section [in module %s]",
+                     bfd_get_filename (abfd));
       return NULL;
     }
   gdb_assert (HOST_CHAR_BIT == 8);
@@ -4917,6 +4944,61 @@ dwarf2_start_subfile (char *filename, char *dirname)
   start_subfile (filename, dirname);
 }
 
+static void
+var_decode_location (struct attribute *attr, struct symbol *sym,
+                    struct objfile *objfile,
+                    const struct comp_unit_head *cu_header)
+{
+  /* NOTE drow/2003-01-30: There used to be a comment and some special
+     code here to turn a symbol with DW_AT_external and a
+     SYMBOL_VALUE_ADDRESS of 0 into a LOC_UNRESOLVED symbol.  This was
+     necessary for platforms (maybe Alpha, certainly PowerPC GNU/Linux
+     with some versions of binutils) where shared libraries could have
+     relocations against symbols in their debug information - the
+     minimal symbol would have the right address, but the debug info
+     would not.  It's no longer necessary, because we will explicitly
+     apply relocations when we read in the debug information now.  */
+
+  /* A DW_AT_location attribute with no contents indicates that a
+     variable has been optimized away.  */
+  if (attr_form_is_block (attr) && DW_BLOCK (attr)->size == 0)
+    {
+      SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
+      return;
+    }
+
+  /* Handle one degenerate form of location expression specially, to
+     preserve GDB's previous behavior when section offsets are
+     specified.  If this is just a DW_OP_addr then mark this symbol
+     as LOC_STATIC.  */
+
+  if (attr_form_is_block (attr)
+      && DW_BLOCK (attr)->size == 1 + cu_header->addr_size
+      && DW_BLOCK (attr)->data[0] == DW_OP_addr)
+    {
+      int dummy;
+
+      SYMBOL_VALUE_ADDRESS (sym) =
+       read_address (objfile->obfd, DW_BLOCK (attr)->data + 1, cu_header,
+                     &dummy);
+      fixup_symbol_section (sym, objfile);
+      SYMBOL_VALUE_ADDRESS (sym) += ANOFFSET (objfile->section_offsets,
+                                             SYMBOL_SECTION (sym));
+      SYMBOL_CLASS (sym) = LOC_STATIC;
+      return;
+    }
+
+  /* NOTE drow/2002-01-30: It might be worthwhile to have a static
+     expression evaluator, and use LOC_COMPUTED only when necessary
+     (i.e. when the value of a register or memory location is
+     referenced, or a thread-local block, etc.).  Then again, it might
+     not be worthwhile.  I'm assuming that it isn't unless performance
+     or memory numbers show me otherwise.  */
+
+  dwarf2_symbol_mark_computed (attr, sym, cu_header, objfile);
+  SYMBOL_CLASS (sym) = LOC_COMPUTED;
+}
+
 /* Given a pointer to a DWARF information entry, figure out if we need
    to make a symbol table entry for it, and if so, create a new entry
    and return a pointer to it.
@@ -4940,8 +5022,10 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
                                             sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
       memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_NAME (sym) = obsavestring (name, strlen (name),
-                                       &objfile->symbol_obstack);
+
+      /* Cache this symbol's name and the name's demangled form (if any).  */
+      SYMBOL_LANGUAGE (sym) = cu_language;
+      SYMBOL_SET_NAMES (sym, name, strlen (name), objfile);
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -4956,15 +5040,6 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
        {
          SYMBOL_LINE (sym) = DW_UNSND (attr);
        }
-
-      /* If this symbol is from a C++ compilation, then attempt to
-         cache the demangled form for future reference.  This is a
-         typical time versus space tradeoff, that was decided in favor
-         of time because it sped up C++ symbol lookups by a factor of
-         about 20. */
-
-      SYMBOL_LANGUAGE (sym) = cu_language;
-      SYMBOL_INIT_DEMANGLED_NAME (sym, &objfile->symbol_obstack);
       switch (die->tag)
        {
        case DW_TAG_label:
@@ -5012,106 +5087,12 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
          attr = dwarf_attr (die, DW_AT_location);
          if (attr)
            {
+             var_decode_location (attr, sym, objfile, cu_header);
              attr2 = dwarf_attr (die, DW_AT_external);
              if (attr2 && (DW_UNSND (attr2) != 0))
-               {
-                  /* Support the .debug_loc offsets */
-                  if (attr_form_is_block (attr))
-                    {
-                     SYMBOL_VALUE_ADDRESS (sym) =
-                       decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
-                    }
-                  else if (attr->form == DW_FORM_data4
-                           || attr->form == DW_FORM_data8)
-                    {
-                     dwarf2_complex_location_expr_complaint ();
-                    }
-                  else
-                    {
-                     dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
-                                                            "external variable");
-                    }
-                 add_symbol_to_list (sym, &global_symbols);
-                  if (is_thread_local)
-                    {
-                      /* SYMBOL_VALUE_ADDRESS contains at this point the
-                        offset of the variable within the thread local
-                        storage.  */
-                      SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
-                      SYMBOL_OBJFILE (sym) = objfile;
-                    }
-
-                 /* In shared libraries the address of the variable
-                    in the location descriptor might still be relocatable,
-                    so its value could be zero.
-                    Enter the symbol as a LOC_UNRESOLVED symbol, if its
-                    value is zero, the address of the variable will then
-                    be determined from the minimal symbol table whenever
-                    the variable is referenced.  */
-                 else if (SYMBOL_VALUE_ADDRESS (sym))
-                   {
-                     fixup_symbol_section (sym, objfile);
-                     SYMBOL_VALUE_ADDRESS (sym) +=
-                       ANOFFSET (objfile->section_offsets,
-                                 SYMBOL_SECTION (sym));
-                     SYMBOL_CLASS (sym) = LOC_STATIC;
-                   }
-                 else
-                   SYMBOL_CLASS (sym) = LOC_UNRESOLVED;
-               }
+               add_symbol_to_list (sym, &global_symbols);
              else
-               {
-                  /* Support the .debug_loc offsets */
-                  if (attr_form_is_block (attr))
-                    {
-                     SYMBOL_VALUE (sym) = addr =
-                       decode_locdesc (DW_BLOCK (attr), objfile, cu_header);
-                    }
-                  else if (attr->form == DW_FORM_data4
-                           || attr->form == DW_FORM_data8)
-                    {
-                     dwarf2_complex_location_expr_complaint ();
-                    }
-                  else
-                    {
-                     dwarf2_invalid_attrib_class_complaint ("DW_AT_location",
-                                                            "external variable");
-                      addr = 0;
-                    }
-                 add_symbol_to_list (sym, list_in_scope);
-                 if (optimized_out)
-                   {
-                     SYMBOL_CLASS (sym) = LOC_OPTIMIZED_OUT;
-                   }
-                 else if (isreg)
-                   {
-                     SYMBOL_CLASS (sym) = LOC_REGISTER;
-                     SYMBOL_VALUE (sym) = 
-                       DWARF2_REG_TO_REGNUM (SYMBOL_VALUE (sym));
-                   }
-                 else if (offreg)
-                   {
-                     SYMBOL_CLASS (sym) = LOC_BASEREG;
-                     SYMBOL_BASEREG (sym) = DWARF2_REG_TO_REGNUM (basereg);
-                   }
-                 else if (islocal)
-                   {
-                     SYMBOL_CLASS (sym) = LOC_LOCAL;
-                   }
-                  else if (is_thread_local)
-                    {
-                      SYMBOL_CLASS (sym) = LOC_THREAD_LOCAL_STATIC;
-                      SYMBOL_OBJFILE (sym) = objfile;
-                    }
-                 else
-                   {
-                     fixup_symbol_section (sym, objfile);
-                     SYMBOL_VALUE_ADDRESS (sym) =
-                       addr + ANOFFSET (objfile->section_offsets,
-                                        SYMBOL_SECTION (sym));
-                     SYMBOL_CLASS (sym) = LOC_STATIC;
-                   }
-               }
+               add_symbol_to_list (sym, list_in_scope);
            }
          else
            {
@@ -5193,8 +5174,8 @@ new_symbol (struct die_info *die, struct type *type, struct objfile *objfile,
              SYMBOL_NAMESPACE (typedef_sym) = VAR_NAMESPACE;
              if (TYPE_NAME (SYMBOL_TYPE (sym)) == 0)
                TYPE_NAME (SYMBOL_TYPE (sym)) =
-                 obsavestring (SYMBOL_NAME (sym),
-                               strlen (SYMBOL_NAME (sym)),
+                 obsavestring (DEPRECATED_SYMBOL_NAME (sym),
+                               strlen (DEPRECATED_SYMBOL_NAME (sym)),
                                &objfile->type_obstack);
              add_symbol_to_list (typedef_sym, list_in_scope);
            }
@@ -5239,7 +5220,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
     {
     case DW_FORM_addr:
       if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != cu_header->addr_size)
-       dwarf2_const_value_length_mismatch_complaint (SYMBOL_NAME (sym),
+       dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym),
                                                      cu_header->addr_size,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
@@ -5255,7 +5236,7 @@ dwarf2_const_value (struct attribute *attr, struct symbol *sym,
     case DW_FORM_block:
       blk = DW_BLOCK (attr);
       if (TYPE_LENGTH (SYMBOL_TYPE (sym)) != blk->size)
-       dwarf2_const_value_length_mismatch_complaint (SYMBOL_NAME (sym),
+       dwarf2_const_value_length_mismatch_complaint (DEPRECATED_SYMBOL_NAME (sym),
                                                      blk->size,
                                                      TYPE_LENGTH (SYMBOL_TYPE
                                                                   (sym)));
@@ -5349,7 +5330,8 @@ die_type (struct die_info *die, struct objfile *objfile,
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
-         error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+         error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", 
+                         ref, objfile->name);
          return NULL;
        }
     }
@@ -5357,7 +5339,8 @@ die_type (struct die_info *die, struct objfile *objfile,
   if (!type)
     {
       dump_die (type_die);
-      error ("Dwarf Error: Problem turning type die at offset into gdb type.");
+      error ("Dwarf Error: Problem turning type die at offset into gdb type [in module %s]",
+                     objfile->name);
     }
   return type;
 }
@@ -5381,7 +5364,8 @@ die_containing_type (struct die_info *die, struct objfile *objfile,
       type_die = follow_die_ref (ref);
       if (!type_die)
        {
-         error ("Dwarf Error: Cannot find referent at offset %d.", ref);
+         error ("Dwarf Error: Cannot find referent at offset %d [in module %s]", ref, 
+                         objfile->name);
          return NULL;
        }
       type = tag_type_to_type (type_die, objfile, cu_header);
@@ -5390,7 +5374,8 @@ die_containing_type (struct die_info *die, struct objfile *objfile,
     {
       if (type_die)
        dump_die (type_die);
-      error ("Dwarf Error: Problem turning containing type into gdb type.");
+      error ("Dwarf Error: Problem turning containing type into gdb type [in module %s]", 
+                     objfile->name);
     }
   return type;
 }
@@ -5427,7 +5412,8 @@ tag_type_to_type (struct die_info *die, struct objfile *objfile,
       if (!die->type)
        {
          dump_die (die);
-         error ("Dwarf Error: Cannot find type of die.");
+         error ("Dwarf Error: Cannot find type of die [in module %s]", 
+                         objfile->name);
        }
       return die->type;
     }
@@ -6602,8 +6588,8 @@ dwarf2_fundamental_type (struct objfile *objfile, int typeid)
 {
   if (typeid < 0 || typeid >= FT_NUM_MEMBERS)
     {
-      error ("Dwarf Error: internal error - invalid fundamental type id %d.",
-            typeid);
+      error ("Dwarf Error: internal error - invalid fundamental type id %d [in module %s]",
+            typeid, objfile->name);
     }
 
   /* Look for this particular type in the fundamental type vector.  If
@@ -7336,3 +7322,32 @@ attr_form_is_block (struct attribute *attr)
       || attr->form == DW_FORM_block4
       || attr->form == DW_FORM_block);
 }
+
+static void
+dwarf2_symbol_mark_computed (struct attribute *attr, struct symbol *sym,
+                            const struct comp_unit_head *cu_header,
+                            struct objfile *objfile)
+{
+  struct dwarf2_locexpr_baton *baton;
+
+  /* When support for location lists is added, this will go away.  */
+  if (!attr_form_is_block (attr))
+    {
+      dwarf2_complex_location_expr_complaint ();
+      return;
+    }
+
+  baton = obstack_alloc (&objfile->symbol_obstack,
+                        sizeof (struct dwarf2_locexpr_baton));
+  baton->objfile = objfile;
+
+  /* Note that we're just copying the block's data pointer here, not
+     the actual data.  We're still pointing into the dwarf_info_buffer
+     for SYM's objfile; right now we never release that buffer, but
+     when we do clean up properly this may need to change.  */
+  baton->size = DW_BLOCK (attr)->size;
+  baton->data = DW_BLOCK (attr)->data;
+
+  SYMBOL_LOCATION_FUNCS (sym) = &dwarf2_locexpr_funcs;
+  SYMBOL_LOCATION_BATON (sym) = baton;
+}
This page took 0.030699 seconds and 4 git commands to generate.