Support AARCH64_TLSLD_ADD_DTPREL_* relocations.
authorJing Yu <jingyu@google.com>
Mon, 30 Mar 2015 21:06:12 +0000 (14:06 -0700)
committerJing Yu <jingyu@google.com>
Mon, 30 Mar 2015 21:11:48 +0000 (14:11 -0700)
Also Change _TLS_MODULE_BASE_. Always let it point to the start
of TLS segment.

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.

gold/ChangeLog
gold/aarch64-reloc.def
gold/aarch64.cc

index 39e025e602c6f927e9d817082ae1e803b3317309..57d500cdfab75dc93d66fdb6ddafa5cf704683fc 100644 (file)
@@ -1,3 +1,19 @@
+2015-03-30  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.
+
 2015-03-27  Rafael Ávila de Espíndola <rafael.espindola@gmail.com>
 
        * merge.cc (Object_merge_map::add_mapping): call
index d03d9b53338c38b1f3aa5d8f090c242729165b26..321e6796a70787d6efb86c40fefcdff53b3b3ac9 100644 (file)
@@ -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  )
index 31176a4b485d36a7fc5a8a7bf752671c2ed11891..4ae987f5307f37304310c36a8ad0631a44bcdf7d 100644 (file)
@@ -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;