diff options
author | Ian Lance Taylor <ian@airs.com> | 2008-05-16 20:44:22 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2008-05-16 20:44:22 +0000 |
commit | 497897f98cc3ae32477afbbf00fd871372a69ce7 (patch) | |
tree | 8dec774b757ecdf7a4a9bb2e81d9407803c40411 /gold/x86_64.cc | |
parent | 7c0d47a533c297ddb977c00493133115ef8c23eb (diff) | |
download | gdb-497897f98cc3ae32477afbbf00fd871372a69ce7.zip gdb-497897f98cc3ae32477afbbf00fd871372a69ce7.tar.gz gdb-497897f98cc3ae32477afbbf00fd871372a69ce7.tar.bz2 |
* i386.cc (Target_i386::Relocate::relocate_tls): Set dynamic type
for TLS_GOTDESC and TLS_DESC_CALL. Only optimize TLS_LDO_32 if we
know the dynamic type.
* x86_64.cc (Target_x86_64::Relocate): Add saw_tls_block_reloc_
field. Initialize it in constructor.
(Target_x86_64::Relocate::relocate_tls): Record that we saw a TLS
block reloc for TLSGD, GOTPC32_TLSDESC, TLSDESC_CALL, and TLSLD.
Only optimize DTPOFF32 and DTPOFF64 if we have seen a TLS block
reloc.
Diffstat (limited to 'gold/x86_64.cc')
-rw-r--r-- | gold/x86_64.cc | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/gold/x86_64.cc b/gold/x86_64.cc index d787700..b7d4933 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -197,7 +197,7 @@ class Target_x86_64 : public Sized_target<64, false> { public: Relocate() - : skip_call_tls_get_addr_(false) + : skip_call_tls_get_addr_(false), saw_tls_block_reloc_(false) { } ~Relocate() @@ -288,6 +288,12 @@ class Target_x86_64 : public Sized_target<64, false> // This is set if we should skip the next reloc, which should be a // PLT32 reloc against ___tls_get_addr. bool skip_call_tls_get_addr_; + + // This is set if we see a relocation which could load the address + // of the TLS block. Whether we see such a relocation determines + // how we handle the R_X86_64_DTPOFF32 relocation, which is used + // in debugging sections. + bool saw_tls_block_reloc_; }; // A class which returns the size required for a relocation type, @@ -1897,6 +1903,7 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, switch (r_type) { case elfcpp::R_X86_64_TLSGD: // Global-dynamic + this->saw_tls_block_reloc_ = true; if (optimized_type == tls::TLSOPT_TO_LE) { gold_assert(tls_segment != NULL); @@ -1947,6 +1954,7 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, case elfcpp::R_X86_64_GOTPC32_TLSDESC: // Global-dynamic (from ~oliva url) case elfcpp::R_X86_64_TLSDESC_CALL: + this->saw_tls_block_reloc_ = true; if (optimized_type == tls::TLSOPT_TO_LE) { gold_assert(tls_segment != NULL); @@ -2000,6 +2008,7 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo, break; case elfcpp::R_X86_64_TLSLD: // Local-dynamic + this->saw_tls_block_reloc_ = true; if (optimized_type == tls::TLSOPT_TO_LE) { gold_assert(tls_segment != NULL); @@ -2026,14 +2035,25 @@ 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 -= tls_segment->memsz(); + { + // This relocation type is used in debugging information. + // In that case we need to not optimize the value. If we + // haven't seen a TLSLD reloc, then we assume we should not + // optimize this reloc. + if (this->saw_tls_block_reloc_) + 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 -= tls_segment->memsz(); + { + // See R_X86_64_DTPOFF32, just above, for why we test this. + if (this->saw_tls_block_reloc_) + value -= tls_segment->memsz(); + } Relocate_functions<64, false>::rela64(view, value, 0); break; |