[binutils, ARM, 5/16] BF insns infrastructure with new global reloc R_ARM_THM_BF16
[binutils-gdb.git] / bfd / dwarf2.c
index 2413542b84b20554f9f6e58edd03880b81cc6171..76af009e33aaf19014fc713ab9122891280cba7d 100644 (file)
@@ -1,5 +1,5 @@
 /* DWARF 2 support.
-   Copyright (C) 1994-2018 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).
@@ -169,6 +169,8 @@ struct dwarf2_debug
 
   /* 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;
@@ -345,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
 {
@@ -527,6 +529,7 @@ 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 (contents == NULL)
@@ -549,7 +552,13 @@ read_section (bfd *              abfd,
       *section_size = msec->rawsize ? msec->rawsize : msec->size;
       /* Paranoia - alloc one extra so that we can make sure a string
         section is NUL terminated.  */
-      contents = (bfd_byte *) bfd_malloc (*section_size + 1);
+      amt = *section_size + 1;
+      if (amt == 0)
+       {
+         bfd_set_error (bfd_error_no_memory);
+         return FALSE;
+       }
+      contents = (bfd_byte *) bfd_malloc (amt);
       if (contents == NULL)
        return FALSE;
       if (syms
@@ -623,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.
@@ -1128,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:
@@ -1139,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:
@@ -1180,8 +1197,7 @@ read_attribute_value (struct attribute *  attr,
       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:
@@ -1191,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:
@@ -1560,7 +1575,7 @@ 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)
@@ -2831,7 +2846,9 @@ find_abstract_instance (struct comp_unit *   unit,
       info_ptr = unit->stash->info_ptr_memory;
       info_ptr_end = unit->stash->info_ptr_end;
       total = info_ptr_end - info_ptr;
-      if (!die_ref || die_ref >= total)
+      if (!die_ref)
+       return TRUE;
+      else if (die_ref >= total)
        {
          _bfd_error_handler
            (_("DWARF error: invalid abstract instance DIE ref"));
@@ -2947,7 +2964,7 @@ find_abstract_instance (struct comp_unit *   unit,
                  break;
                case DW_AT_specification:
                  if (!find_abstract_instance (unit, info_ptr, &attr,
-                                              pname, is_linkage,
+                                              &name, is_linkage,
                                               filename_ptr, linenumber_ptr))
                    return FALSE;
                  break;
@@ -4254,6 +4271,7 @@ 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;
+  stash->sec_vma_count = abfd->section_count;
   for (i = 0, s = abfd->sections; i < abfd->section_count; i++, s = s->next)
     {
       if (s->output_section != NULL)
@@ -4277,6 +4295,12 @@ section_vma_same (const bfd *abfd, const struct dwarf2_debug *stash)
   asection *s;
   unsigned int i;
 
+  /* 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; i < abfd->section_count; i++, s = s->next)
     {
       bfd_vma vma;
@@ -4457,7 +4481,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)