* object.h (class Relocate_info): Add reloc_shdr and data_shdr
fields. * object.cc (Sized_relobj::relocate_sections): Set reloc_shdr and data_shdr fields of relinfo. * i386.cc (class Target_i386::Relocate): Remove ldo_addrs_ field. (Target_i386::Relocate::relocate_tls): Don't call fix_up_ldo. For R_386_TLS_LDO_32, adjust based on section flags. (Target_i386::Relocate::fix_up_ldo): Remove.
This commit is contained in:
parent
7b6964b46c
commit
82bb573a56
@ -1,3 +1,14 @@
|
||||
2009-10-14 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
* object.h (class Relocate_info): Add reloc_shdr and data_shdr
|
||||
fields.
|
||||
* object.cc (Sized_relobj::relocate_sections): Set reloc_shdr and
|
||||
data_shdr fields of relinfo.
|
||||
* i386.cc (class Target_i386::Relocate): Remove ldo_addrs_ field.
|
||||
(Target_i386::Relocate::relocate_tls): Don't call fix_up_ldo. For
|
||||
R_386_TLS_LDO_32, adjust based on section flags.
|
||||
(Target_i386::Relocate::fix_up_ldo): Remove.
|
||||
|
||||
2009-10-13 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
Add support for -pie.
|
||||
|
46
gold/i386.cc
46
gold/i386.cc
@ -221,7 +221,7 @@ class Target_i386 : public Target_freebsd<32, false>
|
||||
public:
|
||||
Relocate()
|
||||
: skip_call_tls_get_addr_(false),
|
||||
local_dynamic_type_(LOCAL_DYNAMIC_NONE), ldo_addrs_()
|
||||
local_dynamic_type_(LOCAL_DYNAMIC_NONE)
|
||||
{ }
|
||||
|
||||
~Relocate()
|
||||
@ -316,10 +316,6 @@ 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
|
||||
@ -335,8 +331,6 @@ 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,
|
||||
@ -1937,8 +1931,6 @@ 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)
|
||||
{
|
||||
@ -1997,8 +1989,6 @@ 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)
|
||||
{
|
||||
@ -2023,21 +2013,19 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
||||
break;
|
||||
|
||||
case elfcpp::R_386_TLS_LDO_32: // Alternate local-dynamic
|
||||
// This reloc can appear in debugging sections, in which case we
|
||||
// won't see the TLS_LDM reloc. The local_dynamic_type field
|
||||
// tells us this.
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
if (this->local_dynamic_type_ != LOCAL_DYNAMIC_NONE)
|
||||
// This reloc can appear in debugging sections, in which
|
||||
// case we must not convert to local-exec. We decide what
|
||||
// to do based on whether the section is marked as
|
||||
// containing executable code. That is what the GNU linker
|
||||
// does as well.
|
||||
elfcpp::Shdr<32, false> shdr(relinfo->data_shdr);
|
||||
if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
|
||||
{
|
||||
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;
|
||||
@ -2445,24 +2433,6 @@ 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
|
||||
|
@ -2007,8 +2007,12 @@ struct Relocate_info
|
||||
Sized_relobj<size, big_endian>* object;
|
||||
// Section index of relocation section.
|
||||
unsigned int reloc_shndx;
|
||||
// Section header of relocation section.
|
||||
const unsigned char* reloc_shdr;
|
||||
// Section index of section being relocated.
|
||||
unsigned int data_shndx;
|
||||
// Section header of data section.
|
||||
const unsigned char* data_shdr;
|
||||
|
||||
// Return a string showing the location of a relocation. This is
|
||||
// only used for error messages.
|
||||
|
@ -890,7 +890,9 @@ Sized_relobj<size, big_endian>::relocate_sections(
|
||||
|| this->relocs_must_follow_section_writes());
|
||||
|
||||
relinfo.reloc_shndx = i;
|
||||
relinfo.reloc_shdr = p;
|
||||
relinfo.data_shndx = index;
|
||||
relinfo.data_shdr = pshdrs + index * This::shdr_size;
|
||||
unsigned char* view = (*pviews)[index].view;
|
||||
Address address = (*pviews)[index].address;
|
||||
section_size_type view_size = (*pviews)[index].view_size;
|
||||
|
Loading…
x
Reference in New Issue
Block a user