summaryrefslogtreecommitdiff
path: root/gold/x86_64.cc
diff options
context:
space:
mode:
authorCary Coutant <ccoutant@google.com>2015-01-28 15:39:08 -0800
committerCary Coutant <ccoutant@google.com>2015-01-28 15:39:08 -0800
commit65d9213705654383804ab8af707975f0721c4a6d (patch)
tree6340936c9adba6e6e27066c0c3230d95a09bd5ae /gold/x86_64.cc
parent37a3056ad4d02a5295e0288d630dea377907a60c (diff)
downloadbinutils-gdb-65d9213705654383804ab8af707975f0721c4a6d.tar.gz
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.
Diffstat (limited to 'gold/x86_64.cc')
-rw-r--r--gold/x86_64.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/gold/x86_64.cc b/gold/x86_64.cc
index dd6c07b9516..a4aebc82c2c 100644
--- a/gold/x86_64.cc
+++ b/gold/x86_64.cc
@@ -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);
}