mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2025-02-17 13:10:12 +08:00
* i386.cc (class Target_i386::Relocate): Add ldo_addrs_ field.
(Target_i386::Relocate::relocate_tls): Call fix_up_ldo before changing local_dynamic_type_ from LOCAL_DYNAMIC_NONE. When handling R_386_TLS_LDO_32, if local_dynamic_type_ is NONE, push the address on ldo_addrs_. (Target_i386::Relocate::fix_up_ldo): New function.
This commit is contained in:
parent
f8bf576366
commit
e8a9fcdace
@ -1,3 +1,12 @@
|
||||
2009-10-06 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* i386.cc (class Target_i386::Relocate): Add ldo_addrs_ field.
|
||||
(Target_i386::Relocate::relocate_tls): Call fix_up_ldo before
|
||||
changing local_dynamic_type_ from LOCAL_DYNAMIC_NONE. When
|
||||
handling R_386_TLS_LDO_32, if local_dynamic_type_ is NONE, push
|
||||
the address on ldo_addrs_.
|
||||
(Target_i386::Relocate::fix_up_ldo): New function.
|
||||
|
||||
2009-10-06 Rafael Espindola <espindola@google.com>
|
||||
|
||||
* plugin.cc (add_input_library): New.
|
||||
|
35
gold/i386.cc
35
gold/i386.cc
@ -212,7 +212,7 @@ class Target_i386 : public Target_freebsd<32, false>
|
||||
public:
|
||||
Relocate()
|
||||
: skip_call_tls_get_addr_(false),
|
||||
local_dynamic_type_(LOCAL_DYNAMIC_NONE)
|
||||
local_dynamic_type_(LOCAL_DYNAMIC_NONE), ldo_addrs_()
|
||||
{ }
|
||||
|
||||
~Relocate()
|
||||
@ -307,6 +307,10 @@ class Target_i386 : public Target_freebsd<32, false>
|
||||
unsigned char* view,
|
||||
section_size_type view_size);
|
||||
|
||||
// Fix up LDO_32 relocations we've already seen.
|
||||
void
|
||||
fix_up_ldo(const Relocate_info<32, false>*);
|
||||
|
||||
// We need to keep track of which type of local dynamic relocation
|
||||
// we have seen, so that we can optimize R_386_TLS_LDO_32 correctly.
|
||||
enum Local_dynamic_type
|
||||
@ -322,6 +326,8 @@ class Target_i386 : public Target_freebsd<32, false>
|
||||
// The type of local dynamic relocation we have seen in the section
|
||||
// being relocated, if any.
|
||||
Local_dynamic_type local_dynamic_type_;
|
||||
// A list of LDO_32 offsets, in case we find LDM after LDO_32.
|
||||
std::vector<unsigned char*> ldo_addrs_;
|
||||
};
|
||||
|
||||
// A class which returns the size required for a relocation type,
|
||||
@ -1922,6 +1928,8 @@ 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_DESC_CALL:
|
||||
if (this->local_dynamic_type_ == LOCAL_DYNAMIC_NONE)
|
||||
this->fix_up_ldo(relinfo);
|
||||
this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
@ -1980,6 +1988,8 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
||||
"TLS relocations"));
|
||||
break;
|
||||
}
|
||||
else if (this->local_dynamic_type_ == LOCAL_DYNAMIC_NONE)
|
||||
this->fix_up_ldo(relinfo);
|
||||
this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
@ -2013,6 +2023,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
||||
gold_assert(tls_segment != NULL);
|
||||
value -= tls_segment->memsz();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We may see the LDM later.
|
||||
this->ldo_addrs_.push_back(view);
|
||||
}
|
||||
Relocate_functions<32, false>::rel32(view, value);
|
||||
break;
|
||||
|
||||
@ -2419,6 +2434,24 @@ Target_i386::Relocate::tls_ie_to_le(const Relocate_info<32, false>* relinfo,
|
||||
Relocate_functions<32, false>::rel32(view, value);
|
||||
}
|
||||
|
||||
// If we see an LDM reloc after we handled any LDO_32 relocs, fix up
|
||||
// the LDO_32 relocs.
|
||||
|
||||
void
|
||||
Target_i386::Relocate::fix_up_ldo(const Relocate_info<32, false>* relinfo)
|
||||
{
|
||||
if (this->ldo_addrs_.empty())
|
||||
return;
|
||||
Output_segment* tls_segment = relinfo->layout->tls_segment();
|
||||
gold_assert(tls_segment != NULL);
|
||||
elfcpp::Elf_types<32>::Elf_Addr value = - tls_segment->memsz();
|
||||
for (std::vector<unsigned char*>::const_iterator p = this->ldo_addrs_.begin();
|
||||
p != this->ldo_addrs_.end();
|
||||
++p)
|
||||
Relocate_functions<32, false>::rel32(*p, value);
|
||||
this->ldo_addrs_.clear();
|
||||
}
|
||||
|
||||
// Relocate section data.
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user