Add bfd_link_pde, and simplify some tests of link_info.type
[deliverable/binutils-gdb.git] / bfd / elf32-s390.c
index 11c726fc7e8e799ddab6d36545d9022c1fd1a4b5..96c1531e7df0c291c0233c009f8f29861389a998 100644 (file)
@@ -1,5 +1,5 @@
 /* IBM S/390-specific support for 32-bit ELF
-   Copyright (C) 2000-2014 Free Software Foundation, Inc.
+   Copyright (C) 2000-2015 Free Software Foundation, Inc.
    Contributed by Carl B. Pedersen and Martin Schwidefsky.
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -39,7 +39,7 @@ static reloc_howto_type elf_howto_table[] =
 {
   HOWTO (R_390_NONE,           /* type */
         0,                     /* rightshift */
-        0,                     /* size (0 = byte, 1 = 2 byte, 2 = 4 byte) */
+        3,                     /* size (0 = byte, 1 = 2 byte, 2 = 4 byte) */
         0,                     /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
@@ -856,11 +856,11 @@ elf_s390_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
   htab->elf.splt = bfd_get_linker_section (dynobj, ".plt");
   htab->elf.srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
   htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
-  if (!info->shared)
+  if (!bfd_link_pic (info))
     htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
 
   if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
-      || (!info->shared && !htab->srelbss))
+      || (!bfd_link_pic (info) && !htab->srelbss))
     abort ();
 
   return TRUE;
@@ -937,7 +937,7 @@ elf_s390_tls_transition (struct bfd_link_info *info,
                         int r_type,
                         int is_local)
 {
-  if (info->shared)
+  if (bfd_link_pic (info))
     return r_type;
 
   switch (r_type)
@@ -978,7 +978,7 @@ elf_s390_check_relocs (bfd *abfd,
   int tls_type, old_tls_type;
   Elf_Internal_Sym *isym;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   BFD_ASSERT (is_s390_elf (abfd));
@@ -1177,7 +1177,7 @@ elf_s390_check_relocs (bfd *abfd,
        case R_390_TLS_GOTIE20:
        case R_390_TLS_GOTIE32:
        case R_390_TLS_IEENT:
-         if (info->shared)
+         if (bfd_link_pic (info))
            info->flags |= DF_STATIC_TLS;
          /* Fall through.  */
 
@@ -1250,7 +1250,13 @@ elf_s390_check_relocs (bfd *abfd,
          /* Fall through.  */
 
        case R_390_TLS_LE32:
-         if (!info->shared)
+         /* For static linking and executables this reloc will be
+            calculated at linktime otherwise a TLS_TPOFF runtime
+            reloc will be generated.  */
+         if (r_type == R_390_TLS_LE32 && bfd_link_pie (info))
+           break;
+
+         if (!bfd_link_pic (info))
            break;
          info->flags |= DF_STATIC_TLS;
          /* Fall through.  */
@@ -1274,7 +1280,7 @@ elf_s390_check_relocs (bfd *abfd,
                 adjust_dynamic_symbol.  */
              h->non_got_ref = 1;
 
-             if (!info->shared)
+             if (!bfd_link_pic (info))
                {
                  /* We may need a .plt entry if the function this reloc
                     refers to is in a shared lib.  */
@@ -1303,7 +1309,7 @@ elf_s390_check_relocs (bfd *abfd,
             may need to keep relocations for symbols satisfied by a
             dynamic library if we manage to avoid copy relocs for the
             symbol.  */
-         if ((info->shared
+         if ((bfd_link_pic (info)
               && (sec->flags & SEC_ALLOC) != 0
               && ((ELF32_R_TYPE (rel->r_info) != R_390_PC16
                    && ELF32_R_TYPE (rel->r_info) != R_390_PC12DBL
@@ -1316,7 +1322,7 @@ elf_s390_check_relocs (bfd *abfd,
                           || h->root.type == bfd_link_hash_defweak
                           || !h->def_regular))))
              || (ELIMINATE_COPY_RELOCS
-                 && !info->shared
+                 && !bfd_link_pic (info)
                  && (sec->flags & SEC_ALLOC) != 0
                  && h != NULL
                  && (h->root.type == bfd_link_hash_defweak
@@ -1453,7 +1459,7 @@ elf_s390_gc_sweep_hook (bfd *abfd,
   bfd_signed_vma *local_got_refcounts;
   const Elf_Internal_Rela *rel, *relend;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   htab = elf_s390_hash_table (info);
@@ -1559,7 +1565,7 @@ elf_s390_gc_sweep_hook (bfd *abfd,
        case R_390_PC24DBL:
        case R_390_PC32DBL:
        case R_390_PC32:
-         if (info->shared)
+         if (bfd_link_pic (info))
            break;
          /* Fall through.  */
 
@@ -1696,7 +1702,7 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
      only references to the symbol are via the global offset table.
      For such cases we need not do anything here; the relocations will
      be handled correctly by relocate_section.  */
-  if (info->shared)
+  if (bfd_link_pic (info))
     return TRUE;
 
   /* If there are no references to this symbol that do not use the
@@ -1756,7 +1762,7 @@ elf_s390_adjust_dynamic_symbol (struct bfd_link_info *info,
 
   s = htab->sdynbss;
 
-  return _bfd_elf_adjust_dynamic_copy (h, s);
+  return _bfd_elf_adjust_dynamic_copy (info, h, s);
 }
 
 /* Allocate space in .plt, .got and associated reloc sections for
@@ -1793,7 +1799,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
            return FALSE;
        }
 
-      if (info->shared
+      if (bfd_link_pic (info)
          || WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, 0, h))
        {
          asection *s = htab->elf.splt;
@@ -1810,7 +1816,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
             location in the .plt.  This is required to make function
             pointers compare as equal between the normal executable and
             the shared library.  */
-         if (! info->shared
+         if (! bfd_link_pic (info)
              && !h->def_regular)
            {
              h->root.u.def.section = s;
@@ -1846,7 +1852,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
      to R_390_TLS_LE32 requiring no TLS entry. For GOTIE12 and IEENT
      we can save the dynamic TLS relocation.  */
   if (h->got.refcount > 0
-      && !info->shared
+      && !bfd_link_pic (info)
       && h->dynindx == -1
       && elf_s390_hash_entry(h)->tls_type >= GOT_TLS_IE)
     {
@@ -1892,7 +1898,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
        htab->elf.srelgot->size += 2 * sizeof (Elf32_External_Rela);
       else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                || h->root.type != bfd_link_hash_undefweak)
-              && (info->shared
+              && (bfd_link_pic (info)
                   || WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, 0, h)))
        htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
     }
@@ -1908,7 +1914,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
      space for pc-relative relocs that have become local due to symbol
      visibility changes.  */
 
-  if (info->shared)
+  if (bfd_link_pic (info))
     {
       if (SYMBOL_CALLS_LOCAL (info, h))
        {
@@ -2033,7 +2039,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   if (htab->elf.dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (info->executable)
+      if (bfd_link_executable (info))
        {
          s = bfd_get_linker_section (dynobj, ".interp");
          if (s == NULL)
@@ -2101,7 +2107,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
              s->size += GOT_ENTRY_SIZE;
              if (*local_tls_type == GOT_TLS_GD)
                s->size += GOT_ENTRY_SIZE;
-             if (info->shared)
+             if (bfd_link_pic (info))
                srela->size += sizeof (Elf32_External_Rela);
            }
          else
@@ -2210,7 +2216,7 @@ elf_s390_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 #define add_dynamic_entry(TAG, VAL) \
   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
-      if (info->executable)
+      if (bfd_link_executable (info))
        {
          if (!add_dynamic_entry (DT_DEBUG, 0))
            return FALSE;
@@ -2426,7 +2432,7 @@ elf_s390_relocate_section (bfd *output_bfd,
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
                                         rel, 1, relend, howto, 0, contents);
 
-      if (info->relocatable)
+      if (bfd_link_relocatable (info))
        continue;
 
       switch (r_type)
@@ -2509,8 +2515,10 @@ elf_s390_relocate_section (bfd *output_bfd,
                         finish_dynamic_symbol.  */
                    }
                }
-             else if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
-                      || (info->shared
+             else if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
+                                                         bfd_link_pic (info),
+                                                         h)
+                      || (bfd_link_pic (info)
                           && SYMBOL_REFERENCES_LOCAL (info, h))
                       || (ELF_ST_VISIBILITY (h->other)
                           && h->root.type == bfd_link_hash_undefweak))
@@ -2538,7 +2546,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                    }
 
                  if ((h->def_regular
-                      && info->shared
+                      && bfd_link_pic (info)
                       && SYMBOL_REFERENCES_LOCAL (info, h))
                      /* lrl rx,sym@GOTENT -> larl rx, sym */
                      && ((r_type == R_390_GOTENT
@@ -2587,7 +2595,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                  bfd_put_32 (output_bfd, relocation,
                              htab->elf.sgot->contents + off);
 
-                 if (info->shared)
+                 if (bfd_link_pic (info))
                    {
                      asection *srelgot;
                      Elf_Internal_Rela outrel;
@@ -2720,7 +2728,7 @@ elf_s390_relocate_section (bfd *output_bfd,
              && s390_is_ifunc_symbol_p (h)
              && h->def_regular)
            {
-             if (!info->shared || !h->non_got_ref)
+             if (!bfd_link_pic (info) || !h->non_got_ref)
                {
                  /* For a non-shared object STT_GNU_IFUNC symbol must
                     go through PLT.  */
@@ -2751,7 +2759,7 @@ elf_s390_relocate_section (bfd *output_bfd,
 
                  if (h->dynindx == -1
                      || h->forced_local
-                     || info->executable)
+                     || bfd_link_executable (info))
                    {
                      /* This symbol is resolved locally.  */
                      outrel.r_info = ELF32_R_INFO (0, R_390_IRELATIVE);
@@ -2780,7 +2788,7 @@ elf_s390_relocate_section (bfd *output_bfd,
          if ((input_section->flags & SEC_ALLOC) == 0)
            break;
 
-         if ((info->shared
+         if ((bfd_link_pic (info)
               && (h == NULL
                   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
                   || h->root.type != bfd_link_hash_undefweak)
@@ -2792,7 +2800,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                    && r_type != R_390_PC32)
                   || !SYMBOL_CALLS_LOCAL (info, h)))
              || (ELIMINATE_COPY_RELOCS
-                 && !info->shared
+                 && !bfd_link_pic (info)
                  && h != NULL
                  && h->dynindx != -1
                  && !h->non_got_ref
@@ -2833,7 +2841,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                           || r_type == R_390_PC24DBL
                           || r_type == R_390_PC32DBL
                           || r_type == R_390_PC32
-                          || !info->shared
+                          || !bfd_link_pic (info)
                           || !SYMBOLIC_BIND (info, h)
                           || !h->def_regular))
                {
@@ -2903,7 +2911,7 @@ elf_s390_relocate_section (bfd *output_bfd,
 
          /* Relocations for tls literal pool entries.  */
        case R_390_TLS_IE32:
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
              Elf_Internal_Rela outrel;
              asection *sreloc;
@@ -2931,7 +2939,9 @@ elf_s390_relocate_section (bfd *output_bfd,
          else if (h != NULL)
            {
              tls_type = elf_s390_hash_entry(h)->tls_type;
-             if (!info->shared && h->dynindx == -1 && tls_type >= GOT_TLS_IE)
+             if (!bfd_link_pic (info)
+                 && h->dynindx == -1
+                 && tls_type >= GOT_TLS_IE)
                r_type = R_390_TLS_LE32;
            }
          if (r_type == R_390_TLS_GD32 && tls_type >= GOT_TLS_IE)
@@ -3042,14 +3052,16 @@ elf_s390_relocate_section (bfd *output_bfd,
              if (local_got_offsets == NULL)
                abort();
              off = local_got_offsets[r_symndx];
-             if (info->shared)
+             if (bfd_link_pic (info))
                goto emit_tls_relocs;
            }
          else
            {
              off = h->got.offset;
              tls_type = elf_s390_hash_entry(h)->tls_type;
-             if (info->shared || h->dynindx != -1 || tls_type < GOT_TLS_IE)
+             if (bfd_link_pic (info)
+                 || h->dynindx != -1
+                 || tls_type < GOT_TLS_IE)
                goto emit_tls_relocs;
            }
 
@@ -3066,7 +3078,7 @@ elf_s390_relocate_section (bfd *output_bfd,
          break;
 
        case R_390_TLS_LDM32:
-         if (! info->shared)
+         if (! bfd_link_pic (info))
            /* The literal pool entry this relocation refers to gets ignored
               by the optimized code of the local exec model. Do nothing
               and the value will turn out zero.  */
@@ -3104,7 +3116,7 @@ elf_s390_relocate_section (bfd *output_bfd,
          break;
 
        case R_390_TLS_LE32:
-         if (info->shared)
+         if (bfd_link_dll (info))
            {
              /* Linking a shared library with non-fpic code requires
                 a R_390_TLS_TPOFF relocation.  */
@@ -3141,7 +3153,7 @@ elf_s390_relocate_section (bfd *output_bfd,
          continue;
 
        case R_390_TLS_LDO32:
-         if (info->shared || (input_section->flags & SEC_DEBUGGING))
+         if (bfd_link_pic (info) || (input_section->flags & SEC_DEBUGGING))
            relocation -= dtpoff_base (info);
          else
            /* When converting LDO to LE, we must negate.  */
@@ -3163,7 +3175,7 @@ elf_s390_relocate_section (bfd *output_bfd,
 
          if (r_type == R_390_TLS_LOAD)
            {
-             if (!info->shared && (h == NULL || h->dynindx == -1))
+             if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
                {
                  /* IE->LE transition. Four valid cases:
                     l %rx,0(0,%ry)    -> lr %rx,%ry + bcr 0,0
@@ -3201,7 +3213,7 @@ elf_s390_relocate_section (bfd *output_bfd,
                  (insn & 0xffff0000) != 0xc0e50000 &&
                  (insn & 0xff000000) != 0x0d000000)
                invalid_tls_insn (input_bfd, input_section, rel);
-             if (!info->shared && (h == NULL || h->dynindx == -1))
+             if (!bfd_link_pic (info) && (h == NULL || h->dynindx == -1))
                {
                  if ((insn & 0xff000000) == 0x0d000000)
                    {
@@ -3251,7 +3263,7 @@ elf_s390_relocate_section (bfd *output_bfd,
            }
          else if (r_type == R_390_TLS_LDCALL)
            {
-             if (!info->shared)
+             if (!bfd_link_pic (info))
                {
                  unsigned int insn;
 
@@ -3416,7 +3428,7 @@ elf_s390_finish_ifunc_symbol (bfd *output_bfd,
       = -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
 
   /* Fill in the entry in the procedure linkage table.  */
-  if (!info->shared)
+  if (!bfd_link_pic (info))
     {
       memcpy (plt->contents + iplt_offset, elf_s390_plt_entry,
              PLT_ENTRY_SIZE);
@@ -3499,7 +3511,7 @@ elf_s390_finish_ifunc_symbol (bfd *output_bfd,
 
   if (!h
       || h->dynindx == -1
-      || ((info->executable
+      || ((bfd_link_executable (info)
           || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
          && h->def_regular))
     {
@@ -3578,7 +3590,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
              = -(unsigned) (((65536 / PLT_ENTRY_SIZE - 1) * PLT_ENTRY_SIZE) / 2);
 
          /* Fill in the entry in the procedure linkage table.  */
-         if (!info->shared)
+         if (!bfd_link_pic (info))
            {
              memcpy (htab->elf.splt->contents + h->plt.offset, elf_s390_plt_entry,
                      PLT_ENTRY_SIZE);
@@ -3702,7 +3714,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
         initialized in the relocate_section function.  */
       if (h->def_regular && s390_is_ifunc_symbol_p (h))
        {
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
              /* An explicit GOT slot usage needs GLOB_DAT.  If the
                 symbol references local the implicit got.iplt slot
@@ -3722,7 +3734,7 @@ elf_s390_finish_dynamic_symbol (bfd *output_bfd,
              return TRUE;
            }
        }
-      else if (info->shared
+      else if (bfd_link_pic (info)
          && SYMBOL_REFERENCES_LOCAL (info, h))
        {
          /* If this is a static link, or it is a -Bsymbolic link and
@@ -3864,7 +3876,7 @@ elf_s390_finish_dynamic_sections (bfd *output_bfd,
       if (htab->elf.splt && htab->elf.splt->size > 0)
        {
          memset (htab->elf.splt->contents, 0, PLT_FIRST_ENTRY_SIZE);
-         if (info->shared)
+         if (bfd_link_pic (info))
            {
              memcpy (htab->elf.splt->contents, elf_s390_plt_pic_first_entry,
                      PLT_FIRST_ENTRY_SIZE);
@@ -3974,9 +3986,18 @@ elf_s390_plt_sym_val (bfd_vma i, const asection *plt,
   return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE;
 }
 
+/* Merge backend specific data from an object file to the output
+   object file when linking.  */
+
 static bfd_boolean
 elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 {
+  if (!is_s390_elf (ibfd) || !is_s390_elf (obfd))
+    return TRUE;
+
+  if (!elf_s390_merge_obj_attributes (ibfd, obfd))
+    return FALSE;
+
   elf_elfheader (obfd)->e_flags |= elf_elfheader (ibfd)->e_flags;
   return TRUE;
 }
@@ -4022,6 +4043,7 @@ elf32_s390_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
 #define elf_backend_grok_prstatus            elf_s390_grok_prstatus
 #define elf_backend_plt_sym_val                      elf_s390_plt_sym_val
 #define elf_backend_add_symbol_hook           elf_s390_add_symbol_hook
+#define elf_backend_sort_relocs_p             elf_s390_elf_sort_relocs_p
 
 #define bfd_elf32_mkobject             elf_s390_mkobject
 #define elf_backend_object_p           elf_s390_object_p
This page took 0.033629 seconds and 4 git commands to generate.