[X86] Fix R_X86_64_TPOFF against weak undefined TLS symbols - #1646
[X86] Fix R_X86_64_TPOFF against weak undefined TLS symbols#1646Rachit Mehta (rachitmeht) wants to merge 2 commits into
Conversation
| // be 0 instead of 1 (true). | ||
| if (!pSymbol->hasFragRef()) | ||
| return true; | ||
| return false; |
There was a problem hiding this comment.
This should be a seperate change.
| (pParent.config().codeGenType() == LinkerConfig::Exec)) { | ||
| Relocator::DWord A = pReloc.addend(); | ||
| return ApplyReloc(pReloc, A, pRelocDesc, DiagEngine, options, pParent); | ||
| } |
There was a problem hiding this comment.
What about shared/pie ?
what is the difference for other targets ?
There was a problem hiding this comment.
TPOFF handling for Weak undef is not done for other architectures also.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
PIE must also handle weak-undefined TPOFF relocations same as static excecutable. When the PIE contains only a weak-undefined TLS reference, no PT_TLS segment is created; computeTLSOffsets() leaves TLSTemplateSize as zero, causing relocTPOFF() to emit the PT_TLS segment not found error instead of resolving the relocation to its addend, as lld does.
| # 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: llvm-objdump -s -j .data %t.addend.exe | FileCheck %s --check-prefix=ADDEND |
There was a problem hiding this comment.
%objdump
dc53d25 to
67a06c5
Compare
Parth (parth-07)
left a comment
There was a problem hiding this comment.
We are fixing TPOFF64 in this PR as well. Can you please update the commit title and the PR title to indicate that?
Additionally, eld only errors out on encountering TPOFF relocation in shared library because there is no PT_TLS segment. This is misleading and not a good error message. LLD properly reports that the relocation is unsupported for shared library. Can you please create an issue regarding this?
Reproducer:
#!/usr/bin/env bash
# Assembly is needed to force exact local-exec TPOFF relocations in data.
#cat > tmp/tpoff32-shared.s <<\EOF
#.weak weak_tls
#.section .data
#.align 4
#result:
# .long 0xdeadbeef
# .reloc result, R_X86_64_TPOFF32, weak_tls
#EOF
cat > tmp/tpoff64-shared.s <<\EOF
.weak weak_tls
.section .data
.align 8
result:
.quad 0xdeadbeefdeadbeef
.reloc result, R_X86_64_TPOFF64, weak_tls
EOF
"$BD/bin/clang" -target x86_64-linux-gnu -c tmp/tpoff32-shared.s -o tmp/tpoff32-shared.o
"$BD/bin/clang" -target x86_64-linux-gnu -c tmp/tpoff64-shared.s -o tmp/tpoff64-shared.o
LDs=(ld.eld ld.lld ld.bfd)
SFs=(eld lld bfd)
for obj in tpoff64-shared; do
for i in "${!SFs[@]}"; do
${LDs[$i]} -m elf_x86_64 -shared tmp/$obj.o -o tmp/$obj.${SFs[$i]}.so
done
done
A weak undefined TLS symbol has no slot in the PT_TLS segment, so the thread-pointer-offset formula (S - templateSize) is meaningless for it. Previously relocTPOFF applied that formula with a bogus symbol value, producing an incorrect tpoff (e.g. -3) instead of the correct 0. Fix: add a weak-undef guard in relocTPOFF mirroring lld's R_TPREL handling (if (sym.isUndefined()) return a) and the existing guard in relocAbs (line 638). Add x86_64/linux/WeakUndefTLS covering TPOFF32/64 and DTPOFF32/64 against weak-undef symbols, a defined-symbol regression guard, and a non-zero addend case. Resolves qualcomm#1540 Signed-off-by: Rachit Mehta <rachmeht@qti.qualcomm.com>
67a06c5 to
cf8edec
Compare
PIE must also handle weak-undefined TPOFF relocations same as static executable. When the PIE contains only a weak-undefined TLS reference, no PT_TLS segment is created; computeTLSOffsets() leaves TLSTemplateSize as zero, causing relocTPOFF() to emit the PT_TLS segment not found error instead of resolving the relocation to its addend, as lld does. Signed-off-by: Rachit Mehta <rachmeht@qti.qualcomm.com>
85a4bdf to
0d18542
Compare
A weak undefined TLS symbol has no slot in the PT_TLS segment, so the thread-pointer-offset formula (S - templateSize) is meaningless for it. Previously relocTPOFF applied that formula with a bogus symbol value, producing an incorrect tpoff (e.g. -3) instead of the correct 0.
Two fixes, comparing lld's R_TPREL handling:
Add x86_64/linux/WeakUndefTLS covering TPOFF32/64 and DTPOFF32/64 against weak-undef symbols, a defined-symbol regression guard, and a non-zero addend case.
Resolves #1540