From edfbb029539d1e67751ca7dd7c6ff3cbe702a6c2 Mon Sep 17 00:00:00 2001 From: Cary Coutant Date: Thu, 17 Apr 2008 02:00:54 +0000 Subject: * 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. --- gold/ChangeLog | 12 ++++++++++++ gold/i386.cc | 31 ++++++++++++++++++++++++++++++- gold/symtab.cc | 4 +++- gold/x86_64.cc | 31 ++++++++++++++++++++++++++++++- 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 228fc93..0bc62ab 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,5 +1,17 @@ 2008-04-16 Cary Coutant + * 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. + +2008-04-16 Cary Coutant + * symtab.h (Symbol::is_strong_undefined): Removed unused function. (Symbol::needs_plt_entry): Allow weak undefined symbols. (Symbol::needs_dynamic_reloc): Allow weak undefined symbols when 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. diff --git a/gold/symtab.cc b/gold/symtab.cc index ee826b3..9b23790 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1839,7 +1839,9 @@ Symbol_table::sized_finalize_symbol(Symbol* unsized_sym) case Symbol::IN_OUTPUT_SEGMENT: { Output_segment* os = sym->output_segment(); - value = sym->value() + os->vaddr(); + value = sym->value(); + if (sym->type() != elfcpp::STT_TLS) + value += os->vaddr(); switch (sym->offset_base()) { case Symbol::SEGMENT_START: diff --git a/gold/x86_64.cc b/gold/x86_64.cc index 6fea4e3..247f9d0 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -63,7 +63,7 @@ class Target_x86_64 : public Sized_target<64, false> : Sized_target<64, false>(&x86_64_info), got_(NULL), plt_(NULL), got_plt_(NULL), rela_dyn_(NULL), copy_relocs_(elfcpp::R_X86_64_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. @@ -324,6 +324,10 @@ class Target_x86_64 : public Sized_target<64, 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 the reserved PLT and GOT entries for the TLS descriptor resolver. void reserve_tlsdesc_entries(Symbol_table* symtab, Layout* layout); @@ -394,6 +398,8 @@ class Target_x86_64 : public Sized_target<64, 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_x86_64::x86_64_info = @@ -771,6 +777,27 @@ Target_x86_64::make_plt_entry(Symbol_table* symtab, Layout* layout, this->plt_->add_entry(gsym); } +// Define the _TLS_MODULE_BASE_ symbol at the end of the TLS segment. + +void +Target_x86_64::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 the reserved PLT and GOT entries for the TLS descriptor resolver. void @@ -1093,6 +1120,7 @@ Target_x86_64::Scan::local(const General_options&, break; case elfcpp::R_X86_64_GOTPC32_TLSDESC: + target->define_tls_base_symbol(symtab, layout); if (optimized_type == tls::TLSOPT_NONE) { // Create reserved PLT and GOT entries for the resolver. @@ -1393,6 +1421,7 @@ Target_x86_64::Scan::global(const General_options&, break; case elfcpp::R_X86_64_GOTPC32_TLSDESC: + target->define_tls_base_symbol(symtab, layout); if (optimized_type == tls::TLSOPT_NONE) { // Create reserved PLT and GOT entries for the resolver. -- cgit v1.1