correct ft32 reloc range test
[deliverable/binutils-gdb.git] / bfd / elfxx-x86.c
index 1a9e5ef7d07e0aed46b7ad9b4599eab5d9da9b2a..5f55c948edc55bff8b0ccf52387f1af6163418cb 100644 (file)
@@ -1,5 +1,5 @@
 /* x86 specific support for ELF
-   Copyright (C) 2017 Free Software Foundation, Inc.
+   Copyright (C) 2017-2018 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -119,7 +119,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
       && h->got.refcount > 0)
     {
       /* Don't use the regular PLT if there are both GOT and GOTPLT
-         reloctions.  */
+        reloctions.  */
       h->plt.offset = (bfd_vma) -1;
 
       /* Use the GOT PLT.  */
@@ -179,6 +179,7 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
          asection *s = htab->elf.splt;
          asection *second_s = htab->plt_second;
          asection *got_s = htab->plt_got;
+         bfd_boolean use_plt;
 
          /* If this is the first .plt entry, make room for the special
             first entry.  The .plt section is used by prelink to undo
@@ -196,12 +197,19 @@ elf_x86_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
            }
 
          /* If this symbol is not defined in a regular file, and we are
-            not generating a shared library, then set the symbol to this
-            location in the .plt.  This is required to make function
-            pointers compare as equal between the normal executable and
-            the shared library.  */
-         if (! bfd_link_pic (info)
-             && !h->def_regular)
+            generating PDE, then set the symbol to this location in the
+            .plt.  This is required to make function pointers compare
+            as equal between PDE and the shared library.
+
+            NB: If PLT is PC-relative, we can use the .plt in PIE for
+            function address. */
+         if (h->def_regular)
+           use_plt = FALSE;
+         else if (htab->pcrel_plt)
+           use_plt = ! bfd_link_dll (info);
+         else
+           use_plt = bfd_link_pde (info);
+         if (use_plt)
            {
              if (use_plt_got)
                {
@@ -560,15 +568,15 @@ maybe_set_textrel (struct elf_link_hash_entry *h, void *inf)
 
       info->flags |= DF_TEXTREL;
       /* xgettext:c-format */
-      info->callbacks->minfo (_("%B: dynamic relocation against `%T' "
-                               "in read-only section `%A'\n"),
+      info->callbacks->minfo (_("%pB: dynamic relocation against `%pT' "
+                               "in read-only section `%pA'\n"),
                              sec->owner, h->root.root.string, sec);
 
       if ((info->warn_shared_textrel && bfd_link_pic (info))
          || info->error_textrel)
        /* xgettext:c-format */
-       info->callbacks->einfo (_("%P: %B: warning: relocation against `%s' "
-                                 "in read-only section `%A'\n"),
+       info->callbacks->einfo (_("%P: %pB: warning: relocation against `%s' "
+                                 "in read-only section `%pA'\n"),
                                sec->owner, h->root.root.string, sec);
 
       /* Not an error, just cut short the traversal.  */
@@ -771,6 +779,7 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd)
       ret->dt_reloc_sz = DT_RELASZ;
       ret->dt_reloc_ent = DT_RELAENT;
       ret->got_entry_size = 8;
+      ret->pcrel_plt = TRUE;
       ret->tls_get_addr = "__tls_get_addr";
     }
   if (ABI_64_P (abfd))
@@ -798,6 +807,7 @@ _bfd_x86_elf_link_hash_table_create (bfd *abfd)
          ret->dt_reloc_ent = DT_RELENT;
          ret->sizeof_reloc = sizeof (Elf32_External_Rel);
          ret->got_entry_size = 4;
+         ret->pcrel_plt = FALSE;
          ret->pointer_r_type = R_386_32;
          ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
          ret->dynamic_interpreter_size
@@ -856,7 +866,16 @@ _bfd_x86_elf_link_check_relocs (bfd *abfd, struct bfd_link_info *info)
                                    htab->tls_get_addr,
                                    FALSE, FALSE, FALSE);
          if (h != NULL)
-           elf_x86_hash_entry (h)->tls_get_addr = 1;
+           {
+             elf_x86_hash_entry (h)->tls_get_addr = 1;
+
+             /* Check the versioned __tls_get_addr symbol.  */
+             while (h->root.type == bfd_link_hash_indirect)
+               {
+                 h = (struct elf_link_hash_entry *) h->root.u.i.link;
+                 elf_x86_hash_entry (h)->tls_get_addr = 1;
+               }
+           }
 
          /* "__ehdr_start" will be defined by linker as a hidden symbol
             later if it is referenced and not defined.  */
@@ -951,8 +970,8 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
                          || info->error_textrel)
                        /* xgettext:c-format */
                        info->callbacks->einfo
-                         (_("%P: %B: warning: relocation "
-                            "in read-only section `%A'\n"),
+                         (_("%P: %pB: warning: relocation "
+                            "in read-only section `%pA'\n"),
                           p->sec->owner, p->sec);
                    }
                }
@@ -1017,7 +1036,7 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
   if (htab->tls_ld_or_ldm_got.refcount > 0)
     {
       /* Allocate 2 got entries and 1 dynamic reloc for R_386_TLS_LDM
-         or R_X86_64_TLSLD relocs.  */
+        or R_X86_64_TLSLD relocs.  */
       htab->tls_ld_or_ldm_got.offset = htab->elf.sgot->size;
       htab->elf.sgot->size += 2 * htab->got_entry_size;
       htab->elf.srelgot->size += htab->sizeof_reloc;
@@ -1077,7 +1096,7 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
       /* Don't allocate .got.plt section if there are no GOT nor PLT
         entries and there is no reference to _GLOBAL_OFFSET_TABLE_.  */
       if ((htab->elf.hgot == NULL
-          || !htab->elf.hgot->ref_regular_nonweak)
+          || !htab->got_referenced)
          && (htab->elf.sgotplt->size == bed->got_header_size)
          && (htab->elf.splt == NULL
              || htab->elf.splt->size == 0)
@@ -1087,7 +1106,22 @@ _bfd_x86_elf_size_dynamic_sections (bfd *output_bfd,
              || htab->elf.iplt->size == 0)
          && (htab->elf.igotplt == NULL
              || htab->elf.igotplt->size == 0))
-       htab->elf.sgotplt->size = 0;
+       {
+         htab->elf.sgotplt->size = 0;
+         /* Solaris requires to keep _GLOBAL_OFFSET_TABLE_ even if it
+            isn't used.  */
+         if (htab->elf.hgot != NULL && htab->target_os != is_solaris)
+           {
+             /* Remove the unused _GLOBAL_OFFSET_TABLE_ from symbol
+                table. */
+             htab->elf.hgot->root.type = bfd_link_hash_undefined;
+             htab->elf.hgot->root.u.undef.abfd
+               = htab->elf.hgot->root.u.def.section->owner;
+             htab->elf.hgot->root.linker_def = 0;
+             htab->elf.hgot->ref_regular = 0;
+             htab->elf.hgot->def_regular = 0;
+           }
+       }
     }
 
   if (_bfd_elf_eh_frame_present (info))
@@ -1333,7 +1367,7 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
       if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
        {
          _bfd_error_handler
-           (_("discarded output section: `%A'"), htab->elf.sgotplt);
+           (_("discarded output section: `%pA'"), htab->elf.sgotplt);
          return NULL;
        }
 
@@ -1345,7 +1379,7 @@ _bfd_x86_elf_finish_dynamic_sections (bfd *output_bfd,
                      : sdyn->output_section->vma + sdyn->output_offset);
 
       /* Set the first entry in the global offset table to the address
-         of the dynamic section.  Write GOT[1] and GOT[2], needed for
+        of the dynamic section.  Write GOT[1] and GOT[2], needed for
         the dynamic linker.  */
       if (htab->got_entry_size == 8)
        {
@@ -2238,10 +2272,10 @@ _bfd_x86_elf_parse_gnu_properties (bfd *abfd, unsigned int type,
        {
          _bfd_error_handler
            ((type == GNU_PROPERTY_X86_ISA_1_USED
-             ? _("error: %B: <corrupt x86 ISA used size: 0x%x>")
+             ? _("error: %pB: <corrupt x86 ISA used size: 0x%x>")
              : (type == GNU_PROPERTY_X86_ISA_1_NEEDED
-                ? _("error: %B: <corrupt x86 ISA needed size: 0x%x>")
-                : _("error: %B: <corrupt x86 feature size: 0x%x>"))),
+                ? _("error: %pB: <corrupt x86 ISA needed size: 0x%x>")
+                : _("error: %pB: <corrupt x86 feature size: 0x%x>"))),
             abfd, datasz);
          return property_corrupt;
        }
@@ -2418,7 +2452,7 @@ _bfd_x86_elf_link_setup_gnu_properties
          if (!bfd_set_section_alignment (ebfd, sec, class_align))
            {
 error_alignment:
-             info->callbacks->einfo (_("%F%A: failed to align section\n"),
+             info->callbacks->einfo (_("%F%pA: failed to align section\n"),
                                      sec);
            }
 
This page took 0.030735 seconds and 4 git commands to generate.