Call cleanup on bfd_check_format_matches error exit
[deliverable/binutils-gdb.git] / bfd / elf.c
index a221bf0d04bd572e6bf1b752339ac42d8c8e3b63..fcd84d2d17bce0d2abb2a48a12857c4a2a532fbb 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,6 +1,6 @@
 /* ELF executable support for BFD.
 
-   Copyright (C) 1993-2019 Free Software Foundation, Inc.
+   Copyright (C) 1993-2020 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -296,16 +296,10 @@ bfd_elf_get_str_section (bfd *abfd, unsigned int shindex)
       /* Allocate and clear an extra byte at the end, to prevent crashes
         in case the string table is not terminated.  */
       if (shstrtabsize + 1 <= 1
-         || shstrtabsize > bfd_get_file_size (abfd)
          || bfd_seek (abfd, offset, SEEK_SET) != 0
-         || (shstrtab = (bfd_byte *) bfd_alloc (abfd, shstrtabsize + 1)) == NULL)
-       shstrtab = NULL;
-      else if (bfd_bread (shstrtab, shstrtabsize, abfd) != shstrtabsize)
-       {
-         if (bfd_get_error () != bfd_error_system_call)
-           bfd_set_error (bfd_error_file_truncated);
-         bfd_release (abfd, shstrtab);
-         shstrtab = NULL;
+         || (shstrtab = _bfd_alloc_and_read (abfd, shstrtabsize + 1,
+                                             shstrtabsize)) == NULL)
+       {
          /* Once we've failed to read it, make sure we don't keep
             trying.  Otherwise, we'll keep allocating space for
             the string table over and over.  */
@@ -402,7 +396,7 @@ bfd_elf_get_elf_syms (bfd *ibfd,
   Elf_Internal_Sym *isymend;
   const struct elf_backend_data *bed;
   size_t extsym_size;
-  bfd_size_type amt;
+  size_t amt;
   file_ptr pos;
 
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
@@ -448,11 +442,16 @@ bfd_elf_get_elf_syms (bfd *ibfd,
   alloc_intsym = NULL;
   bed = get_elf_backend_data (ibfd);
   extsym_size = bed->s->sizeof_sym;
-  amt = (bfd_size_type) symcount * extsym_size;
+  if (_bfd_mul_overflow (symcount, extsym_size, &amt))
+    {
+      bfd_set_error (bfd_error_file_too_big);
+      intsym_buf = NULL;
+      goto out;
+    }
   pos = symtab_hdr->sh_offset + symoffset * extsym_size;
   if (extsym_buf == NULL)
     {
-      alloc_ext = bfd_malloc2 (symcount, extsym_size);
+      alloc_ext = bfd_malloc (amt);
       extsym_buf = alloc_ext;
     }
   if (extsym_buf == NULL
@@ -467,12 +466,16 @@ bfd_elf_get_elf_syms (bfd *ibfd,
     extshndx_buf = NULL;
   else
     {
-      amt = (bfd_size_type) symcount * sizeof (Elf_External_Sym_Shndx);
+      if (_bfd_mul_overflow (symcount, sizeof (Elf_External_Sym_Shndx), &amt))
+       {
+         bfd_set_error (bfd_error_file_too_big);
+         intsym_buf = NULL;
+         goto out;
+       }
       pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
       if (extshndx_buf == NULL)
        {
-         alloc_extshndx = (Elf_External_Sym_Shndx *)
-             bfd_malloc2 (symcount, sizeof (Elf_External_Sym_Shndx));
+         alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
          extshndx_buf = alloc_extshndx;
        }
       if (extshndx_buf == NULL
@@ -486,8 +489,12 @@ bfd_elf_get_elf_syms (bfd *ibfd,
 
   if (intsym_buf == NULL)
     {
-      alloc_intsym = (Elf_Internal_Sym *)
-         bfd_malloc2 (symcount, sizeof (Elf_Internal_Sym));
+      if (_bfd_mul_overflow (symcount, sizeof (Elf_Internal_Sym), &amt))
+       {
+         bfd_set_error (bfd_error_file_too_big);
+         goto out;
+       }
+      alloc_intsym = (Elf_Internal_Sym *) bfd_malloc (amt);
       intsym_buf = alloc_intsym;
       if (intsym_buf == NULL)
        goto out;
@@ -629,15 +636,14 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
        {
          /* We keep a list of elf section headers for group sections,
             so we can find them quickly.  */
-         bfd_size_type amt;
+         size_t amt;
 
          elf_tdata (abfd)->num_group = num_group;
-         elf_tdata (abfd)->group_sect_ptr = (Elf_Internal_Shdr **)
-             bfd_alloc2 (abfd, num_group, sizeof (Elf_Internal_Shdr *));
+         amt = num_group * sizeof (Elf_Internal_Shdr *);
+         elf_tdata (abfd)->group_sect_ptr
+           = (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt);
          if (elf_tdata (abfd)->group_sect_ptr == NULL)
            return FALSE;
-         memset (elf_tdata (abfd)->group_sect_ptr, 0,
-                 num_group * sizeof (Elf_Internal_Shdr *));
          num_group = 0;
 
          for (i = 0; i < shnum; i++)
@@ -659,28 +665,13 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
                  num_group += 1;
 
                  /* Read the raw contents.  */
-                 BFD_ASSERT (sizeof (*dest) >= 4);
-                 amt = shdr->sh_size * sizeof (*dest) / 4;
-                 shdr->contents = (unsigned char *)
-                   bfd_alloc2 (abfd, shdr->sh_size, sizeof (*dest) / 4);
-                 /* PR binutils/4110: Handle corrupt group headers.  */
-                 if (shdr->contents == NULL)
-                   {
-                     _bfd_error_handler
-                       /* xgettext:c-format */
-                       (_("%pB: corrupt size field in group section"
-                          " header: %#" PRIx64),
-                        abfd, (uint64_t) shdr->sh_size);
-                     bfd_set_error (bfd_error_bad_value);
-                     -- num_group;
-                     continue;
-                   }
-
-                 memset (shdr->contents, 0, amt);
-
-                 if (bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
-                     || (bfd_bread (shdr->contents, shdr->sh_size, abfd)
-                         != shdr->sh_size))
+                 BFD_ASSERT (sizeof (*dest) >= 4 && sizeof (*dest) % 4 == 0);
+                 shdr->contents = NULL;
+                 if (_bfd_mul_overflow (shdr->sh_size,
+                                        sizeof (*dest) / 4, &amt)
+                     || bfd_seek (abfd, shdr->sh_offset, SEEK_SET) != 0
+                     || !(shdr->contents
+                          = _bfd_alloc_and_read (abfd, amt, shdr->sh_size)))
                    {
                      _bfd_error_handler
                        /* xgettext:c-format */
@@ -689,10 +680,6 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
                         abfd, (uint64_t) shdr->sh_size);
                      bfd_set_error (bfd_error_bad_value);
                      -- num_group;
-                     /* PR 17510: If the group contents are even
-                        partially corrupt, do not allow any of the
-                        contents to be used.  */
-                     memset (shdr->contents, 0, amt);
                      continue;
                    }
 
@@ -712,6 +699,7 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
                      idx = H_GET_32 (abfd, src);
                      if (src == shdr->contents)
                        {
+                         dest->shdr = NULL;
                          dest->flags = idx;
                          if (shdr->bfd_section != NULL && (idx & GRP_COMDAT))
                            shdr->bfd_section->flags
@@ -1102,23 +1090,16 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
         not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
       if (name [0] == '.')
        {
-         const char *p;
-         int n;
-         if (name[1] == 'd')
-           p = ".debug", n = 6;
-         else if (name[1] == 'g' && name[2] == 'n')
-           p = ".gnu.linkonce.wi.", n = 17;
-         else if (name[1] == 'g' && name[2] == 'd')
-           p = ".gdb_index", n = 11; /* yes we really do mean 11.  */
-         else if (name[1] == 'l')
-           p = ".line", n = 5;
-         else if (name[1] == 's')
-           p = ".stab", n = 5;
-         else if (name[1] == 'z')
-           p = ".zdebug", n = 7;
-         else
-           p = NULL, n = 0;
-         if (p != NULL && strncmp (name, p, n) == 0)
+         if (strncmp (name, ".debug", 6) == 0
+             || strncmp (name, ".gnu.linkonce.wi.", 17) == 0
+             || strncmp (name, ".zdebug", 7) == 0)
+           flags |= SEC_DEBUGGING | SEC_ELF_OCTETS;
+         else if (strncmp (name, GNU_BUILD_ATTRS_SECTION_NAME, 21) == 0
+                  || strncmp (name, ".note.gnu", 9) == 0)
+           flags |= SEC_ELF_OCTETS;
+         else if (strncmp (name, ".line", 5) == 0
+                  || strncmp (name, ".stab", 5) == 0
+                  || strcmp (name, ".gdb_index") == 0)
            flags |= SEC_DEBUGGING;
        }
     }
@@ -1133,14 +1114,14 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
       && elf_next_in_group (newsect) == NULL)
     flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
 
+  if (!bfd_set_section_flags (newsect, flags))
+    return FALSE;
+
   bed = get_elf_backend_data (abfd);
   if (bed->elf_backend_section_flags)
-    if (! bed->elf_backend_section_flags (&flags, hdr))
+    if (!bed->elf_backend_section_flags (hdr))
       return FALSE;
 
-  if (!bfd_set_section_flags (newsect, flags))
-    return FALSE;
-
   /* We do not parse the PT_NOTE segments as we are interested even in the
      separate debug info files which may have the segments offsets corrupted.
      PT_NOTEs from the core files are currently not parsed using BFD.  */
@@ -1156,7 +1137,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
       free (contents);
     }
 
-  if ((flags & SEC_ALLOC) != 0)
+  if ((newsect->flags & SEC_ALLOC) != 0)
     {
       Elf_Internal_Phdr *phdr;
       unsigned int i, nload;
@@ -1182,7 +1163,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
               || phdr->p_type == PT_TLS)
              && ELF_SECTION_IN_SEGMENT (hdr, phdr))
            {
-             if ((flags & SEC_LOAD) == 0)
+             if ((newsect->flags & SEC_LOAD) == 0)
                newsect->lma = (phdr->p_paddr
                                + hdr->sh_addr - phdr->p_vaddr);
              else
@@ -1210,7 +1191,7 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
 
   /* Compress/decompress DWARF debug sections with names: .debug_* and
      .zdebug_*, after the section flags is set.  */
-  if ((flags & SEC_DEBUGGING)
+  if ((newsect->flags & SEC_DEBUGGING)
       && ((name[1] == 'd' && name[6] == '_')
          || (name[1] == 'z' && name[7] == '_')))
     {
@@ -2076,8 +2057,10 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
        sections_being_created = NULL;
       if (sections_being_created == NULL)
        {
-         sections_being_created = (bfd_boolean *)
-           bfd_zalloc2 (abfd, elf_numsections (abfd), sizeof (bfd_boolean));
+         size_t amt = elf_numsections (abfd) * sizeof (bfd_boolean);
+         sections_being_created = (bfd_boolean *) bfd_zalloc (abfd, amt);
+         if (sections_being_created == NULL)
+           return FALSE;
          sections_being_created_abfd = abfd;
        }
       if (sections_being_created [shindex])
@@ -2917,28 +2900,13 @@ _bfd_elf_new_section_hook (bfd *abfd, asection *sec)
   bed = get_elf_backend_data (abfd);
   sec->use_rela_p = bed->default_use_rela_p;
 
-  /* When we read a file, we don't need to set ELF section type and
-     flags.  They will be overridden in _bfd_elf_make_section_from_shdr
-     anyway.  We will set ELF section type and flags for all linker
-     created sections.  If user specifies BFD section flags, we will
-     set ELF section type and flags based on BFD section flags in
-     elf_fake_sections.  Special handling for .init_array/.fini_array
-     output sections since they may contain .ctors/.dtors input
-     sections.  We don't want _bfd_elf_init_private_section_data to
-     copy ELF section type from .ctors/.dtors input sections.  */
-  if (abfd->direction != read_direction
-      || (sec->flags & SEC_LINKER_CREATED) != 0)
+  /* Set up ELF section type and flags for newly created sections, if
+     there is an ABI mandated section.  */
+  ssect = (*bed->get_sec_type_attr) (abfd, sec);
+  if (ssect != NULL)
     {
-      ssect = (*bed->get_sec_type_attr) (abfd, sec);
-      if (ssect != NULL
-         && (!sec->flags
-             || (sec->flags & SEC_LINKER_CREATED) != 0
-             || ssect->type == SHT_INIT_ARRAY
-             || ssect->type == SHT_FINI_ARRAY))
-       {
-         elf_section_type (sec) = ssect->type;
-         elf_section_flags (sec) = ssect->attr;
-       }
+      elf_section_type (sec) = ssect->type;
+      elf_section_flags (sec) = ssect->attr;
     }
 
   return _bfd_generic_new_section_hook (abfd, sec);
@@ -3728,6 +3696,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
   Elf_Internal_Shdr **i_shdrp;
   struct bfd_elf_section_data *d;
   bfd_boolean need_symtab;
+  size_t amt;
 
   section_number = 1;
 
@@ -3835,8 +3804,8 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
 
   /* Set up the list of section header pointers, in agreement with the
      indices.  */
-  i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc2 (abfd, section_number,
-                                               sizeof (Elf_Internal_Shdr *));
+  amt = section_number * sizeof (Elf_Internal_Shdr *);
+  i_shdrp = (Elf_Internal_Shdr **) bfd_zalloc (abfd, amt);
   if (i_shdrp == NULL)
     return FALSE;
 
@@ -4155,6 +4124,7 @@ elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
   unsigned int idx;
   asection *asect;
   asymbol **new_syms;
+  size_t amt;
 
 #ifdef DEBUG
   fprintf (stderr, "elf_map_symbols\n");
@@ -4168,7 +4138,8 @@ elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
     }
 
   max_index++;
-  sect_syms = (asymbol **) bfd_zalloc2 (abfd, max_index, sizeof (asymbol *));
+  amt = max_index * sizeof (asymbol *);
+  sect_syms = (asymbol **) bfd_zalloc (abfd, amt);
   if (sect_syms == NULL)
     return FALSE;
   elf_section_syms (abfd) = sect_syms;
@@ -4219,9 +4190,8 @@ elf_map_symbols (bfd *abfd, unsigned int *pnum_locals)
     }
 
   /* Now sort the symbols so the local symbols are first.  */
-  new_syms = (asymbol **) bfd_alloc2 (abfd, num_locals + num_globals,
-                                     sizeof (asymbol *));
-
+  amt = (num_locals + num_globals) * sizeof (asymbol *);
+  new_syms = (asymbol **) bfd_alloc (abfd, amt);
   if (new_syms == NULL)
     return FALSE;
 
@@ -4558,7 +4528,7 @@ make_mapping (bfd *abfd,
   struct elf_segment_map *m;
   unsigned int i;
   asection **hdrpp;
-  bfd_size_type amt;
+  size_t amt;
 
   amt = sizeof (struct elf_segment_map) - sizeof (asection *);
   amt += (to - from) * sizeof (asection *);
@@ -4685,18 +4655,18 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       bfd_boolean phdr_in_segment;
       bfd_boolean writable;
       bfd_boolean executable;
-      int tls_count = 0;
+      unsigned int tls_count = 0;
       asection *first_tls = NULL;
       asection *first_mbind = NULL;
       asection *dynsec, *eh_frame_hdr;
-      bfd_size_type amt;
+      size_t amt;
       bfd_vma addr_mask, wrap_to = 0;
       bfd_size_type phdr_size;
 
       /* Select the allocated sections, and sort them.  */
 
-      sections = (asection **) bfd_malloc2 (bfd_count_sections (abfd),
-                                           sizeof (asection *));
+      amt = bfd_count_sections (abfd) * sizeof (asection *);
+      sections = (asection **) bfd_malloc (amt);
       if (sections == NULL)
        goto error_return;
 
@@ -5081,7 +5051,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
          m->p_flags = PF_R;
          m->p_flags_valid = 1;
          s = first_tls;
-         for (i = 0; i < (unsigned int) tls_count; ++i)
+         for (i = 0; i < tls_count; ++i)
            {
              if ((s->flags & SEC_THREAD_LOCAL) == 0)
                {
@@ -5089,7 +5059,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
                    (_("%pB: TLS sections are not adjacent:"), abfd);
                  s = first_tls;
                  i = 0;
-                 while (i < (unsigned int) tls_count)
+                 while (i < tls_count)
                    {
                      if ((s->flags & SEC_THREAD_LOCAL) != 0)
                        {
@@ -5759,7 +5729,21 @@ assign_file_positions_for_load_sections (bfd *abfd,
          || (p->p_type == PT_NOTE && bfd_get_format (abfd) == bfd_core))
        {
          if (!m->includes_filehdr && !m->includes_phdrs)
-           p->p_offset = off;
+           {
+             p->p_offset = off;
+             if (no_contents)
+               {
+                 /* Put meaningless p_offset for PT_LOAD segments
+                    without file contents somewhere within the first
+                    page, in an attempt to not point past EOF.  */
+                 bfd_size_type align = maxpagesize;
+                 if (align < p->p_align)
+                   align = p->p_align;
+                 if (align < 1)
+                   align = 1;
+                 p->p_offset = off % align;
+               }
+           }
          else
            {
              file_ptr adjust;
@@ -5927,7 +5911,11 @@ assign_file_positions_for_load_sections (bfd *abfd,
          _bfd_error_handler (_("%pB: error: PHDR segment not covered"
                                " by LOAD segment"),
                              abfd);
-         return FALSE;
+         if (link_info == NULL)
+           return FALSE;
+         /* Arrange for the linker to exit with an error, deleting
+            the output file unless --noinhibit-exec is given.  */
+         link_info->callbacks->info ("%X");
        }
 
       /* Check that all sections are in a PT_LOAD segment.
@@ -7020,7 +7008,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
       asection *matching_lma;
       asection *suggested_lma;
       unsigned int j;
-      bfd_size_type amt;
+      size_t amt;
       asection *first_section;
 
       if (segment->p_type == PT_NULL)
@@ -7046,7 +7034,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
       /* Allocate a segment map big enough to contain
         all of the sections we have selected.  */
       amt = sizeof (struct elf_segment_map) - sizeof (asection *);
-      amt += (bfd_size_type) section_count * sizeof (asection *);
+      amt += section_count * sizeof (asection *);
       map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
       if (map == NULL)
        return FALSE;
@@ -7138,7 +7126,8 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
         pointers that we are interested in.  As these sections get assigned
         to a segment, they are removed from this array.  */
 
-      sections = (asection **) bfd_malloc2 (section_count, sizeof (asection *));
+      amt = section_count * sizeof (asection *);
+      sections = (asection **) bfd_malloc (amt);
       if (sections == NULL)
        return FALSE;
 
@@ -7353,14 +7342,9 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
 
          /* PR 23932.  A corrupt input file may contain sections that cannot
             be assigned to any segment - because for example they have a
-            negative size - or segments that do not contain any sections.  */
-         if (map->count == 0)
-           {
-           sorry:
-             bfd_set_error (bfd_error_sorry);
-             free (sections);
-             return FALSE;
-           }
+            negative size - or segments that do not contain any sections.
+            But there are also valid reasons why a segment can be empty.
+            So allow a count of zero.  */
 
          /* Add the current segment to the list of built segments.  */
          *pointer_to_map = map;
@@ -7372,7 +7356,7 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
                 segments.  Create a new segment here, initialise it
                 and carry on looping.  */
              amt = sizeof (struct elf_segment_map) - sizeof (asection *);
-             amt += (bfd_size_type) section_count * sizeof (asection *);
+             amt += section_count * sizeof (asection *);
              map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
              if (map == NULL)
                {
@@ -7392,6 +7376,12 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
              map->includes_filehdr = 0;
              map->includes_phdrs = 0;
            }
+
+         continue;
+       sorry:
+         bfd_set_error (bfd_error_sorry);
+         free (sections);
+         return FALSE;
        }
       while (isec < section_count);
 
@@ -7477,7 +7467,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
     {
       asection *section;
       unsigned int section_count;
-      bfd_size_type amt;
+      size_t amt;
       Elf_Internal_Shdr *this_hdr;
       asection *first_section = NULL;
       asection *lowest_section;
@@ -7499,7 +7489,7 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
       /* Allocate a segment map big enough to contain
         all of the sections we have selected.  */
       amt = sizeof (struct elf_segment_map) - sizeof (asection *);
-      amt += (bfd_size_type) section_count * sizeof (asection *);
+      amt += section_count * sizeof (asection *);
       map = (struct elf_segment_map *) bfd_zalloc (obfd, amt);
       if (map == NULL)
        return FALSE;
@@ -7699,7 +7689,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
       return copy_elf_program_header (ibfd, obfd);
     }
 
-rewrite:
+ rewrite:
   if (ibfd->xvec == obfd->xvec)
     {
       /* When rewriting program header, set the output maxpagesize to
@@ -7752,10 +7742,19 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
 
   BFD_ASSERT (elf_section_data (osec) != NULL);
 
-  /* For objcopy and relocatable link, don't copy the output ELF
-     section type from input if the output BFD section flags have been
-     set to something different.  For a final link allow some flags
-     that the linker clears to differ.  */
+  /* If this is a known ABI section, ELF section type and flags may
+     have been set up when OSEC was created.  For normal sections we
+     allow the user to override the type and flags other than
+     SHF_MASKOS and SHF_MASKPROC.  */
+  if (elf_section_type (osec) == SHT_PROGBITS
+      || elf_section_type (osec) == SHT_NOTE
+      || elf_section_type (osec) == SHT_NOBITS)
+    elf_section_type (osec) = SHT_NULL;
+  /* For objcopy and relocatable link, copy the ELF section type from
+     the input file if the BFD section flags are the same.  (If they
+     are different the user may be doing something like
+     "objcopy --set-section-flags .text=alloc,data".)  For a final
+     link allow some flags that the linker clears to differ.  */
   if (elf_section_type (osec) == SHT_NULL
       && (osec->flags == isec->flags
          || (final_link
@@ -7764,8 +7763,8 @@ _bfd_elf_init_private_section_data (bfd *ibfd,
     elf_section_type (osec) = elf_section_type (isec);
 
   /* FIXME: Is this correct for all OS/PROC specific flags?  */
-  elf_section_flags (osec) |= (elf_section_flags (isec)
-                              & (SHF_MASKOS | SHF_MASKPROC));
+  elf_section_flags (osec) = (elf_section_flags (isec)
+                             & (SHF_MASKOS | SHF_MASKPROC));
 
   /* Copy sh_info from input for mbind section.  */
   if ((elf_tdata (ibfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0
@@ -8002,7 +8001,7 @@ swap_out_syms (bfd *abfd,
               int relocatable_p)
 {
   const struct elf_backend_data *bed;
-  int symcount;
+  unsigned int symcount;
   asymbol **syms;
   struct elf_strtab_hash *stt;
   Elf_Internal_Shdr *symtab_hdr;
@@ -8013,9 +8012,9 @@ swap_out_syms (bfd *abfd,
   bfd_byte *outbound_shndx;
   unsigned long outbound_syms_index;
   unsigned long outbound_shndx_index;
-  int idx;
+  unsigned int idx;
   unsigned int num_locals;
-  bfd_size_type amt;
+  size_t amt;
   bfd_boolean name_local_sections;
 
   if (!elf_map_symbols (abfd, &num_locals))
@@ -8039,21 +8038,22 @@ swap_out_syms (bfd *abfd,
   symstrtab_hdr->sh_type = SHT_STRTAB;
 
   /* Allocate buffer to swap out the .strtab section.  */
-  symstrtab = (struct elf_sym_strtab *) bfd_malloc2 (symcount + 1,
-                                                    sizeof (*symstrtab));
-  if (symstrtab == NULL)
+  if (_bfd_mul_overflow (symcount + 1, sizeof (*symstrtab), &amt)
+      || (symstrtab = (struct elf_sym_strtab *) bfd_malloc (amt)) == NULL)
     {
+      bfd_set_error (bfd_error_no_memory);
       _bfd_elf_strtab_free (stt);
       return FALSE;
     }
 
-  outbound_syms = (bfd_byte *) bfd_alloc2 (abfd, 1 + symcount,
-                                          bed->s->sizeof_sym);
-  if (outbound_syms == NULL)
+  if (_bfd_mul_overflow (symcount + 1, bed->s->sizeof_sym, &amt)
+      || (outbound_syms = (bfd_byte *) bfd_alloc (abfd, amt)) == NULL)
     {
-error_return:
-      _bfd_elf_strtab_free (stt);
+    error_no_mem:
+      bfd_set_error (bfd_error_no_memory);
+    error_return:
       free (symstrtab);
+      _bfd_elf_strtab_free (stt);
       return FALSE;
     }
   symtab_hdr->contents = outbound_syms;
@@ -8067,9 +8067,10 @@ error_return:
       symtab_shndx_hdr = & elf_symtab_shndx_list (abfd)->hdr;
       if (symtab_shndx_hdr->sh_name != 0)
        {
-         amt = (bfd_size_type) (1 + symcount) * sizeof (Elf_External_Sym_Shndx);
-         outbound_shndx =  (bfd_byte *)
-           bfd_zalloc2 (abfd, 1 + symcount, sizeof (Elf_External_Sym_Shndx));
+         if (_bfd_mul_overflow (symcount + 1,
+                                sizeof (Elf_External_Sym_Shndx), &amt))
+           goto error_no_mem;
+         outbound_shndx =  (bfd_byte *) bfd_zalloc (abfd, amt);
          if (outbound_shndx == NULL)
            goto error_return;
 
@@ -8191,9 +8192,26 @@ error_return:
                  if (elf_symtab_shndx_list (abfd))
                    shndx = elf_symtab_shndx_list (abfd)->ndx;
                  break;
-               default:
+               case SHN_COMMON:
+               case SHN_ABS:
                  shndx = SHN_ABS;
                  break;
+               default:
+                 if (shndx >= SHN_LOPROC && shndx <= SHN_HIOS)
+                   {
+                     if (bed->symbol_section_index)
+                       shndx = bed->symbol_section_index (abfd, type_ptr);
+                     /* Otherwise just leave the index alone.  */
+                   }
+                 else
+                   {
+                     if (shndx > SHN_HIOS && shndx < SHN_HIRESERVE)
+                       _bfd_error_handler (_("%pB: \
+Unable to handle section index %x in ELF symbol.  Using ABS instead."),
+                                         abfd, shndx);
+                     shndx = SHN_ABS;
+                   }
+                 break;
                }
            }
          else
@@ -8557,6 +8575,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
 {
   bfd_byte *contents = NULL;
   unsigned int freeidx = 0;
+  size_t amt;
 
   if (elf_dynverref (abfd) != 0)
     {
@@ -8571,39 +8590,28 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
       if (hdr->sh_info == 0
          || hdr->sh_info > hdr->sh_size / sizeof (Elf_External_Verneed))
        {
-error_return_bad_verref:
+       error_return_bad_verref:
          _bfd_error_handler
            (_("%pB: .gnu.version_r invalid entry"), abfd);
          bfd_set_error (bfd_error_bad_value);
-error_return_verref:
+       error_return_verref:
          elf_tdata (abfd)->verref = NULL;
          elf_tdata (abfd)->cverrefs = 0;
          goto error_return;
        }
 
-      ufile_ptr filesize = bfd_get_file_size (abfd);
-      if (filesize > 0 && filesize < hdr->sh_size)
-       {
-         /* PR 24708: Avoid attempts to allocate a ridiculous amount
-            of memory.  */
-         bfd_set_error (bfd_error_no_memory);
-         _bfd_error_handler
-           /* xgettext:c-format */
-           (_("error: %pB version reference section is too large (%#" PRIx64 " bytes)"),
-            abfd, (uint64_t) hdr->sh_size);
-         goto error_return_verref;
-       }
-      contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
-      if (contents == NULL)
+      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
        goto error_return_verref;
-
-      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
-         || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
+      contents = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size);
+      if (contents == NULL)
        goto error_return_verref;
 
-      elf_tdata (abfd)->verref = (Elf_Internal_Verneed *)
-       bfd_alloc2 (abfd, hdr->sh_info, sizeof (Elf_Internal_Verneed));
-
+      if (_bfd_mul_overflow (hdr->sh_info, sizeof (Elf_Internal_Verneed), &amt))
+       {
+         bfd_set_error (bfd_error_file_too_big);
+         goto error_return_verref;
+       }
+      elf_tdata (abfd)->verref = (Elf_Internal_Verneed *) bfd_alloc (abfd, amt);
       if (elf_tdata (abfd)->verref == NULL)
        goto error_return_verref;
 
@@ -8632,9 +8640,14 @@ error_return_verref:
            iverneed->vn_auxptr = NULL;
          else
            {
+             if (_bfd_mul_overflow (iverneed->vn_cnt,
+                                    sizeof (Elf_Internal_Vernaux), &amt))
+               {
+                 bfd_set_error (bfd_error_file_too_big);
+                 goto error_return_verref;
+               }
              iverneed->vn_auxptr = (struct elf_internal_vernaux *)
-                 bfd_alloc2 (abfd, iverneed->vn_cnt,
-                             sizeof (Elf_Internal_Vernaux));
+               bfd_alloc (abfd, amt);
              if (iverneed->vn_auxptr == NULL)
                goto error_return_verref;
            }
@@ -8720,11 +8733,10 @@ error_return_verref:
          goto error_return;
        }
 
-      contents = (bfd_byte *) bfd_malloc (hdr->sh_size);
-      if (contents == NULL)
+      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
        goto error_return_verdef;
-      if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0
-         || bfd_bread (contents, hdr->sh_size, abfd) != hdr->sh_size)
+      contents = _bfd_malloc_and_read (abfd, hdr->sh_size, hdr->sh_size);
+      if (contents == NULL)
        goto error_return_verdef;
 
       BFD_ASSERT (sizeof (Elf_External_Verdef)
@@ -8766,9 +8778,12 @@ error_return_verref:
          else
            freeidx = ++maxidx;
        }
-
-      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
-       bfd_zalloc2 (abfd, maxidx, sizeof (Elf_Internal_Verdef));
+      if (_bfd_mul_overflow (maxidx, sizeof (Elf_Internal_Verdef), &amt))
+       {
+         bfd_set_error (bfd_error_file_too_big);
+         goto error_return_verdef;
+       }
+      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
       if (elf_tdata (abfd)->verdef == NULL)
        goto error_return_verdef;
 
@@ -8796,9 +8811,14 @@ error_return_verref:
            iverdef->vd_auxptr = NULL;
          else
            {
+             if (_bfd_mul_overflow (iverdef->vd_cnt,
+                                    sizeof (Elf_Internal_Verdaux), &amt))
+               {
+                 bfd_set_error (bfd_error_file_too_big);
+                 goto error_return_verdef;
+               }
              iverdef->vd_auxptr = (struct elf_internal_verdaux *)
-                 bfd_alloc2 (abfd, iverdef->vd_cnt,
-                             sizeof (Elf_Internal_Verdaux));
+               bfd_alloc (abfd, amt);
              if (iverdef->vd_auxptr == NULL)
                goto error_return_verdef;
            }
@@ -8861,8 +8881,12 @@ error_return_verref:
       else
        freeidx++;
 
-      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *)
-         bfd_zalloc2 (abfd, freeidx, sizeof (Elf_Internal_Verdef));
+      if (_bfd_mul_overflow (freeidx, sizeof (Elf_Internal_Verdef), &amt))
+       {
+         bfd_set_error (bfd_error_file_too_big);
+         goto error_return;
+       }
+      elf_tdata (abfd)->verdef = (Elf_Internal_Verdef *) bfd_zalloc (abfd, amt);
       if (elf_tdata (abfd)->verdef == NULL)
        goto error_return;
 
@@ -9037,10 +9061,11 @@ _bfd_elf_find_nearest_line (bfd *abfd,
                                     filename_ptr, functionname_ptr,
                                     line_ptr, discriminator_ptr,
                                     dwarf_debug_sections,
-                                    &elf_tdata (abfd)->dwarf2_find_line_info)
-      || _bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
-                                       filename_ptr, functionname_ptr,
-                                       line_ptr))
+                                    &elf_tdata (abfd)->dwarf2_find_line_info))
+    return TRUE;
+
+  if (_bfd_dwarf1_find_nearest_line (abfd, symbols, section, offset,
+                                    filename_ptr, functionname_ptr, line_ptr))
     {
       if (!*functionname_ptr)
        _bfd_elf_find_function (abfd, symbols, section, offset,
@@ -11897,7 +11922,7 @@ elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size,
   if (bfd_seek (abfd, offset, SEEK_SET) != 0)
     return FALSE;
 
-  buf = (char *) bfd_malloc (size + 1);
+  buf = (char *) _bfd_malloc_and_read (abfd, size + 1, size);
   if (buf == NULL)
     return FALSE;
 
@@ -11905,8 +11930,7 @@ elf_read_notes (bfd *abfd, file_ptr offset, bfd_size_type size,
      0-termintate the buffer so that string searches will not overflow.  */
   buf[size] = 0;
 
-  if (bfd_bread (buf, size, abfd) != size
-      || !elf_parse_notes (abfd, buf, size, offset, align))
+  if (!elf_parse_notes (abfd, buf, size, offset, align))
     {
       free (buf);
       return FALSE;
@@ -12054,7 +12078,8 @@ _bfd_elf_section_offset (bfd *abfd,
 
          /* address_size and sec->size are in octets.  Convert
             to bytes before subtracting the original offset.  */
-         offset = (sec->size - address_size) / bfd_octets_per_byte (abfd) - offset;
+         offset = ((sec->size - address_size)
+                   / bfd_octets_per_byte (abfd, sec) - offset);
        }
       return offset;
     }
This page took 0.037442 seconds and 4 git commands to generate.