diff options
author | Cary Coutant <ccoutant@google.com> | 2015-01-28 15:39:08 -0800 |
---|---|---|
committer | Cary Coutant <ccoutant@google.com> | 2015-01-28 15:39:08 -0800 |
commit | 65d9213705654383804ab8af707975f0721c4a6d (patch) | |
tree | 6340936c9adba6e6e27066c0c3230d95a09bd5ae /gold/x86_64.cc | |
parent | 37a3056ad4d02a5295e0288d630dea377907a60c (diff) | |
download | fsf-binutils-gdb-65d9213705654383804ab8af707975f0721c4a6d.zip fsf-binutils-gdb-65d9213705654383804ab8af707975f0721c4a6d.tar.gz fsf-binutils-gdb-65d9213705654383804ab8af707975f0721c4a6d.tar.bz2 |
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.cc | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/gold/x86_64.cc b/gold/x86_64.cc index dd6c07b..a4aebc8 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); } |