2002-05-11 Daniel Jacobowitz <drow@mvista.com>
[deliverable/binutils-gdb.git] / gdb / dwarf2read.c
index 2ecfe8a7a1c71ee354bcc2daeb59a6f2e20e3214..b47baefb935bb3018225a78ddbbe7674fe7586cc 100644 (file)
@@ -1,5 +1,5 @@
 /* DWARF 2 debugging format support for GDB.
-   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
    Free Software Foundation, Inc.
 
    Adapted by Gary Funck (gary@intrepid.com), Intrepid Technology,
@@ -43,6 +43,7 @@
 #include "bcache.h"
 #include <fcntl.h>
 #include "gdb_string.h"
+#include "gdb_assert.h"
 #include <sys/types.h>
 
 #ifndef DWARF2_REG_TO_REGNUM
@@ -131,6 +132,8 @@ static file_ptr dwarf_aranges_offset;
 static file_ptr dwarf_loc_offset;
 static file_ptr dwarf_macinfo_offset;
 static file_ptr dwarf_str_offset;
+file_ptr dwarf_frame_offset;
+file_ptr dwarf_eh_frame_offset;
 
 static unsigned int dwarf_info_size;
 static unsigned int dwarf_abbrev_size;
@@ -140,6 +143,8 @@ static unsigned int dwarf_aranges_size;
 static unsigned int dwarf_loc_size;
 static unsigned int dwarf_macinfo_size;
 static unsigned int dwarf_str_size;
+unsigned int dwarf_frame_size;
+unsigned int dwarf_eh_frame_size;
 
 /* names of the debugging sections */
 
@@ -151,6 +156,8 @@ static unsigned int dwarf_str_size;
 #define LOC_SECTION      ".debug_loc"
 #define MACINFO_SECTION  ".debug_macinfo"
 #define STR_SECTION      ".debug_str"
+#define FRAME_SECTION    ".debug_frame"
+#define EH_FRAME_SECTION ".eh_frame"
 
 /* local data types */
 
@@ -168,19 +175,49 @@ struct comp_unit_head
                                          4 or 12 */
   };
 
-/* The data in the .debug_line statement prologue looks like this.  */
-struct line_head
+/* The line number information for a compilation unit (found in the
+   .debug_line section) begins with a "statement program header",
+   which contains the following information.  */
+struct line_header
+{
+  unsigned int total_length;
+  unsigned short version;
+  unsigned int header_length;
+  unsigned char minimum_instruction_length;
+  unsigned char default_is_stmt;
+  int line_base;
+  unsigned char line_range;
+  unsigned char opcode_base;
+
+  /* standard_opcode_lengths[i] is the number of operands for the
+     standard opcode whose value is i.  This means that
+     standard_opcode_lengths[0] is unused, and the last meaningful
+     element is standard_opcode_lengths[opcode_base - 1].  */
+  unsigned char *standard_opcode_lengths;
+
+  /* The include_directories table.  NOTE!  These strings are not
+     allocated with xmalloc; instead, they are pointers into
+     debug_line_buffer.  If you try to free them, `free' will get
+     indigestion.  */
+  unsigned int num_include_dirs, include_dirs_size;
+  char **include_dirs;
+
+  /* The file_names table.  NOTE!  These strings are not allocated
+     with xmalloc; instead, they are pointers into debug_line_buffer.
+     Don't try to free them directly.  */
+  unsigned int num_file_names, file_names_size;
+  struct file_entry
   {
-    unsigned int total_length;
-    unsigned short version;
-    unsigned int prologue_length;
-    unsigned char minimum_instruction_length;
-    unsigned char default_is_stmt;
-    int line_base;
-    unsigned char line_range;
-    unsigned char opcode_base;
-    unsigned char *standard_opcode_lengths;
-  };
+    char *name;
+    unsigned int dir_index;
+    unsigned int mod_time;
+    unsigned int length;
+  } *file_names;
+
+  /* The start and end of the statement program following this
+     header.  These point into dwarf_line_buffer.  */
+  char *statement_program_start, *statement_program_end;
+};
 
 /* When we construct a partial symbol table entry we only
    need this much information. */
@@ -249,6 +286,16 @@ struct attribute
     u;
   };
 
+struct function_range
+{
+  const char *name;
+  CORE_ADDR lowpc, highpc;
+  int seen_line;
+  struct function_range *next;
+};
+
+static struct function_range *cu_first_fn, *cu_last_fn, *cu_cached_fn;
+
 /* Get at parts of an attribute structure */
 
 #define DW_STRING(attr)    ((attr)->u.str)
@@ -302,6 +349,7 @@ static const struct language_defn *cu_language_defn;
 static char *dwarf_info_buffer;
 static char *dwarf_abbrev_buffer;
 static char *dwarf_line_buffer;
+static char *dwarf_str_buffer;
 
 /* A zeroed version of a partial die for initialization purposes.  */
 static struct partial_die_info zeroed_partial_die;
@@ -383,6 +431,18 @@ struct dwarf2_pinfo
     /* Pointer to start of dwarf line buffer for the objfile.  */
 
     char *dwarf_line_buffer;
+
+    /* Size of dwarf_line_buffer, in bytes.  */
+    
+    unsigned int dwarf_line_size;
+
+    /* Pointer to start of dwarf string buffer for the objfile.  */
+
+    char *dwarf_str_buffer;
+
+    /* Size of dwarf string section for the objfile.  */
+
+    unsigned int dwarf_str_size;
   };
 
 #define PST_PRIVATE(p) ((struct dwarf2_pinfo *)(p)->read_symtab_private)
@@ -391,6 +451,9 @@ struct dwarf2_pinfo
 #define DWARF_ABBREV_BUFFER(p) (PST_PRIVATE(p)->dwarf_abbrev_buffer)
 #define DWARF_ABBREV_SIZE(p) (PST_PRIVATE(p)->dwarf_abbrev_size)
 #define DWARF_LINE_BUFFER(p) (PST_PRIVATE(p)->dwarf_line_buffer)
+#define DWARF_LINE_SIZE(p)   (PST_PRIVATE(p)->dwarf_line_size)
+#define DWARF_STR_BUFFER(p)  (PST_PRIVATE(p)->dwarf_str_buffer)
+#define DWARF_STR_SIZE(p)    (PST_PRIVATE(p)->dwarf_str_size)
 
 /* Maintain an array of referenced fundamental types for the current
    compilation unit being read.  For DWARF version 1, we have to construct
@@ -456,17 +519,6 @@ struct field_info
     int nfnfields;
   };
 
-/* FIXME: Kludge to mark a varargs function type for C++ member function
-   argument processing.  */
-#define TYPE_FLAG_VARARGS      (1 << 10)
-
-/* Dwarf2 has no clean way to discern C++ static and non-static member
-   functions. G++ helps GDB by marking the first parameter for non-static
-   member functions (which is the this pointer) as artificial.
-   We pass this information between dwarf2_add_member_fn and
-   read_subroutine_type via TYPE_FIELD_ARTIFICIAL.  */
-#define TYPE_FIELD_ARTIFICIAL  TYPE_FIELD_BITPOS
-
 /* Various complaints about symbol reading that don't abort the process */
 
 static struct complaint dwarf2_const_ignored =
@@ -485,6 +537,10 @@ static struct complaint dwarf2_missing_line_number_section =
 {
   "missing .debug_line section", 0, 0
 };
+static struct complaint dwarf2_statement_list_fits_in_line_number_section =
+{
+  "statement list doesn't fit in .debug_line section", 0, 0
+};
 static struct complaint dwarf2_mangled_line_number_section =
 {
   "mangled .debug_line section", 0, 0
@@ -553,6 +609,14 @@ static struct complaint dwarf2_unsupported_const_value_attr =
 {
   "unsupported const value attribute form: '%s'", 0, 0
 };
+static struct complaint dwarf2_misplaced_line_number =
+{
+  "misplaced first line number at 0x%lx for '%s'", 0, 0
+};
+static struct complaint dwarf2_line_header_too_long =
+{
+  "line number info header doesn't fit in `.debug_line' section", 0, 0
+};
 
 /* local function prototypes */
 
@@ -575,7 +639,7 @@ static void dwarf2_psymtab_to_symtab (struct partial_symtab *);
 
 static void psymtab_to_symtab_1 (struct partial_symtab *);
 
-static char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int);
+char *dwarf2_read_section (struct objfile *, file_ptr, unsigned int);
 
 static void dwarf2_read_abbrevs (bfd *, unsigned int);
 
@@ -593,6 +657,9 @@ static char *read_full_die (struct die_info **, bfd *, char *,
 static char *read_attribute (struct attribute *, struct attr_abbrev *,
                             bfd *, char *, const struct comp_unit_head *);
 
+static char *read_attribute_value (struct attribute *, unsigned,
+                            bfd *, char *, const struct comp_unit_head *);
+
 static unsigned int read_1_byte (bfd *, char *);
 
 static int read_1_signed_byte (bfd *, char *);
@@ -616,6 +683,9 @@ static char *read_n_bytes (bfd *, char *, unsigned int);
 
 static char *read_string (bfd *, char *, unsigned int *);
 
+static char *read_indirect_string (bfd *, char *, const struct comp_unit_head *,
+                                  unsigned int *);
+
 static unsigned long read_unsigned_leb128 (bfd *, char *, unsigned int *);
 
 static long read_signed_leb128 (bfd *, char *, unsigned int *);
@@ -626,7 +696,14 @@ static struct attribute *dwarf_attr (struct die_info *, unsigned int);
 
 static int die_is_declaration (struct die_info *);
 
-static void dwarf_decode_lines (unsigned int, char *, bfd *,
+static void free_line_header (struct line_header *lh);
+
+static struct line_header *(dwarf_decode_line_header
+                            (unsigned int offset,
+                             bfd *abfd,
+                             const struct comp_unit_head *cu_header));
+
+static void dwarf_decode_lines (struct line_header *, char *, bfd *,
                                const struct comp_unit_head *);
 
 static void dwarf2_start_subfile (char *, char *);
@@ -781,6 +858,10 @@ static struct abbrev_info *dwarf_alloc_abbrev (void);
 
 static struct die_info *dwarf_alloc_die (void);
 
+static void initialize_cu_func_list (void);
+
+static void add_to_cu_func_list (const char *, CORE_ADDR, CORE_ADDR);
+
 /* Try to locate the sections we need for DWARF 2 debugging
    information and return true if we have enough to do something.  */
 
@@ -788,6 +869,8 @@ int
 dwarf2_has_info (bfd *abfd)
 {
   dwarf_info_offset = dwarf_abbrev_offset = dwarf_line_offset = 0;
+  dwarf_str_offset = 0;
+  dwarf_frame_offset = dwarf_eh_frame_offset = 0;
   bfd_map_over_sections (abfd, dwarf2_locate_sections, NULL);
   if (dwarf_info_offset && dwarf_abbrev_offset)
     {
@@ -846,6 +929,16 @@ dwarf2_locate_sections (bfd *ignore_abfd, asection *sectp, PTR ignore_ptr)
       dwarf_str_offset = sectp->filepos;
       dwarf_str_size = bfd_get_section_size_before_reloc (sectp);
     }
+  else if (STREQ (sectp->name, FRAME_SECTION))
+    {
+      dwarf_frame_offset = sectp->filepos;
+      dwarf_frame_size = bfd_get_section_size_before_reloc (sectp);
+    }
+  else if (STREQ (sectp->name, EH_FRAME_SECTION))
+    {
+      dwarf_eh_frame_offset = sectp->filepos;
+      dwarf_eh_frame_size = bfd_get_section_size_before_reloc (sectp);
+    }
 }
 
 /* Build a partial symbol table.  */
@@ -866,6 +959,13 @@ dwarf2_build_psymtabs (struct objfile *objfile, int mainline)
                                           dwarf_line_offset,
                                           dwarf_line_size);
 
+  if (dwarf_str_offset)
+    dwarf_str_buffer = dwarf2_read_section (objfile,
+                                           dwarf_str_offset,
+                                           dwarf_str_size);
+  else
+    dwarf_str_buffer = NULL;
+
   if (mainline
       || (objfile->global_psymbols.size == 0
          && objfile->static_psymbols.size == 0))
@@ -1071,6 +1171,9 @@ dwarf2_build_psymtabs_hard (struct objfile *objfile, int mainline)
       DWARF_ABBREV_BUFFER (pst) = dwarf_abbrev_buffer;
       DWARF_ABBREV_SIZE (pst) = dwarf_abbrev_size;
       DWARF_LINE_BUFFER (pst) = dwarf_line_buffer;
+      DWARF_LINE_SIZE (pst) = dwarf_line_size;
+      DWARF_STR_BUFFER (pst) = dwarf_str_buffer;
+      DWARF_STR_SIZE (pst) = dwarf_str_size;
       baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
       /* Store the function that reads in the rest of the symbol table */
@@ -1370,6 +1473,9 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   dwarf_abbrev_buffer = DWARF_ABBREV_BUFFER (pst);
   dwarf_abbrev_size = DWARF_ABBREV_SIZE (pst);
   dwarf_line_buffer = DWARF_LINE_BUFFER (pst);
+  dwarf_line_size = DWARF_LINE_SIZE (pst);
+  dwarf_str_buffer = DWARF_STR_BUFFER (pst);
+  dwarf_str_size = DWARF_STR_SIZE (pst);
   baseaddr = ANOFFSET (pst->section_offsets, SECT_OFF_TEXT (objfile));
   cu_header_offset = offset;
   info_ptr = dwarf_info_buffer + offset;
@@ -1505,11 +1611,17 @@ process_die (struct die_info *die, struct objfile *objfile,
     }
 }
 
+static void
+initialize_cu_func_list (void)
+{
+  cu_first_fn = cu_last_fn = cu_cached_fn = NULL;
+}
+
 static void
 read_file_scope (struct die_info *die, struct objfile *objfile,
                 const struct comp_unit_head *cu_header)
 {
-  unsigned int line_offset = 0;
+  struct cleanup *back_to = make_cleanup (null_cleanup, 0);
   CORE_ADDR lowpc = ((CORE_ADDR) -1);
   CORE_ADDR highpc = ((CORE_ADDR) 0);
   struct attribute *attr;
@@ -1517,6 +1629,7 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
   char *comp_dir = NULL;
   struct die_info *child_die;
   bfd *abfd = objfile->obfd;
+  struct line_header *line_header = 0;
 
   if (!dwarf2_get_pc_bounds (die, &lowpc, &highpc, objfile))
     {
@@ -1597,13 +1710,7 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
   start_symtab (name, comp_dir, lowpc);
   record_debugformat ("DWARF 2");
 
-  /* Decode line number information if present.  */
-  attr = dwarf_attr (die, DW_AT_stmt_list);
-  if (attr)
-    {
-      line_offset = DW_UNSND (attr);
-      dwarf_decode_lines (line_offset, comp_dir, abfd, cu_header);
-    }
+  initialize_cu_func_list ();
 
   /* Process all dies in compilation unit.  */
   if (die->has_children)
@@ -1615,6 +1722,44 @@ read_file_scope (struct die_info *die, struct objfile *objfile,
          child_die = sibling_die (child_die);
        }
     }
+
+  /* Decode line number information if present.  */
+  attr = dwarf_attr (die, DW_AT_stmt_list);
+  if (attr)
+    {
+      unsigned int line_offset = DW_UNSND (attr);
+      line_header = dwarf_decode_line_header (line_offset,
+                                              abfd, cu_header);
+      if (line_header)
+        {
+          make_cleanup ((make_cleanup_ftype *) free_line_header,
+                        (void *) line_header);
+          dwarf_decode_lines (line_header, comp_dir, abfd, cu_header);
+        }
+    }
+
+  do_cleanups (back_to);
+}
+
+static void
+add_to_cu_func_list (const char *name, CORE_ADDR lowpc, CORE_ADDR highpc)
+{
+  struct function_range *thisfn;
+
+  thisfn = (struct function_range *)
+    obstack_alloc (&dwarf2_tmp_obstack, sizeof (struct function_range));
+  thisfn->name = name;
+  thisfn->lowpc = lowpc;
+  thisfn->highpc = highpc;
+  thisfn->seen_line = 0;
+  thisfn->next = NULL;
+
+  if (cu_last_fn == NULL)
+      cu_first_fn = thisfn;
+  else
+      cu_last_fn->next = thisfn;
+
+  cu_last_fn = thisfn;
 }
 
 static void
@@ -1638,6 +1783,9 @@ read_func_scope (struct die_info *die, struct objfile *objfile,
   lowpc += baseaddr;
   highpc += baseaddr;
 
+  /* Record the function range for dwarf_decode_lines.  */
+  add_to_cu_func_list (name, lowpc, highpc);
+
   if (objfile->ei.entry_point >= lowpc &&
       objfile->ei.entry_point < highpc)
     {
@@ -2091,7 +2239,7 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
        arg_types[iparams] = TYPE_FIELD_TYPE (die->type, iparams);
 
       /* Set last entry in argument type vector.  */
-      if (TYPE_FLAGS (die->type) & TYPE_FLAG_VARARGS)
+      if (TYPE_VARARGS (die->type))
        arg_types[nparams] = NULL;
       else
        arg_types[nparams] = dwarf2_fundamental_type (objfile, FT_VOID);
@@ -2132,6 +2280,11 @@ dwarf2_add_member_fn (struct field_info *fip, struct die_info *die,
        }
     }
 
+  /* Check for artificial methods.  */
+  attr = dwarf_attr (die, DW_AT_artificial);
+  if (attr && DW_UNSND (attr) != 0)
+    fnp->is_artificial = 1;
+
   /* Get index in virtual function table if it is a virtual member function.  */
   attr = dwarf_attr (die, DW_AT_vtable_elem_location);
   if (attr)
@@ -2334,7 +2487,7 @@ read_structure_scope (struct die_info *die, struct objfile *objfile,
       TYPE_FLAGS (type) |= TYPE_FLAG_STUB;
     }
 
-  die->type = type;
+  finish_cv_type (die->type);
 }
 
 /* Given a pointer to a die which begins an enumeration, process all
@@ -2497,7 +2650,8 @@ read_array_type (struct die_info *die, struct objfile *objfile,
              else if (attr->form == DW_FORM_udata
                       || attr->form == DW_FORM_data1
                       || attr->form == DW_FORM_data2
-                      || attr->form == DW_FORM_data4)
+                      || attr->form == DW_FORM_data4
+                      || attr->form == DW_FORM_data8)
                {
                  low = DW_UNSND (attr);
                }
@@ -2523,7 +2677,8 @@ read_array_type (struct die_info *die, struct objfile *objfile,
              else if (attr->form == DW_FORM_udata
                       || attr->form == DW_FORM_data1
                       || attr->form == DW_FORM_data2
-                      || attr->form == DW_FORM_data4)
+                      || attr->form == DW_FORM_data4
+                      || attr->form == DW_FORM_data8)
                {
                  high = DW_UNSND (attr);
                }
@@ -2569,6 +2724,16 @@ read_array_type (struct die_info *die, struct objfile *objfile,
   while (ndim-- > 0)
     type = create_array_type (NULL, type, range_types[ndim]);
 
+  /* Understand Dwarf2 support for vector types (like they occur on
+     the PowerPC w/ AltiVec).  Gcc just adds another attribute to the
+     array type.  This is not part of the Dwarf2/3 standard yet, but a
+     custom vendor extension.  The main difference between a regular
+     array and the vector variant is that vectors are passed by value
+     to functions.  */
+  attr = dwarf_attr (die, DW_AT_GNU_vector);
+  if (attr)
+    TYPE_FLAGS (type) |= TYPE_FLAG_VECTOR;
+
   do_cleanups (back_to);
 
   /* Install the type in the die. */
@@ -2743,12 +2908,30 @@ read_tag_string_type (struct die_info *die, struct objfile *objfile)
     }
   else
     {
-      length = 1;
+      /* check for the DW_AT_byte_size attribute */
+      attr = dwarf_attr (die, DW_AT_byte_size);
+      if (attr)
+        {
+          length = DW_UNSND (attr);
+        }
+      else
+        {
+          length = 1;
+        }
     }
   index_type = dwarf2_fundamental_type (objfile, FT_INTEGER);
   range_type = create_range_type (NULL, index_type, 1, length);
-  char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
-  type = create_string_type (char_type, range_type);
+  if (cu_language == language_fortran)
+    {
+      /* Need to create a unique string type for bounds
+         information */
+      type = create_string_type (0, range_type);
+    }
+  else
+    {
+      char_type = dwarf2_fundamental_type (objfile, FT_CHAR);
+      type = create_string_type (char_type, range_type);
+    }
   die->type = type;
 }
 
@@ -2839,26 +3022,18 @@ static void
 read_typedef (struct die_info *die, struct objfile *objfile,
              const struct comp_unit_head *cu_header)
 {
-  struct type *type;
+  struct attribute *attr;
+  char *name = NULL;
 
   if (!die->type)
     {
-      struct attribute *attr;
-      struct type *xtype;
-
-      xtype = die_type (die, objfile, cu_header);
-
-      type = alloc_type (objfile);
-      TYPE_CODE (type) = TYPE_CODE_TYPEDEF;
-      TYPE_FLAGS (type) |= TYPE_FLAG_TARGET_STUB;
-      TYPE_TARGET_TYPE (type) = xtype;
       attr = dwarf_attr (die, DW_AT_name);
       if (attr && DW_STRING (attr))
-       TYPE_NAME (type) = obsavestring (DW_STRING (attr),
-                                        strlen (DW_STRING (attr)),
-                                        &objfile->type_obstack);
-
-      die->type = type;
+       {
+         name = DW_STRING (attr);
+       }
+      die->type = init_type (TYPE_CODE_TYPEDEF, 0, TYPE_FLAG_TARGET_STUB, name, objfile);
+      TYPE_TARGET_TYPE (die->type) = die_type (die, objfile, cu_header);
     }
 }
 
@@ -2892,18 +3067,18 @@ read_base_type (struct die_info *die, struct objfile *objfile)
   if (attr && DW_STRING (attr))
     {
       enum type_code code = TYPE_CODE_INT;
-      int is_unsigned = 0;
+      int type_flags = 0;
 
       switch (encoding)
        {
        case DW_ATE_address:
          /* Turn DW_ATE_address into a void * pointer.  */
          code = TYPE_CODE_PTR;
-         is_unsigned = 1;
+         type_flags |= TYPE_FLAG_UNSIGNED;
          break;
        case DW_ATE_boolean:
          code = TYPE_CODE_BOOL;
-         is_unsigned = 1;
+         type_flags |= TYPE_FLAG_UNSIGNED;
          break;
        case DW_ATE_complex_float:
          code = TYPE_CODE_COMPLEX;
@@ -2916,16 +3091,28 @@ read_base_type (struct die_info *die, struct objfile *objfile)
          break;
        case DW_ATE_unsigned:
        case DW_ATE_unsigned_char:
-         is_unsigned = 1;
+         type_flags |= TYPE_FLAG_UNSIGNED;
          break;
        default:
          complain (&dwarf2_unsupported_at_encoding,
                    dwarf_type_encoding_name (encoding));
          break;
        }
-      type = init_type (code, size, is_unsigned, DW_STRING (attr), objfile);
+      type = init_type (code, size, type_flags, DW_STRING (attr), objfile);
       if (encoding == DW_ATE_address)
        TYPE_TARGET_TYPE (type) = dwarf2_fundamental_type (objfile, FT_VOID);
+      else if (encoding == DW_ATE_complex_float)
+       {
+         if (size == 32)
+           TYPE_TARGET_TYPE (type)
+             = dwarf2_fundamental_type (objfile, FT_EXT_PREC_FLOAT);
+         else if (size == 16)
+           TYPE_TARGET_TYPE (type)
+             = dwarf2_fundamental_type (objfile, FT_DBL_PREC_FLOAT);
+         else if (size == 8)
+           TYPE_TARGET_TYPE (type)
+             = dwarf2_fundamental_type (objfile, FT_FLOAT);
+       }
     }
   else
     {
@@ -3015,7 +3202,7 @@ make_cleanup_free_die_list (struct die_info *dies)
 /* Read the contents of the section at OFFSET and of size SIZE from the
    object file specified by OBJFILE into the psymbol_obstack and return it.  */
 
-static char *
+char *
 dwarf2_read_section (struct objfile *objfile, file_ptr offset,
                     unsigned int size)
 {
@@ -3333,19 +3520,18 @@ read_full_die (struct die_info **diep, bfd *abfd, char *info_ptr,
   return info_ptr;
 }
 
-/* Read an attribute described by an abbreviated attribute.  */
+/* Read an attribute value described by an attribute form.  */
 
 static char *
-read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
+read_attribute_value (struct attribute *attr, unsigned form,
                bfd *abfd, char *info_ptr,
                const struct comp_unit_head *cu_header)
 {
   unsigned int bytes_read;
   struct dwarf_block *blk;
 
-  attr->name = abbrev->name;
-  attr->form = abbrev->form;
-  switch (abbrev->form)
+  attr->form = form;
+  switch (form)
     {
     case DW_FORM_addr:
     case DW_FORM_ref_addr:
@@ -3384,6 +3570,11 @@ read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
       DW_STRING (attr) = read_string (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
       break;
+    case DW_FORM_strp:
+      DW_STRING (attr) = read_indirect_string (abfd, info_ptr, cu_header,
+                                              &bytes_read);
+      info_ptr += bytes_read;
+      break;
     case DW_FORM_block:
       blk = dwarf_alloc_block ();
       blk->size = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
@@ -3436,15 +3627,29 @@ read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
       DW_UNSND (attr) = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
       info_ptr += bytes_read;
       break;
-    case DW_FORM_strp:
     case DW_FORM_indirect:
+      form = read_unsigned_leb128 (abfd, info_ptr, &bytes_read);
+      info_ptr += bytes_read;
+      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 (abbrev->form));
+            dwarf_form_name (form));
     }
   return info_ptr;
 }
 
+/* Read an attribute described by an abbreviated attribute.  */
+
+static char *
+read_attribute (struct attribute *attr, struct attr_abbrev *abbrev,
+               bfd *abfd, char *info_ptr,
+               const struct comp_unit_head *cu_header)
+{
+  attr->name = abbrev->name;
+  return read_attribute_value (attr, abbrev->form, abfd, info_ptr, cu_header);
+}
+
 /* read dwarf information from a buffer */
 
 static unsigned int
@@ -3626,20 +3831,8 @@ read_n_bytes (bfd *abfd, char *buf, unsigned int size)
   /* If the size of a host char is 8 bits, we can return a pointer
      to the buffer, otherwise we have to copy the data to a buffer
      allocated on the temporary obstack.  */
-#if HOST_CHAR_BIT == 8
+  gdb_assert (HOST_CHAR_BIT == 8);
   return buf;
-#else
-  char *ret;
-  unsigned int i;
-
-  ret = obstack_alloc (&dwarf2_tmp_obstack, size);
-  for (i = 0; i < size; ++i)
-    {
-      ret[i] = bfd_get_8 (abfd, (bfd_byte *) buf);
-      buf++;
-    }
-  return ret;
-#endif
 }
 
 static char *
@@ -3648,7 +3841,7 @@ read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
   /* If the size of a host char is 8 bits, we can return a pointer
      to the string, otherwise we have to copy the string to a buffer
      allocated on the temporary obstack.  */
-#if HOST_CHAR_BIT == 8
+  gdb_assert (HOST_CHAR_BIT == 8);
   if (*buf == '\0')
     {
       *bytes_read_ptr = 1;
@@ -3656,25 +3849,30 @@ read_string (bfd *abfd, char *buf, unsigned int *bytes_read_ptr)
     }
   *bytes_read_ptr = strlen (buf) + 1;
   return buf;
-#else
-  int byte;
-  unsigned int i = 0;
+}
+
+static char *
+read_indirect_string (bfd *abfd, char *buf,
+                     const struct comp_unit_head *cu_header,
+                     unsigned int *bytes_read_ptr)
+{
+  LONGEST str_offset = read_offset (abfd, buf, cu_header,
+                                   (int *) bytes_read_ptr);
 
-  while ((byte = bfd_get_8 (abfd, (bfd_byte *) buf)) != 0)
+  if (dwarf_str_buffer == NULL)
     {
-      obstack_1grow (&dwarf2_tmp_obstack, byte);
-      i++;
-      buf++;
+      error ("DW_FORM_strp used without .debug_str section");
+      return NULL;
     }
-  if (i == 0)
+  if (str_offset >= dwarf_str_size)
     {
-      *bytes_read_ptr = 1;
+      error ("DW_FORM_strp pointing outside of .debug_str section");
       return NULL;
     }
-  obstack_1grow (&dwarf2_tmp_obstack, '\0');
-  *bytes_read_ptr = i + 1;
-  return obstack_finish (&dwarf2_tmp_obstack);
-#endif
+  gdb_assert (HOST_CHAR_BIT == 8);
+  if (dwarf_str_buffer[str_offset] == '\0')
+    return NULL;
+  return dwarf_str_buffer + str_offset;
 }
 
 static unsigned long
@@ -3751,6 +3949,7 @@ set_cu_language (unsigned int lang)
       break;
     case DW_LANG_Fortran77:
     case DW_LANG_Fortran90:
+    case DW_LANG_Fortran95:
       cu_language = language_fortran;
       break;
     case DW_LANG_Mips_Assembler:
@@ -3808,87 +4007,153 @@ die_is_declaration (struct die_info *die)
          && ! dwarf_attr (die, DW_AT_specification));
 }
 
-/* Decode the line number information for the compilation unit whose
-   line number info is at OFFSET in the .debug_line section.
-   The compilation directory of the file is passed in COMP_DIR.  */
 
-struct filenames
+/* Free the line_header structure *LH, and any arrays and strings it
+   refers to.  */
+static void
+free_line_header (struct line_header *lh)
+{
+  if (lh->standard_opcode_lengths)
+    free (lh->standard_opcode_lengths);
+
+  /* Remember that all the lh->file_names[i].name pointers are
+     pointers into debug_line_buffer, and don't need to be freed.  */
+  if (lh->file_names)
+    free (lh->file_names);
+
+  /* Similarly for the include directory names.  */
+  if (lh->include_dirs)
+    free (lh->include_dirs);
+
+  free (lh);
+}
+
+
+/* Add an entry to LH's include directory table.  */
+static void
+add_include_dir (struct line_header *lh, char *include_dir)
 {
-  unsigned int num_files;
-  struct fileinfo
+  /* Grow the array if necessary.  */
+  if (lh->include_dirs_size == 0)
     {
-      char *name;
-      unsigned int dir;
-      unsigned int time;
-      unsigned int size;
+      lh->include_dirs_size = 1; /* for testing */
+      lh->include_dirs = xmalloc (lh->include_dirs_size
+                                  * sizeof (*lh->include_dirs));
+    }
+  else if (lh->num_include_dirs >= lh->include_dirs_size)
+    {
+      lh->include_dirs_size *= 2;
+      lh->include_dirs = xrealloc (lh->include_dirs,
+                                   (lh->include_dirs_size
+                                    * sizeof (*lh->include_dirs)));
     }
-   *files;
-};
 
-struct directories
-  {
-    unsigned int num_dirs;
-    char **dirs;
-  };
+  lh->include_dirs[lh->num_include_dirs++] = include_dir;
+}
 
+/* Add an entry to LH's file name table.  */
 static void
-dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
-                   const struct comp_unit_head *cu_header)
+add_file_name (struct line_header *lh,
+               char *name,
+               unsigned int dir_index,
+               unsigned int mod_time,
+               unsigned int length)
 {
-  char *line_ptr;
-  char *line_end;
-  struct line_head lh;
-  struct cleanup *back_to;
-  unsigned int i, bytes_read;
-  char *cur_file, *cur_dir;
-  unsigned char op_code, extended_op, adj_opcode;
+  struct file_entry *fe;
 
-#define FILE_ALLOC_CHUNK 5
-#define DIR_ALLOC_CHUNK 5
+  /* Grow the array if necessary.  */
+  if (lh->file_names_size == 0)
+    {
+      lh->file_names_size = 1; /* for testing */
+      lh->file_names = xmalloc (lh->file_names_size
+                                * sizeof (*lh->file_names));
+    }
+  else if (lh->num_file_names >= lh->file_names_size)
+    {
+      lh->file_names_size *= 2;
+      lh->file_names = xrealloc (lh->file_names,
+                                 (lh->file_names_size
+                                  * sizeof (*lh->file_names)));
+    }
 
-  struct filenames files;
-  struct directories dirs;
+  fe = &lh->file_names[lh->num_file_names++];
+  fe->name = name;
+  fe->dir_index = dir_index;
+  fe->mod_time = mod_time;
+  fe->length = length;
+}
+
+/* Read the statement program header starting at OFFSET in
+   dwarf_line_buffer, according to the endianness of ABFD.  Return a
+   pointer to a struct line_header, allocated using xmalloc.
+
+   NOTE: the strings in the include directory and file name tables of
+   the returned object point into debug_line_buffer, and must not be
+   freed.  */
+static struct line_header *
+dwarf_decode_line_header (unsigned int offset, bfd *abfd,
+                          const struct comp_unit_head *cu_header)
+{
+  struct cleanup *back_to;
+  struct line_header *lh;
+  char *line_ptr;
+  int bytes_read;
+  int i;
+  char *cur_dir, *cur_file;
 
   if (dwarf_line_buffer == NULL)
     {
       complain (&dwarf2_missing_line_number_section);
-      return;
+      return 0;
     }
 
-  files.num_files = 0;
-  files.files = NULL;
+  /* Make sure that at least there's room for the total_length field.  That
+     could be 12 bytes long, but we're just going to fudge that.  */
+  if (offset + 4 >= dwarf_line_size)
+    {
+      complain (&dwarf2_statement_list_fits_in_line_number_section);
+      return 0;
+    }
 
-  dirs.num_dirs = 0;
-  dirs.dirs = NULL;
+  lh = xmalloc (sizeof (*lh));
+  memset (lh, 0, sizeof (*lh));
+  back_to = make_cleanup ((make_cleanup_ftype *) free_line_header,
+                          (void *) lh);
 
   line_ptr = dwarf_line_buffer + offset;
 
-  /* read in the prologue */
-  lh.total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
+  /* read in the header */
+  lh->total_length = read_initial_length (abfd, line_ptr, NULL, &bytes_read);
   line_ptr += bytes_read;
-  line_end = line_ptr + lh.total_length;
-  lh.version = read_2_bytes (abfd, line_ptr);
+  if (line_ptr + lh->total_length > dwarf_line_buffer + dwarf_line_size)
+    {
+      complain (&dwarf2_statement_list_fits_in_line_number_section);
+      return 0;
+    }
+  lh->statement_program_end = line_ptr + lh->total_length;
+  lh->version = read_2_bytes (abfd, line_ptr);
   line_ptr += 2;
-  lh.prologue_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
+  lh->header_length = read_offset (abfd, line_ptr, cu_header, &bytes_read);
   line_ptr += bytes_read;
-  lh.minimum_instruction_length = read_1_byte (abfd, line_ptr);
+  lh->minimum_instruction_length = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
-  lh.default_is_stmt = read_1_byte (abfd, line_ptr);
+  lh->default_is_stmt = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
-  lh.line_base = read_1_signed_byte (abfd, line_ptr);
+  lh->line_base = read_1_signed_byte (abfd, line_ptr);
   line_ptr += 1;
-  lh.line_range = read_1_byte (abfd, line_ptr);
+  lh->line_range = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
-  lh.opcode_base = read_1_byte (abfd, line_ptr);
+  lh->opcode_base = read_1_byte (abfd, line_ptr);
   line_ptr += 1;
-  lh.standard_opcode_lengths = (unsigned char *)
-    xmalloc (lh.opcode_base * sizeof (unsigned char));
-  back_to = make_cleanup (free_current_contents, &lh.standard_opcode_lengths);
+  lh->standard_opcode_lengths
+    = (unsigned char *) xmalloc (lh->opcode_base * sizeof (unsigned char));
 
-  lh.standard_opcode_lengths[0] = 1;
-  for (i = 1; i < lh.opcode_base; ++i)
+  lh->standard_opcode_lengths[0] = 1;  /* This should never be used anyway.  */
+  for (i = 1; i < lh->opcode_base; ++i)
     {
-      lh.standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
+      lh->standard_opcode_lengths[i] = read_1_byte (abfd, line_ptr);
       line_ptr += 1;
     }
 
@@ -3896,44 +4161,96 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
   while ((cur_dir = read_string (abfd, line_ptr, &bytes_read)) != NULL)
     {
       line_ptr += bytes_read;
-      if ((dirs.num_dirs % DIR_ALLOC_CHUNK) == 0)
-       {
-         dirs.dirs = (char **)
-           xrealloc (dirs.dirs,
-                     (dirs.num_dirs + DIR_ALLOC_CHUNK) * sizeof (char *));
-         if (dirs.num_dirs == 0)
-           make_cleanup (free_current_contents, &dirs.dirs);
-       }
-      dirs.dirs[dirs.num_dirs++] = cur_dir;
+      add_include_dir (lh, cur_dir);
     }
   line_ptr += bytes_read;
 
   /* Read file name table */
   while ((cur_file = read_string (abfd, line_ptr, &bytes_read)) != NULL)
     {
+      unsigned int dir_index, mod_time, length;
+
       line_ptr += bytes_read;
-      if ((files.num_files % FILE_ALLOC_CHUNK) == 0)
-       {
-         files.files = (struct fileinfo *)
-           xrealloc (files.files,
-                     (files.num_files + FILE_ALLOC_CHUNK)
-                     * sizeof (struct fileinfo));
-         if (files.num_files == 0)
-           make_cleanup (free_current_contents, &files.files);
-       }
-      files.files[files.num_files].name = cur_file;
-      files.files[files.num_files].dir =
-       read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+      dir_index = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
       line_ptr += bytes_read;
-      files.files[files.num_files].time =
-       read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+      mod_time = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
       line_ptr += bytes_read;
-      files.files[files.num_files].size =
-       read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+      length = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
       line_ptr += bytes_read;
-      files.num_files++;
+
+      add_file_name (lh, cur_file, dir_index, mod_time, length);
     }
   line_ptr += bytes_read;
+  lh->statement_program_start = line_ptr; 
+
+  if (line_ptr > dwarf_line_buffer + dwarf_line_size)
+    complain (&dwarf2_line_header_too_long);
+
+  discard_cleanups (back_to);
+  return lh;
+}
+
+/* This function exists to work around a bug in certain compilers
+   (particularly GCC 2.95), in which the first line number marker of a
+   function does not show up until after the prologue, right before
+   the second line number marker.  This function shifts ADDRESS down
+   to the beginning of the function if necessary, and is called on
+   addresses passed to record_line.  */
+
+static CORE_ADDR
+check_cu_functions (CORE_ADDR address)
+{
+  struct function_range *fn;
+
+  /* Find the function_range containing address.  */
+  if (!cu_first_fn)
+    return address;
+
+  if (!cu_cached_fn)
+    cu_cached_fn = cu_first_fn;
+
+  fn = cu_cached_fn;
+  while (fn)
+    if (fn->lowpc <= address && fn->highpc > address)
+      goto found;
+    else
+      fn = fn->next;
+
+  fn = cu_first_fn;
+  while (fn && fn != cu_cached_fn)
+    if (fn->lowpc <= address && fn->highpc > address)
+      goto found;
+    else
+      fn = fn->next;
+
+  return address;
+
+ found:
+  if (fn->seen_line)
+    return address;
+  if (address != fn->lowpc)
+    complain (&dwarf2_misplaced_line_number,
+             (unsigned long) address, fn->name);
+  fn->seen_line = 1;
+  return fn->lowpc;
+}
+
+/* Decode the line number information for the compilation unit whose
+   line number info is at OFFSET in the .debug_line section.
+   The compilation directory of the file is passed in COMP_DIR.  */
+
+static void
+dwarf_decode_lines (struct line_header *lh, char *comp_dir, bfd *abfd,
+                   const struct comp_unit_head *cu_header)
+{
+  char *line_ptr;
+  char *line_end;
+  unsigned int i, bytes_read;
+  char *cur_dir;
+  unsigned char op_code, extended_op, adj_opcode;
+
+  line_ptr = lh->statement_program_start;
+  line_end = lh->statement_program_end;
 
   /* Read the statement sequences until there's nothing left.  */
   while (line_ptr < line_end)
@@ -3943,19 +4260,23 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
       unsigned int file = 1;
       unsigned int line = 1;
       unsigned int column = 0;
-      int is_stmt = lh.default_is_stmt;
+      int is_stmt = lh->default_is_stmt;
       int basic_block = 0;
       int end_sequence = 0;
 
       /* Start a subfile for the current file of the state machine.  */
-      if (files.num_files >= file)
+      if (lh->num_file_names >= file)
        {
-         /* The file and directory tables are 0 based, the references
-            are 1 based.  */
-         dwarf2_start_subfile (files.files[file - 1].name,
-                               (files.files[file - 1].dir
-                                ? dirs.dirs[files.files[file - 1].dir - 1]
-                                : comp_dir));
+         /* lh->include_dirs and lh->file_names are 0-based, but the
+            directory and file name numbers in the statement program
+            are 1-based.  */
+          struct file_entry *fe = &lh->file_names[file - 1];
+          char *dir;
+          if (fe->dir_index)
+            dir = lh->include_dirs[fe->dir_index - 1];
+          else
+            dir = comp_dir;
+         dwarf2_start_subfile (fe->name, dir);
        }
 
       /* Decode the table. */
@@ -3964,13 +4285,14 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
          op_code = read_1_byte (abfd, line_ptr);
          line_ptr += 1;
 
-         if (op_code >= lh.opcode_base)
+         if (op_code >= lh->opcode_base)
            {           /* Special operand.  */
-             adj_opcode = op_code - lh.opcode_base;
-             address += (adj_opcode / lh.line_range)
-               * lh.minimum_instruction_length;
-             line += lh.line_base + (adj_opcode % lh.line_range);
+             adj_opcode = op_code - lh->opcode_base;
+             address += (adj_opcode / lh->line_range)
+               * lh->minimum_instruction_length;
+             line += lh->line_base + (adj_opcode % lh->line_range);
              /* append row to matrix using current values */
+             address = check_cu_functions (address);
              record_line (current_subfile, line, address);
              basic_block = 1;
            }
@@ -3984,12 +4306,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
                {
                case DW_LNE_end_sequence:
                  end_sequence = 1;
-                 /* Don't call record_line here.  The end_sequence
-                    instruction provides the address of the first byte
-                    *after* the last line in the sequence; it's not the
-                    address of any real source line.  However, the GDB
-                    linetable structure only records the starts of lines,
-                    not the ends.  This is a weakness of GDB.  */
+                 record_line (current_subfile, 0, address);
                  break;
                case DW_LNE_set_address:
                  address = read_address (abfd, line_ptr, cu_header, &bytes_read);
@@ -3997,40 +4314,36 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
                  address += baseaddr;
                  break;
                case DW_LNE_define_file:
-                 cur_file = read_string (abfd, line_ptr, &bytes_read);
-                 line_ptr += bytes_read;
-                 if ((files.num_files % FILE_ALLOC_CHUNK) == 0)
-                   {
-                     files.files = (struct fileinfo *)
-                       xrealloc (files.files,
-                                 (files.num_files + FILE_ALLOC_CHUNK)
-                                 * sizeof (struct fileinfo));
-                     if (files.num_files == 0)
-                       make_cleanup (free_current_contents, &files.files);
-                   }
-                 files.files[files.num_files].name = cur_file;
-                 files.files[files.num_files].dir =
-                   read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-                 line_ptr += bytes_read;
-                 files.files[files.num_files].time =
-                   read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-                 line_ptr += bytes_read;
-                 files.files[files.num_files].size =
-                   read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-                 line_ptr += bytes_read;
-                 files.num_files++;
+                  {
+                    char *cur_file;
+                    unsigned int dir_index, mod_time, length;
+                    
+                    cur_file = read_string (abfd, line_ptr, &bytes_read);
+                    line_ptr += bytes_read;
+                    dir_index =
+                      read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                    line_ptr += bytes_read;
+                    mod_time =
+                      read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                    line_ptr += bytes_read;
+                    length =
+                      read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                    line_ptr += bytes_read;
+                    add_file_name (lh, cur_file, dir_index, mod_time, length);
+                  }
                  break;
                default:
                  complain (&dwarf2_mangled_line_number_section);
-                 goto done;
+                 return;
                }
              break;
            case DW_LNS_copy:
+             address = check_cu_functions (address);
              record_line (current_subfile, line, address);
              basic_block = 0;
              break;
            case DW_LNS_advance_pc:
-             address += lh.minimum_instruction_length
+             address += lh->minimum_instruction_length
                * read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
              line_ptr += bytes_read;
              break;
@@ -4039,15 +4352,21 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
              line_ptr += bytes_read;
              break;
            case DW_LNS_set_file:
-             /* The file and directory tables are 0 based, the references
-                are 1 based.  */
-             file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
-             line_ptr += bytes_read;
-             dwarf2_start_subfile
-               (files.files[file - 1].name,
-                (files.files[file - 1].dir
-                 ? dirs.dirs[files.files[file - 1].dir - 1]
-                 : comp_dir));
+              {
+                /* lh->include_dirs and lh->file_names are 0-based,
+                   but the directory and file name numbers in the
+                   statement program are 1-based.  */
+                struct file_entry *fe;
+                char *dir;
+                file = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
+                line_ptr += bytes_read;
+                fe = &lh->file_names[file - 1];
+                if (fe->dir_index)
+                  dir = lh->include_dirs[fe->dir_index - 1];
+                else
+                  dir = comp_dir;
+                dwarf2_start_subfile (fe->name, dir);
+              }
              break;
            case DW_LNS_set_column:
              column = read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
@@ -4065,8 +4384,8 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
               length since special opcode 255 would have scaled the
               the increment.  */
            case DW_LNS_const_add_pc:
-             address += (lh.minimum_instruction_length
-                         * ((255 - lh.opcode_base) / lh.line_range));
+             address += (lh->minimum_instruction_length
+                         * ((255 - lh->opcode_base) / lh->line_range));
              break;
            case DW_LNS_fixed_advance_pc:
              address += read_2_bytes (abfd, line_ptr);
@@ -4075,7 +4394,7 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
            default:
              {  /* Unknown standard opcode, ignore it.  */
                int i;
-               for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++)
+               for (i = 0; i < lh->standard_opcode_lengths[op_code]; i++)
                  {
                    (void) read_unsigned_leb128 (abfd, line_ptr, &bytes_read);
                    line_ptr += bytes_read;
@@ -4084,8 +4403,6 @@ dwarf_decode_lines (unsigned int offset, char *comp_dir, bfd *abfd,
            }
        }
     }
-done:
-  do_cleanups (back_to);
 }
 
 /* Start a subfile for DWARF.  FILENAME is the name of the file and
@@ -5098,6 +5415,8 @@ dwarf_attr_name (register unsigned attr)
       return "DW_AT_body_begin";
     case DW_AT_body_end:
       return "DW_AT_body_end";
+    case DW_AT_GNU_vector:
+      return "DW_AT_GNU_vector";
     default:
       return "DW_AT_<unknown>";
     }
@@ -5540,9 +5859,31 @@ dwarf_cfi_name (register unsigned cfi_opc)
       return "DW_CFA_def_cfa_register";
     case DW_CFA_def_cfa_offset:
       return "DW_CFA_def_cfa_offset";
+
+    /* DWARF 3 */
+    case DW_CFA_def_cfa_expression:
+      return "DW_CFA_def_cfa_expression";
+    case DW_CFA_expression:
+      return "DW_CFA_expression";
+    case DW_CFA_offset_extended_sf:
+      return "DW_CFA_offset_extended_sf";
+    case DW_CFA_def_cfa_sf:
+      return "DW_CFA_def_cfa_sf";
+    case DW_CFA_def_cfa_offset_sf:
+      return "DW_CFA_def_cfa_offset_sf";
+
       /* SGI/MIPS specific */
     case DW_CFA_MIPS_advance_loc8:
       return "DW_CFA_MIPS_advance_loc8";
+
+    /* GNU extensions */
+    case DW_CFA_GNU_window_save:
+      return "DW_CFA_GNU_window_save";
+    case DW_CFA_GNU_args_size:
+      return "DW_CFA_GNU_args_size";
+    case DW_CFA_GNU_negative_offset_extended:
+      return "DW_CFA_GNU_negative_offset_extended";
+
     default:
       return "DW_CFA_<unknown>";
     }
@@ -5554,29 +5895,29 @@ dump_die (struct die_info *die)
 {
   unsigned int i;
 
-  fprintf (stderr, "Die: %s (abbrev = %d, offset = %d)\n",
+  fprintf_unfiltered (gdb_stderr, "Die: %s (abbrev = %d, offset = %d)\n",
           dwarf_tag_name (die->tag), die->abbrev, die->offset);
-  fprintf (stderr, "\thas children: %s\n",
+  fprintf_unfiltered (gdb_stderr, "\thas children: %s\n",
           dwarf_bool_name (die->has_children));
 
-  fprintf (stderr, "\tattributes:\n");
+  fprintf_unfiltered (gdb_stderr, "\tattributes:\n");
   for (i = 0; i < die->num_attrs; ++i)
     {
-      fprintf (stderr, "\t\t%s (%s) ",
+      fprintf_unfiltered (gdb_stderr, "\t\t%s (%s) ",
               dwarf_attr_name (die->attrs[i].name),
               dwarf_form_name (die->attrs[i].form));
       switch (die->attrs[i].form)
        {
        case DW_FORM_ref_addr:
        case DW_FORM_addr:
-         fprintf (stderr, "address: ");
+         fprintf_unfiltered (gdb_stderr, "address: ");
          print_address_numeric (DW_ADDR (&die->attrs[i]), 1, gdb_stderr);
          break;
        case DW_FORM_block2:
        case DW_FORM_block4:
        case DW_FORM_block:
        case DW_FORM_block1:
-         fprintf (stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
+         fprintf_unfiltered (gdb_stderr, "block: size %d", DW_BLOCK (&die->attrs[i])->size);
          break;
        case DW_FORM_data1:
        case DW_FORM_data2:
@@ -5587,27 +5928,30 @@ dump_die (struct die_info *die)
        case DW_FORM_ref4:
        case DW_FORM_udata:
        case DW_FORM_sdata:
-         fprintf (stderr, "constant: %ld", DW_UNSND (&die->attrs[i]));
+         fprintf_unfiltered (gdb_stderr, "constant: %ld", DW_UNSND (&die->attrs[i]));
          break;
        case DW_FORM_string:
-         fprintf (stderr, "string: \"%s\"",
+       case DW_FORM_strp:
+         fprintf_unfiltered (gdb_stderr, "string: \"%s\"",
                   DW_STRING (&die->attrs[i])
                   ? DW_STRING (&die->attrs[i]) : "");
          break;
        case DW_FORM_flag:
          if (DW_UNSND (&die->attrs[i]))
-           fprintf (stderr, "flag: TRUE");
+           fprintf_unfiltered (gdb_stderr, "flag: TRUE");
          else
-           fprintf (stderr, "flag: FALSE");
+           fprintf_unfiltered (gdb_stderr, "flag: FALSE");
+         break;
+       case DW_FORM_indirect:
+         /* the reader will have reduced the indirect form to
+            the "base form" so this form should not occur */
+         fprintf_unfiltered (gdb_stderr, "unexpected attribute form: DW_FORM_indirect");
          break;
-       case DW_FORM_strp:      /* we do not support separate string
-                                  section yet */
-       case DW_FORM_indirect:  /* we do not handle indirect yet */
        default:
-         fprintf (stderr, "unsupported attribute form: %d.",
+         fprintf_unfiltered (gdb_stderr, "unsupported attribute form: %d.",
                   die->attrs[i].form);
        }
-      fprintf (stderr, "\n");
+      fprintf_unfiltered (gdb_stderr, "\n");
     }
 }
 
@@ -5758,6 +6102,41 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
       op = data[i++];
       switch (op)
        {
+       case DW_OP_lit0:
+       case DW_OP_lit1:
+       case DW_OP_lit2:
+       case DW_OP_lit3:
+       case DW_OP_lit4:
+       case DW_OP_lit5:
+       case DW_OP_lit6:
+       case DW_OP_lit7:
+       case DW_OP_lit8:
+       case DW_OP_lit9:
+       case DW_OP_lit10:
+       case DW_OP_lit11:
+       case DW_OP_lit12:
+       case DW_OP_lit13:
+       case DW_OP_lit14:
+       case DW_OP_lit15:
+       case DW_OP_lit16:
+       case DW_OP_lit17:
+       case DW_OP_lit18:
+       case DW_OP_lit19:
+       case DW_OP_lit20:
+       case DW_OP_lit21:
+       case DW_OP_lit22:
+       case DW_OP_lit23:
+       case DW_OP_lit24:
+       case DW_OP_lit25:
+       case DW_OP_lit26:
+       case DW_OP_lit27:
+       case DW_OP_lit28:
+       case DW_OP_lit29:
+       case DW_OP_lit30:
+       case DW_OP_lit31:
+         stack[++stacki] = op - DW_OP_lit0;
+         break;
+
        case DW_OP_reg0:
        case DW_OP_reg1:
        case DW_OP_reg2:
@@ -5916,6 +6295,11 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
          i += bytes_read;
          break;
 
+       case DW_OP_dup:
+         stack[stacki + 1] = stack[stacki];
+         stacki++;
+         break;
+
        case DW_OP_plus:
          stack[stacki - 1] += stack[stacki];
          stacki--;
@@ -5927,7 +6311,7 @@ decode_locdesc (struct dwarf_block *blk, struct objfile *objfile,
          break;
 
        case DW_OP_minus:
-         stack[stacki - 1] = stack[stacki] - stack[stacki - 1];
+         stack[stacki - 1] -= stack[stacki];
          stacki--;
          break;
 
This page took 0.04311 seconds and 4 git commands to generate.