aboutsummaryrefslogtreecommitdiff
path: root/gold/i386.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2008-04-17 02:00:54 +0000
committerCary Coutant <ccoutant@google.com>2008-04-17 02:00:54 +0000
commitedfbb029539d1e67751ca7dd7c6ff3cbe702a6c2 (patch)
tree040f027806994825a8d677b455d77362de6ab65e /gold/i386.cc
parent700b53b17a52448cb49f04a4e27d5f0130537924 (diff)
downloadfsf-binutils-gdb-edfbb029539d1e67751ca7dd7c6ff3cbe702a6c2.zip
fsf-binutils-gdb-edfbb029539d1e67751ca7dd7c6ff3cbe702a6c2.tar.gz
fsf-binutils-gdb-edfbb029539d1e67751ca7dd7c6ff3cbe702a6c2.tar.bz2
* i386.cc (Target_i386::define_tls_base_symbol): New function.
(Target_i386::tls_base_symbol_defined_): New field. (Target_i386::Scan::local): Define _TLS_MODULE_BASE_ symbol. (Target_i386::Scan::global): Likewise. * symtab.cc (sized_finalize_symbol): Add check for TLS symbol. * x86_64.cc (Target_x86_64::define_tls_base_symbol): New function. (Target_x86_64::tls_base_symbol_defined_): New field. (Target_x86_64::Scan::local): Define _TLS_MODULE_BASE_ symbol. (Target_x86_64::Scan::global): Likewise.
Diffstat (limited to 'gold/i386.cc')
-rw-r--r--gold/i386.cc31
1 files changed, 30 insertions, 1 deletions
diff --git a/gold/i386.cc b/gold/i386.cc
index 917ec0b..3e24836 100644
--- a/gold/i386.cc
+++ b/gold/i386.cc
@@ -59,7 +59,7 @@ class Target_i386 : public Sized_target<32, false>
: Sized_target<32, false>(&i386_info),
got_(NULL), plt_(NULL), got_plt_(NULL), rel_dyn_(NULL),
copy_relocs_(elfcpp::R_386_COPY), dynbss_(NULL),
- got_mod_index_offset_(-1U)
+ got_mod_index_offset_(-1U), tls_base_symbol_defined_(false)
{ }
// Scan the relocations to look for symbol adjustments.
@@ -323,6 +323,10 @@ class Target_i386 : public Sized_target<32, false>
void
make_plt_entry(Symbol_table*, Layout*, Symbol*);
+ // Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+ void
+ define_tls_base_symbol(Symbol_table*, Layout*);
+
// Create a GOT entry for the TLS module index.
unsigned int
got_mod_index_entry(Symbol_table* symtab, Layout* layout,
@@ -391,6 +395,8 @@ class Target_i386 : public Sized_target<32, false>
Output_data_space* dynbss_;
// Offset of the GOT entry for the TLS module index.
unsigned int got_mod_index_offset_;
+ // True if the _TLS_MODULE_BASE_ symbol has been defined.
+ bool tls_base_symbol_defined_;
};
const Target::Target_info Target_i386::i386_info =
@@ -719,6 +725,27 @@ Target_i386::make_plt_entry(Symbol_table* symtab, Layout* layout, Symbol* gsym)
this->plt_->add_entry(gsym);
}
+// Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment.
+
+void
+Target_i386::define_tls_base_symbol(Symbol_table* symtab, Layout* layout)
+{
+ if (this->tls_base_symbol_defined_)
+ return;
+
+ Output_segment* tls_segment = layout->tls_segment();
+ if (tls_segment != NULL)
+ {
+ symtab->define_in_output_segment("_TLS_MODULE_BASE_", NULL,
+ tls_segment, 0, 0,
+ elfcpp::STT_TLS,
+ elfcpp::STB_LOCAL,
+ elfcpp::STV_HIDDEN, 0,
+ Symbol::SEGMENT_END, true);
+ }
+ this->tls_base_symbol_defined_ = true;
+}
+
// Create a GOT entry for the TLS module index.
unsigned int
@@ -959,6 +986,7 @@ Target_i386::Scan::local(const General_options&,
break;
case elfcpp::R_386_TLS_GOTDESC: // Global-dynamic (from ~oliva)
+ target->define_tls_base_symbol(symtab, layout);
if (optimized_type == tls::TLSOPT_NONE)
{
// Create a double GOT entry with an R_386_TLS_DESC reloc.
@@ -1285,6 +1313,7 @@ Target_i386::Scan::global(const General_options&,
break;
case elfcpp::R_386_TLS_GOTDESC: // Global-dynamic (~oliva url)
+ target->define_tls_base_symbol(symtab, layout);
if (optimized_type == tls::TLSOPT_NONE)
{
// Create a double GOT entry with an R_386_TLS_DESC reloc.