* 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.
This commit is contained in:
parent
700b53b17a
commit
edfbb02953
4 changed files with 75 additions and 3 deletions
|
@ -1,3 +1,15 @@
|
|||
2008-04-16 Cary Coutant <ccoutant@google.com>
|
||||
|
||||
* 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 <ccoutant@google.com>
|
||||
|
||||
* symtab.h (Symbol::is_strong_undefined): Removed unused function.
|
||||
|
|
31
gold/i386.cc
31
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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue