diff options
author | Ian Lance Taylor <ian@airs.com> | 2009-10-15 00:33:18 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2009-10-15 00:33:18 +0000 |
commit | 82bb573a567ac147a333b86e36208e2397d5f5df (patch) | |
tree | e2c38c03b45f7749e5614c152278bc670231b719 /gold | |
parent | 7b6964b46ccee427823c18726e262f09284821d1 (diff) | |
download | gdb-82bb573a567ac147a333b86e36208e2397d5f5df.zip gdb-82bb573a567ac147a333b86e36208e2397d5f5df.tar.gz gdb-82bb573a567ac147a333b86e36208e2397d5f5df.tar.bz2 |
* 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.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 11 | ||||
-rw-r--r-- | gold/i386.cc | 46 | ||||
-rw-r--r-- | gold/object.h | 4 | ||||
-rw-r--r-- | gold/reloc.cc | 2 |
4 files changed, 25 insertions, 38 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index 9b0623d..f5b1fd5 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -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. diff --git a/gold/i386.cc b/gold/i386.cc index 5ac9ff4..445a7ac 100644 --- a/gold/i386.cc +++ b/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 diff --git a/gold/object.h b/gold/object.h index 66f5dbb..ff96682 100644 --- a/gold/object.h +++ b/gold/object.h @@ -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. diff --git a/gold/reloc.cc b/gold/reloc.cc index d618ea4..3018dc3 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -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; |