RISC-V: Ouput __global_pointer$ as dynamic symbol when generating dynamic PDE.
[deliverable/binutils-gdb.git] / bfd / elf.c
index 9624df7271ea9deba7b451b10ac0d3af0c83a643..3f4ccd20559bfea3cbd714644203641ee3bf5e97 100644 (file)
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1,6 +1,6 @@
 /* ELF executable support for BFD.
 
-   Copyright (C) 1993-2020 Free Software Foundation, Inc.
+   Copyright (C) 1993-2021 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -2045,49 +2045,20 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
   const struct elf_backend_data *bed;
   const char *name;
   bfd_boolean ret = TRUE;
-  static bfd_boolean * sections_being_created = NULL;
-  static bfd * sections_being_created_abfd = NULL;
-  static unsigned int nesting = 0;
 
   if (shindex >= elf_numsections (abfd))
     return FALSE;
 
-  if (++ nesting > 3)
+  /* PR17512: A corrupt ELF binary might contain a loop of sections via
+     sh_link or sh_info.  Detect this here, by refusing to load a
+     section that we are already in the process of loading.  */
+  if (elf_tdata (abfd)->being_created[shindex])
     {
-      /* PR17512: A corrupt ELF binary might contain a recursive group of
-        sections, with each the string indices pointing to the next in the
-        loop.  Detect this here, by refusing to load a section that we are
-        already in the process of loading.  We only trigger this test if
-        we have nested at least three sections deep as normal ELF binaries
-        can expect to recurse at least once.
-
-        FIXME: It would be better if this array was attached to the bfd,
-        rather than being held in a static pointer.  */
-
-      if (sections_being_created_abfd != abfd)
-       {
-         free (sections_being_created);
-         sections_being_created = NULL;
-       }
-      if (sections_being_created == NULL)
-       {
-         size_t amt = elf_numsections (abfd) * sizeof (bfd_boolean);
-
-         /* 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_zmalloc (amt);
-         if (sections_being_created == NULL)
-           return FALSE;
-         sections_being_created_abfd = abfd;
-       }
-      if (sections_being_created [shindex])
-       {
-         _bfd_error_handler
-           (_("%pB: warning: loop in section dependencies detected"), abfd);
-         return FALSE;
-       }
-      sections_being_created [shindex] = TRUE;
+      _bfd_error_handler
+       (_("%pB: warning: loop in section dependencies detected"), abfd);
+      return FALSE;
     }
+  elf_tdata (abfd)->being_created[shindex] = TRUE;
 
   hdr = elf_elfsections (abfd)[shindex];
   ehdr = elf_elfheader (abfd);
@@ -2611,14 +2582,7 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
  fail:
   ret = FALSE;
  success:
-  if (sections_being_created && sections_being_created_abfd == abfd)
-    sections_being_created [shindex] = FALSE;
-  if (-- nesting == 0)
-    {
-      free (sections_being_created);
-      sections_being_created = NULL;
-      sections_being_created_abfd = NULL;
-    }
+  elf_tdata (abfd)->being_created[shindex] = FALSE;
   return ret;
 }
 
@@ -2705,6 +2669,8 @@ static const struct bfd_elf_special_section special_sections_f[] =
 static const struct bfd_elf_special_section special_sections_g[] =
 {
   { STRING_COMMA_LEN (".gnu.linkonce.b"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".gnu.linkonce.n"), -2, SHT_NOBITS,      SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".gnu.linkonce.p"), -2, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".gnu.lto_"),      -1, SHT_PROGBITS,    SHF_EXCLUDE },
   { STRING_COMMA_LEN (".got"),            0, SHT_PROGBITS,    SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".gnu.version"),    0, SHT_GNU_versym,  0 },
@@ -2738,6 +2704,7 @@ static const struct bfd_elf_special_section special_sections_l[] =
 
 static const struct bfd_elf_special_section special_sections_n[] =
 {
+  { STRING_COMMA_LEN (".noinit"),       -2, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".note.GNU-stack"), 0, SHT_PROGBITS, 0 },
   { STRING_COMMA_LEN (".note"),                 -1, SHT_NOTE,     0 },
   { NULL,                   0,           0, 0,            0 }
@@ -2745,6 +2712,7 @@ static const struct bfd_elf_special_section special_sections_n[] =
 
 static const struct bfd_elf_special_section special_sections_p[] =
 {
+  { STRING_COMMA_LEN (".persistent"),   -2, SHT_PROGBITS,      SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".preinit_array"), -2, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_WRITE },
   { STRING_COMMA_LEN (".plt"),           0, SHT_PROGBITS,      SHF_ALLOC + SHF_EXECINSTR },
   { NULL,                  0,            0, 0,                 0 }
@@ -4460,7 +4428,14 @@ get_program_header_size (bfd *abfd, struct bfd_link_info *info)
       && (elf_tdata (abfd)->has_gnu_osabi & elf_gnu_osabi_mbind) != 0)
     {
       /* Add a PT_GNU_MBIND segment for each mbind section.  */
-      unsigned int page_align_power = bfd_log2 (bed->commonpagesize);
+      bfd_vma commonpagesize;
+      unsigned int page_align_power;
+
+      if (info != NULL)
+       commonpagesize = info->commonpagesize;
+      else
+       commonpagesize = bed->commonpagesize;
+      page_align_power = bfd_log2 (commonpagesize);
       for (s = abfd->sections; s != NULL; s = s->next)
        if (elf_section_flags (s) & SHF_GNU_MBIND)
          {
@@ -4704,7 +4679,10 @@ _bfd_elf_map_sections_to_segments (bfd *abfd, struct bfd_link_info *info)
       phdr_size += bed->s->sizeof_ehdr;
       /* phdr_size is compared to LMA values which are in bytes.  */
       phdr_size /= opb;
-      maxpagesize = bed->maxpagesize;
+      if (info != NULL)
+       maxpagesize = info->maxpagesize;
+      else
+       maxpagesize = bed->maxpagesize;
       if (maxpagesize == 0)
        maxpagesize = 1;
       phdr_in_segment = info != NULL && info->load_phdrs;
@@ -5253,7 +5231,8 @@ elf_sort_sections (const void *arg1, const void *arg2)
 
   /* Put !SEC_LOAD sections after SEC_LOAD ones.  */
 
-#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0)
+#define TOEND(x) (((x)->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 \
+                 && (x)->size != 0)
 
   if (TOEND (sec1))
     {
@@ -5506,7 +5485,12 @@ assign_file_positions_for_load_sections (bfd *abfd,
 
   maxpagesize = 1;
   if ((abfd->flags & D_PAGED) != 0)
-    maxpagesize = bed->maxpagesize;
+    {
+      if (link_info != NULL)
+       maxpagesize = link_info->maxpagesize;
+      else
+       maxpagesize = bed->maxpagesize;
+    }
 
   /* Sections must map to file offsets past the ELF file header.  */
   off = bed->s->sizeof_ehdr;
@@ -6087,7 +6071,12 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
   struct elf_segment_map *m;
   file_ptr off;
   unsigned int opb = bfd_octets_per_byte (abfd, NULL);
+  bfd_vma maxpagesize;
 
+  if (link_info != NULL)
+    maxpagesize = link_info->maxpagesize;
+  else
+    maxpagesize = bed->maxpagesize;
   i_shdrpp = elf_elfsections (abfd);
   end_hdrpp = i_shdrpp + elf_numsections (abfd);
   off = elf_next_file_pos (abfd);
@@ -6120,7 +6109,7 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
          /* We don't need to page align empty sections.  */
          if ((abfd->flags & D_PAGED) != 0 && hdr->sh_size != 0)
            off += vma_page_aligned_bias (hdr->sh_addr, off,
-                                         bed->maxpagesize);
+                                         maxpagesize);
          else
            off += vma_page_aligned_bias (hdr->sh_addr, off,
                                          hdr->sh_addralign);
@@ -6798,7 +6787,7 @@ _bfd_elf_symbol_from_bfd_symbol (bfd *abfd, asymbol **asym_ptr_ptr)
 /* Rewrite program header information.  */
 
 static bfd_boolean
-rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
+rewrite_elf_program_header (bfd *ibfd, bfd *obfd, bfd_vma maxpagesize)
 {
   Elf_Internal_Ehdr *iehdr;
   struct elf_segment_map *map;
@@ -6810,7 +6799,6 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
   unsigned int num_segments;
   bfd_boolean phdr_included = FALSE;
   bfd_boolean p_paddr_valid;
-  bfd_vma maxpagesize;
   struct elf_segment_map *phdr_adjust_seg = NULL;
   unsigned int phdr_adjust_num = 0;
   const struct elf_backend_data *bed;
@@ -6823,7 +6811,6 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
   pointer_to_map = &map_first;
 
   num_segments = elf_elfheader (ibfd)->e_phnum;
-  maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
 
   /* Returns the end address of the segment + 1.  */
 #define SEGMENT_END(segment, start)                                    \
@@ -7080,6 +7067,17 @@ rewrite_elf_program_header (bfd *ibfd, bfd *obfd)
       map->p_flags = segment->p_flags;
       map->p_flags_valid = 1;
 
+      if (map->p_type == PT_LOAD
+         && (ibfd->flags & D_PAGED) != 0
+         && maxpagesize > 1
+         && segment->p_align > 1)
+       {
+         map->p_align = segment->p_align;
+         if (segment->p_align > maxpagesize)
+           map->p_align = maxpagesize;
+         map->p_align_valid = 1;
+       }
+
       /* If the first section in the input segment is removed, there is
         no need to preserve segment physical address in the corresponding
         output segment.  */
@@ -7644,6 +7642,8 @@ copy_elf_program_header (bfd *ibfd, bfd *obfd)
 static bfd_boolean
 copy_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
+  bfd_vma maxpagesize;
+
   if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
       || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
     return TRUE;
@@ -7728,6 +7728,7 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
     }
 
  rewrite:
+  maxpagesize = 0;
   if (ibfd->xvec == obfd->xvec)
     {
       /* When rewriting program header, set the output maxpagesize to
@@ -7735,7 +7736,6 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
       Elf_Internal_Phdr *segment;
       unsigned int i;
       unsigned int num_segments = elf_elfheader (ibfd)->e_phnum;
-      bfd_vma maxpagesize = 0;
 
       for (i = 0, segment = elf_tdata (ibfd)->phdr;
           i < num_segments;
@@ -7752,12 +7752,11 @@ copy_private_bfd_data (bfd *ibfd, bfd *obfd)
            else
              maxpagesize = segment->p_align;
          }
-
-      if (maxpagesize != get_elf_backend_data (obfd)->maxpagesize)
-       bfd_emul_set_maxpagesize (bfd_get_target (obfd), maxpagesize);
     }
+  if (maxpagesize == 0)
+    maxpagesize = get_elf_backend_data (obfd)->maxpagesize;
 
-  return rewrite_elf_program_header (ibfd, obfd);
+  return rewrite_elf_program_header (ibfd, obfd, maxpagesize);
 }
 
 /* Initialize private output section information from input section.  */
@@ -12560,9 +12559,10 @@ _bfd_elf_init_secondary_reloc_section (bfd * abfd,
 /* Read in any secondary relocs associated with SEC.  */
 
 bfd_boolean
-_bfd_elf_slurp_secondary_reloc_section (bfd *      abfd,
-                                       asection * sec,
-                                       asymbol ** symbols)
+_bfd_elf_slurp_secondary_reloc_section (bfd *       abfd,
+                                       asection *  sec,
+                                       asymbol **  symbols,
+                                       bfd_boolean dynamic)
 {
   const struct elf_backend_data * const ebd = get_elf_backend_data (abfd);
   asection * relsec;
@@ -12641,7 +12641,10 @@ _bfd_elf_slurp_secondary_reloc_section (bfd *      abfd,
              continue;
            }
 
-         symcount = bfd_get_symcount (abfd);
+         if (dynamic)
+           symcount = bfd_get_dynamic_symcount (abfd);
+         else
+           symcount = bfd_get_symcount (abfd);
 
          for (i = 0, internal_reloc = internal_relocs,
                 native_reloc = native_relocs;
@@ -12688,7 +12691,6 @@ _bfd_elf_slurp_secondary_reloc_section (bfd *      abfd,
                  asymbol **ps;
 
                  ps = symbols + r_sym (rela.r_info) - 1;
-
                  internal_reloc->sym_ptr_ptr = ps;
                  /* Make sure that this symbol is not removed by strip.  */
                  (*ps)->flags |= BSF_KEEP;
This page took 0.027497 seconds and 4 git commands to generate.