diff options
| -rw-r--r-- | lld/ELF/Writer.cpp | 13 | ||||
| -rw-r--r-- | lld/test/ELF/tls-two-relocs.s | 30 |
2 files changed, 37 insertions, 6 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index e8fbc2ce621..8ba203fa469 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -253,12 +253,13 @@ static bool handleTlsRelocation(unsigned Type, SymbolBody *Body, return false; if (Target->isTlsGlobalDynamicRel(Type)) { - if (!Target->canRelaxTls(Type, Body) && - Out<ELFT>::Got->addDynTlsEntry(Body)) { - Out<ELFT>::RelaDyn->addReloc( - {Target->TlsModuleIndexRel, DynamicReloc<ELFT>::Off_GTlsIndex, Body}); - Out<ELFT>::RelaDyn->addReloc( - {Target->TlsOffsetRel, DynamicReloc<ELFT>::Off_GTlsOffset, Body}); + if (!Target->canRelaxTls(Type, Body)) { + if (Out<ELFT>::Got->addDynTlsEntry(Body)) { + Out<ELFT>::RelaDyn->addReloc({Target->TlsModuleIndexRel, + DynamicReloc<ELFT>::Off_GTlsIndex, Body}); + Out<ELFT>::RelaDyn->addReloc( + {Target->TlsOffsetRel, DynamicReloc<ELFT>::Off_GTlsOffset, Body}); + } return true; } if (!canBePreempted(Body, true)) diff --git a/lld/test/ELF/tls-two-relocs.s b/lld/test/ELF/tls-two-relocs.s new file mode 100644 index 00000000000..7c5d6abf77f --- /dev/null +++ b/lld/test/ELF/tls-two-relocs.s @@ -0,0 +1,30 @@ +// REQUIRES: x86 +// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +// RUN: ld.lld %t -o %tout -shared +// RUN: llvm-readobj -r %tout | FileCheck %s + + data16 + leaq g_tls_s@TLSGD(%rip), %rdi + data16 + data16 + rex64 + callq __tls_get_addr@PLT + + data16 + leaq g_tls_s@TLSGD(%rip), %rdi + data16 + data16 + rex64 + callq __tls_get_addr@PLT + +// Check that we handle two gd relocations to the same symbol. + +// CHECK: Relocations [ +// CHECK-NEXT: Section (4) .rela.dyn { +// CHECK-NEXT: R_X86_64_DTPMOD64 g_tls_s 0x0 +// CHECK-NEXT: R_X86_64_DTPOFF64 g_tls_s 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: Section (5) .rela.plt { +// CHECK-NEXT: R_X86_64_JUMP_SLOT __tls_get_addr 0x0 +// CHECK-NEXT: } +// CHECK-NEXT: ] |

