Properly check --compress-debug-sections=XXX
[deliverable/binutils-gdb.git] / gold / aarch64.cc
index f2505d66290564465183a504576839a65e9a0ebf..dea64c0ba8f321b3fc6461958b1d8a23ca001863 100644 (file)
@@ -1,6 +1,6 @@
 // aarch64.cc -- aarch64 target support for gold.
 
-// Copyright (C) 2014 Free Software Foundation, Inc.
+// Copyright (C) 2014-2015 Free Software Foundation, Inc.
 // Written by Jing Yu <jingyu@google.com> and Han Shen <shenhan@google.com>.
 
 // This file is part of gold.
@@ -1749,9 +1749,8 @@ class Target_aarch64 : public Sized_target<size, big_endian>
   }
 
   // Return the addend to use for a target specific relocation.
-  typename elfcpp::Elf_types<size>::Elf_Addr
-  do_reloc_addend(void* arg, unsigned int r_type,
-                 typename elfcpp::Elf_types<size>::Elf_Addr addend) const;
+  uint64_t
+  do_reloc_addend(void* arg, unsigned int r_type, uint64_t addend) const;
 
   // Return the PLT section.
   uint64_t
@@ -3082,7 +3081,7 @@ class Output_data_plt_aarch64 : public Output_section_data
   // The number of PLT entries.
   unsigned int count_;
 
-  // Number of PLT entries with R_X86_64_IRELATIVE relocs.  These
+  // Number of PLT entries with R_AARCH64_IRELATIVE relocs.  These
   // follow the regular PLT entries.
   unsigned int irelative_count_;
 
@@ -4205,7 +4204,7 @@ maybe_apply_stub(unsigned int r_type,
   if (status != This::STATUS_OKAY)
     gold_error(_("Stub is too far away, try a smaller value "
                 "for '--stub-group-size'. The current value is 0x%lx."),
-              current_group_size);
+              static_cast<unsigned long>(current_group_size));
   return true;
 }
 
@@ -4389,10 +4388,9 @@ Target_aarch64<size, big_endian>::new_stub_table(
 
 
 template<int size, bool big_endian>
-typename elfcpp::Elf_types<size>::Elf_Addr
+uint64_t
 Target_aarch64<size, big_endian>::do_reloc_addend(
-    void* arg, unsigned int r_type,
-    typename elfcpp::Elf_types<size>::Elf_Addr) const
+    void* arg, unsigned int r_type, uint64_t) const
 {
   gold_assert(r_type == elfcpp::R_AARCH64_TLSDESC);
   uintptr_t intarg = reinterpret_cast<uintptr_t>(arg);
@@ -4446,16 +4444,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 +4542,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.
@@ -4860,6 +4858,11 @@ Target_aarch64<size, big_endian>::Scan::local(
       }
       break;
 
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
@@ -4889,6 +4892,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:
@@ -5213,7 +5218,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:
@@ -5248,6 +5255,11 @@ Target_aarch64<size, big_endian>::Scan::global(
       }
       break;
 
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:  // Local executable
@@ -5774,8 +5786,15 @@ 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:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
@@ -5966,7 +5985,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)
@@ -5977,9 +5998,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)
          {
@@ -5989,6 +6007,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;
@@ -6049,6 +6069,11 @@ Target_aarch64<size, big_endian>::Relocate::relocate_tls(
       // We shall never reach here.
       break;
 
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1_NC:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
+    case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0_NC:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_HI12:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12:
     case elfcpp::R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
@@ -6061,11 +6086,21 @@ Target_aarch64<size, big_endian>::Relocate::relocate_tls(
            AArch64_address aligned_tcb_size =
                align_address(target->tcb_size(),
                              tls_segment->maximum_alignment());
-           return aarch64_reloc_funcs::template
-               rela_general<32>(view,
-                                value + aligned_tcb_size,
-                                addend,
-                                reloc_property);
+           value += aligned_tcb_size;
+           switch (r_type)
+             {
+             case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G2:
+             case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G1:
+             case elfcpp::R_AARCH64_TLSLE_MOVW_TPREL_G0:
+               return aarch64_reloc_funcs::movnz(view, value + addend,
+                                                 reloc_property);
+             default:
+               return aarch64_reloc_funcs::template
+                 rela_general<32>(view,
+                                  value,
+                                  addend,
+                                  reloc_property);
+             }
          }
        else
          gold_error(_("%s: unsupported reloc %u "
This page took 0.032433 seconds and 4 git commands to generate.