Unify Solaris procfs and largefile handling
[deliverable/binutils-gdb.git] / bfd / elf.c
index 86dadea05caff48339c36872f1bff867f711fd17..5fb1995bad2b267026fd4a14d97ef26e25daaaff 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -513,17 +513,14 @@ bfd_elf_get_elf_syms (bfd *ibfd,
        _bfd_error_handler (_("%pB symbol number %lu references"
                              " nonexistent SHT_SYMTAB_SHNDX section"),
                            ibfd, (unsigned long) symoffset);
-       if (alloc_intsym != NULL)
-         free (alloc_intsym);
+       free (alloc_intsym);
        intsym_buf = NULL;
        goto out;
       }
 
  out:
-  if (alloc_ext != NULL)
-    free (alloc_ext);
-  if (alloc_extshndx != NULL)
-    free (alloc_extshndx);
+  free (alloc_ext);
+  free (alloc_extshndx);
 
   return intsym_buf;
 }
@@ -1878,8 +1875,7 @@ _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
   return TRUE;
 
  error_return:
-  if (dynbuf != NULL)
-    free (dynbuf);
+  free (dynbuf);
   return FALSE;
 }
 
@@ -1911,8 +1907,12 @@ _bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
        {
          const char *nodename
            = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
-         version_string = ((base_p || strcmp (symbol->name, nodename))
-                           ? nodename : "");
+         version_string = "";
+         if (base_p
+             || nodename == NULL
+             || symbol->name == NULL
+             || strcmp (symbol->name, nodename) != 0)
+           version_string = nodename;
        }
       else
        {
@@ -2067,9 +2067,13 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
       if (sections_being_created == NULL)
        {
          size_t amt = elf_numsections (abfd) * sizeof (bfd_boolean);
-         sections_being_created = (bfd_boolean *) bfd_zalloc (abfd, amt);
+
+         /* PR 26005: Do not use bfd_zalloc here as the memory might
+            be released before the bfd has been fully scanned.  */
+         sections_being_created = (bfd_boolean *) bfd_malloc (amt);
          if (sections_being_created == NULL)
            return FALSE;
+         memset (sections_being_created, FALSE, amt);
          sections_being_created_abfd = abfd;
        }
       if (sections_being_created [shindex])
@@ -2607,8 +2611,9 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
     sections_being_created [shindex] = FALSE;
   if (-- nesting == 0)
     {
+      free (sections_being_created);
       sections_being_created = NULL;
-      sections_being_created_abfd = abfd;
+      sections_being_created_abfd = NULL;
     }
   return ret;
 }
@@ -3021,14 +3026,6 @@ _bfd_elf_make_section_from_phdr (bfd *abfd,
       newsect->alignment_power = bfd_log2 (align);
       if (hdr->p_type == PT_LOAD)
        {
-         /* Hack for gdb.  Segments that have not been modified do
-            not have their contents written to a core file, on the
-            assumption that a debugger can find the contents in the
-            executable.  We flag this case by setting the fake
-            section size to zero.  Note that "real" bss sections will
-            always have their contents dumped to the core file.  */
-         if (bfd_get_format (abfd) == bfd_core)
-           newsect->size = 0;
          newsect->flags |= SEC_ALLOC;
          if (hdr->p_flags & PF_X)
            newsect->flags |= SEC_CODE;
@@ -3707,7 +3704,8 @@ elf_get_reloc_section (asection *reloc_sec)
 
 /* Assign all ELF section numbers.  The dummy first section is handled here
    too.  The link/info pointers for the standard section types are filled
-   in here too, while we're at it.  */
+   in here too, while we're at it.  LINK_INFO will be 0 when arriving
+   here for objcopy, and when using the generic ELF linker.  */
 
 static bfd_boolean
 assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
@@ -3892,48 +3890,37 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
          s = elf_linked_to_section (sec);
          if (s)
            {
-             /* elf_linked_to_section points to the input section.  */
-             if (link_info != NULL)
-               {
-                 /* Check discarded linkonce section.  */
-                 if (discarded_section (s))
-                   {
-                     asection *kept;
-                     _bfd_error_handler
-                       /* xgettext:c-format */
-                       (_("%pB: sh_link of section `%pA' points to"
-                          " discarded section `%pA' of `%pB'"),
-                        abfd, d->this_hdr.bfd_section,
-                        s, s->owner);
-                     /* Point to the kept section if it has the same
-                        size as the discarded one.  */
-                     kept = _bfd_elf_check_kept_section (s, link_info);
-                     if (kept == NULL)
-                       {
-                         bfd_set_error (bfd_error_bad_value);
-                         return FALSE;
-                       }
-                     s = kept;
-                   }
-
-                 s = s->output_section;
-                 BFD_ASSERT (s != NULL);
-               }
-             else
+             /* Check discarded linkonce section.  */
+             if (discarded_section (s))
                {
-                 /* Handle objcopy. */
-                 if (s->output_section == NULL)
+                 asection *kept;
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB: sh_link of section `%pA' points to"
+                      " discarded section `%pA' of `%pB'"),
+                    abfd, d->this_hdr.bfd_section, s, s->owner);
+                 /* Point to the kept section if it has the same
+                    size as the discarded one.  */
+                 kept = _bfd_elf_check_kept_section (s, link_info);
+                 if (kept == NULL)
                    {
-                     _bfd_error_handler
-                       /* xgettext:c-format */
-                       (_("%pB: sh_link of section `%pA' points to"
-                          " removed section `%pA' of `%pB'"),
-                        abfd, d->this_hdr.bfd_section, s, s->owner);
                      bfd_set_error (bfd_error_bad_value);
                      return FALSE;
                    }
-                 s = s->output_section;
+                 s = kept;
+               }
+             /* Handle objcopy. */
+             else if (s->output_section == NULL)
+               {
+                 _bfd_error_handler
+                   /* xgettext:c-format */
+                   (_("%pB: sh_link of section `%pA' points to"
+                      " removed section `%pA' of `%pB'"),
+                    abfd, d->this_hdr.bfd_section, s, s->owner);
+                 bfd_set_error (bfd_error_bad_value);
+                 return FALSE;
                }
+             s = s->output_section;
              d->this_hdr.sh_link = elf_section_data (s)->this_idx;
            }
          else
@@ -3998,9 +3985,7 @@ assign_section_numbers (bfd *abfd, struct bfd_link_info *link_info)
                  elf_section_data (s)->this_hdr.sh_link = d->this_idx;
 
                  /* This is a .stab section.  */
-                 if (elf_section_data (s)->this_hdr.sh_entsize == 0)
-                   elf_section_data (s)->this_hdr.sh_entsize
-                     = 4 + 2 * bfd_get_arch_size (abfd) / 8;
+                 elf_section_data (s)->this_hdr.sh_entsize = 12;
                }
            }
          break;
@@ -5245,8 +5230,7 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
   return TRUE;
 
  error_return:
-  if (sections != NULL)
-    free (sections);
+  free (sections);
   return FALSE;
 }
 
@@ -7929,19 +7913,34 @@ _bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
                elf_section_flags (s->output_section) &= ~SHF_GROUP;
                elf_group_name (s->output_section) = NULL;
              }
-           /* Conversely, if the member section is not being output
-              but the SHT_GROUP section is, then adjust its size.  */
-           else if (s->output_section == discarded
-                    && isec->output_section != discarded)
+           else
              {
                struct bfd_elf_section_data *elf_sec = elf_section_data (s);
-               removed += 4;
-               if (elf_sec->rel.hdr != NULL
-                   && (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)
-                 removed += 4;
-               if (elf_sec->rela.hdr != NULL
-                   && (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)
-                 removed += 4;
+               if (s->output_section == discarded
+                   && isec->output_section != discarded)
+                 {
+                   /* Conversely, if the member section is not being
+                      output but the SHT_GROUP section is, then adjust
+                      its size.  */
+                   removed += 4;
+                   if (elf_sec->rel.hdr != NULL
+                       && (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)
+                     removed += 4;
+                   if (elf_sec->rela.hdr != NULL
+                       && (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)
+                     removed += 4;
+                 }
+               else
+                 {
+                   /* Also adjust for zero-sized relocation member
+                      section.  */
+                   if (elf_sec->rel.hdr != NULL
+                       && elf_sec->rel.hdr->sh_size == 0)
+                     removed += 4;
+                   if (elf_sec->rela.hdr != NULL
+                       && elf_sec->rela.hdr->sh_size == 0)
+                     removed += 4;
+                 }
              }
            s = elf_next_in_group (s);
            if (s == first)
@@ -8486,9 +8485,23 @@ _bfd_elf_get_dynamic_symtab_upper_bound (bfd *abfd)
 }
 
 long
-_bfd_elf_get_reloc_upper_bound (bfd *abfd ATTRIBUTE_UNUSED,
-                               sec_ptr asect)
+_bfd_elf_get_reloc_upper_bound (bfd *abfd, sec_ptr asect)
 {
+  if (asect->reloc_count != 0)
+    {
+      /* Sanity check reloc section size.  */
+      struct bfd_elf_section_data *d = elf_section_data (asect);
+      Elf_Internal_Shdr *rel_hdr = &d->this_hdr;
+      bfd_size_type ext_rel_size = rel_hdr->sh_size;
+      ufile_ptr filesize = bfd_get_file_size (abfd);
+
+      if (filesize != 0 && ext_rel_size > filesize)
+       {
+         bfd_set_error (bfd_error_file_truncated);
+         return -1;
+       }
+    }
+
 #if SIZEOF_LONG == SIZEOF_INT
   if (asect->reloc_count >= LONG_MAX / sizeof (arelent *))
     {
@@ -8554,7 +8567,7 @@ _bfd_elf_canonicalize_dynamic_symtab (bfd *abfd,
 long
 _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
 {
-  bfd_size_type count;
+  bfd_size_type count, ext_rel_size;
   asection *s;
 
   if (elf_dynsymtab (abfd) == 0)
@@ -8564,11 +8577,18 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
     }
 
   count = 1;
+  ext_rel_size = 0;
   for (s = abfd->sections; s != NULL; s = s->next)
     if (elf_section_data (s)->this_hdr.sh_link == elf_dynsymtab (abfd)
        && (elf_section_data (s)->this_hdr.sh_type == SHT_REL
            || elf_section_data (s)->this_hdr.sh_type == SHT_RELA))
       {
+       ext_rel_size += s->size;
+       if (ext_rel_size < s->size)
+         {
+           bfd_set_error (bfd_error_file_truncated);
+           return -1;
+         }
        count += s->size / elf_section_data (s)->this_hdr.sh_entsize;
        if (count > LONG_MAX / sizeof (arelent *))
          {
@@ -8576,6 +8596,16 @@ _bfd_elf_get_dynamic_reloc_upper_bound (bfd *abfd)
            return -1;
          }
       }
+  if (count > 1)
+    {
+      /* Sanity check reloc section sizes.  */
+      ufile_ptr filesize = bfd_get_file_size (abfd);
+      if (filesize != 0 && ext_rel_size > filesize)
+       {
+         bfd_set_error (bfd_error_file_truncated);
+         return -1;
+       }
+    }
   return count * sizeof (arelent *);
 }
 
@@ -8984,8 +9014,7 @@ _bfd_elf_slurp_version_tables (bfd *abfd, bfd_boolean default_imported_symver)
   return TRUE;
 
  error_return:
-  if (contents != NULL)
-    free (contents);
+  free (contents);
   return FALSE;
 }
 \f
@@ -9391,7 +9420,9 @@ bfd_boolean
 _bfd_elf_close_and_cleanup (bfd *abfd)
 {
   struct elf_obj_tdata *tdata = elf_tdata (abfd);
-  if (bfd_get_format (abfd) == bfd_object && tdata != NULL)
+  if (tdata != NULL
+      && (bfd_get_format (abfd) == bfd_object
+         || bfd_get_format (abfd) == bfd_core))
     {
       if (elf_tdata (abfd)->o != NULL && elf_shstrtab (abfd) != NULL)
        _bfd_elf_strtab_free (elf_shstrtab (abfd));
@@ -9422,8 +9453,6 @@ _bfd_elf_rel_vtable_reloc_fn
    out details about the corefile.  */
 
 #ifdef HAVE_SYS_PROCFS_H
-/* Needed for new procfs interface on sparc-solaris.  */
-# define _STRUCTURED_PROC 1
 # include <sys/procfs.h>
 #endif
 
@@ -9848,6 +9877,12 @@ elfcore_grok_aarch_pauth (bfd *abfd, Elf_Internal_Note *note)
   return elfcore_make_note_pseudosection (abfd, ".reg-aarch-pauth", note);
 }
 
+static bfd_boolean
+elfcore_grok_arc_v2 (bfd *abfd, Elf_Internal_Note *note)
+{
+  return elfcore_make_note_pseudosection (abfd, ".reg-arc-v2", note);
+}
+
 #if defined (HAVE_PRPSINFO_T)
 typedef prpsinfo_t   elfcore_psinfo_t;
 #if defined (HAVE_PRPSINFO32_T)                /* Sparc64 cross Sparc32 */
@@ -10407,6 +10442,13 @@ elfcore_grok_note (bfd *abfd, Elf_Internal_Note *note)
       else
        return TRUE;
 
+    case NT_ARC_V2:
+      if (note->namesz == 6
+         && strcmp (note->namedata, "LINUX") == 0)
+       return elfcore_grok_arc_v2 (abfd, note);
+      else
+       return TRUE;
+
     case NT_ARM_VFP:
       if (note->namesz == 6
          && strcmp (note->namedata, "LINUX") == 0)
@@ -11818,6 +11860,18 @@ elfcore_write_aarch_pauth (bfd *abfd,
                             note_name, NT_ARM_PAC_MASK, aarch_pauth, size);
 }
 
+char *
+elfcore_write_arc_v2 (bfd *abfd,
+                     char *buf,
+                     int *bufsiz,
+                     const void *arc_v2,
+                     int size)
+{
+  char *note_name = "LINUX";
+  return elfcore_write_note (abfd, buf, bufsiz,
+                            note_name, NT_ARC_V2, arc_v2, size);
+}
+
 char *
 elfcore_write_register_note (bfd *abfd,
                             char *buf,
@@ -11900,6 +11954,8 @@ elfcore_write_register_note (bfd *abfd,
     return elfcore_write_aarch_sve (abfd, buf, bufsiz, data, size);
   if (strcmp (section, ".reg-aarch-pauth") == 0)
     return elfcore_write_aarch_pauth (abfd, buf, bufsiz, data, size);
+  if (strcmp (section, ".reg-arc-v2") == 0)
+    return elfcore_write_arc_v2 (abfd, buf, bufsiz, data, size);
   return NULL;
 }
 
This page took 0.030515 seconds and 4 git commands to generate.