Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions lib/Target/X86/x86_64Relocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,13 @@ Relocator::Result eld::relocTPOFF(Relocation &pReloc, x86_64Relocator &pParent,

uint64_t TLSTemplateSize = pParent.getTarget().getTLSTemplateSize();

ResolveInfo *rsym = pReloc.symInfo();
if (rsym && rsym->isWeakUndef() &&
(pParent.config().codeGenType() == LinkerConfig::Exec)) {
Relocator::DWord A = pReloc.addend();
return ApplyReloc(pReloc, A, pRelocDesc, DiagEngine, options, pParent);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about shared/pie ?

what is the difference for other targets ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TPOFF handling for Weak undef is not done for other architectures also.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied the check from relocAbs(), it mentions that weak-undef symbol resolving to 0 is only the correct link-time behavior in a static executable. So, for a shared/PIE, an unresolved symbol should be handled via dynamic relocations.


if (TLSTemplateSize == 0) {
pParent.config().raise(Diag::no_pt_tls_segment);
return Relocator::BadReloc;
Expand Down
11 changes: 11 additions & 0 deletions test/x86_64/linux/WeakUndefTLS/Inputs/weak_tls_defined.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.section .tdata, "awT", @progbits
.align 4
.global real_tls
real_tls:
.long 0

.section .data
.align 4
result:
.long 0xdeadbeef
.reloc result, R_X86_64_TPOFF32, real_tls
6 changes: 6 additions & 0 deletions test/x86_64/linux/WeakUndefTLS/Inputs/weak_tls_ld.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.weak weak_tls
.section .data
.align 4
result:
.long 0xdeadbeef
.reloc result, R_X86_64_DTPOFF32, weak_tls
6 changes: 6 additions & 0 deletions test/x86_64/linux/WeakUndefTLS/Inputs/weak_tls_ld64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.weak weak_tls
.section .data
.align 8
result:
.quad 0xdeadbeefdeadbeef
.reloc result, R_X86_64_DTPOFF64, weak_tls
6 changes: 6 additions & 0 deletions test/x86_64/linux/WeakUndefTLS/Inputs/weak_tls_le.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.weak weak_tls
.section .data
.align 4
result:
.long 0xdeadbeef
.reloc result, R_X86_64_TPOFF32, weak_tls
6 changes: 6 additions & 0 deletions test/x86_64/linux/WeakUndefTLS/Inputs/weak_tls_le64.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.weak weak_tls
.section .data
.align 8
result:
.quad 0xdeadbeefdeadbeef
.reloc result, R_X86_64_TPOFF64, weak_tls
6 changes: 6 additions & 0 deletions test/x86_64/linux/WeakUndefTLS/Inputs/weak_tls_le_addend.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.weak weak_tls
.section .data
.align 4
result:
.long 0xdeadbeef
.reloc result, R_X86_64_TPOFF32, weak_tls+2
61 changes: 61 additions & 0 deletions test/x86_64/linux/WeakUndefTLS/WeakUndefTLS.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#--WeakUndefTLS.test----------Executable--------#
BEGIN_COMMENT
# Test R_X86_64_TPOFF32/64 and R_X86_64_DTPOFF32/64 relocations against
# weak undefined TLS symbols. A weak undefined TLS symbol has no TLS slot,
# so the tpoff formula must not run; the result is the addend only (= 0
# for the common case). Mirrors lld's R_TPREL guard:
# if (sym.isUndefined()) return a;
# Also verifies that defined TLS symbols are unaffected (regression guard).
#END_COMMENT

#START_TEST

# Case 1: TPOFF32 + weak-undef -> 0x00000000
RUN: %clang %clangopts -c %p/Inputs/weak_tls_le.s -o %t.le.o
RUN: %link %linkopts -static %t.le.o -o %t.le.exe
RUN: %objdump -s -j .data %t.le.exe | %filecheck %s --check-prefix=LE32

# Case 2: TPOFF64 + weak-undef -> 0x0000000000000000
RUN: %clang %clangopts -c %p/Inputs/weak_tls_le64.s -o %t.le64.o
RUN: %link %linkopts -static %t.le64.o -o %t.le64.exe
RUN: %objdump -s -j .data %t.le64.exe | %filecheck %s --check-prefix=LE64

# Case 3: DTPOFF32 + weak-undef -> 0x00000000
RUN: %clang %clangopts -c %p/Inputs/weak_tls_ld.s -o %t.ld.o
RUN: %link %linkopts -static %t.ld.o -o %t.ld.exe
RUN: %objdump -s -j .data %t.ld.exe | %filecheck %s --check-prefix=LD32

# Case 4: DTPOFF64 + weak-undef -> 0x0000000000000000
RUN: %clang %clangopts -c %p/Inputs/weak_tls_ld64.s -o %t.ld64.o
RUN: %link %linkopts -static %t.ld64.o -o %t.ld64.exe
RUN: %objdump -s -j .data %t.ld64.exe | %filecheck %s --check-prefix=LD64

# Case 5: TPOFF32 + defined symbol -> -4 = 0xfffffffc (regression guard)
RUN: %clang %clangopts -c %p/Inputs/weak_tls_defined.s -o %t.def.o
RUN: %link %linkopts -static %t.def.o -o %t.def.exe
RUN: %objdump -s -j .data %t.def.exe | %filecheck %s --check-prefix=DEFINED

# Case 6: TPOFF32 + weak-undef + addend=2 -> 0x00000002
RUN: %clang %clangopts -c %p/Inputs/weak_tls_le_addend.s -o %t.addend.o
RUN: %link %linkopts -static %t.addend.o -o %t.addend.exe
RUN: %objdump -s -j .data %t.addend.exe | %filecheck %s --check-prefix=ADDEND

LE32: Contents of section .data:
LE32-NEXT: {{[0-9a-f]+}} 00000000

LE64: Contents of section .data:
LE64-NEXT: {{[0-9a-f]+}} 00000000 00000000

LD32: Contents of section .data:
LD32-NEXT: {{[0-9a-f]+}} 00000000

LD64: Contents of section .data:
LD64-NEXT: {{[0-9a-f]+}} 00000000 00000000

DEFINED: Contents of section .data:
DEFINED-NEXT: {{[0-9a-f]+}} fcffffff

ADDEND: Contents of section .data:
ADDEND-NEXT: {{[0-9a-f]+}} 02000000

#END_TEST