XCOFF linker segmentation fault
[deliverable/binutils-gdb.git] / bfd / dwarf2.c
index cbd4cf64869f47a400151d7976b6b3525b212c5e..65c41611710e33462dc328ce827caa38d87a49f9 100644 (file)
@@ -1,5 +1,5 @@
 /* DWARF 2 support.
-   Copyright (C) 1994-2015 Free Software Foundation, Inc.
+   Copyright (C) 1994-2019 Free Software Foundation, Inc.
 
    Adapted from gdb/dwarf2read.c by Gavin Koch of Cygnus Solutions
    (gavin@cygnus.com).
@@ -100,6 +100,12 @@ struct dwarf2_debug
   /* Pointer to the end of the .debug_info section memory buffer.  */
   bfd_byte *info_ptr_end;
 
+  /* Pointer to the original bfd for which debug was loaded.  This is what
+     we use to compare and so check that the cached debug data is still
+     valid - it saves having to possibly dereference the gnu_debuglink each
+     time.  */
+  bfd *orig_bfd;
+
   /* Pointer to the bfd, section and address of the beginning of the
      section.  The bfd might be different than expected because of
      gnu_debuglink sections.  */
@@ -111,16 +117,15 @@ struct dwarf2_debug
      This includes a pointer to an alternate bfd which contains *extra*,
      possibly duplicate debug sections, and pointers to the loaded
      .debug_str and .debug_info sections from this bfd.  */
-  bfd *          alt_bfd_ptr;
-  bfd_byte *     alt_dwarf_str_buffer;
-  bfd_size_type  alt_dwarf_str_size;
-  bfd_byte *     alt_dwarf_info_buffer;
-  bfd_size_type  alt_dwarf_info_size;
+  bfd *                 alt_bfd_ptr;
+  bfd_byte *    alt_dwarf_str_buffer;
+  bfd_size_type         alt_dwarf_str_size;
+  bfd_byte *    alt_dwarf_info_buffer;
+  bfd_size_type         alt_dwarf_info_size;
 
   /* A pointer to the memory block allocated for info_ptr.  Neither
      info_ptr nor sec_info_ptr are guaranteed to stay pointing to the
-     beginning of the malloc block.  This is used only to free the
-     memory later.  */
+     beginning of the malloc block.  */
   bfd_byte *info_ptr_memory;
 
   /* Pointer to the symbol table.  */
@@ -144,20 +149,28 @@ struct dwarf2_debug
   /* Length of the loaded .debug_str section.  */
   bfd_size_type dwarf_str_size;
 
-  /* Pointer to the .debug_ranges section loaded into memory. */
+  /* Pointer to the .debug_line_str section loaded into memory.  */
+  bfd_byte *dwarf_line_str_buffer;
+
+  /* Length of the loaded .debug_line_str section.  */
+  bfd_size_type dwarf_line_str_size;
+
+  /* Pointer to the .debug_ranges section loaded into memory.  */
   bfd_byte *dwarf_ranges_buffer;
 
-  /* Length of the loaded .debug_ranges section. */
+  /* Length of the loaded .debug_ranges section.  */
   bfd_size_type dwarf_ranges_size;
 
   /* If the most recent call to bfd_find_nearest_line was given an
      address in an inlined function, preserve a pointer into the
      calling chain for subsequent calls to bfd_find_inliner_info to
-     use. */
+     use.  */
   struct funcinfo *inliner_chain;
 
   /* Section VMAs at the time the stash was built.  */
   bfd_vma *sec_vma;
+  /* Number of sections in the SEC_VMA table.  */
+  unsigned int sec_vma_count;
 
   /* Number of sections whose VMA we must adjust.  */
   int adjusted_section_count;
@@ -182,8 +195,8 @@ struct dwarf2_debug
 
   /* Status of info hash.  */
   int info_hash_status;
-#define STASH_INFO_HASH_OFF        0
-#define STASH_INFO_HASH_ON         1
+#define STASH_INFO_HASH_OFF       0
+#define STASH_INFO_HASH_ON        1
 #define STASH_INFO_HASH_DISABLED   2
 
   /* True if we opened bfd_ptr.  */
@@ -238,9 +251,6 @@ struct comp_unit
      by its reference.  */
   bfd_byte *info_ptr_unit;
 
-  /* Pointer to the start of the debug section, for DW_FORM_ref_addr.  */
-  bfd_byte *sec_info_ptr;
-
   /* The offset into .debug_line of the line number table.  */
   unsigned long line_offset;
 
@@ -256,6 +266,12 @@ struct comp_unit
   /* A list of the functions found in this comp. unit.  */
   struct funcinfo *function_table;
 
+  /* A table of function information references searchable by address.  */
+  struct lookup_funcinfo *lookup_funcinfo_table;
+
+  /* Number of functions in the function_table and sorted_function_table.  */
+  bfd_size_type number_of_functions;
+
   /* A list of the variables found in this comp. unit.  */
   struct varinfo *variable_table;
 
@@ -294,6 +310,7 @@ struct attr_abbrev
 {
   enum dwarf_attribute name;
   enum dwarf_form form;
+  bfd_vma implicit_const;
 };
 
 /* Map of uncompressed DWARF debug section name to compressed one.  It
@@ -317,6 +334,7 @@ const struct dwarf_debug_section dwarf_debug_sections[] =
   { ".debug_static_vars",      ".zdebug_static_vars" },
   { ".debug_str",              ".zdebug_str", },
   { ".debug_str",              ".zdebug_str", },
+  { ".debug_line_str",         ".zdebug_line_str", },
   { ".debug_types",            ".zdebug_types" },
   /* GNU DWARF 1 extensions */
   { ".debug_sfnames",          ".zdebug_sfnames" },
@@ -329,7 +347,7 @@ const struct dwarf_debug_section dwarf_debug_sections[] =
   { NULL,                      NULL },
 };
 
-/* NB/ Numbers in this enum must match up with indicies
+/* NB/ Numbers in this enum must match up with indices
    into the dwarf_debug_sections[] array above.  */
 enum dwarf_debug_section_enum
 {
@@ -349,15 +367,21 @@ enum dwarf_debug_section_enum
   debug_static_vars,
   debug_str,
   debug_str_alt,
+  debug_line_str,
   debug_types,
   debug_sfnames,
   debug_srcinfo,
   debug_funcnames,
   debug_typenames,
   debug_varnames,
-  debug_weaknames
+  debug_weaknames,
+  debug_max
 };
 
+/* A static assertion.  */
+extern int dwarf_debug_section_assert[ARRAY_SIZE (dwarf_debug_sections)
+                                     == debug_max + 1 ? 1 : -1];
+
 #ifndef ABBREV_HASH_SIZE
 #define ABBREV_HASH_SIZE 121
 #endif
@@ -390,7 +414,7 @@ struct info_hash_table
   struct bfd_hash_table base;
 };
 
-/* Function to create a new entry in info hash table. */
+/* Function to create a new entry in info hash table.  */
 
 static struct bfd_hash_entry *
 info_hash_table_newfunc (struct bfd_hash_entry *entry,
@@ -476,7 +500,7 @@ insert_info_hash_table (struct info_hash_table *hash_table,
 }
 
 /* Look up an info entry list from an info hash table.  Return NULL
-   if there is none. */
+   if there is none.  */
 
 static struct info_list_node *
 lookup_info_hash_table (struct info_hash_table *hash_table, const char *key)
@@ -495,7 +519,7 @@ lookup_info_hash_table (struct info_hash_table *hash_table, const char *key)
    the located section does not contain at least OFFSET bytes.  */
 
 static bfd_boolean
-read_section (bfd *           abfd,
+read_section (bfd *          abfd,
              const struct dwarf_debug_section *sec,
              asymbol **      syms,
              bfd_uint64_t    offset,
@@ -504,9 +528,11 @@ read_section (bfd *           abfd,
 {
   asection *msec;
   const char *section_name = sec->uncompressed_name;
+  bfd_byte *contents = *section_buffer;
+  bfd_size_type amt;
 
   /* The section may have already been read.  */
-  if (*section_buffer == NULL)
+  if (contents == NULL)
     {
       msec = bfd_get_section_by_name (abfd, section_name);
       if (! msec)
@@ -517,38 +543,45 @@ read_section (bfd *           abfd,
        }
       if (! msec)
        {
-         (*_bfd_error_handler) (_("Dwarf Error: Can't find %s section."),
-                                sec->uncompressed_name);
+         _bfd_error_handler (_("DWARF error: can't find %s section."),
+                             sec->uncompressed_name);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
        }
 
       *section_size = msec->rawsize ? msec->rawsize : msec->size;
-      if (syms)
+      /* Paranoia - alloc one extra so that we can make sure a string
+        section is NUL terminated.  */
+      amt = *section_size + 1;
+      if (amt == 0)
        {
-         *section_buffer
-           = bfd_simple_get_relocated_section_contents (abfd, msec, NULL, syms);
-         if (! *section_buffer)
-           return FALSE;
+         bfd_set_error (bfd_error_no_memory);
+         return FALSE;
        }
-      else
+      contents = (bfd_byte *) bfd_malloc (amt);
+      if (contents == NULL)
+       return FALSE;
+      if (syms
+         ? !bfd_simple_get_relocated_section_contents (abfd, msec, contents,
+                                                       syms)
+         : !bfd_get_section_contents (abfd, msec, contents, 0, *section_size))
        {
-         *section_buffer = (bfd_byte *) bfd_malloc (*section_size);
-         if (! *section_buffer)
-           return FALSE;
-         if (! bfd_get_section_contents (abfd, msec, *section_buffer,
-                                         0, *section_size))
-           return FALSE;
+         free (contents);
+         return FALSE;
        }
+      contents[*section_size] = 0;
+      *section_buffer = contents;
     }
 
   /* It is possible to get a bad value for the offset into the section
      that the client wants.  Validate it here to avoid trouble later.  */
   if (offset != 0 && offset >= *section_size)
     {
-      (*_bfd_error_handler) (_("Dwarf Error: Offset (%lu)"
-                              " greater than or equal to %s size (%lu)."),
-                            (long) offset, section_name, *section_size);
+      /* xgettext: c-format */
+      _bfd_error_handler (_("DWARF error: offset (%" PRIu64 ")"
+                           " greater than or equal to %s size (%" PRIu64 ")"),
+                         (uint64_t) offset, section_name,
+                         (uint64_t) *section_size);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
@@ -599,14 +632,24 @@ read_8_bytes (bfd *abfd, bfd_byte *buf, bfd_byte *end)
 }
 
 static bfd_byte *
-read_n_bytes (bfd *abfd ATTRIBUTE_UNUSED,
-             bfd_byte *buf,
-             bfd_byte *end,
-             unsigned int size ATTRIBUTE_UNUSED)
+read_n_bytes (bfd_byte *           buf,
+             bfd_byte *           end,
+             struct dwarf_block * block)
 {
-  if (buf + size > end)
-    return NULL;
-  return buf;
+  unsigned int  size = block->size;
+  bfd_byte *    block_end = buf + size;
+
+  if (block_end > end || block_end < buf)
+    {
+      block->data = NULL;
+      block->size = 0;
+      return end;
+    }
+  else
+    {
+      block->data = buf;
+      return block_end;
+    }
 }
 
 /* Scans a NUL terminated string starting at BUF, returning a pointer to it.
@@ -616,9 +659,9 @@ read_n_bytes (bfd *abfd ATTRIBUTE_UNUSED,
    problem, or if the string is empty.  */
 
 static char *
-read_string (bfd *          abfd ATTRIBUTE_UNUSED,
-            bfd_byte *     buf,
-            bfd_byte *     buf_end,
+read_string (bfd *         abfd ATTRIBUTE_UNUSED,
+            bfd_byte *     buf,
+            bfd_byte *     buf_end,
             unsigned int * bytes_read_ptr)
 {
   bfd_byte *str = buf;
@@ -656,9 +699,9 @@ read_string (bfd *          abfd ATTRIBUTE_UNUSED,
 
 static char *
 read_indirect_string (struct comp_unit * unit,
-                     bfd_byte *         buf,
-                     bfd_byte *         buf_end,
-                     unsigned int *     bytes_read_ptr)
+                     bfd_byte *         buf,
+                     bfd_byte *         buf_end,
+                     unsigned int *     bytes_read_ptr)
 {
   bfd_uint64_t offset;
   struct dwarf2_debug *stash = unit->stash;
@@ -690,14 +733,53 @@ read_indirect_string (struct comp_unit * unit,
   return str;
 }
 
+/* Like read_indirect_string but from .debug_line_str section.  */
+
+static char *
+read_indirect_line_string (struct comp_unit * unit,
+                          bfd_byte *         buf,
+                          bfd_byte *         buf_end,
+                          unsigned int *     bytes_read_ptr)
+{
+  bfd_uint64_t offset;
+  struct dwarf2_debug *stash = unit->stash;
+  char *str;
+
+  if (buf + unit->offset_size > buf_end)
+    {
+      * bytes_read_ptr = 0;
+      return NULL;
+    }
+
+  if (unit->offset_size == 4)
+    offset = read_4_bytes (unit->abfd, buf, buf_end);
+  else
+    offset = read_8_bytes (unit->abfd, buf, buf_end);
+
+  *bytes_read_ptr = unit->offset_size;
+
+  if (! read_section (unit->abfd, &stash->debug_sections[debug_line_str],
+                     stash->syms, offset,
+                     &stash->dwarf_line_str_buffer,
+                     &stash->dwarf_line_str_size))
+    return NULL;
+
+  if (offset >= stash->dwarf_line_str_size)
+    return NULL;
+  str = (char *) stash->dwarf_line_str_buffer + offset;
+  if (*str == '\0')
+    return NULL;
+  return str;
+}
+
 /* Like read_indirect_string but uses a .debug_str located in
    an alternate file pointed to by the .gnu_debugaltlink section.
    Used to impement DW_FORM_GNU_strp_alt.  */
 
 static char *
 read_alt_indirect_string (struct comp_unit * unit,
-                         bfd_byte *         buf,
-                         bfd_byte *         buf_end,
+                         bfd_byte *         buf,
+                         bfd_byte *         buf_end,
                          unsigned int *     bytes_read_ptr)
 {
   bfd_uint64_t offset;
@@ -893,7 +975,8 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
 
   abbrev_ptr = stash->dwarf_abbrev_buffer + offset;
   abbrev_end = stash->dwarf_abbrev_buffer + stash->dwarf_abbrev_size;
-  abbrev_number = safe_read_leb128 (abfd, abbrev_ptr, &bytes_read, FALSE, abbrev_end);
+  abbrev_number = _bfd_safe_read_leb128 (abfd, abbrev_ptr, &bytes_read,
+                                        FALSE, abbrev_end);
   abbrev_ptr += bytes_read;
 
   /* Loop until we reach an abbrev number of 0.  */
@@ -907,19 +990,35 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
       /* Read in abbrev header.  */
       cur_abbrev->number = abbrev_number;
       cur_abbrev->tag = (enum dwarf_tag)
-       safe_read_leb128 (abfd, abbrev_ptr, &bytes_read, FALSE, abbrev_end);
+       _bfd_safe_read_leb128 (abfd, abbrev_ptr, &bytes_read,
+                              FALSE, abbrev_end);
       abbrev_ptr += bytes_read;
       cur_abbrev->has_children = read_1_byte (abfd, abbrev_ptr, abbrev_end);
       abbrev_ptr += 1;
 
       /* Now read in declarations.  */
-      abbrev_name = safe_read_leb128 (abfd, abbrev_ptr, &bytes_read, FALSE, abbrev_end);
-      abbrev_ptr += bytes_read;
-      abbrev_form = safe_read_leb128 (abfd, abbrev_ptr, &bytes_read, FALSE, abbrev_end);
-      abbrev_ptr += bytes_read;
-
-      while (abbrev_name)
+      for (;;)
        {
+         /* Initialize it just to avoid a GCC false warning.  */
+         bfd_vma implicit_const = -1;
+
+         abbrev_name = _bfd_safe_read_leb128 (abfd, abbrev_ptr, &bytes_read,
+                                              FALSE, abbrev_end);
+         abbrev_ptr += bytes_read;
+         abbrev_form = _bfd_safe_read_leb128 (abfd, abbrev_ptr, &bytes_read,
+                                              FALSE, abbrev_end);
+         abbrev_ptr += bytes_read;
+         if (abbrev_form == DW_FORM_implicit_const)
+           {
+             implicit_const = _bfd_safe_read_leb128 (abfd, abbrev_ptr,
+                                                     &bytes_read, TRUE,
+                                                     abbrev_end);
+             abbrev_ptr += bytes_read;
+           }
+
+         if (abbrev_name == 0)
+           break;
+
          if ((cur_abbrev->num_attrs % ATTR_ALLOC_CHUNK) == 0)
            {
              struct attr_abbrev *tmp;
@@ -948,12 +1047,11 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
 
          cur_abbrev->attrs[cur_abbrev->num_attrs].name
            = (enum dwarf_attribute) abbrev_name;
-         cur_abbrev->attrs[cur_abbrev->num_attrs++].form
+         cur_abbrev->attrs[cur_abbrev->num_attrs].form
            = (enum dwarf_form) abbrev_form;
-         abbrev_name = safe_read_leb128 (abfd, abbrev_ptr, &bytes_read, FALSE, abbrev_end);
-         abbrev_ptr += bytes_read;
-         abbrev_form = safe_read_leb128 (abfd, abbrev_ptr, &bytes_read, FALSE, abbrev_end);
-         abbrev_ptr += bytes_read;
+         cur_abbrev->attrs[cur_abbrev->num_attrs].implicit_const
+           = implicit_const;
+         ++cur_abbrev->num_attrs;
        }
 
       hash_number = abbrev_number % ABBREV_HASH_SIZE;
@@ -970,7 +1068,8 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
       if ((unsigned int) (abbrev_ptr - stash->dwarf_abbrev_buffer)
          >= stash->dwarf_abbrev_size)
        break;
-      abbrev_number = safe_read_leb128 (abfd, abbrev_ptr, &bytes_read, FALSE, abbrev_end);
+      abbrev_number = _bfd_safe_read_leb128 (abfd, abbrev_ptr,
+                                            &bytes_read, FALSE, abbrev_end);
       abbrev_ptr += bytes_read;
       if (lookup_abbrev (abbrev_number, abbrevs) != NULL)
        break;
@@ -984,7 +1083,8 @@ read_abbrevs (bfd *abfd, bfd_uint64_t offset, struct dwarf2_debug *stash)
 static inline bfd_boolean
 is_str_attr (enum dwarf_form form)
 {
-  return form == DW_FORM_string || form == DW_FORM_strp || form == DW_FORM_GNU_strp_alt;
+  return (form == DW_FORM_string || form == DW_FORM_strp
+         || form == DW_FORM_line_strp || form == DW_FORM_GNU_strp_alt);
 }
 
 /* Read and fill in the value of attribute ATTR as described by FORM.
@@ -993,19 +1093,20 @@ is_str_attr (enum dwarf_form form)
 
 static bfd_byte *
 read_attribute_value (struct attribute *  attr,
-                     unsigned            form,
+                     unsigned            form,
+                     bfd_vma             implicit_const,
                      struct comp_unit *  unit,
-                     bfd_byte *          info_ptr,
-                     bfd_byte *          info_ptr_end)
+                     bfd_byte *          info_ptr,
+                     bfd_byte *          info_ptr_end)
 {
   bfd *abfd = unit->abfd;
   unsigned int bytes_read;
   struct dwarf_block *blk;
   bfd_size_type amt;
 
-  if (info_ptr >= info_ptr_end)
+  if (info_ptr >= info_ptr_end && form != DW_FORM_flag_present)
     {
-      (*_bfd_error_handler) (_("Dwarf Error: Info pointer extends beyond end of attributes"));
+      _bfd_error_handler (_("DWARF error: info pointer extends beyond end of attributes"));
       bfd_set_error (bfd_error_bad_value);
       return info_ptr;
     }
@@ -1046,8 +1147,7 @@ read_attribute_value (struct attribute *  attr,
        return NULL;
       blk->size = read_2_bytes (abfd, info_ptr, info_ptr_end);
       info_ptr += 2;
-      blk->data = read_n_bytes (abfd, info_ptr, info_ptr_end, blk->size);
-      info_ptr += blk->size;
+      info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
     case DW_FORM_block4:
@@ -1057,8 +1157,7 @@ read_attribute_value (struct attribute *  attr,
        return NULL;
       blk->size = read_4_bytes (abfd, info_ptr, info_ptr_end);
       info_ptr += 4;
-      blk->data = read_n_bytes (abfd, info_ptr, info_ptr_end, blk->size);
-      info_ptr += blk->size;
+      info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
     case DW_FORM_data2:
@@ -1081,6 +1180,10 @@ read_attribute_value (struct attribute *  attr,
       attr->u.str = read_indirect_string (unit, info_ptr, info_ptr_end, &bytes_read);
       info_ptr += bytes_read;
       break;
+    case DW_FORM_line_strp:
+      attr->u.str = read_indirect_line_string (unit, info_ptr, info_ptr_end, &bytes_read);
+      info_ptr += bytes_read;
+      break;
     case DW_FORM_GNU_strp_alt:
       attr->u.str = read_alt_indirect_string (unit, info_ptr, info_ptr_end, &bytes_read);
       info_ptr += bytes_read;
@@ -1091,10 +1194,10 @@ read_attribute_value (struct attribute *  attr,
       blk = (struct dwarf_block *) bfd_alloc (abfd, amt);
       if (blk == NULL)
        return NULL;
-      blk->size = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, info_ptr_end);
+      blk->size = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                        FALSE, info_ptr_end);
       info_ptr += bytes_read;
-      blk->data = read_n_bytes (abfd, info_ptr, info_ptr_end, blk->size);
-      info_ptr += blk->size;
+      info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
     case DW_FORM_block1:
@@ -1104,8 +1207,7 @@ read_attribute_value (struct attribute *  attr,
        return NULL;
       blk->size = read_1_byte (abfd, info_ptr, info_ptr_end);
       info_ptr += 1;
-      blk->data = read_n_bytes (abfd, info_ptr, info_ptr_end, blk->size);
-      info_ptr += blk->size;
+      info_ptr = read_n_bytes (info_ptr, info_ptr_end, blk);
       attr->u.blk = blk;
       break;
     case DW_FORM_data1:
@@ -1120,11 +1222,13 @@ read_attribute_value (struct attribute *  attr,
       attr->u.val = 1;
       break;
     case DW_FORM_sdata:
-      attr->u.sval = safe_read_leb128 (abfd, info_ptr, &bytes_read, TRUE, info_ptr_end);
+      attr->u.sval = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                           TRUE, info_ptr_end);
       info_ptr += bytes_read;
       break;
     case DW_FORM_udata:
-      attr->u.val = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, info_ptr_end);
+      attr->u.val = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                          FALSE, info_ptr_end);
       info_ptr += bytes_read;
       break;
     case DW_FORM_ref1:
@@ -1148,17 +1252,30 @@ read_attribute_value (struct attribute *  attr,
       info_ptr += 8;
       break;
     case DW_FORM_ref_udata:
-      attr->u.val = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, info_ptr_end);
+      attr->u.val = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                          FALSE, info_ptr_end);
       info_ptr += bytes_read;
       break;
     case DW_FORM_indirect:
-      form = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, info_ptr_end);
+      form = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                   FALSE, info_ptr_end);
       info_ptr += bytes_read;
-      info_ptr = read_attribute_value (attr, form, unit, info_ptr, info_ptr_end);
+      if (form == DW_FORM_implicit_const)
+       {
+         implicit_const = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                                 TRUE, info_ptr_end);
+         info_ptr += bytes_read;
+       }
+      info_ptr = read_attribute_value (attr, form, implicit_const, unit,
+                                      info_ptr, info_ptr_end);
+      break;
+    case DW_FORM_implicit_const:
+      attr->form = DW_FORM_sdata;
+      attr->u.sval = implicit_const;
       break;
     default:
-      (*_bfd_error_handler) (_("Dwarf Error: Invalid or unhandled FORM value: %#x."),
-                            form);
+      _bfd_error_handler (_("DWARF error: invalid or unhandled FORM value: %#x"),
+                         form);
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
@@ -1171,11 +1288,12 @@ static bfd_byte *
 read_attribute (struct attribute *    attr,
                struct attr_abbrev *  abbrev,
                struct comp_unit *    unit,
-               bfd_byte *            info_ptr,
-               bfd_byte *            info_ptr_end)
+               bfd_byte *            info_ptr,
+               bfd_byte *            info_ptr_end)
 {
   attr->name = abbrev->name;
-  info_ptr = read_attribute_value (attr, abbrev->form, unit, info_ptr, info_ptr_end);
+  info_ptr = read_attribute_value (attr, abbrev->form, abbrev->implicit_const,
+                                  unit, info_ptr, info_ptr_end);
   return info_ptr;
 }
 
@@ -1213,42 +1331,44 @@ non_mangled (int lang)
 
 struct line_info
 {
-  struct line_info* prev_line;
-  bfd_vma address;
-  char *filename;
-  unsigned int line;
-  unsigned int column;
-  unsigned int discriminator;
-  unsigned char op_index;
-  unsigned char end_sequence;          /* End of (sequential) code sequence.  */
+  struct line_info *   prev_line;
+  bfd_vma              address;
+  char *               filename;
+  unsigned int         line;
+  unsigned int         column;
+  unsigned int         discriminator;
+  unsigned char                op_index;
+  unsigned char                end_sequence;           /* End of (sequential) code sequence.  */
 };
 
 struct fileinfo
 {
-  char *name;
-  unsigned int dir;
-  unsigned int time;
-  unsigned int size;
+  char *               name;
+  unsigned int         dir;
+  unsigned int         time;
+  unsigned int         size;
 };
 
 struct line_sequence
 {
-  bfd_vma               low_pc;
+  bfd_vma              low_pc;
   struct line_sequence* prev_sequence;
-  struct line_info*     last_line;  /* Largest VMA.  */
+  struct line_info*    last_line;  /* Largest VMA.  */
+  struct line_info**   line_info_lookup;
+  bfd_size_type                num_lines;
 };
 
 struct line_info_table
 {
-  bfd*                  abfd;
-  unsigned int          num_files;
-  unsigned int          num_dirs;
-  unsigned int          num_sequences;
-  char *                comp_dir;
-  char **               dirs;
-  struct fileinfo*      files;
+  bfd *                        abfd;
+  unsigned int         num_files;
+  unsigned int         num_dirs;
+  unsigned int         num_sequences;
+  char *               comp_dir;
+  char **              dirs;
+  struct fileinfo*     files;
   struct line_sequence* sequences;
-  struct line_info*     lcl_head;   /* Local head; used in 'add_line_info'.  */
+  struct line_info*    lcl_head;   /* Local head; used in 'add_line_info'.  */
 };
 
 /* Remember some information about each function.  If the function is
@@ -1259,23 +1379,37 @@ struct line_info_table
 struct funcinfo
 {
   /* Pointer to previous function in list of all functions.  */
-  struct funcinfo *prev_func;
+  struct funcinfo *    prev_func;
   /* Pointer to function one scope higher.  */
-  struct funcinfo *caller_func;
+  struct funcinfo *    caller_func;
   /* Source location file name where caller_func inlines this func.  */
-  char *caller_file;
+  char *               caller_file;
   /* Source location file name.  */
-  char *file;
+  char *               file;
   /* Source location line number where caller_func inlines this func.  */
-  int caller_line;
+  int                  caller_line;
   /* Source location line number.  */
-  int line;
-  int tag;
-  bfd_boolean is_linkage;
-  const char *name;
-  struct arange arange;
+  int                  line;
+  int                  tag;
+  bfd_boolean          is_linkage;
+  const char *         name;
+  struct arange                arange;
   /* Where the symbol is defined.  */
-  asection *sec;
+  asection *           sec;
+};
+
+struct lookup_funcinfo
+{
+  /* Function information corresponding to this lookup table entry.  */
+  struct funcinfo *    funcinfo;
+
+  /* The lowest address for this specific function.  */
+  bfd_vma              low_addr;
+
+  /* The highest address of this function before the lookup table is sorted.
+     The highest address of all prior functions after the lookup table is
+     sorted, which is used for binary search.  */
+  bfd_vma              high_addr;
 };
 
 struct varinfo
@@ -1302,9 +1436,7 @@ new_line_sorts_after (struct line_info *new_line, struct line_info *line)
 {
   return (new_line->address > line->address
          || (new_line->address == line->address
-             && (new_line->op_index > line->op_index
-                 || (new_line->op_index == line->op_index
-                     && new_line->end_sequence < line->end_sequence))));
+             && new_line->op_index > line->op_index));
 }
 
 
@@ -1390,7 +1522,8 @@ add_line_info (struct line_info_table *table,
       table->sequences = seq;
       table->num_sequences++;
     }
-  else if (new_line_sorts_after (info, seq->last_line))
+  else if (info->end_sequence
+          || new_line_sorts_after (info, seq->last_line))
     {
       /* Normal case: add 'info' to the beginning of the current sequence.  */
       info->prev_line = seq->last_line;
@@ -1442,16 +1575,18 @@ concat_filename (struct line_info_table *table, unsigned int file)
 {
   char *filename;
 
-  if (file - 1 >= table->num_files)
+  if (table == NULL || file - 1 >= table->num_files)
     {
       /* FILE == 0 means unknown.  */
       if (file)
-       (*_bfd_error_handler)
-         (_("Dwarf Error: mangled line number section (bad file number)."));
+       _bfd_error_handler
+         (_("DWARF error: mangled line number section (bad file number)"));
       return strdup ("<unknown>");
     }
 
   filename = table->files[file - 1].name;
+  if (filename == NULL)
+    return strdup ("<unknown>");
 
   if (!IS_ABSOLUTE_PATH (filename))
     {
@@ -1538,7 +1673,7 @@ arange_add (const struct comp_unit *unit, struct arange *first_arange,
   while (arange);
 
   /* Need to allocate a new arange and insert it into the arange list.
-     Order isn't significant, so just insert after the first arange. */
+     Order isn't significant, so just insert after the first arange.  */
   arange = (struct arange *) bfd_alloc (unit->abfd, sizeof (*arange));
   if (arange == NULL)
     return FALSE;
@@ -1578,17 +1713,62 @@ compare_sequences (const void* a, const void* b)
   return 0;
 }
 
+/* Construct the line information table for quick lookup.  */
+
+static bfd_boolean
+build_line_info_table (struct line_info_table *  table,
+                      struct line_sequence *    seq)
+{
+  bfd_size_type      amt;
+  struct line_info** line_info_lookup;
+  struct line_info*  each_line;
+  unsigned int       num_lines;
+  unsigned int       line_index;
+
+  if (seq->line_info_lookup != NULL)
+    return TRUE;
+
+  /* Count the number of line information entries.  We could do this while
+     scanning the debug information, but some entries may be added via
+     lcl_head without having a sequence handy to increment the number of
+     lines.  */
+  num_lines = 0;
+  for (each_line = seq->last_line; each_line; each_line = each_line->prev_line)
+    num_lines++;
+
+  if (num_lines == 0)
+    return TRUE;
+
+  /* Allocate space for the line information lookup table.  */
+  amt = sizeof (struct line_info*) * num_lines;
+  line_info_lookup = (struct line_info**) bfd_alloc (table->abfd, amt);
+  if (line_info_lookup == NULL)
+    return FALSE;
+
+  /* Create the line information lookup table.  */
+  line_index = num_lines;
+  for (each_line = seq->last_line; each_line; each_line = each_line->prev_line)
+    line_info_lookup[--line_index] = each_line;
+
+  BFD_ASSERT (line_index == 0);
+
+  seq->num_lines = num_lines;
+  seq->line_info_lookup = line_info_lookup;
+
+  return TRUE;
+}
+
 /* Sort the line sequences for quick lookup.  */
 
 static bfd_boolean
 sort_line_sequences (struct line_info_table* table)
 {
-  bfd_size_type amt;
-  struct line_sequence* sequences;
-  struct line_sequence* seq;
-  unsigned int n = 0;
-  unsigned int num_sequences = table->num_sequences;
-  bfd_vma last_high_pc;
+  bfd_size_type                 amt;
+  struct line_sequence*         sequences;
+  struct line_sequence*         seq;
+  unsigned int          n = 0;
+  unsigned int          num_sequences = table->num_sequences;
+  bfd_vma               last_high_pc;
 
   if (num_sequences == 0)
     return TRUE;
@@ -1609,6 +1789,8 @@ sort_line_sequences (struct line_info_table* table)
       sequences[n].low_pc = seq->low_pc;
       sequences[n].prev_sequence = NULL;
       sequences[n].last_line = seq->last_line;
+      sequences[n].line_info_lookup = NULL;
+      sequences[n].num_lines = 0;
       seq = seq->prev_sequence;
       free (last_seq);
     }
@@ -1646,6 +1828,192 @@ sort_line_sequences (struct line_info_table* table)
   return TRUE;
 }
 
+/* Add directory to TABLE.  CUR_DIR memory ownership is taken by TABLE.  */
+
+static bfd_boolean
+line_info_add_include_dir (struct line_info_table *table, char *cur_dir)
+{
+  if ((table->num_dirs % DIR_ALLOC_CHUNK) == 0)
+    {
+      char **tmp;
+      bfd_size_type amt;
+
+      amt = table->num_dirs + DIR_ALLOC_CHUNK;
+      amt *= sizeof (char *);
+
+      tmp = (char **) bfd_realloc (table->dirs, amt);
+      if (tmp == NULL)
+       return FALSE;
+      table->dirs = tmp;
+    }
+
+  table->dirs[table->num_dirs++] = cur_dir;
+  return TRUE;
+}
+
+static bfd_boolean
+line_info_add_include_dir_stub (struct line_info_table *table, char *cur_dir,
+                               unsigned int dir ATTRIBUTE_UNUSED,
+                               unsigned int xtime ATTRIBUTE_UNUSED,
+                               unsigned int size ATTRIBUTE_UNUSED)
+{
+  return line_info_add_include_dir (table, cur_dir);
+}
+
+/* Add file to TABLE.  CUR_FILE memory ownership is taken by TABLE.  */
+
+static bfd_boolean
+line_info_add_file_name (struct line_info_table *table, char *cur_file,
+                        unsigned int dir, unsigned int xtime,
+                        unsigned int size)
+{
+  if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
+    {
+      struct fileinfo *tmp;
+      bfd_size_type amt;
+
+      amt = table->num_files + FILE_ALLOC_CHUNK;
+      amt *= sizeof (struct fileinfo);
+
+      tmp = (struct fileinfo *) bfd_realloc (table->files, amt);
+      if (tmp == NULL)
+       return FALSE;
+      table->files = tmp;
+    }
+
+  table->files[table->num_files].name = cur_file;
+  table->files[table->num_files].dir = dir;
+  table->files[table->num_files].time = xtime;
+  table->files[table->num_files].size = size;
+  table->num_files++;
+  return TRUE;
+}
+
+/* Read directory or file name entry format, starting with byte of
+   format count entries, ULEB128 pairs of entry formats, ULEB128 of
+   entries count and the entries themselves in the described entry
+   format.  */
+
+static bfd_boolean
+read_formatted_entries (struct comp_unit *unit, bfd_byte **bufp,
+                       bfd_byte *buf_end, struct line_info_table *table,
+                       bfd_boolean (*callback) (struct line_info_table *table,
+                                                char *cur_file,
+                                                unsigned int dir,
+                                                unsigned int time,
+                                                unsigned int size))
+{
+  bfd *abfd = unit->abfd;
+  bfd_byte format_count, formati;
+  bfd_vma data_count, datai;
+  bfd_byte *buf = *bufp;
+  bfd_byte *format_header_data;
+  unsigned int bytes_read;
+
+  format_count = read_1_byte (abfd, buf, buf_end);
+  buf += 1;
+  format_header_data = buf;
+  for (formati = 0; formati < format_count; formati++)
+    {
+      _bfd_safe_read_leb128 (abfd, buf, &bytes_read, FALSE, buf_end);
+      buf += bytes_read;
+      _bfd_safe_read_leb128 (abfd, buf, &bytes_read, FALSE, buf_end);
+      buf += bytes_read;
+    }
+
+  data_count = _bfd_safe_read_leb128 (abfd, buf, &bytes_read, FALSE, buf_end);
+  buf += bytes_read;
+  if (format_count == 0 && data_count != 0)
+    {
+      _bfd_error_handler (_("DWARF error: zero format count"));
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
+  /* PR 22210.  Paranoia check.  Don't bother running the loop
+     if we know that we are going to run out of buffer.  */
+  if (data_count > (bfd_vma) (buf_end - buf))
+    {
+      _bfd_error_handler
+       (_("DWARF error: data count (%" PRIx64 ") larger than buffer size"),
+        (uint64_t) data_count);
+      bfd_set_error (bfd_error_bad_value);
+      return FALSE;
+    }
+
+  for (datai = 0; datai < data_count; datai++)
+    {
+      bfd_byte *format = format_header_data;
+      struct fileinfo fe;
+
+      memset (&fe, 0, sizeof fe);
+      for (formati = 0; formati < format_count; formati++)
+       {
+         bfd_vma content_type, form;
+         char *string_trash;
+         char **stringp = &string_trash;
+         unsigned int uint_trash, *uintp = &uint_trash;
+         struct attribute attr;
+
+         content_type = _bfd_safe_read_leb128 (abfd, format, &bytes_read,
+                                               FALSE, buf_end);
+         format += bytes_read;
+         switch (content_type)
+           {
+           case DW_LNCT_path:
+             stringp = &fe.name;
+             break;
+           case DW_LNCT_directory_index:
+             uintp = &fe.dir;
+             break;
+           case DW_LNCT_timestamp:
+             uintp = &fe.time;
+             break;
+           case DW_LNCT_size:
+             uintp = &fe.size;
+             break;
+           case DW_LNCT_MD5:
+             break;
+           default:
+             _bfd_error_handler
+               (_("DWARF error: unknown format content type %" PRIu64),
+                (uint64_t) content_type);
+             bfd_set_error (bfd_error_bad_value);
+             return FALSE;
+           }
+
+         form = _bfd_safe_read_leb128 (abfd, format, &bytes_read, FALSE,
+                                       buf_end);
+         format += bytes_read;
+
+         buf = read_attribute_value (&attr, form, 0, unit, buf, buf_end);
+         if (buf == NULL)
+           return FALSE;
+         switch (form)
+           {
+           case DW_FORM_string:
+           case DW_FORM_line_strp:
+             *stringp = attr.u.str;
+             break;
+
+           case DW_FORM_data1:
+           case DW_FORM_data2:
+           case DW_FORM_data4:
+           case DW_FORM_data8:
+           case DW_FORM_udata:
+             *uintp = attr.u.val;
+             break;
+           }
+       }
+
+      if (!callback (table, fe.name, fe.dir, fe.time, fe.size))
+       return FALSE;
+    }
+
+  *bufp = buf;
+  return TRUE;
+}
+
 /* Decode the line number information for UNIT.  */
 
 static struct line_info_table*
@@ -1687,9 +2055,9 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
 
   if (stash->dwarf_line_size < 16)
     {
-      (*_bfd_error_handler)
-       (_("Dwarf Error: Line info section is too small (%ld)"),
-        (long) stash->dwarf_line_size);
+      _bfd_error_handler
+       (_("DWARF error: line info section is too small (%" PRId64 ")"),
+        (int64_t) stash->dwarf_line_size);
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
@@ -1714,11 +2082,13 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
       offset_size = 8;
     }
 
-  if (lh.total_length > stash->dwarf_line_size)
+  if (lh.total_length > (size_t) (line_end - line_ptr))
     {
-      (*_bfd_error_handler)
-       (_("Dwarf Error: Line info data is bigger (0x%lx) than the section (0x%lx)"),
-        (long) lh.total_length, (long) stash->dwarf_line_size);
+      _bfd_error_handler
+       /* xgettext: c-format */
+       (_("DWARF error: line info data is bigger (%#" PRIx64 ")"
+          " than the space remaining in the section (%#lx)"),
+        (uint64_t) lh.total_length, (unsigned long) (line_end - line_ptr));
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
@@ -1726,23 +2096,44 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
   line_end = line_ptr + lh.total_length;
 
   lh.version = read_2_bytes (abfd, line_ptr, line_end);
-  if (lh.version < 2 || lh.version > 4)
+  if (lh.version < 2 || lh.version > 5)
     {
-      (*_bfd_error_handler)
-       (_("Dwarf Error: Unhandled .debug_line version %d."), lh.version);
+      _bfd_error_handler
+       (_("DWARF error: unhandled .debug_line version %d"), lh.version);
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
   line_ptr += 2;
 
-  if (line_ptr + offset_size + (lh.version >=4 ? 6 : 5) >= line_end)
+  if (line_ptr + offset_size + (lh.version >= 5 ? 8 : (lh.version >= 4 ? 6 : 5))
+      >= line_end)
     {
-      (*_bfd_error_handler)
-       (_("Dwarf Error: Ran out of room reading prologue"));
+      _bfd_error_handler
+       (_("DWARF error: ran out of room reading prologue"));
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
 
+  if (lh.version >= 5)
+    {
+      unsigned int segment_selector_size;
+
+      /* Skip address size.  */
+      read_1_byte (abfd, line_ptr, line_end);
+      line_ptr += 1;
+
+      segment_selector_size = read_1_byte (abfd, line_ptr, line_end);
+      line_ptr += 1;
+      if (segment_selector_size != 0)
+       {
+         _bfd_error_handler
+           (_("DWARF error: line info unsupported segment selector size %u"),
+            segment_selector_size);
+         bfd_set_error (bfd_error_bad_value);
+         return NULL;
+       }
+    }
+
   if (offset_size == 4)
     lh.prologue_length = read_4_bytes (abfd, line_ptr, line_end);
   else
@@ -1762,8 +2153,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
 
   if (lh.maximum_ops_per_insn == 0)
     {
-      (*_bfd_error_handler)
-       (_("Dwarf Error: Invalid maximum operations per instruction."));
+      _bfd_error_handler
+       (_("DWARF error: invalid maximum operations per instruction"));
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
@@ -1782,7 +2173,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
 
   if (line_ptr + (lh.opcode_base - 1) >= line_end)
     {
-      (*_bfd_error_handler) (_("Dwarf Error: Ran out of room reading opcodes"));
+      _bfd_error_handler (_("DWARF error: ran out of room reading opcodes"));
       bfd_set_error (bfd_error_bad_value);
       return NULL;
     }
@@ -1798,60 +2189,52 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
       line_ptr += 1;
     }
 
-  /* Read directory table.  */
-  while ((cur_dir = read_string (abfd, line_ptr, line_end, &bytes_read)) != NULL)
+  if (lh.version >= 5)
     {
-      line_ptr += bytes_read;
+      /* Read directory table.  */
+      if (!read_formatted_entries (unit, &line_ptr, line_end, table,
+                                  line_info_add_include_dir_stub))
+       goto fail;
 
-      if ((table->num_dirs % DIR_ALLOC_CHUNK) == 0)
+      /* Read file name table.  */
+      if (!read_formatted_entries (unit, &line_ptr, line_end, table,
+                                  line_info_add_file_name))
+       goto fail;
+    }
+  else
+    {
+      /* Read directory table.  */
+      while ((cur_dir = read_string (abfd, line_ptr, line_end, &bytes_read)) != NULL)
        {
-         char **tmp;
-
-         amt = table->num_dirs + DIR_ALLOC_CHUNK;
-         amt *= sizeof (char *);
+         line_ptr += bytes_read;
 
-         tmp = (char **) bfd_realloc (table->dirs, amt);
-         if (tmp == NULL)
+         if (!line_info_add_include_dir (table, cur_dir))
            goto fail;
-         table->dirs = tmp;
        }
 
-      table->dirs[table->num_dirs++] = cur_dir;
-    }
-
-  line_ptr += bytes_read;
-
-  /* Read file name table.  */
-  while ((cur_file = read_string (abfd, line_ptr, line_end, &bytes_read)) != NULL)
-    {
       line_ptr += bytes_read;
 
-      if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
+      /* Read file name table.  */
+      while ((cur_file = read_string (abfd, line_ptr, line_end, &bytes_read)) != NULL)
        {
-         struct fileinfo *tmp;
+         unsigned int dir, xtime, size;
 
-         amt = table->num_files + FILE_ALLOC_CHUNK;
-         amt *= sizeof (struct fileinfo);
+         line_ptr += bytes_read;
 
-         tmp = (struct fileinfo *) bfd_realloc (table->files, amt);
-         if (tmp == NULL)
+         dir = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+         line_ptr += bytes_read;
+         xtime = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+         line_ptr += bytes_read;
+         size = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+         line_ptr += bytes_read;
+
+         if (!line_info_add_file_name (table, cur_file, dir, xtime, size))
            goto fail;
-         table->files = tmp;
        }
 
-      table->files[table->num_files].name = cur_file;
-      table->files[table->num_files].dir =
-       safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
-      line_ptr += bytes_read;
-      table->files[table->num_files].time = safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
       line_ptr += bytes_read;
-      table->files[table->num_files].size = safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
-      line_ptr += bytes_read;
-      table->num_files++;
     }
 
-  line_ptr += bytes_read;
-
   /* Read the statement sequences until there's nothing left.  */
   while (line_ptr < line_end)
     {
@@ -1864,6 +2247,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
       unsigned int discriminator = 0;
       int is_stmt = lh.default_is_stmt;
       int end_sequence = 0;
+      unsigned int dir, xtime, size;
       /* eraxxon@alumni.rice.edu: Against the DWARF2 specs, some
         compilers generate address sequences that are wildly out of
         order using DW_LNE_set_address (e.g. Intel C++ 6.0 compiler
@@ -1873,7 +2257,7 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
       bfd_vma high_pc = 0;
 
       /* Decode the table.  */
-      while (! end_sequence)
+      while (!end_sequence && line_ptr < line_end)
        {
          op_code = read_1_byte (abfd, line_ptr, line_end);
          line_ptr += 1;
@@ -1909,7 +2293,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
          else switch (op_code)
            {
            case DW_LNS_extended_op:
-             exop_len = safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+             exop_len = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                               FALSE, line_end);
              line_ptr += bytes_read;
              extended_op = read_1_byte (abfd, line_ptr, line_end);
              line_ptr += 1;
@@ -1937,40 +2322,31 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
                case DW_LNE_define_file:
                  cur_file = read_string (abfd, line_ptr, line_end, &bytes_read);
                  line_ptr += bytes_read;
-                 if ((table->num_files % FILE_ALLOC_CHUNK) == 0)
-                   {
-                     struct fileinfo *tmp;
-
-                     amt = table->num_files + FILE_ALLOC_CHUNK;
-                     amt *= sizeof (struct fileinfo);
-                     tmp = (struct fileinfo *) bfd_realloc (table->files, amt);
-                     if (tmp == NULL)
-                       goto line_fail;
-                     table->files = tmp;
-                   }
-                 table->files[table->num_files].name = cur_file;
-                 table->files[table->num_files].dir =
-                   safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+                 dir = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                              FALSE, line_end);
                  line_ptr += bytes_read;
-                 table->files[table->num_files].time =
-                   safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+                 xtime = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                                FALSE, line_end);
                  line_ptr += bytes_read;
-                 table->files[table->num_files].size =
-                   safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+                 size = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                               FALSE, line_end);
                  line_ptr += bytes_read;
-                 table->num_files++;
+                 if (!line_info_add_file_name (table, cur_file, dir,
+                                               xtime, size))
+                   goto line_fail;
                  break;
                case DW_LNE_set_discriminator:
                  discriminator =
-                   safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+                   _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                          FALSE, line_end);
                  line_ptr += bytes_read;
                  break;
                case DW_LNE_HP_source_file_correlation:
                  line_ptr += exop_len - 1;
                  break;
                default:
-                 (*_bfd_error_handler)
-                   (_("Dwarf Error: mangled line number section."));
+                 _bfd_error_handler
+                   (_("DWARF error: mangled line number section"));
                  bfd_set_error (bfd_error_bad_value);
                line_fail:
                  if (filename != NULL)
@@ -1991,12 +2367,14 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
            case DW_LNS_advance_pc:
              if (lh.maximum_ops_per_insn == 1)
                address += (lh.minimum_instruction_length
-                           * safe_read_leb128 (abfd, line_ptr, &bytes_read,
-                                               FALSE, line_end));
+                           * _bfd_safe_read_leb128 (abfd, line_ptr,
+                                                    &bytes_read,
+                                                    FALSE, line_end));
              else
                {
-                 bfd_vma adjust = safe_read_leb128 (abfd, line_ptr, &bytes_read,
-                                                    FALSE, line_end);
+                 bfd_vma adjust = _bfd_safe_read_leb128 (abfd, line_ptr,
+                                                         &bytes_read,
+                                                         FALSE, line_end);
                  address = ((op_index + adjust) / lh.maximum_ops_per_insn
                             * lh.minimum_instruction_length);
                  op_index = (op_index + adjust) % lh.maximum_ops_per_insn;
@@ -2004,7 +2382,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
              line_ptr += bytes_read;
              break;
            case DW_LNS_advance_line:
-             line += safe_read_leb128 (abfd, line_ptr, &bytes_read, TRUE, line_end);
+             line += _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                            TRUE, line_end);
              line_ptr += bytes_read;
              break;
            case DW_LNS_set_file:
@@ -2013,7 +2392,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
 
                /* The file and directory tables are 0
                   based, the references are 1 based.  */
-               file = safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+               file = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                             FALSE, line_end);
                line_ptr += bytes_read;
                if (filename)
                  free (filename);
@@ -2021,7 +2401,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
                break;
              }
            case DW_LNS_set_column:
-             column = safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+             column = _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                             FALSE, line_end);
              line_ptr += bytes_read;
              break;
            case DW_LNS_negate_stmt:
@@ -2030,6 +2411,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
            case DW_LNS_set_basic_block:
              break;
            case DW_LNS_const_add_pc:
+             if (lh.line_range == 0)
+               goto line_fail;
              if (lh.maximum_ops_per_insn == 1)
                address += (lh.minimum_instruction_length
                            * ((255 - lh.opcode_base) / lh.line_range));
@@ -2051,7 +2434,8 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
              /* Unknown standard opcode, ignore it.  */
              for (i = 0; i < lh.standard_opcode_lengths[op_code]; i++)
                {
-                 (void) safe_read_leb128 (abfd, line_ptr, &bytes_read, FALSE, line_end);
+                 (void) _bfd_safe_read_leb128 (abfd, line_ptr, &bytes_read,
+                                               FALSE, line_end);
                  line_ptr += bytes_read;
                }
              break;
@@ -2066,8 +2450,12 @@ decode_line_info (struct comp_unit *unit, struct dwarf2_debug *stash)
     return table;
 
  fail:
-  if (table->sequences != NULL)
-    free (table->sequences);
+  while (table->sequences != NULL)
+    {
+      struct line_sequence* seq = table->sequences;
+      table->sequences = table->sequences->prev_sequence;
+      free (seq);
+    }
   if (table->files != NULL)
     free (table->files);
   if (table->dirs != NULL)
@@ -2089,7 +2477,7 @@ lookup_address_in_line_info_table (struct line_info_table *table,
                                   unsigned int *discriminator_ptr)
 {
   struct line_sequence *seq = NULL;
-  struct line_info *each_line;
+  struct line_info *info;
   int low, high, mid;
 
   /* Binary search the array of sequences.  */
@@ -2107,26 +2495,43 @@ lookup_address_in_line_info_table (struct line_info_table *table,
        break;
     }
 
-  if (seq && addr >= seq->low_pc && addr < seq->last_line->address)
+  /* Check for a valid sequence.  */
+  if (!seq || addr < seq->low_pc || addr >= seq->last_line->address)
+    goto fail;
+
+  if (!build_line_info_table (table, seq))
+    goto fail;
+
+  /* Binary search the array of line information.  */
+  low = 0;
+  high = seq->num_lines;
+  info = NULL;
+  while (low < high)
     {
-      /* Note: seq->last_line should be a descendingly sorted list.  */
-      for (each_line = seq->last_line;
-          each_line;
-          each_line = each_line->prev_line)
-       if (addr >= each_line->address)
-         break;
+      mid = (low + high) / 2;
+      info = seq->line_info_lookup[mid];
+      if (addr < info->address)
+       high = mid;
+      else if (addr >= seq->line_info_lookup[mid + 1]->address)
+       low = mid + 1;
+      else
+       break;
+    }
 
-      if (each_line
-         && !(each_line->end_sequence || each_line == seq->last_line))
-       {
-         *filename_ptr = each_line->filename;
-         *linenumber_ptr = each_line->line;
-         if (discriminator_ptr)
-           *discriminator_ptr = each_line->discriminator;
-         return seq->last_line->address - seq->low_pc;
-       }
+  /* Check for a valid line information entry.  */
+  if (info
+      && addr >= info->address
+      && addr < seq->line_info_lookup[mid + 1]->address
+      && !(info->end_sequence || info == seq->last_line))
+    {
+      *filename_ptr = info->filename;
+      *linenumber_ptr = info->line;
+      if (discriminator_ptr)
+       *discriminator_ptr = info->discriminator;
+      return seq->last_line->address - seq->low_pc;
     }
 
+fail:
   *filename_ptr = NULL;
   return 0;
 }
@@ -2134,16 +2539,102 @@ lookup_address_in_line_info_table (struct line_info_table *table,
 /* Read in the .debug_ranges section for future reference.  */
 
 static bfd_boolean
-read_debug_ranges (struct comp_unit *unit)
+read_debug_ranges (struct comp_unit * unit)
 {
-  struct dwarf2_debug *stash = unit->stash;
+  struct dwarf2_debug * stash = unit->stash;
+
   return read_section (unit->abfd, &stash->debug_sections[debug_ranges],
                       stash->syms, 0,
-                      &stash->dwarf_ranges_buffer, &stash->dwarf_ranges_size);
+                      &stash->dwarf_ranges_buffer,
+                      &stash->dwarf_ranges_size);
 }
 
 /* Function table functions.  */
 
+static int
+compare_lookup_funcinfos (const void * a, const void * b)
+{
+  const struct lookup_funcinfo * lookup1 = a;
+  const struct lookup_funcinfo * lookup2 = b;
+
+  if (lookup1->low_addr < lookup2->low_addr)
+    return -1;
+  if (lookup1->low_addr > lookup2->low_addr)
+    return 1;
+  if (lookup1->high_addr < lookup2->high_addr)
+    return -1;
+  if (lookup1->high_addr > lookup2->high_addr)
+    return 1;
+
+  return 0;
+}
+
+static bfd_boolean
+build_lookup_funcinfo_table (struct comp_unit * unit)
+{
+  struct lookup_funcinfo *lookup_funcinfo_table = unit->lookup_funcinfo_table;
+  unsigned int number_of_functions = unit->number_of_functions;
+  struct funcinfo *each;
+  struct lookup_funcinfo *entry;
+  size_t func_index;
+  struct arange *range;
+  bfd_vma low_addr, high_addr;
+
+  if (lookup_funcinfo_table || number_of_functions == 0)
+    return TRUE;
+
+  /* Create the function info lookup table.  */
+  lookup_funcinfo_table = (struct lookup_funcinfo *)
+    bfd_malloc (number_of_functions * sizeof (struct lookup_funcinfo));
+  if (lookup_funcinfo_table == NULL)
+    return FALSE;
+
+  /* Populate the function info lookup table.  */
+  func_index = number_of_functions;
+  for (each = unit->function_table; each; each = each->prev_func)
+    {
+      entry = &lookup_funcinfo_table[--func_index];
+      entry->funcinfo = each;
+
+      /* Calculate the lowest and highest address for this function entry.  */
+      low_addr  = entry->funcinfo->arange.low;
+      high_addr = entry->funcinfo->arange.high;
+
+      for (range = entry->funcinfo->arange.next; range; range = range->next)
+       {
+         if (range->low < low_addr)
+           low_addr = range->low;
+         if (range->high > high_addr)
+           high_addr = range->high;
+       }
+
+      entry->low_addr = low_addr;
+      entry->high_addr = high_addr;
+    }
+
+  BFD_ASSERT (func_index == 0);
+
+  /* Sort the function by address.  */
+  qsort (lookup_funcinfo_table,
+        number_of_functions,
+        sizeof (struct lookup_funcinfo),
+        compare_lookup_funcinfos);
+
+  /* Calculate the high watermark for each function in the lookup table.  */
+  high_addr = lookup_funcinfo_table[0].high_addr;
+  for (func_index = 1; func_index < number_of_functions; func_index++)
+    {
+      entry = &lookup_funcinfo_table[func_index];
+      if (entry->high_addr > high_addr)
+       high_addr = entry->high_addr;
+      else
+       entry->high_addr = high_addr;
+    }
+
+  unit->lookup_funcinfo_table = lookup_funcinfo_table;
+  return TRUE;
+}
+
 /* If ADDR is within UNIT's function tables, set FUNCTION_PTR, and return
    TRUE.  Note that we need to find the function that has the smallest range
    that contains ADDR, to handle inlined functions without depending upon
@@ -2154,37 +2645,77 @@ lookup_address_in_function_table (struct comp_unit *unit,
                                  bfd_vma addr,
                                  struct funcinfo **function_ptr)
 {
-  struct funcinfo* each_func;
+  unsigned int number_of_functions = unit->number_of_functions;
+  struct lookup_funcinfo* lookup_funcinfo = NULL;
+  struct funcinfo* funcinfo = NULL;
   struct funcinfo* best_fit = NULL;
   bfd_vma best_fit_len = 0;
+  bfd_size_type low, high, mid, first;
   struct arange *arange;
 
-  for (each_func = unit->function_table;
-       each_func;
-       each_func = each_func->prev_func)
+  if (number_of_functions == 0)
+    return FALSE;
+
+  if (!build_lookup_funcinfo_table (unit))
+    return FALSE;
+
+  if (unit->lookup_funcinfo_table[number_of_functions - 1].high_addr < addr)
+    return FALSE;
+
+  /* Find the first function in the lookup table which may contain the
+     specified address.  */
+  low = 0;
+  high = number_of_functions;
+  first = high;
+  while (low < high)
     {
-      for (arange = &each_func->arange;
-          arange;
-          arange = arange->next)
+      mid = (low + high) / 2;
+      lookup_funcinfo = &unit->lookup_funcinfo_table[mid];
+      if (addr < lookup_funcinfo->low_addr)
+       high = mid;
+      else if (addr >= lookup_funcinfo->high_addr)
+       low = mid + 1;
+      else
+       high = first = mid;
+    }
+
+  /* Find the 'best' match for the address.  The prior algorithm defined the
+     best match as the function with the smallest address range containing
+     the specified address.  This definition should probably be changed to the
+     innermost inline routine containing the address, but right now we want
+     to get the same results we did before.  */
+  while (first < number_of_functions)
+    {
+      if (addr < unit->lookup_funcinfo_table[first].low_addr)
+       break;
+      funcinfo = unit->lookup_funcinfo_table[first].funcinfo;
+
+      for (arange = &funcinfo->arange; arange; arange = arange->next)
        {
-         if (addr >= arange->low && addr < arange->high)
+         if (addr < arange->low || addr >= arange->high)
+           continue;
+
+         if (!best_fit
+             || arange->high - arange->low < best_fit_len
+             /* The following comparison is designed to return the same
+                match as the previous algorithm for routines which have the
+                same best fit length.  */
+             || (arange->high - arange->low == best_fit_len
+                 && funcinfo > best_fit))
            {
-             if (!best_fit
-                 || arange->high - arange->low < best_fit_len)
-               {
-                 best_fit = each_func;
-                 best_fit_len = arange->high - arange->low;
-               }
+             best_fit = funcinfo;
+             best_fit_len = arange->high - arange->low;
            }
        }
-    }
 
-  if (best_fit)
-    {
-      *function_ptr = best_fit;
-      return TRUE;
+      first++;
     }
-  return FALSE;
+
+  if (!best_fit)
+    return FALSE;
+
+  *function_ptr = best_fit;
+  return TRUE;
 }
 
 /* If SYM at ADDR is within function table of UNIT, set FILENAME_PTR
@@ -2269,14 +2800,18 @@ lookup_symbol_in_variable_table (struct comp_unit *unit,
       *linenumber_ptr = each->line;
       return TRUE;
     }
-  else
-    return FALSE;
+
+  return FALSE;
 }
 
-static char *
-find_abstract_instance_name (struct comp_unit *unit,
-                            struct attribute *attr_ptr,
-                            bfd_boolean *is_linkage)
+static bfd_boolean
+find_abstract_instance (struct comp_unit *   unit,
+                       bfd_byte *           orig_info_ptr,
+                       struct attribute *   attr_ptr,
+                       const char **        pname,
+                       bfd_boolean *        is_linkage,
+                       char **              filename_ptr,
+                       int *                linenumber_ptr)
 {
   bfd *abfd = unit->abfd;
   bfd_byte *info_ptr;
@@ -2285,23 +2820,46 @@ find_abstract_instance_name (struct comp_unit *unit,
   struct abbrev_info *abbrev;
   bfd_uint64_t die_ref = attr_ptr->u.val;
   struct attribute attr;
-  char *name = NULL;
+  const char *name = NULL;
 
   /* DW_FORM_ref_addr can reference an entry in a different CU. It
      is an offset from the .debug_info section, not the current CU.  */
   if (attr_ptr->form == DW_FORM_ref_addr)
     {
       /* We only support DW_FORM_ref_addr within the same file, so
-        any relocations should be resolved already.  */
+        any relocations should be resolved already.  Check this by
+        testing for a zero die_ref;  There can't be a valid reference
+        to the header of a .debug_info section.
+        DW_FORM_ref_addr is an offset relative to .debug_info.
+        Normally when using the GNU linker this is accomplished by
+        emitting a symbolic reference to a label, because .debug_info
+        sections are linked at zero.  When there are multiple section
+        groups containing .debug_info, as there might be in a
+        relocatable object file, it would be reasonable to assume that
+        a symbolic reference to a label in any .debug_info section
+        might be used.  Since we lay out multiple .debug_info
+        sections at non-zero VMAs (see place_sections), and read
+        them contiguously into stash->info_ptr_memory, that means
+        the reference is relative to stash->info_ptr_memory.  */
+      size_t total;
+
+      info_ptr = unit->stash->info_ptr_memory;
+      info_ptr_end = unit->stash->info_ptr_end;
+      total = info_ptr_end - info_ptr;
       if (!die_ref)
-       abort ();
-
-      info_ptr = unit->sec_info_ptr + die_ref;
-      info_ptr_end = unit->end_ptr;
+       return TRUE;
+      else if (die_ref >= total)
+       {
+         _bfd_error_handler
+           (_("DWARF error: invalid abstract instance DIE ref"));
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+      info_ptr += die_ref;
 
       /* Now find the CU containing this pointer.  */
       if (info_ptr >= unit->info_ptr_unit && info_ptr < unit->end_ptr)
-       ;
+       info_ptr_end = unit->end_ptr;
       else
        {
          /* Check other CUs to see if they contain the abbrev.  */
@@ -2317,7 +2875,10 @@ find_abstract_instance_name (struct comp_unit *unit,
                break;
 
          if (u)
-           unit = u;
+           {
+             unit = u;
+             info_ptr_end = unit->end_ptr;
+           }
          /* else FIXME: What do we do now ?  */
        }
     }
@@ -2326,23 +2887,40 @@ find_abstract_instance_name (struct comp_unit *unit,
       info_ptr = read_alt_indirect_ref (unit, die_ref);
       if (info_ptr == NULL)
        {
-         (*_bfd_error_handler)
-           (_("Dwarf Error: Unable to read alt ref %u."), die_ref);
+         _bfd_error_handler
+           (_("DWARF error: unable to read alt ref %" PRIu64),
+            (uint64_t) die_ref);
          bfd_set_error (bfd_error_bad_value);
-         return NULL;
+         return FALSE;
        }
-      info_ptr_end = unit->stash->alt_dwarf_info_buffer + unit->stash->alt_dwarf_info_size;
+      info_ptr_end = (unit->stash->alt_dwarf_info_buffer
+                     + unit->stash->alt_dwarf_info_size);
 
       /* FIXME: Do we need to locate the correct CU, in a similar
         fashion to the code in the DW_FORM_ref_addr case above ?  */
     }
   else
     {
-      info_ptr = unit->info_ptr_unit + die_ref;
+      /* DW_FORM_ref1, DW_FORM_ref2, DW_FORM_ref4, DW_FORM_ref8 or
+        DW_FORM_ref_udata.  These are all references relative to the
+        start of the current CU.  */
+      size_t total;
+
+      info_ptr = unit->info_ptr_unit;
       info_ptr_end = unit->end_ptr;
+      total = info_ptr_end - info_ptr;
+      if (!die_ref || die_ref >= total)
+       {
+         _bfd_error_handler
+           (_("DWARF error: invalid abstract instance DIE ref"));
+         bfd_set_error (bfd_error_bad_value);
+         return FALSE;
+       }
+      info_ptr += die_ref;
     }
 
-  abbrev_number = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, info_ptr_end);
+  abbrev_number = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                        FALSE, info_ptr_end);
   info_ptr += bytes_read;
 
   if (abbrev_number)
@@ -2350,9 +2928,10 @@ find_abstract_instance_name (struct comp_unit *unit,
       abbrev = lookup_abbrev (abbrev_number, unit->abbrevs);
       if (! abbrev)
        {
-         (*_bfd_error_handler)
-           (_("Dwarf Error: Could not find abbrev number %u."), abbrev_number);
+         _bfd_error_handler
+           (_("DWARF error: could not find abbrev number %u"), abbrev_number);
          bfd_set_error (bfd_error_bad_value);
+         return FALSE;
        }
       else
        {
@@ -2362,6 +2941,15 @@ find_abstract_instance_name (struct comp_unit *unit,
                                         info_ptr, info_ptr_end);
              if (info_ptr == NULL)
                break;
+             /* It doesn't ever make sense for DW_AT_specification to
+                refer to the same DIE.  Stop simple recursion.  */
+             if (info_ptr == orig_info_ptr)
+               {
+                 _bfd_error_handler
+                   (_("DWARF error: abstract instance recursion detected"));
+                 bfd_set_error (bfd_error_bad_value);
+                 return FALSE;
+               }
              switch (attr.name)
                {
                case DW_AT_name:
@@ -2375,7 +2963,10 @@ find_abstract_instance_name (struct comp_unit *unit,
                    }
                  break;
                case DW_AT_specification:
-                 name = find_abstract_instance_name (unit, &attr, is_linkage);
+                 if (!find_abstract_instance (unit, info_ptr, &attr,
+                                              &name, is_linkage,
+                                              filename_ptr, linenumber_ptr))
+                   return FALSE;
                  break;
                case DW_AT_linkage_name:
                case DW_AT_MIPS_linkage_name:
@@ -2387,13 +2978,21 @@ find_abstract_instance_name (struct comp_unit *unit,
                      *is_linkage = TRUE;
                    }
                  break;
+               case DW_AT_decl_file:
+                 *filename_ptr = concat_filename (unit->line_table,
+                                                  attr.u.val);
+                 break;
+               case DW_AT_decl_line:
+                 *linenumber_ptr = attr.u.val;
+                 break;
                default:
                  break;
                }
            }
        }
     }
-  return name;
+  *pname = name;
+  return TRUE;
 }
 
 static bfd_boolean
@@ -2454,20 +3053,22 @@ scan_unit_for_symbols (struct comp_unit *unit)
   bfd *abfd = unit->abfd;
   bfd_byte *info_ptr = unit->first_child_die_ptr;
   bfd_byte *info_ptr_end = unit->stash->info_ptr_end;
-  int nesting_level = 1;
-  struct funcinfo **nested_funcs;
+  int nesting_level = 0;
+  struct nest_funcinfo {
+    struct funcinfo *func;
+  } *nested_funcs;
   int nested_funcs_size;
 
   /* Maintain a stack of in-scope functions and inlined functions, which we
      can use to set the caller_func field.  */
   nested_funcs_size = 32;
-  nested_funcs = (struct funcinfo **)
-    bfd_malloc (nested_funcs_size * sizeof (struct funcinfo *));
+  nested_funcs = (struct nest_funcinfo *)
+    bfd_malloc (nested_funcs_size * sizeof (*nested_funcs));
   if (nested_funcs == NULL)
     return FALSE;
-  nested_funcs[nesting_level] = 0;
+  nested_funcs[nesting_level].func = 0;
 
-  while (nesting_level)
+  while (nesting_level >= 0)
     {
       unsigned int abbrev_number, bytes_read, i;
       struct abbrev_info *abbrev;
@@ -2482,7 +3083,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
       if (info_ptr >= info_ptr_end)
        goto fail;
 
-      abbrev_number = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, info_ptr_end);
+      abbrev_number = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                            FALSE, info_ptr_end);
       info_ptr += bytes_read;
 
       if (! abbrev_number)
@@ -2491,12 +3093,19 @@ scan_unit_for_symbols (struct comp_unit *unit)
          continue;
        }
 
-      abbrev = lookup_abbrev (abbrev_number,unit->abbrevs);
+      abbrev = lookup_abbrev (abbrev_number, unit->abbrevs);
       if (! abbrev)
        {
-         (*_bfd_error_handler)
-           (_("Dwarf Error: Could not find abbrev number %u."),
-            abbrev_number);
+         static unsigned int previous_failed_abbrev = -1U;
+
+         /* Avoid multiple reports of the same missing abbrev.  */
+         if (abbrev_number != previous_failed_abbrev)
+           {
+             _bfd_error_handler
+               (_("DWARF error: could not find abbrev number %u"),
+                abbrev_number);
+             previous_failed_abbrev = abbrev_number;
+           }
          bfd_set_error (bfd_error_bad_value);
          goto fail;
        }
@@ -2513,16 +3122,17 @@ scan_unit_for_symbols (struct comp_unit *unit)
          func->tag = abbrev->tag;
          func->prev_func = unit->function_table;
          unit->function_table = func;
+         unit->number_of_functions++;
          BFD_ASSERT (!unit->cached);
 
          if (func->tag == DW_TAG_inlined_subroutine)
-           for (i = nesting_level - 1; i >= 1; i--)
-             if (nested_funcs[i])
+           for (i = nesting_level; i-- != 0; )
+             if (nested_funcs[i].func)
                {
-                 func->caller_func = nested_funcs[i];
+                 func->caller_func = nested_funcs[i].func;
                  break;
                }
-         nested_funcs[nesting_level] = func;
+         nested_funcs[nesting_level].func = func;
        }
       else
        {
@@ -2537,16 +3147,18 @@ scan_unit_for_symbols (struct comp_unit *unit)
              var->stack = 1;
              var->prev_var = unit->variable_table;
              unit->variable_table = var;
-             BFD_ASSERT (!unit->cached);
+             /* PR 18205: Missing debug information can cause this
+                var to be attached to an already cached unit.  */
            }
 
          /* No inline function in scope at this nesting level.  */
-         nested_funcs[nesting_level] = 0;
+         nested_funcs[nesting_level].func = 0;
        }
 
       for (i = 0; i < abbrev->num_attrs; ++i)
        {
-         info_ptr = read_attribute (&attr, &abbrev->attrs[i], unit, info_ptr, info_ptr_end);
+         info_ptr = read_attribute (&attr, &abbrev->attrs[i],
+                                    unit, info_ptr, info_ptr_end);
          if (info_ptr == NULL)
            goto fail;
 
@@ -2565,8 +3177,12 @@ scan_unit_for_symbols (struct comp_unit *unit)
 
                case DW_AT_abstract_origin:
                case DW_AT_specification:
-                 func->name = find_abstract_instance_name (unit, &attr,
-                                                           &func->is_linkage);
+                 if (!find_abstract_instance (unit, info_ptr, &attr,
+                                              &func->name,
+                                              &func->is_linkage,
+                                              &func->file,
+                                              &func->line))
+                   goto fail;
                  break;
 
                case DW_AT_name:
@@ -2623,7 +3239,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
              switch (attr.name)
                {
                case DW_AT_name:
-                 var->name = attr.u.str;
+                 if (is_str_attr (attr.form))
+                   var->name = attr.u.str;
                  break;
 
                case DW_AT_decl_file:
@@ -2648,7 +3265,8 @@ scan_unit_for_symbols (struct comp_unit *unit)
                    case DW_FORM_block2:
                    case DW_FORM_block4:
                    case DW_FORM_exprloc:
-                     if (*attr.u.blk->data == DW_OP_addr)
+                     if (attr.u.blk->data != NULL
+                         && *attr.u.blk->data == DW_OP_addr)
                        {
                          var->stack = 0;
 
@@ -2691,17 +3309,17 @@ scan_unit_for_symbols (struct comp_unit *unit)
 
          if (nesting_level >= nested_funcs_size)
            {
-             struct funcinfo **tmp;
+             struct nest_funcinfo *tmp;
 
              nested_funcs_size *= 2;
-             tmp = (struct funcinfo **)
+             tmp = (struct nest_funcinfo *)
                bfd_realloc (nested_funcs,
-                            nested_funcs_size * sizeof (struct funcinfo *));
+                            nested_funcs_size * sizeof (*nested_funcs));
              if (tmp == NULL)
                goto fail;
              nested_funcs = tmp;
            }
-         nested_funcs[nesting_level] = 0;
+         nested_funcs[nesting_level].func = 0;
        }
     }
 
@@ -2731,7 +3349,8 @@ parse_comp_unit (struct dwarf2_debug *stash,
   struct comp_unit* unit;
   unsigned int version;
   bfd_uint64_t abbrev_offset = 0;
-  unsigned int addr_size;
+  /* Initialize it just to avoid a GCC false warning.  */
+  unsigned int addr_size = -1;
   struct abbrev_info** abbrevs;
   unsigned int abbrev_number, bytes_read, i;
   struct abbrev_info *abbrev;
@@ -2743,69 +3362,104 @@ parse_comp_unit (struct dwarf2_debug *stash,
   bfd_vma high_pc = 0;
   bfd *abfd = stash->bfd_ptr;
   bfd_boolean high_pc_relative = FALSE;
+  enum dwarf_unit_type unit_type;
 
   version = read_2_bytes (abfd, info_ptr, end_ptr);
   info_ptr += 2;
+  if (version < 2 || version > 5)
+    {
+      /* PR 19872: A version number of 0 probably means that there is padding
+        at the end of the .debug_info section.  Gold puts it there when
+        performing an incremental link, for example.  So do not generate
+        an error, just return a NULL.  */
+      if (version)
+       {
+         _bfd_error_handler
+           (_("DWARF error: found dwarf version '%u', this reader"
+              " only handles version 2, 3, 4 and 5 information"), version);
+         bfd_set_error (bfd_error_bad_value);
+       }
+      return NULL;
+    }
+
+  if (version < 5)
+    unit_type = DW_UT_compile;
+  else
+    {
+      unit_type = read_1_byte (abfd, info_ptr, end_ptr);
+      info_ptr += 1;
+
+      addr_size = read_1_byte (abfd, info_ptr, end_ptr);
+      info_ptr += 1;
+    }
+
   BFD_ASSERT (offset_size == 4 || offset_size == 8);
   if (offset_size == 4)
     abbrev_offset = read_4_bytes (abfd, info_ptr, end_ptr);
   else
     abbrev_offset = read_8_bytes (abfd, info_ptr, end_ptr);
   info_ptr += offset_size;
-  addr_size = read_1_byte (abfd, info_ptr, end_ptr);
-  info_ptr += 1;
 
-  if (version != 2 && version != 3 && version != 4)
+  if (version < 5)
     {
-      (*_bfd_error_handler)
-       (_("Dwarf Error: found dwarf version '%u', this reader"
-          " only handles version 2, 3 and 4 information."), version);
-      bfd_set_error (bfd_error_bad_value);
-      return 0;
+      addr_size = read_1_byte (abfd, info_ptr, end_ptr);
+      info_ptr += 1;
+    }
+
+  if (unit_type == DW_UT_type)
+    {
+      /* Skip type signature.  */
+      info_ptr += 8;
+
+      /* Skip type offset.  */
+      info_ptr += offset_size;
     }
 
   if (addr_size > sizeof (bfd_vma))
     {
-      (*_bfd_error_handler)
-       (_("Dwarf Error: found address size '%u', this reader"
-          " can not handle sizes greater than '%u'."),
+      _bfd_error_handler
+       /* xgettext: c-format */
+       (_("DWARF error: found address size '%u', this reader"
+          " can not handle sizes greater than '%u'"),
         addr_size,
         (unsigned int) sizeof (bfd_vma));
       bfd_set_error (bfd_error_bad_value);
-      return 0;
+      return NULL;
     }
 
   if (addr_size != 2 && addr_size != 4 && addr_size != 8)
     {
-      (*_bfd_error_handler)
-       ("Dwarf Error: found address size '%u', this reader"
-        " can only handle address sizes '2', '4' and '8'.", addr_size);
+      _bfd_error_handler
+       ("DWARF error: found address size '%u', this reader"
+        " can only handle address sizes '2', '4' and '8'", addr_size);
       bfd_set_error (bfd_error_bad_value);
-      return 0;
+      return NULL;
     }
 
   /* Read the abbrevs for this compilation unit into a table.  */
   abbrevs = read_abbrevs (abfd, abbrev_offset, stash);
   if (! abbrevs)
-    return 0;
+    return NULL;
 
-  abbrev_number = safe_read_leb128 (abfd, info_ptr, &bytes_read, FALSE, end_ptr);
+  abbrev_number = _bfd_safe_read_leb128 (abfd, info_ptr, &bytes_read,
+                                        FALSE, end_ptr);
   info_ptr += bytes_read;
   if (! abbrev_number)
     {
-      (*_bfd_error_handler) (_("Dwarf Error: Bad abbrev number: %u."),
-                            abbrev_number);
-      bfd_set_error (bfd_error_bad_value);
-      return 0;
+      /* PR 19872: An abbrev number of 0 probably means that there is padding
+        at the end of the .debug_abbrev section.  Gold puts it there when
+        performing an incremental link, for example.  So do not generate
+        an error, just return a NULL.  */
+      return NULL;
     }
 
   abbrev = lookup_abbrev (abbrev_number, abbrevs);
   if (! abbrev)
     {
-      (*_bfd_error_handler) (_("Dwarf Error: Could not find abbrev number %u."),
-                            abbrev_number);
+      _bfd_error_handler (_("DWARF error: could not find abbrev number %u"),
+                         abbrev_number);
       bfd_set_error (bfd_error_bad_value);
-      return 0;
+      return NULL;
     }
 
   amt = sizeof (struct comp_unit);
@@ -2820,7 +3474,6 @@ parse_comp_unit (struct dwarf2_debug *stash,
   unit->end_ptr = end_ptr;
   unit->stash = stash;
   unit->info_ptr_unit = info_ptr_unit;
-  unit->sec_info_ptr = stash->sec_info_ptr;
 
   for (i = 0; i < abbrev->num_attrs; ++i)
     {
@@ -2838,14 +3491,15 @@ parse_comp_unit (struct dwarf2_debug *stash,
          break;
 
        case DW_AT_name:
-         unit->name = attr.u.str;
+         if (is_str_attr (attr.form))
+           unit->name = attr.u.str;
          break;
 
        case DW_AT_low_pc:
          low_pc = attr.u.val;
          /* If the compilation unit DIE has a DW_AT_low_pc attribute,
             this is the base address to use when reading location
-            lists or range lists. */
+            lists or range lists.  */
          if (abbrev->tag == DW_TAG_compile_unit)
            unit->base_address = low_pc;
          break;
@@ -2867,8 +3521,8 @@ parse_comp_unit (struct dwarf2_debug *stash,
            /* PR 17512: file: 1fe726be.  */
            if (! is_str_attr (attr.form))
              {
-               (*_bfd_error_handler)
-                 (_("Dwarf Error: DW_AT_comp_dir attribute encountered with a non-string form."));
+               _bfd_error_handler
+                 (_("DWARF error: DW_AT_comp_dir attribute encountered with a non-string form"));
                comp_dir = NULL;
              }
 
@@ -3116,7 +3770,7 @@ comp_unit_hash_info (struct dwarf2_debug *stash,
        each_func && okay;
        each_func = each_func->prev_func)
     {
-      /* Skip nameless functions. */
+      /* Skip nameless functions.  */
       if (each_func->name)
        /* There is no need to copy name string into hash table as
           name string is either in the dwarf string buffer or
@@ -3354,8 +4008,8 @@ place_sections (bfd *orig_bfd, struct dwarf2_debug *stash)
                  /* Align the new address to the current section
                     alignment.  */
                  last_vma = ((last_vma
-                              + ~((bfd_vma) -1 << sect->alignment_power))
-                             & ((bfd_vma) -1 << sect->alignment_power));
+                              + ~(-((bfd_vma) 1 << sect->alignment_power)))
+                             & (-((bfd_vma) 1 << sect->alignment_power)));
                  sect->vma = last_vma;
                  last_vma += sz;
                }
@@ -3498,7 +4152,7 @@ stash_maybe_update_info_hash_tables (struct dwarf2_debug *stash)
   return TRUE;
 }
 
-/* Check consistency of info hash tables.  This is for debugging only. */
+/* Check consistency of info hash tables.  This is for debugging only.  */
 
 static void ATTRIBUTE_UNUSED
 stash_verify_info_hash_table (struct dwarf2_debug *stash)
@@ -3617,7 +4271,10 @@ save_section_vma (const bfd *abfd, struct dwarf2_debug *stash)
   stash->sec_vma = bfd_malloc (sizeof (*stash->sec_vma) * abfd->section_count);
   if (stash->sec_vma == NULL)
     return FALSE;
-  for (i = 0, s = abfd->sections; i < abfd->section_count; i++, s = s->next)
+  stash->sec_vma_count = abfd->section_count;
+  for (i = 0, s = abfd->sections;
+       s != NULL && i < abfd->section_count;
+       i++, s = s->next)
     {
       if (s->output_section != NULL)
        stash->sec_vma[i] = s->output_section->vma + s->output_offset;
@@ -3640,7 +4297,15 @@ section_vma_same (const bfd *abfd, const struct dwarf2_debug *stash)
   asection *s;
   unsigned int i;
 
-  for (i = 0, s = abfd->sections; i < abfd->section_count; i++, s = s->next)
+  /* PR 24334: If the number of sections in ABFD has changed between
+     when the stash was created and now, then we cannot trust the
+     stashed vma information.  */
+  if (abfd->section_count != stash->sec_vma_count)
+    return FALSE;
+
+  for (i = 0, s = abfd->sections;
+       s != NULL && i < abfd->section_count;
+       i++, s = s->next)
     {
       bfd_vma vma;
 
@@ -3673,8 +4338,20 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
 
   if (stash != NULL)
     {
-      if (section_vma_same (abfd, stash))
-       return TRUE;
+      if (stash->orig_bfd == abfd
+         && section_vma_same (abfd, stash))
+       {
+         /* Check that we did previously find some debug information
+            before attempting to make use of it.  */
+         if (stash->bfd_ptr != NULL)
+           {
+             if (do_place && !place_sections (abfd, stash))
+               return FALSE;
+             return TRUE;
+           }
+
+         return FALSE;
+       }
       _bfd_dwarf2_cleanup_debug_info (abfd, pinfo);
       memset (stash, 0, amt);
     }
@@ -3684,6 +4361,7 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
       if (! stash)
        return FALSE;
     }
+  stash->orig_bfd = abfd;
   stash->debug_sections = debug_sections;
   stash->syms = symbols;
   if (!save_section_vma (abfd, stash))
@@ -3697,7 +4375,11 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
   msec = find_debug_info (debug_bfd, debug_sections, NULL);
   if (msec == NULL && abfd == debug_bfd)
     {
-      char * debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
+      char * debug_filename;
+
+      debug_filename = bfd_follow_build_id_debuglink (abfd, DEBUGDIR);
+      if (debug_filename == NULL)
+       debug_filename = bfd_follow_gnu_debuglink (abfd, DEBUGDIR);
 
       if (debug_filename == NULL)
        /* No dwarf2 info, and no gnu_debuglink to follow.
@@ -3706,8 +4388,10 @@ _bfd_dwarf2_slurp_debug_info (bfd *abfd, bfd *debug_bfd,
           fail more quickly.  */
        return FALSE;
 
+      /* Set BFD_DECOMPRESS to decompress debug sections.  */
       if ((debug_bfd = bfd_openr (debug_filename, NULL)) == NULL
-         || ! bfd_check_format (debug_bfd, bfd_object)
+         || !(debug_bfd->flags |= BFD_DECOMPRESS,
+              bfd_check_format (debug_bfd, bfd_object))
          || (msec = find_debug_info (debug_bfd,
                                      debug_sections, NULL)) == NULL
          || !bfd_generic_link_read_symbols (debug_bfd))
@@ -3801,7 +4485,7 @@ _bfd_dwarf2_find_symbol_bias (asymbol ** symbols, void ** pinfo)
 
   stash = (struct dwarf2_debug *) *pinfo;
 
-  if (stash == NULL)
+  if (stash == NULL || symbols == NULL)
     return 0;
 
   for (unit = stash->all_comp_units; unit; unit = unit->next_unit)
@@ -3906,6 +4590,38 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
     {
       BFD_ASSERT (section != NULL && functionname_ptr != NULL);
       addr = offset;
+
+      /* If we have no SYMBOL but the section we're looking at is not a
+        code section, then take a look through the list of symbols to see
+        if we have a symbol at the address we're looking for.  If we do
+        then use this to look up line information.  This will allow us to
+        give file and line results for data symbols.  We exclude code
+        symbols here, if we look up a function symbol and then look up the
+        line information we'll actually return the line number for the
+        opening '{' rather than the function definition line.  This is
+        because looking up by symbol uses the line table, in which the
+        first line for a function is usually the opening '{', while
+        looking up the function by section + offset uses the
+        DW_AT_decl_line from the function DW_TAG_subprogram for the line,
+        which will be the line of the function name.  */
+      if (symbols != NULL && (section->flags & SEC_CODE) == 0)
+       {
+         asymbol **tmp;
+
+         for (tmp = symbols; (*tmp) != NULL; ++tmp)
+           if ((*tmp)->the_bfd == abfd
+               && (*tmp)->section == section
+               && (*tmp)->value == offset
+               && ((*tmp)->flags & BSF_SECTION_SYM) == 0)
+             {
+               symbol = *tmp;
+               do_line = TRUE;
+               /* For local symbols, keep going in the hope we find a
+                  global.  */
+               if ((symbol->flags & BSF_GLOBAL) != 0)
+                 break;
+             }
+       }
     }
 
   if (section->output_section)
@@ -3930,7 +4646,7 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
        stash_maybe_enable_info_hash_tables (abfd, stash);
 
       /* Keep info hash table up to date if they are available.  Note that we
-        may disable the hash tables if there is any error duing update. */
+        may disable the hash tables if there is any error duing update.  */
       if (stash->info_hash_status == STASH_INFO_HASH_ON)
        stash_maybe_update_info_hash_tables (stash);
 
@@ -4064,6 +4780,10 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
        {
          bfd_byte * new_ptr;
 
+         /* PR 21151  */
+         if (stash->info_ptr + length > stash->info_ptr_end)
+           return FALSE;
+
          each = parse_comp_unit (stash, length, info_ptr_unit,
                                  offset_size);
          if (!each)
@@ -4129,16 +4849,25 @@ _bfd_dwarf2_find_nearest_line (bfd *abfd,
  done:
   if (function)
     {
-      if (!function->is_linkage
-         && _bfd_elf_find_function (abfd, symbols, section, offset,
-                                    *filename_ptr ? NULL : filename_ptr,
-                                    functionname_ptr))
+      if (!function->is_linkage)
        {
-         function->name = *functionname_ptr;
+         asymbol *fun;
+         bfd_vma sec_vma;
+
+         fun = _bfd_elf_find_function (abfd, symbols, section, offset,
+                                       *filename_ptr ? NULL : filename_ptr,
+                                       functionname_ptr);
+         sec_vma = section->vma;
+         if (section->output_section != NULL)
+           sec_vma = section->output_section->vma + section->output_offset;
+         if (fun != NULL
+             && fun->value + sec_vma == function->arange.low)
+           function->name = *functionname_ptr;
+         /* Even if we didn't find a linkage name, say that we have
+            to stop a repeated search of symbols.  */
          function->is_linkage = TRUE;
        }
-      else
-       *functionname_ptr = function->name;
+      *functionname_ptr = function->name;
     }
   if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
     unset_sections (stash);
@@ -4222,6 +4951,12 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
          function_table = function_table->prev_func;
        }
 
+      if (each->lookup_funcinfo_table)
+       {
+         free (each->lookup_funcinfo_table);
+         each->lookup_funcinfo_table = NULL;
+       }
+
       while (variable_table)
        {
          if (variable_table->file)
@@ -4234,12 +4969,18 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
        }
     }
 
+  if (stash->funcinfo_hash_table)
+    bfd_hash_table_free (&stash->funcinfo_hash_table->base);
+  if (stash->varinfo_hash_table)
+    bfd_hash_table_free (&stash->varinfo_hash_table->base);
   if (stash->dwarf_abbrev_buffer)
     free (stash->dwarf_abbrev_buffer);
   if (stash->dwarf_line_buffer)
     free (stash->dwarf_line_buffer);
   if (stash->dwarf_str_buffer)
     free (stash->dwarf_str_buffer);
+  if (stash->dwarf_line_str_buffer)
+    free (stash->dwarf_line_str_buffer);
   if (stash->dwarf_ranges_buffer)
     free (stash->dwarf_ranges_buffer);
   if (stash->info_ptr_memory)
@@ -4261,7 +5002,7 @@ _bfd_dwarf2_cleanup_debug_info (bfd *abfd, void **pinfo)
 /* Find the function to a particular section and offset,
    for error reporting.  */
 
-bfd_boolean
+asymbol *
 _bfd_elf_find_function (bfd *abfd,
                        asymbol **symbols,
                        asection *section,
@@ -4278,10 +5019,10 @@ _bfd_elf_find_function (bfd *abfd,
   } *cache;
 
   if (symbols == NULL)
-    return FALSE;
+    return NULL;
 
   if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
-    return FALSE;
+    return NULL;
 
   cache = elf_tdata (abfd)->elf_find_function_cache;
   if (cache == NULL)
@@ -4289,7 +5030,7 @@ _bfd_elf_find_function (bfd *abfd,
       cache = bfd_zalloc (abfd, sizeof (*cache));
       elf_tdata (abfd)->elf_find_function_cache = cache;
       if (cache == NULL)
-       return FALSE;
+       return NULL;
     }
   if (cache->last_section != section
       || cache->func == NULL
@@ -4354,12 +5095,12 @@ _bfd_elf_find_function (bfd *abfd,
     }
 
   if (cache->func == NULL)
-    return FALSE;
+    return NULL;
 
   if (filename_ptr)
     *filename_ptr = cache->filename;
   if (functionname_ptr)
     *functionname_ptr = bfd_asymbol_name (cache->func);
 
-  return TRUE;
+  return cache->func;
 }
This page took 0.056001 seconds and 4 git commands to generate.