? .DS_Store ? fileread.cc-debug ? gold-thin-archive-changelog.txt ? gold-thin-archive-patch.txt ? got-changelog.txt ? got-patch.txt ? object.cc-trace ? options.cc-trace ? options.h-trace ? symtab.cc-trace ? tlsdesc-changelog-2.txt ? tlsdesc-patch-2.txt ? tlsdesc.changelog.txt ? tlsdesc.patch.txt ? trace.patch ? weak-undef-changelog-2.txt ? weak-undef-changelog.txt ? weak-undef-patch-2.txt ? weak-undef-patch.txt Index: i386.cc =================================================================== RCS file: /cvs/src/src/gold/i386.cc,v retrieving revision 1.70 diff -u -p -r1.70 i386.cc --- i386.cc 16 Apr 2008 22:54:29 -0000 1.70 +++ i386.cc 17 Apr 2008 01:02:04 -0000 @@ -59,7 +59,7 @@ class Target_i386 : public Sized_target< : 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< 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< 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 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_o 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_ 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. Index: symtab.cc =================================================================== RCS file: /cvs/src/src/gold/symtab.cc,v retrieving revision 1.90 diff -u -p -r1.90 symtab.cc --- symtab.cc 10 Apr 2008 00:58:58 -0000 1.90 +++ symtab.cc 17 Apr 2008 01:02:04 -0000 @@ -1839,7 +1839,9 @@ Symbol_table::sized_finalize_symbol(Symb 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: Index: x86_64.cc =================================================================== RCS file: /cvs/src/src/gold/x86_64.cc,v retrieving revision 1.63 diff -u -p -r1.63 x86_64.cc --- x86_64.cc 16 Apr 2008 22:54:29 -0000 1.63 +++ x86_64.cc 17 Apr 2008 01:02:04 -0000 @@ -63,7 +63,7 @@ class Target_x86_64 : public Sized_targe : 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_targe 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_targe 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_tab 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 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 Genera 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.