Allow undefined references to TLS symbols.

When --warn-unresolved-symbols is used, gold tries to create a dynamic relocation
for it, and gives an internal error if the TLS segment has not already been
created. This patch allows the IE-to-LE optimization for an undefined symbol
when building an executable, which suppresses the dynamic relocation, and
relaxes the requirement to have a TLS segment when applying a relocation for
an undefined symbol.

2015-01-28  Cary Coutant  <ccoutant@google.com>

gold/
	* x86_64.cc (Target_x86_64::Scan::global): Allow IE-to-LE optimization
	for undef TLS symbols.
	(Target_x86_64::Relocate::relocate_tls): Likewise.
	(Target_x86_64::Relocate::tls_ie_to_le): Likewise.
This commit is contained in:
Cary Coutant 2015-01-28 15:39:08 -08:00
parent 37a3056ad4
commit 65d9213705
2 changed files with 24 additions and 3 deletions

View file

@ -1,3 +1,10 @@
2015-01-28 Cary Coutant <ccoutant@google.com>
* x86_64.cc (Target_x86_64::Scan::global): Allow IE-to-LE optimization
for undef TLS symbols.
(Target_x86_64::Relocate::relocate_tls): Likewise.
(Target_x86_64::Relocate::tls_ie_to_le): Likewise.
2015-01-25 Cary Coutant <ccoutant@google.com>
* output.cc (Output_segment::set_section_addresses): Fix calculation

View file

@ -2983,7 +2983,12 @@ Target_x86_64<size>::Scan::global(Symbol_table* symtab,
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
case elfcpp::R_X86_64_TPOFF32: // Local-exec
{
const bool is_final = gsym->final_value_is_known();
// For the Initial-Exec model, we can treat undef symbols as final
// when building an executable.
const bool is_final = (gsym->final_value_is_known() ||
(r_type == elfcpp::R_X86_64_GOTTPOFF &&
gsym->is_undefined() &&
parameters->options().output_is_executable()));
const tls::Tls_optimization optimized_type
= Target_x86_64<size>::optimize_tls_reloc(is_final, r_type);
switch (r_type)
@ -3779,7 +3784,15 @@ Target_x86_64<size>::Relocate::relocate_tls(
break;
case elfcpp::R_X86_64_GOTTPOFF: // Initial-exec
if (optimized_type == tls::TLSOPT_TO_LE)
if (gsym != NULL && gsym->is_undefined())
{
Target_x86_64<size>::Relocate::tls_ie_to_le(relinfo, relnum,
NULL, rela,
r_type, value, view,
view_size);
break;
}
else if (optimized_type == tls::TLSOPT_TO_LE)
{
if (tls_segment == NULL)
{
@ -4126,7 +4139,8 @@ Target_x86_64<size>::Relocate::tls_ie_to_le(
view[-1] = 0x80 | reg | (reg << 3);
}
value -= tls_segment->memsz();
if (tls_segment != NULL)
value -= tls_segment->memsz();
Relocate_functions<size, false>::rela32(view, value, 0);
}