XCOFF64 uninitialised read
[deliverable/binutils-gdb.git] / bfd / elf.c
index 6aaa96f83f6228d535138164b4e55d950402ef74..975eeb06b8058ef754a74e33f9c795e6e0b2d1be 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -857,11 +857,10 @@ _bfd_elf_setup_sections (bfd *abfd)
          if (elfsec == 0)
            {
              const struct elf_backend_data *bed = get_elf_backend_data (abfd);
-             if (bed->link_order_error_handler)
-               bed->link_order_error_handler
-                 /* xgettext:c-format */
-                 (_("%pB: warning: sh_link not set for section `%pA'"),
-                  abfd, s);
+             bed->link_order_error_handler
+               /* xgettext:c-format */
+               (_("%pB: warning: sh_link not set for section `%pA'"),
+                abfd, s);
            }
          else
            {
@@ -1424,9 +1423,8 @@ copy_special_section_fields (const bfd *ibfd,
     }
 
   /* Allow the target a chance to decide how these fields should be set.  */
-  if (bed->elf_backend_copy_special_section_fields != NULL
-      && bed->elf_backend_copy_special_section_fields
-      (ibfd, obfd, iheader, oheader))
+  if (bed->elf_backend_copy_special_section_fields (ibfd, obfd,
+                                                   iheader, oheader))
     return TRUE;
 
   /* We have an iheader which might match oheader, and which has non-zero
@@ -1610,8 +1608,8 @@ _bfd_elf_copy_private_bfd_data (bfd *ibfd, bfd *obfd)
        {
          /* Final attempt.  Call the backend copy function
             with a NULL input section.  */
-         if (bed->elf_backend_copy_special_section_fields != NULL)
-           (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd, NULL, oheader);
+         (void) bed->elf_backend_copy_special_section_fields (ibfd, obfd,
+                                                              NULL, oheader);
        }
     }
 
@@ -2462,12 +2460,12 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
           sections.  */
        if (*p_hdr != NULL)
          {
-           if (bed->init_secondary_reloc_section == NULL
-               || ! bed->init_secondary_reloc_section (abfd, hdr, name, shindex))
+           if (!bed->init_secondary_reloc_section (abfd, hdr, name, shindex))
              {
                _bfd_error_handler
                  /* xgettext:c-format */
-                 (_("%pB: warning: secondary relocation section '%s' for section %pA found - ignoring"),
+                 (_("%pB: warning: secondary relocation section '%s' "
+                    "for section %pA found - ignoring"),
                   abfd, name, target_sect);
              }
            goto success;
@@ -3533,8 +3531,13 @@ bfd_elf_set_group_contents (bfd *abfd, asection *sec, void *failedptrarg)
       if (symindx == 0)
        {
          /* If called from the assembler, swap_out_syms will have set up
-            elf_section_syms.  */
-         BFD_ASSERT (elf_section_syms (abfd) != NULL);
+            elf_section_syms.
+            PR 25699: A corrupt input file could contain bogus group info.  */
+         if (elf_section_syms (abfd) == NULL)
+           {
+             *failedptr = TRUE;
+             return;
+           }
          symindx = elf_section_syms (abfd)[sec->index]->udata.i;
        }
       elf_section_data (sec)->this_hdr.sh_info = symindx;
@@ -3935,11 +3938,10 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
                 where s is NULL.  */
              const struct elf_backend_data *bed
                = get_elf_backend_data (abfd);
-             if (bed->link_order_error_handler)
-               bed->link_order_error_handler
-                 /* xgettext:c-format */
-                 (_("%pB: warning: sh_link not set for section `%pA'"),
-                  abfd, sec);
+             bed->link_order_error_handler
+               /* xgettext:c-format */
+               (_("%pB: warning: sh_link not set for section `%pA'"),
+                abfd, sec);
            }
        }
 
@@ -12637,6 +12639,10 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
   bfd_vma addr_offset;
   asection * relsec;
   bfd_vma (*r_info) (bfd_vma, bfd_vma);
+  bfd_boolean result = TRUE;
+
+  if (sec == NULL)
+    return FALSE;
 
 #if BFD_DEFAULT_TARGET_SIZE > 32
   if (bfd_arch_bits_per_address (abfd) != 32)
@@ -12645,9 +12651,6 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
 #endif
     r_info = elf32_r_info;
 
-  if (sec == NULL)
-    return FALSE;
-
   /* The address of an ELF reloc is section relative for an object
      file, and absolute for an executable file or shared library.
      The address of a BFD reloc is always section relative.  */
@@ -12672,10 +12675,28 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
          arelent *    src_irel;
          bfd_byte *   dst_rela;
 
-         BFD_ASSERT (hdr->contents == NULL);
+         if (hdr->contents != NULL)
+           {
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB(%pA): error: secondary reloc section processed twice"),
+                abfd, relsec);
+             bfd_set_error (bfd_error_bad_value);
+             result = FALSE;
+             continue;
+           }
 
          reloc_count = hdr->sh_size / hdr->sh_entsize;
-         BFD_ASSERT (reloc_count > 0);
+         if (reloc_count <= 0)
+           {
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB(%pA): error: secondary reloc section is empty!"),
+                abfd, relsec);
+             bfd_set_error (bfd_error_bad_value);
+             result = FALSE;
+             continue;
+           }
 
          hdr->contents = bfd_alloc (abfd, hdr->sh_size);
          if (hdr->contents == NULL)
@@ -12689,7 +12710,16 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
          last_sym_idx = 0;
          dst_rela = hdr->contents;
          src_irel = (arelent *) esd->sec_info;
-         BFD_ASSERT (src_irel != NULL);
+         if (src_irel == NULL)
+           {
+             _bfd_error_handler
+               /* xgettext:c-format */
+               (_("%pB(%pA): error: internal relocs missing for secondary reloc section"),
+                abfd, relsec);
+             bfd_set_error (bfd_error_bad_value);
+             result = FALSE;
+             continue;
+           }
 
          for (idx = 0; idx < reloc_count; idx++, dst_rela += hdr->sh_entsize)
            {
@@ -12699,55 +12729,78 @@ _bfd_elf_write_secondary_reloc_section (bfd *abfd, asection *sec)
              int n;
 
              ptr = src_irel + idx;
-             sym = *ptr->sym_ptr_ptr;
+             if (ptr == NULL)
+               {
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB(%pA): error: reloc table entry %u is empty"),
+                    abfd, relsec, idx);
+                 bfd_set_error (bfd_error_bad_value);
+                 result = FALSE;
+                 break;
+               }
 
-             if (sym == last_sym)
-               n = last_sym_idx;
+             if (ptr->sym_ptr_ptr == NULL)
+               {
+                 /* FIXME: Is this an error ? */
+                 n = 0;
+               }
              else
                {
-                 last_sym = sym;
-                 n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym);
-                 if (n < 0)
+                 sym = *ptr->sym_ptr_ptr;
+
+                 if (sym == last_sym)
+                   n = last_sym_idx;
+                 else
                    {
-#if DEBUG_SECONDARY_RELOCS
-                     fprintf (stderr, "failed to find symbol %s whilst rewriting relocs\n",
-                              sym->name);
-#endif
-                     /* FIXME: Signal failure somehow.  */
-                     n = 0;
+                     n = _bfd_elf_symbol_from_bfd_symbol (abfd, & sym);
+                     if (n < 0)
+                       {
+                         _bfd_error_handler
+                           /* xgettext:c-format */
+                           (_("%pB(%pA): error: secondary reloc %u references a missing symbol"),
+                            abfd, relsec, idx);
+                         bfd_set_error (bfd_error_bad_value);
+                         result = FALSE;
+                         n = 0;
+                       }
+
+                     last_sym = sym;
+                     last_sym_idx = n;
                    }
-                 last_sym_idx = n;
-               }
 
-             if ((*ptr->sym_ptr_ptr)->the_bfd != NULL
-                 && (*ptr->sym_ptr_ptr)->the_bfd->xvec != abfd->xvec
-                 && ! _bfd_elf_validate_reloc (abfd, ptr))
-               {
-#if DEBUG_SECONDARY_RELOCS
-                 fprintf (stderr, "symbol %s is not in the output bfd\n",
-                          sym->name);
-#endif
-                 /* FIXME: Signal failure somehow.  */
-                 n = 0;
+                 if (sym->the_bfd != NULL
+                     && sym->the_bfd->xvec != abfd->xvec
+                     && ! _bfd_elf_validate_reloc (abfd, ptr))
+                   {
+                     _bfd_error_handler
+                       /* xgettext:c-format */
+                       (_("%pB(%pA): error: secondary reloc %u references a deleted symbol"),
+                        abfd, relsec, idx);
+                     bfd_set_error (bfd_error_bad_value);
+                     result = FALSE;
+                     n = 0;
+                   }
                }
 
+             src_rela.r_offset = ptr->address + addr_offset;
              if (ptr->howto == NULL)
                {
-#if DEBUG_SECONDARY_RELOCS
-                 fprintf (stderr, "reloc for symbol %s does not have a howto associated with it\n",
-                          sym->name);
-#endif
-                 /* FIXME: Signal failure somehow.  */
-                 n = 0;
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB(%pA): error: secondary reloc %u is of an unknown type"),
+                    abfd, relsec, idx);
+                 bfd_set_error (bfd_error_bad_value);
+                 result = FALSE;
+                 src_rela.r_info = r_info (0, 0);
                }
-
-             src_rela.r_offset = ptr->address + addr_offset;
-             src_rela.r_info = r_info (n, ptr->howto->type);
+             else
+               src_rela.r_info = r_info (n, ptr->howto->type);
              src_rela.r_addend = ptr->addend;
              ebd->s->swap_reloca_out (abfd, &src_rela, dst_rela);
            }
        }
     }
 
-  return TRUE;
+  return result;
 }
This page took 0.029792 seconds and 4 git commands to generate.