This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AArch64] Don't generate GOT entry for large model TLS LE relocation


This patch revert the following commit

commit b7a944fea3a0194d81f6de4d958f3a1d2c6ad03a
Author: Renlin Li <renlin.li@arm.com>
Date:   Fri Oct 2 17:02:53 2015 +0100

    [BFD][AARCH64]Create GOT section for TLSLE_MOVW_TPREL_G(1, 1_NC, 2).

    bfd/

    2015-10-02  Renlin Li <renlin.li@arm.com>

        * elfnn-aarch64.c (elfNN_aarch64_check_relocs): Create GOT section
        for TLSLE_MOVW_TPREL_G(1, 1_NC, 2) relocation.

We shouldn't generate GOT entries for TLS Local Executable relocation
types as they don't need GOT.

This commit was trying to fix the following problem:

  1. In large code model, the instruction sequences for TLS traditional
     general dynamic will be:

       movz a0, #:tlsgd_g1:var      R_AARCH64_TLSGD_MOVW_G1
       movk a0, #:tlsgd_g0_nc:var   R_AARCH64_TLSGD_MOVW_G0_NC
       add  a0, gp, a0
       bl   __tls_get_addr        R_AARCH64_CALL26
       nop

     While in large code model, GOT section might be very far from text
     section that is out of the addressing range of our pc-relative
     instructions, so need to initialize gp register by loading the
     address from literal pool, then the full instruction sequences will
     become the following:


        ldr     x1, .Lgot
        adr     x2, .Lgot
        add     x1, x2, x1

        movz    x0, #:tlsgd_g1:var
        movk    x0, #:tlsgd_g0_nc:var
        add     x0, x1, x0
        bl      __tls_get_addr
        nop

.Lgot:
        .dword _GLOBAL_OFFSET_TABLE_ - .  // R_AARCH64_PREL64 _GOT_


   2. When TLS relaxation happen, all GD relocations will be turned into
      LE relocation types which don't need GOT support, but the PREL64
      relocation for literal pool is still referencing the special
      symbol _GLOBAL_OFFSET_TABLE_ which is defined by linker to the
      start address of .got section.  We can't remove it, and we can't
      remove the symbol, as gp may needed in other places across this
      object, or even gp is only used in above TLS sequences, it will be
      impossible to remove the literal pool entry and the symbol under
      current BFD linker intrastructure.

      So if TLS GD -> LE relaxation happen, and if there is no
      relocation types which require GOT support, then .got section
      won't be generated, that this symbol will not be defined, we will
      end up with a undefined symbol static linking error.


  The correct approach to fix this is not by cheating linker that large
  model LE relocation require GOT support, but we should always generate
  .got section if a relocation has referenced the special symbol
  _GLOBAL_OFFSET_TABLE_ during check_relocs.  This can fix all
  situations where _GLOBAL_OFFSET_TABLE_ are referenced.

  This is also the approach ppc is using.

  build & check-ld ok.  OK for trunk and 2.26?

2015-12-23  Jiong Wang  <jiong.wang@arm.com>

bfd/
  * elfnn-aarch64.c (elfNN_aarch64_check_relocs): Require .got section
  is a relocation referenced _GLOBAL_OFFSET_TABLE_, meanwhile don't
  generate GOT entry for large model TLS LE relocation types.

diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index 59c51cc42e08f78d28221aeecf0f72e86fdd7d16..ae3de56ffe0277dfe8e324ca82fcfc20707cd0e1 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -7053,6 +7053,22 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 
       if (h != NULL)
 	{
+	  /* If a relocation refers to _GLOBAL_OFFSET_TABLE_, create the .got.
+	     This shows up in particular in an R_AARCH64_PREL64 in large model
+	     when calculatin the pc-relative address to .got section which is
+	     used for initialize gp register.  */
+	  if (h->root.root.string
+	      && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
+	    {
+	      if (htab->root.dynobj == NULL)
+		htab->root.dynobj = abfd;
+
+	      if (! aarch64_elf_create_got_section (htab->root.dynobj, info))
+		return FALSE;
+
+	      BFD_ASSERT (h == htab->root.hgot);
+	    }
+
 	  /* Create the ifunc sections for static executables.  If we
 	     never see an indirect function symbol nor we are building
 	     a static executable, those sections will be empty and
@@ -7213,9 +7229,6 @@ elfNN_aarch64_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	case BFD_RELOC_AARCH64_TLSLD_ADD_LO12_NC:
 	case BFD_RELOC_AARCH64_TLSLD_ADR_PAGE21:
 	case BFD_RELOC_AARCH64_TLSLD_ADR_PREL21:
-	case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1:
-	case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
-	case BFD_RELOC_AARCH64_TLSLE_MOVW_TPREL_G2:
 	  {
 	    unsigned got_type;
 	    unsigned old_got_type;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]