aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>2009-10-15 00:33:18 +0000
committerIan Lance Taylor <ian@airs.com>2009-10-15 00:33:18 +0000
commit82bb573a567ac147a333b86e36208e2397d5f5df (patch)
treee2c38c03b45f7749e5614c152278bc670231b719
parent7b6964b46ccee427823c18726e262f09284821d1 (diff)
downloadbinutils-82bb573a567ac147a333b86e36208e2397d5f5df.zip
binutils-82bb573a567ac147a333b86e36208e2397d5f5df.tar.gz
binutils-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.
-rw-r--r--gold/ChangeLog11
-rw-r--r--gold/i386.cc46
-rw-r--r--gold/object.h4
-rw-r--r--gold/reloc.cc2
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;