Handle EITR records in VMS Alpha binaries with overlarge command length parameters.
[deliverable/binutils-gdb.git] / bfd / elf32-s390.c
index 79c40509381ffa102ba414e8d809b51f9e239550..c26bdcf900a666b4a267372674edabc4570bc2ab 100644 (file)
@@ -1,5 +1,5 @@
 /* IBM S/390-specific support for 32-bit ELF
-   Copyright (C) 2000-2016 Free Software Foundation, Inc.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
    Contributed by Carl B. Pedersen and Martin Schwidefsky.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -873,7 +873,8 @@ elf_s390_copy_indirect_symbol (struct bfd_link_info *info,
       /* If called to transfer flags for a weakdef during processing
         of elf_adjust_dynamic_symbol, don't copy non_got_ref.
         We clear it ourselves for ELIMINATE_COPY_RELOCS.  */
-      dir->ref_dynamic |= ind->ref_dynamic;
+      if (dir->versioned != versioned_hidden)
+       dir->ref_dynamic |= ind->ref_dynamic;
       dir->ref_regular |= ind->ref_regular;
       dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
       dir->needs_plt |= ind->needs_plt;
@@ -995,7 +996,7 @@ elf_s390_check_relocs (bfd *abfd,
 
          /* 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;
        }
 
       /* Create got section and local_got_refcounts array if they
@@ -1607,7 +1608,7 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
                                struct elf_link_hash_entry *h)
 {
   struct elf_s390_link_hash_table *htab;
-  asection *s;
+  asection *s, *srel;
 
   /* STT_GNU_IFUNC symbol must go through PLT. */
   if (s390_is_ifunc_symbol_p (h))
@@ -1757,14 +1758,22 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
   /* We must generate a R_390_COPY reloc to tell the dynamic linker to
      copy the initial value out of the dynamic object and into the
      runtime process image.  */
+  if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
+    {
+      s = htab->elf.sdynrelro;
+      srel = htab->elf.sreldynrelro;
+    }
+  else
+    {
+      s = htab->elf.sdynbss;
+      srel = htab->elf.srelbss;
+    }
   if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
     {
-      htab->elf.srelbss->size += sizeof (Elf32_External_Rela);
+      srel->size += sizeof (Elf32_External_Rela);
       h->needs_copy = 1;
     }
 
-  s = htab->elf.sdynbss;
-
   return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
@@ -2157,6 +2166,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          || s == htab->elf.sgot
          || s == htab->elf.sgotplt
          || s == htab->elf.sdynbss
+         || s == htab->elf.sdynrelro
          || s == htab->elf.iplt
          || s == htab->elf.igotplt
          || s == htab->irelifunc)
@@ -2764,7 +2774,7 @@ elf_s390_relocate_section (bfd *output_bfd,
              && s390_is_ifunc_symbol_p (h)
              && h->def_regular)
            {
-             if (!bfd_link_pic (info) || !h->non_got_ref)
+             if (!bfd_link_pic (info))
                {
                  /* For a non-shared object STT_GNU_IFUNC symbol must
                     go through PLT.  */
@@ -3221,7 +3231,6 @@ elf_s390_relocate_section (bfd *output_bfd,
                  unsigned int insn, ry;
 
                  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
-                 ry = 0;
                  if ((insn & 0xff00f000) == 0x58000000)
                    /* l %rx,0(%ry,0) -> lr %rx,%ry + bcr 0,0  */
                    ry = (insn & 0x000f0000);
@@ -3235,7 +3244,10 @@ elf_s390_relocate_section (bfd *output_bfd,
                    /* l %rx,0(%r12,%ry) -> lr %rx,%ry + bcr 0,0  */
                    ry = (insn & 0x0000f000) << 4;
                  else
-                   invalid_tls_insn (input_bfd, input_section, rel);
+                   {
+                     invalid_tls_insn (input_bfd, input_section, rel);
+                     return FALSE;
+                   }
                  insn = 0x18000700 | (insn & 0x00f00000) | ry;
                  bfd_put_32 (output_bfd, insn, contents + rel->r_offset);
                }
@@ -3248,7 +3260,10 @@ elf_s390_relocate_section (bfd *output_bfd,
              if ((insn & 0xff000fff) != 0x4d000000 &&
                  (insn & 0xffff0000) != 0xc0e50000 &&
                  (insn & 0xff000000) != 0x0d000000)
-               invalid_tls_insn (input_bfd, input_section, rel);
+               {
+                 invalid_tls_insn (input_bfd, input_section, rel);
+                 return FALSE;
+               }
              if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
                {
                  if ((insn & 0xff000000) == 0x0d000000)
@@ -3277,7 +3292,10 @@ elf_s390_relocate_section (bfd *output_bfd,
                  /* If basr is used in the pic case to invoke
                     _tls_get_offset, something went wrong before.  */
                  if ((insn & 0xff000000) == 0x0d000000)
-                   invalid_tls_insn (input_bfd, input_section, rel);
+                   {
+                     invalid_tls_insn (input_bfd, input_section, rel);
+                     return FALSE;
+                   }
 
                  if ((insn & 0xff000000) == 0x4d000000)
                    {
@@ -3307,7 +3325,10 @@ elf_s390_relocate_section (bfd *output_bfd,
                  if ((insn & 0xff000fff) != 0x4d000000 &&
                      (insn & 0xffff0000) != 0xc0e50000 &&
                      (insn & 0xff000000) != 0x0d000000)
-                   invalid_tls_insn (input_bfd, input_section, rel);
+                   {
+                     invalid_tls_insn (input_bfd, input_section, rel);
+                     return FALSE;
+                   }
 
                  if ((insn & 0xff000000) == 0x0d000000)
                    {
@@ -3775,7 +3796,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
             RELATIVE reloc.  The entry in the global offset table
             will already have been initialized in the
             relocate_section function.  */
-         if (!h->def_regular)
+         if (!(h->def_regular || ELF_COMMON_DEF_P (h)))
            return FALSE;
          BFD_ASSERT((h->got.offset & 1) != 0);
          rela.r_info = ELF32_R_INFO (0, R_390_RELATIVE);
@@ -3800,6 +3821,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
   if (h->needs_copy)
     {
       Elf_Internal_Rela rela;
+      asection *s;
       bfd_byte *loc;
 
       /* This symbols needs a copy reloc.  Set it up.  */
@@ -3807,7 +3829,8 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
       if (h->dynindx == -1
          || (h->root.type != bfd_link_hash_defined
              && h->root.type != bfd_link_hash_defweak)
-         || htab->elf.srelbss == NULL)
+         || htab->elf.srelbss == NULL
+         || htab->elf.sreldynrelro == NULL)
        abort ();
 
       rela.r_offset = (h->root.u.def.value
@@ -3815,8 +3838,11 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
                       + h->root.u.def.section->output_offset);
       rela.r_info = ELF32_R_INFO (h->dynindx, R_390_COPY);
       rela.r_addend = 0;
-      loc = htab->elf.srelbss->contents;
-      loc += htab->elf.srelbss->reloc_count++ * sizeof (Elf32_External_Rela);
+      if (h->root.u.def.section == htab->elf.sdynrelro)
+       s = htab->elf.sreldynrelro;
+      else
+       s = htab->elf.srelbss;
+      loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
       bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
     }
 
@@ -4154,6 +4180,7 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 #define elf_backend_plt_readonly       1
 #define elf_backend_want_plt_sym       0
 #define elf_backend_got_header_size    12
+#define elf_backend_want_dynrelro      1
 #define elf_backend_rela_normal                1
 
 #define elf_info_to_howto                    elf_s390_info_to_howto
This page took 0.025436 seconds and 4 git commands to generate.