PR gold/12279
* resolve.cc (Symbol_table::should_override): Add fromtype parameter. Change all callers. Give error when linking together TLS and non-TLS symbol. (Symbol_table::should_override_with_special): Add fromtype parameter. Change all callers. * i386.cc (Target_i386::Relocate::relocate_tls): Don't crash if there is no TLS segment if we have reported some errors. * x86_64.cc (Target_x86_64::relocate_tls): Likewise.
This commit is contained in:
parent
67181c72fb
commit
6285534768
|
@ -1,3 +1,15 @@
|
|||
2011-07-08 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
PR gold/12279
|
||||
* resolve.cc (Symbol_table::should_override): Add fromtype
|
||||
parameter. Change all callers. Give error when linking together
|
||||
TLS and non-TLS symbol.
|
||||
(Symbol_table::should_override_with_special): Add fromtype
|
||||
parameter. Change all callers.
|
||||
* i386.cc (Target_i386::Relocate::relocate_tls): Don't crash if
|
||||
there is no TLS segment if we have reported some errors.
|
||||
* x86_64.cc (Target_x86_64::relocate_tls): Likewise.
|
||||
|
||||
2011-07-08 Ian Lance Taylor <iant@google.com>
|
||||
|
||||
PR gold/12372
|
||||
|
|
54
gold/i386.cc
54
gold/i386.cc
|
@ -2638,7 +2638,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
case elfcpp::R_386_TLS_GD: // Global-dynamic
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
this->tls_gd_to_le(relinfo, relnum, tls_segment,
|
||||
rel, r_type, value, view,
|
||||
view_size);
|
||||
|
@ -2664,7 +2668,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
this->tls_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type,
|
||||
got_offset, view, view_size);
|
||||
break;
|
||||
|
@ -2687,7 +2695,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
|
||||
rel, r_type, value, view,
|
||||
view_size);
|
||||
|
@ -2722,7 +2734,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
this->tls_desc_gd_to_ie(relinfo, relnum, tls_segment, rel, r_type,
|
||||
got_offset, view, view_size);
|
||||
break;
|
||||
|
@ -2754,7 +2770,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
this->local_dynamic_type_ = LOCAL_DYNAMIC_GNU;
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
this->tls_ld_to_le(relinfo, relnum, tls_segment, rel, r_type,
|
||||
value, view, view_size);
|
||||
break;
|
||||
|
@ -2785,7 +2805,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
elfcpp::Shdr<32, false> shdr(relinfo->data_shdr);
|
||||
if ((shdr.get_sh_flags() & elfcpp::SHF_EXECINSTR) != 0)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
value -= tls_segment->memsz();
|
||||
}
|
||||
}
|
||||
|
@ -2797,7 +2821,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
case elfcpp::R_386_TLS_IE_32:
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
Target_i386::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
|
||||
rel, r_type, value, view,
|
||||
view_size);
|
||||
|
@ -2841,7 +2869,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
// have been created for this location, so do not apply it now.
|
||||
if (!parameters->options().shared())
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<32, false>::rel32(view, value);
|
||||
}
|
||||
|
@ -2852,7 +2884,11 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
// have been created for this location, so do not apply it now.
|
||||
if (!parameters->options().shared())
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
value = tls_segment->memsz() - value;
|
||||
Relocate_functions<32, false>::rel32(view, value);
|
||||
}
|
||||
|
|
|
@ -351,8 +351,8 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
|||
bool adjust_common_sizes;
|
||||
bool adjust_dyndef;
|
||||
typename Sized_symbol<size>::Size_type tosize = to->symsize();
|
||||
if (Symbol_table::should_override(to, frombits, OBJECT, object,
|
||||
&adjust_common_sizes,
|
||||
if (Symbol_table::should_override(to, frombits, sym.get_st_type(), OBJECT,
|
||||
object, &adjust_common_sizes,
|
||||
&adjust_dyndef))
|
||||
{
|
||||
elfcpp::STB tobinding = to->binding();
|
||||
|
@ -409,8 +409,8 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
|||
|
||||
bool
|
||||
Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
||||
Defined defined, Object* object,
|
||||
bool* adjust_common_sizes,
|
||||
elfcpp::STT fromtype, Defined defined,
|
||||
Object* object, bool* adjust_common_sizes,
|
||||
bool* adjust_dyndef)
|
||||
{
|
||||
*adjust_common_sizes = false;
|
||||
|
@ -434,7 +434,13 @@ Symbol_table::should_override(const Symbol* to, unsigned int frombits,
|
|||
to->type());
|
||||
}
|
||||
|
||||
// FIXME: Warn if either but not both of TO and SYM are STT_TLS.
|
||||
if (to->type() == elfcpp::STT_TLS
|
||||
? fromtype != elfcpp::STT_TLS
|
||||
: fromtype == elfcpp::STT_TLS)
|
||||
Symbol_table::report_resolve_problem(true,
|
||||
_("symbol '%s' used as both __thread "
|
||||
"and non-__thread"),
|
||||
to, defined, object);
|
||||
|
||||
// We use a giant switch table for symbol resolution. This code is
|
||||
// unwieldy, but: 1) it is efficient; 2) we definitely handle all
|
||||
|
@ -870,13 +876,15 @@ Symbol_table::report_resolve_problem(bool is_error, const char* msg,
|
|||
// defining special symbols.
|
||||
|
||||
bool
|
||||
Symbol_table::should_override_with_special(const Symbol* to, Defined defined)
|
||||
Symbol_table::should_override_with_special(const Symbol* to,
|
||||
elfcpp::STT fromtype,
|
||||
Defined defined)
|
||||
{
|
||||
bool adjust_common_sizes;
|
||||
bool adjust_dyn_def;
|
||||
unsigned int frombits = global_flag | regular_flag | def_flag;
|
||||
bool ret = Symbol_table::should_override(to, frombits, defined, NULL,
|
||||
&adjust_common_sizes,
|
||||
bool ret = Symbol_table::should_override(to, frombits, fromtype, defined,
|
||||
NULL, &adjust_common_sizes,
|
||||
&adjust_dyn_def);
|
||||
gold_assert(!adjust_common_sizes && !adjust_dyn_def);
|
||||
return ret;
|
||||
|
|
|
@ -1883,7 +1883,7 @@ Symbol_table::do_define_in_output_data(
|
|||
return sym;
|
||||
}
|
||||
|
||||
if (Symbol_table::should_override_with_special(oldsym, defined))
|
||||
if (Symbol_table::should_override_with_special(oldsym, type, defined))
|
||||
this->override_with_special(oldsym, sym);
|
||||
|
||||
if (resolve_oldsym)
|
||||
|
@ -1997,7 +1997,7 @@ Symbol_table::do_define_in_output_segment(
|
|||
return sym;
|
||||
}
|
||||
|
||||
if (Symbol_table::should_override_with_special(oldsym, defined))
|
||||
if (Symbol_table::should_override_with_special(oldsym, type, defined))
|
||||
this->override_with_special(oldsym, sym);
|
||||
|
||||
if (resolve_oldsym)
|
||||
|
@ -2116,7 +2116,7 @@ Symbol_table::do_define_as_constant(
|
|||
}
|
||||
|
||||
if (force_override
|
||||
|| Symbol_table::should_override_with_special(oldsym, defined))
|
||||
|| Symbol_table::should_override_with_special(oldsym, type, defined))
|
||||
this->override_with_special(oldsym, sym);
|
||||
|
||||
if (resolve_oldsym)
|
||||
|
|
|
@ -1661,7 +1661,8 @@ class Symbol_table
|
|||
// Whether we should override a symbol, based on flags in
|
||||
// resolve.cc.
|
||||
static bool
|
||||
should_override(const Symbol*, unsigned int, Defined, Object*, bool*, bool*);
|
||||
should_override(const Symbol*, unsigned int, elfcpp::STT, Defined,
|
||||
Object*, bool*, bool*);
|
||||
|
||||
// Report a problem in symbol resolution.
|
||||
static void
|
||||
|
@ -1679,7 +1680,7 @@ class Symbol_table
|
|||
// Whether we should override a symbol with a special symbol which
|
||||
// is automatically defined by the linker.
|
||||
static bool
|
||||
should_override_with_special(const Symbol*, Defined);
|
||||
should_override_with_special(const Symbol*, elfcpp::STT, Defined);
|
||||
|
||||
// Override a symbol with a special symbol.
|
||||
template<int size>
|
||||
|
|
|
@ -3110,7 +3110,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
this->tls_gd_to_le(relinfo, relnum, tls_segment,
|
||||
rela, r_type, value, view,
|
||||
view_size);
|
||||
|
@ -3136,7 +3140,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
value = target->got_plt_section()->address() + got_offset;
|
||||
this->tls_gd_to_ie(relinfo, relnum, tls_segment, rela, r_type,
|
||||
value, view, address, view_size);
|
||||
|
@ -3165,7 +3173,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
this->tls_desc_gd_to_le(relinfo, relnum, tls_segment,
|
||||
rela, r_type, value, view,
|
||||
view_size);
|
||||
|
@ -3200,7 +3212,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_IE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
value = target->got_plt_section()->address() + got_offset;
|
||||
this->tls_desc_gd_to_ie(relinfo, relnum, tls_segment,
|
||||
rela, r_type, value, view, address,
|
||||
|
@ -3232,7 +3248,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
}
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
this->tls_ld_to_le(relinfo, relnum, tls_segment, rela, r_type,
|
||||
value, view, view_size);
|
||||
break;
|
||||
|
@ -3262,7 +3282,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
// R_X86_64_TLSLD.
|
||||
if (optimized_type == tls::TLSOPT_TO_LE && is_executable)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
value -= tls_segment->memsz();
|
||||
}
|
||||
Relocate_functions<64, false>::rela32(view, value, addend);
|
||||
|
@ -3272,7 +3296,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
// See R_X86_64_DTPOFF32, just above, for why we check for is_executable.
|
||||
if (optimized_type == tls::TLSOPT_TO_LE && is_executable)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
value -= tls_segment->memsz();
|
||||
}
|
||||
Relocate_functions<64, false>::rela64(view, value, addend);
|
||||
|
@ -3281,7 +3309,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
|
||||
if (optimized_type == tls::TLSOPT_TO_LE)
|
||||
{
|
||||
gold_assert(tls_segment != NULL);
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
Target_x86_64::Relocate::tls_ie_to_le(relinfo, relnum, tls_segment,
|
||||
rela, r_type, value, view,
|
||||
view_size);
|
||||
|
@ -3316,6 +3348,11 @@ Target_x86_64::Relocate::relocate_tls(const Relocate_info<64, false>* relinfo,
|
|||
break;
|
||||
|
||||
case elfcpp::R_X86_64_TPOFF32: // Local-exec
|
||||
if (tls_segment == NULL)
|
||||
{
|
||||
gold_assert(parameters->errors()->error_count() > 0);
|
||||
return;
|
||||
}
|
||||
value -= tls_segment->memsz();
|
||||
Relocate_functions<64, false>::rela32(view, value, addend);
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue