mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-24 20:28:28 +08:00
* 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.
This commit is contained in:
@ -1,5 +1,15 @@
|
|||||||
2008-05-16 Ian Lance Taylor <iant@google.com>
|
2008-05-16 Ian Lance Taylor <iant@google.com>
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
* output.cc (Output_reloc::get_address): Change return type to
|
* output.cc (Output_reloc::get_address): Change return type to
|
||||||
Elf_Addr.
|
Elf_Addr.
|
||||||
* output.h (class Output_reloc): Update get_address declaration.
|
* output.h (class Output_reloc): Update get_address declaration.
|
||||||
|
@ -1843,6 +1843,7 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||||||
|
|
||||||
case elfcpp::R_386_TLS_GOTDESC: // Global-dynamic (from ~oliva url)
|
case elfcpp::R_386_TLS_GOTDESC: // Global-dynamic (from ~oliva url)
|
||||||
case elfcpp::R_386_TLS_DESC_CALL:
|
case elfcpp::R_386_TLS_DESC_CALL:
|
||||||
|
this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||||
{
|
{
|
||||||
gold_assert(tls_segment != NULL);
|
gold_assert(tls_segment != NULL);
|
||||||
@ -1927,7 +1928,8 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||||||
// This reloc can appear in debugging sections, in which case we
|
// This reloc can appear in debugging sections, in which case we
|
||||||
// won't see the TLS_LDM reloc. The local_dynamic_type field
|
// won't see the TLS_LDM reloc. The local_dynamic_type field
|
||||||
// tells us this.
|
// tells us this.
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE
|
||||||
|
&& this->local_dynamic_type_ != LOCAL_DYNAMIC_NONE)
|
||||||
{
|
{
|
||||||
gold_assert(tls_segment != NULL);
|
gold_assert(tls_segment != NULL);
|
||||||
value -= tls_segment->memsz();
|
value -= tls_segment->memsz();
|
||||||
|
@ -197,7 +197,7 @@ class Target_x86_64 : public Sized_target<64, false>
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Relocate()
|
Relocate()
|
||||||
: skip_call_tls_get_addr_(false)
|
: skip_call_tls_get_addr_(false), saw_tls_block_reloc_(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~Relocate()
|
~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
|
// This is set if we should skip the next reloc, which should be a
|
||||||
// PLT32 reloc against ___tls_get_addr.
|
// PLT32 reloc against ___tls_get_addr.
|
||||||
bool skip_call_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,
|
// 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)
|
switch (r_type)
|
||||||
{
|
{
|
||||||
case elfcpp::R_X86_64_TLSGD: // Global-dynamic
|
case elfcpp::R_X86_64_TLSGD: // Global-dynamic
|
||||||
|
this->saw_tls_block_reloc_ = true;
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||||
{
|
{
|
||||||
gold_assert(tls_segment != NULL);
|
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_GOTPC32_TLSDESC: // Global-dynamic (from ~oliva url)
|
||||||
case elfcpp::R_X86_64_TLSDESC_CALL:
|
case elfcpp::R_X86_64_TLSDESC_CALL:
|
||||||
|
this->saw_tls_block_reloc_ = true;
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||||
{
|
{
|
||||||
gold_assert(tls_segment != NULL);
|
gold_assert(tls_segment != NULL);
|
||||||
@ -2000,6 +2008,7 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case elfcpp::R_X86_64_TLSLD: // Local-dynamic
|
case elfcpp::R_X86_64_TLSLD: // Local-dynamic
|
||||||
|
this->saw_tls_block_reloc_ = true;
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||||
{
|
{
|
||||||
gold_assert(tls_segment != NULL);
|
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:
|
case elfcpp::R_X86_64_DTPOFF32:
|
||||||
gold_assert(tls_segment != NULL);
|
gold_assert(tls_segment != NULL);
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||||
|
{
|
||||||
|
// 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();
|
value -= tls_segment->memsz();
|
||||||
|
}
|
||||||
Relocate_functions<64, false>::rela32(view, value, 0);
|
Relocate_functions<64, false>::rela32(view, value, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case elfcpp::R_X86_64_DTPOFF64:
|
case elfcpp::R_X86_64_DTPOFF64:
|
||||||
gold_assert(tls_segment != NULL);
|
gold_assert(tls_segment != NULL);
|
||||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||||
|
{
|
||||||
|
// See R_X86_64_DTPOFF32, just above, for why we test this.
|
||||||
|
if (this->saw_tls_block_reloc_)
|
||||||
value -= tls_segment->memsz();
|
value -= tls_segment->memsz();
|
||||||
|
}
|
||||||
Relocate_functions<64, false>::rela64(view, value, 0);
|
Relocate_functions<64, false>::rela64(view, value, 0);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user