From 6a41d30bc2a8440b3f0085c77d1b5f4ad3f8bd7b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 7 Dec 2007 23:26:51 +0000 Subject: [PATCH] From Cary Coutant: Fix x86_64 TLS. Also set DT_TEXTREL as well as DF_TEXTREL. --- gold/layout.cc | 6 +++++- gold/x86_64.cc | 36 +++++++++++++++++++----------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/gold/layout.cc b/gold/layout.cc index f5a1f671e05..0a08f71d8cf 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -1728,7 +1728,11 @@ Layout::finish_dynamic_section(const Input_objects* input_objects, // post-link tools can easily modify these flags if desired. unsigned int flags = 0; if (have_textrel) - flags |= elfcpp::DF_TEXTREL; + { + // Add a DT_TEXTREL for compatibility with older loaders. + odyn->add_constant(elfcpp::DT_TEXTREL, 0); + flags |= elfcpp::DF_TEXTREL; + } odyn->add_constant(elfcpp::DT_FLAGS, flags); } diff --git a/gold/x86_64.cc b/gold/x86_64.cc index bdc28d45c6e..e478a48e084 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -1585,12 +1585,13 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, const Sized_symbol<64>* gsym, const Symbol_value<64>* psymval, unsigned char* view, - elfcpp::Elf_types<64>::Elf_Addr, + elfcpp::Elf_types<64>::Elf_Addr address, off_t view_size) { Output_segment* tls_segment = relinfo->layout->tls_segment(); const Sized_relobj<64, false>* object = relinfo->object; + const elfcpp::Elf_Xword addend = rela.get_r_addend(); elfcpp::Elf_types<64>::Elf_Addr value = psymval->value(relinfo->object, 0); @@ -1638,7 +1639,9 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, { // Relocate the field with the offset of the pair of GOT // entries. - Relocate_functions<64, false>::rel64(view, got_offset); + value = target->got_plt_section()->address() + got_offset; + Relocate_functions<64, false>::pcrela32(view, value, addend, + address); break; } } @@ -1671,7 +1674,9 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, got_offset = (object->local_tls_got_offset(r_sym, false) - target->got_size()); } - Relocate_functions<64, false>::rel64(view, got_offset); + value = target->got_plt_section()->address() + got_offset; + Relocate_functions<64, false>::pcrela32(view, value, addend, + address); break; } gold_error_at_location(relinfo, relnum, rela.get_r_offset(), @@ -1681,19 +1686,15 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, case elfcpp::R_X86_64_DTPOFF32: gold_assert(tls_segment != NULL); if (optimized_type == tls::TLSOPT_TO_LE) - value = value - (tls_segment->vaddr() + tls_segment->memsz()); - else - value = value - tls_segment->vaddr(); - Relocate_functions<64, false>::rel32(view, value); + value -= tls_segment->memsz(); + Relocate_functions<64, false>::rela32(view, value, 0); break; case elfcpp::R_X86_64_DTPOFF64: gold_assert(tls_segment != NULL); if (optimized_type == tls::TLSOPT_TO_LE) - value = value - (tls_segment->vaddr() + tls_segment->memsz()); - else - value = value - tls_segment->vaddr(); - Relocate_functions<64, false>::rel64(view, value); + value -= tls_segment->memsz(); + Relocate_functions<64, false>::rela64(view, value, 0); break; case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec @@ -1722,7 +1723,8 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, got_offset = (object->local_got_offset(r_sym) - target->got_size()); } - Relocate_functions<64, false>::rel64(view, got_offset); + value = target->got_plt_section()->address() + got_offset; + Relocate_functions<64, false>::pcrela32(view, value, addend, address); break; } gold_error_at_location(relinfo, relnum, rela.get_r_offset(), @@ -1731,8 +1733,8 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, break; case elfcpp::R_X86_64_TPOFF32: // Local-exec - value = value - (tls_segment->vaddr() + tls_segment->memsz()); - Relocate_functions<64, false>::rel32(view, value); + value -= tls_segment->memsz(); + Relocate_functions<64, false>::rela32(view, value, 0); break; } } @@ -1764,7 +1766,7 @@ Target_x86_64::Relocate::tls_gd_to_ie(const Relocate_info<64, false>* relinfo, memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x03\x05\0\0\0\0", 16); - value = value - (tls_segment->vaddr() + tls_segment->memsz()); + value -= tls_segment->memsz(); Relocate_functions<64, false>::rela32(view + 8, value, 0); // The next reloc should be a PLT32 reloc against __tls_get_addr. @@ -1799,7 +1801,7 @@ Target_x86_64::Relocate::tls_gd_to_le(const Relocate_info<64, false>* relinfo, memcpy(view - 4, "\x64\x48\x8b\x04\x25\0\0\0\0\x48\x8d\x80\0\0\0\0", 16); - value = value - (tls_segment->vaddr() + tls_segment->memsz()); + value -= tls_segment->memsz(); Relocate_functions<64, false>::rela32(view + 8, value, 0); // The next reloc should be a PLT32 reloc against __tls_get_addr. @@ -1888,7 +1890,7 @@ Target_x86_64::Relocate::tls_ie_to_le(const Relocate_info<64, false>* relinfo, view[-1] = 0x80 | reg | (reg << 3); } - value = value - (tls_segment->vaddr() + tls_segment->memsz()); + value -= tls_segment->memsz(); Relocate_functions<64, false>::rela32(view, value, 0); } -- 2.30.2