PR21910, segfault in common symbol override test when hash-style=gnu
[deliverable/binutils-gdb.git] / bfd / elf32-nios2.c
index ad8eb45342c0065ecdaa238d98594988537b5484..860a3d7af5004574f51d8dbf4a46132487a70845 100644 (file)
@@ -1,5 +1,5 @@
 /* 32-bit ELF support for Nios II.
-   Copyright (C) 2012-2016 Free Software Foundation, Inc.
+   Copyright (C) 2012-2017 Free Software Foundation, Inc.
    Contributed by Nigel Gray (ngray@altera.com).
    Contributed by Mentor Graphics, Inc.
 
@@ -1820,8 +1820,6 @@ struct elf32_nios2_link_hash_table
     Elf_Internal_Sym **all_local_syms;
 
     /* Short-cuts to get to dynamic linker sections.  */
-    asection *sdynbss;
-    asection *srelbss;
     asection *sbss;
 
     /* GOT pointer symbol _gp_got.  */
@@ -3715,10 +3713,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
   splt = htab->root.splt;
   local_got_offsets = elf_local_got_offsets (input_bfd);
 
-  if (elf32_nios2_hash_table (info)->h_gp_got == NULL)
+  if (htab->h_gp_got == NULL)
     got_base = 0;
   else
-    got_base = elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value;
+    got_base = htab->h_gp_got->root.u.def.value;
 
   for (rel = relocs; rel < relend; rel++)
     {
@@ -4000,7 +3998,7 @@ nios2_elf32_relocate_section (bfd *output_bfd,
 
                  off = h->got.offset;
                  BFD_ASSERT (off != (bfd_vma) -1);
-                 dyn = elf_hash_table (info)->dynamic_sections_created;
+                 dyn = htab->root.dynamic_sections_created;
                  if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
                                                         bfd_link_pic (info),
                                                         h)
@@ -4371,10 +4369,10 @@ nios2_elf32_relocate_section (bfd *output_bfd,
                {
                  _bfd_error_handler
                    /* xgettext:c-format */
-                   (_("%B(%A+0x%lx): R_NIOS2_TLS_LE16 relocation not "
+                   (_("%B(%A+%#Lx): %s relocation not "
                       "permitted in shared object"),
                     input_bfd, input_section,
-                    (long) rel->r_offset, howto->name);
+                    rel->r_offset, howto->name);
                  return FALSE;
                }
              else
@@ -4582,7 +4580,7 @@ create_got_section (bfd *dynobj, struct bfd_link_info *info)
      points to the base of the GOT while _gp_got may include a bias.  */
   h = _bfd_elf_define_linkage_sym (dynobj, info, htab->root.sgotplt,
                                   "_gp_got");
-  elf32_nios2_hash_table (info)->h_gp_got = h;
+  htab->h_gp_got = h;
   if (h == NULL)
     return FALSE;
 
@@ -4602,26 +4600,14 @@ nios2_elf32_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
   if (!htab->root.sgot && !create_got_section (dynobj, info))
     return FALSE;
 
-  _bfd_elf_create_dynamic_sections (dynobj, info);
+  if (!_bfd_elf_create_dynamic_sections (dynobj, info))
+    return FALSE;
 
   /* In order for the two loads in a shared object .PLTresolve to share the
      same %hiadj, the start of the PLT (as well as the GOT) must be aligned
      to a 16-byte boundary.  This is because the addresses for these loads
      include the -(.plt+4) PIC correction.  */
-  if (!bfd_set_section_alignment (dynobj, htab->root.splt, 4))
-    return FALSE;
-
-  htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
-  if (!htab->sdynbss)
-    return FALSE;
-  if (!bfd_link_pic (info))
-    {
-      htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
-      if (!htab->srelbss)
-       return FALSE;
-    }
-
-  return TRUE;
+  return bfd_set_section_alignment (dynobj, htab->root.splt, 4);
 }
 
 /* Implement elf_backend_copy_indirect_symbol:
@@ -4708,21 +4694,17 @@ static bfd_boolean
 nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                          asection *sec, const Elf_Internal_Rela *relocs)
 {
-  bfd *dynobj;
   Elf_Internal_Shdr *symtab_hdr;
   struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
   const Elf_Internal_Rela *rel;
   const Elf_Internal_Rela *rel_end;
   struct elf32_nios2_link_hash_table *htab;
-  asection *sgot;
-  asection *srelgot;
   asection *sreloc = NULL;
   bfd_signed_vma *local_got_refcounts;
 
   if (bfd_link_relocatable (info))
     return TRUE;
 
-  dynobj = elf_hash_table (info)->dynobj;
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   sym_hashes = elf_sym_hashes (abfd);
   sym_hashes_end = (sym_hashes
@@ -4732,8 +4714,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
   local_got_refcounts = elf_local_got_refcounts (abfd);
 
   htab = elf32_nios2_hash_table (info);
-  sgot = htab->root.sgot;
-  srelgot = htab->root.srelgot;
 
   rel_end = relocs + sec->reloc_count;
   for (rel = relocs; rel < rel_end; rel++)
@@ -4754,7 +4734,7 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
          /* PR15323, ref flags aren't set for references in the same
             object.  */
-         h->root.non_ir_ref = 1;
+         h->root.non_ir_ref_regular = 1;
        }
 
       r_type = ELF32_R_TYPE (rel->r_info);
@@ -4792,26 +4772,6 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                break;
              }
 
-           if (dynobj == NULL)
-             {
-               /* Create the .got section.  */
-               elf_hash_table (info)->dynobj = dynobj = abfd;
-               nios2_elf32_create_dynamic_sections (dynobj, info);
-             }
-
-           if (sgot == NULL)
-             {
-               sgot = htab->root.sgot;
-               BFD_ASSERT (sgot != NULL);
-             }
-
-           if (srelgot == NULL
-               && (h != NULL || bfd_link_pic (info)))
-             {
-               srelgot = htab->root.srelgot;
-               BFD_ASSERT (srelgot != NULL);
-             }
-
            if (h != NULL)
              {
                struct elf32_nios2_link_hash_entry *eh
@@ -4870,11 +4830,7 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                  elf32_nios2_local_got_tls_type (abfd) [r_symndx] = tls_type;
              }
          }
-         /* Fall through */
-       case R_NIOS2_TLS_LDM16:
-         if (r_type == R_NIOS2_TLS_LDM16)
-           htab->tls_ldm_got.refcount++;
-
+       make_got:
          if (htab->root.sgot == NULL)
            {
              if (htab->root.dynobj == NULL)
@@ -4884,6 +4840,10 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
            }
          break;
 
+       case R_NIOS2_TLS_LDM16:
+         htab->tls_ldm_got.refcount++;
+         goto make_got;
+
          /* This relocation describes the C++ object vtable hierarchy.
             Reconstruct it for later use during GC.  */
        case R_NIOS2_GNU_VTINHERIT:
@@ -4939,8 +4899,11 @@ nios2_elf32_check_relocs (bfd *abfd, struct bfd_link_info *info,
                 section in dynobj and make room for this reloc.  */
              if (sreloc == NULL)
                {
+                 if (htab->root.dynobj == NULL)
+                   htab->root.dynobj = abfd;
+
                  sreloc = _bfd_elf_make_dynamic_reloc_section
-                   (sec, dynobj, 2, abfd, TRUE);
+                   (sec, htab->root.dynobj, 2, abfd, TRUE);
                  if (sreloc == NULL)
                    return FALSE;
                }
@@ -5289,22 +5252,24 @@ nios2_elf32_finish_dynamic_symbol (bfd *output_bfd,
                  && (h->root.type == bfd_link_hash_defined
                      || h->root.type == bfd_link_hash_defweak));
 
-      s = htab->srelbss;
-      BFD_ASSERT (s != NULL);
-
       rela.r_offset = (h->root.u.def.value
                       + h->root.u.def.section->output_section->vma
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_NIOS2_COPY);
       rela.r_addend = 0;
+      if (h->root.u.def.section == htab->root.sdynrelro)
+       s = htab->root.sreldynrelro;
+      else
+       s = htab->root.srelbss;
+      BFD_ASSERT (s != NULL);
       loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
 
   /* Mark _DYNAMIC, _GLOBAL_OFFSET_TABLE_, and _gp_got as absolute.  */
   if (strcmp (h->root.root.string, "_DYNAMIC") == 0
-      || h == elf_hash_table (info)->hgot
-      || h == elf32_nios2_hash_table (info)->h_gp_got)
+      || h == htab->root.hgot
+      || h == htab->h_gp_got)
     sym->st_shndx = SHN_ABS;
 
   return TRUE;
@@ -5315,24 +5280,22 @@ static bfd_boolean
 nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
                                     struct bfd_link_info *info)
 {
-  bfd *dynobj;
   asection *sgotplt;
   asection *sdyn;
   struct elf32_nios2_link_hash_table *htab;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
   sgotplt = htab->root.sgotplt;
-  BFD_ASSERT (sgotplt != NULL);
-  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
+  sdyn = NULL;
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       asection *splt;
       Elf32_External_Dyn *dyncon, *dynconend;
 
       splt = htab->root.splt;
-      BFD_ASSERT (splt != NULL && sdyn != NULL);
+      sdyn = bfd_get_linker_section (htab->root.dynobj, ".dynamic");
+      BFD_ASSERT (splt != NULL && sdyn != NULL && sgotplt != NULL);
 
       dyncon = (Elf32_External_Dyn *) sdyn->contents;
       dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
@@ -5341,7 +5304,7 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
          Elf_Internal_Dyn dyn;
          asection *s;
 
-         bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
+         bfd_elf32_swap_dyn_in (htab->root.dynobj, dyncon, &dyn);
 
          switch (dyn.d_tag)
            {
@@ -5366,20 +5329,6 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
-           case DT_RELASZ:
-             /* The procedure linkage table relocs (DT_JMPREL) should
-                not be included in the overall relocs (DT_RELA).
-                Therefore, we override the DT_RELASZ entry here to
-                make it not include the JMPREL relocs.  Since the
-                linker script arranges for .rela.plt to follow all
-                other relocation sections, we don't have to worry
-                about changing the DT_RELA entry.  */
-             s = htab->root.srelplt;
-             if (s != NULL)
-               dyn.d_un.d_val -= s->size;
-             bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
-             break;
-
            case DT_NIOS2_GP:
              s = htab->root.sgotplt;
              dyn.d_un.d_ptr
@@ -5439,8 +5388,9 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
            }
        }
     }
+
   /* Fill in the first three entries in the global offset table.  */
-  if (sgotplt->size > 0)
+  if (sgotplt != NULL && sgotplt->size > 0)
     {
       if (sdyn == NULL)
        bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents);
@@ -5450,9 +5400,10 @@ nios2_elf32_finish_dynamic_sections (bfd *output_bfd,
                    sgotplt->contents);
       bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 4);
       bfd_put_32 (output_bfd, (bfd_vma) 0, sgotplt->contents + 8);
-    }
 
-  elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+      if (sgotplt->output_section != bfd_abs_section_ptr)
+       elf_section_data (sgotplt->output_section)->this_hdr.sh_entsize = 4;
+    }
 
   return TRUE;
 }
@@ -5469,11 +5420,11 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
 {
   struct elf32_nios2_link_hash_table *htab;
   bfd *dynobj;
-  asection *s;
+  asection *s, *srel;
   unsigned align2;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
 
   /* Make sure we know what is going on here.  */
   BFD_ASSERT (dynobj != NULL
@@ -5551,19 +5502,22 @@ nios2_elf32_adjust_dynamic_symbol (struct bfd_link_info *info,
      determine the address it must put in the global offset table, so
      both the dynamic object and the regular object will refer to the
      same memory location for the variable.  */
-  s = htab->sdynbss;
-  BFD_ASSERT (s != NULL);
-
   /* We must generate a R_NIOS2_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  We need to remember the offset into the
      .rela.bss section we are going to use.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->root.sdynrelro;
+      srel = htab->root.sreldynrelro;
+    }
+  else
+    {
+      s = htab->root.sdynbss;
+      srel = htab->root.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
     {
-      asection *srel;
-
-      srel = htab->srelbss;
-      BFD_ASSERT (srel != NULL);
       srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
@@ -5857,18 +5811,16 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 {
   bfd *dynobj;
   asection *s;
-  bfd_boolean plt;
-  bfd_boolean got;
   bfd_boolean relocs;
   bfd *ibfd;
   struct elf32_nios2_link_hash_table *htab;
 
   htab = elf32_nios2_hash_table (info);
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = htab->root.dynobj;
   BFD_ASSERT (dynobj != NULL);
 
   htab->res_n_size = 0;
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
       if (bfd_link_executable (info) && !info->nointerp)
@@ -5976,21 +5928,19 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
      sym dynamic relocs.  */
   elf_link_hash_traverse (& htab->root, allocate_dynrelocs, info);
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* If the .got section is more than 0x8000 bytes, we add
         0x8000 to the value of _gp_got, so that 16-bit relocations
         have a greater chance of working. */
       if (htab->root.sgot->size >= 0x8000
-         && elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value == 0)
-       elf32_nios2_hash_table (info)->h_gp_got->root.u.def.value = 0x8000;
+         && htab->h_gp_got->root.u.def.value == 0)
+       htab->h_gp_got->root.u.def.value = 0x8000;
     }
 
   /* The check_relocs and adjust_dynamic_symbol entry points have
      determined the sizes of the various dynamic sections.  Allocate
      memory for them.  */
-  plt = FALSE;
-  got = FALSE;
   relocs = FALSE;
   for (s = dynobj->sections; s != NULL; s = s->next)
     {
@@ -6003,46 +5953,37 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
         of the dynobj section names depend upon the input files.  */
       name = bfd_get_section_name (dynobj, s);
 
-      if (strcmp (name, ".plt") == 0)
-       {
-         /* Remember whether there is a PLT.  */
-         plt = s->size != 0;
-
-         /* Correct for the number of res_N branches.  */
-         if (plt && !bfd_link_pic (info))
-           {
-             htab->res_n_size = (s->size-28) / 3;
-             s->size += htab->res_n_size;
-           }
-       }
-      else if (CONST_STRNEQ (name, ".rela"))
+      if (CONST_STRNEQ (name, ".rela"))
        {
          if (s->size != 0)
            {
-             relocs = TRUE;
+             if (s != htab->root.srelplt)
+               relocs = TRUE;
 
              /* We use the reloc_count field as a counter if we need
                 to copy relocs into the output file.  */
              s->reloc_count = 0;
            }
        }
-      else if (CONST_STRNEQ (name, ".got"))
-       got = s->size != 0;
-      else if (strcmp (name, ".dynbss") != 0)
+      else if (s == htab->root.splt)
+       {
+         /* Correct for the number of res_N branches.  */
+         if (s->size != 0 && !bfd_link_pic (info))
+           {
+             htab->res_n_size = (s->size - 28) / 3;
+             s->size += htab->res_n_size;
+           }
+       }
+      else if (s != htab->sbss
+              && s != htab->root.sgot
+              && s != htab->root.sgotplt
+              && s != htab->root.sdynbss
+              && s != htab->root.sdynrelro)
        /* It's not one of our sections, so don't allocate space.  */
        continue;
 
       if (s->size == 0)
        {
-         /* If we don't need this section, strip it from the
-            output file.  This is mostly to handle .rela.bss and
-            .rela.plt.  We must create both sections in
-            create_dynamic_sections, because they must be created
-            before the linker maps input sections to output
-            sections.  The linker does that before
-            adjust_dynamic_symbol is called, and it is that
-            function which decides whether anything needs to go
-            into these sections.  */
          s->flags |= SEC_EXCLUDE;
          continue;
        }
@@ -6051,11 +5992,6 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
        continue;
 
       /* Allocate memory for the section contents.  */
-      /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
-        Unused entries should be reclaimed before the section's contents
-        are written out, but at the moment this does not happen.  Thus in
-        order to prevent writing out garbage, we initialize the section's
-        contents to zero.  */
       s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
       if (s->contents == NULL)
        return FALSE;
@@ -6066,7 +6002,7 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (htab->res_n_size)
     elf_link_hash_traverse (& htab->root, adjust_dynrelocs, info);
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (htab->root.dynamic_sections_created)
     {
       /* Add some entries to the .dynamic section.  We fill in the
         values later, in elf_nios2_finish_dynamic_sections, but we
@@ -6079,10 +6015,11 @@ nios2_elf32_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       if (!bfd_link_pic (info) && !add_dynamic_entry (DT_DEBUG, 0))
        return FALSE;
 
-      if (got && !add_dynamic_entry (DT_PLTGOT, 0))
+      if (htab->root.sgotplt->size != 0
+         && !add_dynamic_entry (DT_PLTGOT, 0))
        return FALSE;
 
-      if (plt
+      if (htab->root.splt->size != 0
          && (!add_dynamic_entry (DT_PLTRELSZ, 0)
              || !add_dynamic_entry (DT_PLTREL, DT_RELA)
              || !add_dynamic_entry (DT_JMPREL, 0)))
@@ -6189,8 +6126,6 @@ nios2_elf_add_symbol_hook (bfd *abfd,
                           asection **secp,
                           bfd_vma *valp)
 {
-  bfd *dynobj;
-
   if (sym->st_shndx == SHN_COMMON
       && !bfd_link_relocatable (info)
       && sym->st_size <= elf_gp_size (abfd)
@@ -6205,12 +6140,11 @@ nios2_elf_add_symbol_hook (bfd *abfd,
        {
          flagword flags = SEC_IS_COMMON | SEC_LINKER_CREATED;
 
-         dynobj = elf_hash_table (info)->dynobj;
-         if (!dynobj)
-           dynobj = abfd;
+         if (htab->root.dynobj == NULL)
+           htab->root.dynobj = abfd;
 
-         htab->sbss = bfd_make_section_anyway_with_flags (dynobj, ".sbss",
-                                                          flags);
+         htab->sbss = bfd_make_section_anyway_with_flags (htab->root.dynobj,
+                                                          ".sbss", flags);
          if (htab->sbss == NULL)
            return FALSE;
        }
@@ -6277,7 +6211,9 @@ const struct bfd_elf_special_section elf32_nios2_special_sections[] =
 #define elf_backend_can_refcount       1
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_got_plt       1
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
+#define elf_backend_dtrel_excludes_plt 1
 
 #define elf_backend_relocate_section     nios2_elf32_relocate_section
 #define elf_backend_section_flags        nios2_elf32_section_flags
This page took 0.036916 seconds and 4 git commands to generate.