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]

[gold][aarch64]Patch to support 2 TLSLD relocations and change _TLS_MODULE_BASE_


Hi reviewers,

This is the patch to support 2 aarch64 TLSLD relocations that are
required by LLVM.
* R_AARCH64_TLSLD_ ADD_DTPREL_HI12 (528)
* R_AARCH64_TLSLD_ ADD_DTPREL_LO12_NC (530)

Also, in order to make LLVM generated code work, I always let
_TLS_MODULE_BASE_ point to the beginning of TLS segment. The LLVM
generated code directly uses _TLS_MODULE_BASE_ symbol, assuming it
always points to the beginning of TLS segment.

Without this patch, _TLS_MODULE_BASE_ pointed to the end of TLS
segment if generating executable. This behavior was copied from gold
x86 backend and arm backend, when I initially wrote this piece of
code. Now I think maybe I was wrong. x86 does this way because @DTPOFF
has historically been relaxed in main executables. There is no such a
history on aarch64 backend. TLSLD_*_DTPREL relocations haven't been
supported by bfd ld linker so far. I think as long as the calculation
is consistent in gold, we are fine. If you have different opinion,
please let me know.

I have tested the patch on object code that was generated by clang with command:
$ /work/llvm.org/cmake-git-build/bin/clang -target aarch64-linux-gnu
-mllvm -aarch64-elf-ldtls-generation t.c -fPIC -O2 -c -o t.o
The result looks fine.

OK for trunk?

Thanks,
Jing

gold/ChangeLog:

2015-03-28  Jing Yu  <jingyu@google.com>

      * aarch64-reloc.def: New TLSLD_ADD_DTPREL_HI12,
      TLSLD_ADD_DTPREL_LO12_NC.
      * aarch64.cc (Target_aarch64::define_tls_base_symbol): Always let
      _TLS_MODULE_BASE_ point to the start of tls segment.
      (Target_aarch64::optimize_tls_reloc): Add cases for
      R_AARCH64_TLSLD_ADD_DTPREL_HI12 and
      R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC.
      (Target_aarch64::Scan::local): Likewise.
      (Target_aarch64::Scan::global): Likewise.
      (Target_aarch64::Relocate::relocate): Likewise.
      (Target_aarch64::Relocate::relocate_tls): Likewise. And remove
      subtracting tls segment size from symbol value for TLSLD_*_DTPREL
      relocations.


diff --git a/gold/aarch64-reloc.def b/gold/aarch64-reloc.def
index d03d9b5..321e679 100644
--- a/gold/aarch64-reloc.def
+++ b/gold/aarch64-reloc.def
@@ -71,6 +71,8 @@ ARD(TLSLD_ADR_PAGE21             , STATIC ,  AARCH64
   ,   Y,  -1,   32,32
 ARD(TLSLD_ADD_LO12_NC            , STATIC ,  AARCH64    ,   Y,  -1,
 0,0                ,    0,11 , Symbol::TLS_REF ,
        ADD   )
 ARD(TLSLD_MOVW_DTPREL_G1         , STATIC ,  AARCH64    ,   Y,   1,
32,32               ,   16,31 , Symbol::TLS_REF ,
        ADRP  )
 ARD(TLSLD_MOVW_DTPREL_G0_NC      , STATIC ,  AARCH64    ,   Y,   0,
 0,0                ,    0,15 , Symbol::TLS_REF ,
        MOVW  )
+ARD(TLSLD_ADD_DTPREL_HI12        , STATIC ,  AARCH64    ,   Y,  -1,
 0,24               ,   12,23 , Symbol::TLS_REF ,
        ADD   )
+ARD(TLSLD_ADD_DTPREL_LO12_NC     , STATIC ,  AARCH64    ,   Y,  -1,
 0,0                ,    0,11 , Symbol::TLS_REF ,
        ADD   )
 // Above is from Table 4-16, Local Dynamic TLS relocations, 517-573.

 ARD(TLSIE_MOVW_GOTTPREL_G1       , STATIC ,  AARCH64    ,   N,  -1,
32,32               ,   16,31 , Symbol::TLS_REF ,
        MOVW  )
diff --git a/gold/aarch64.cc b/gold/aarch64.cc
index 31176a4..4ae987f 100644
--- a/gold/aarch64.cc
+++ b/gold/aarch64.cc
@@ -4446,16 +4446,14 @@ Target_aarch64<size,
big_endian>::define_tls_base_symbol(
   Output_segment* tls_segment = layout->tls_segment();
   if (tls_segment != NULL)
     {
-      bool is_exec = parameters->options().output_is_executable();
+      // _TLS_MODULE_BASE_ always points to the beginning of tls segment.
       symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
                                       Symbol_table::PREDEFINED,
                                       tls_segment, 0, 0,
                                       elfcpp::STT_TLS,
                                       elfcpp::STB_LOCAL,
                                       elfcpp::STV_HIDDEN, 0,
-                                      (is_exec
-                                       ? Symbol::SEGMENT_END
-                                       : Symbol::SEGMENT_START),
+                                      Symbol::SEGMENT_START,
                                       true);
     }
   this->tls_base_symbol_defined_ = true;
@@ -4546,6 +4544,8 @@ Target_aarch64<size,
big_endian>::optimize_tls_reloc(bool is_final,
     case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
     case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
     case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
       // These are Local-Dynamic, which refer to local symbols in the
       // dynamic TLS block. Since we know that we generating an
       // executable, we can switch to Local-Exec.
@@ -4894,6 +4894,8 @@ Target_aarch64<size, big_endian>::Scan::local(

     case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
     case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
       break;

     case elfcpp::R_AARCH64_TLSDESC_ADR_PAGE21:
@@ -5218,7 +5220,9 @@ Target_aarch64<size, big_endian>::Scan::global(
       break;

     case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
-    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:  // Other local dynamic
+    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:  // Other local dynamic
       break;

     case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
@@ -5784,6 +5788,8 @@ Target_aarch64<size, big_endian>::Relocate::relocate(
     case elfcpp::R_AARCH64_TLSLD_ADD_LO12_NC:
     case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
     case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
     case elfcpp::R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21:
     case elfcpp::R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
     case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
@@ -5981,7 +5987,9 @@ Target_aarch64<size, big_endian>::Relocate::relocate_tls(
       break;

     case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G1:
-    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:  // Other local-dynamic
+    case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
+    case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:  // Other local-dynamic
       {
        AArch64_address value = psymval->value(object, 0);
        if (tlsopt == tls::TLSOPT_TO_LE)
@@ -5992,9 +6000,6 @@ Target_aarch64<size, big_endian>::Relocate::relocate_tls(
                            || issue_undefined_symbol_error(gsym));
                return aarch64_reloc_funcs::STATUS_BAD_RELOC;
              }
-         // If building executable, _TLS_MODULE_BASE_ points to segment
-         // end. Thus we must subtract it from value.
-         value -= tls_segment->memsz();
          }
        switch (r_type)
          {
@@ -6004,6 +6009,8 @@ Target_aarch64<size, big_endian>::Relocate::relocate_tls(
            break;

          case elfcpp::R_AARCH64_TLSLD_MOVW_DTPREL_G0_NC:
+         case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_HI12:
+         case elfcpp::R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC:
            return aarch64_reloc_funcs::template rela_general<32>(
                view, value, addend, reloc_property);
            break;


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