summaryrefslogtreecommitdiffstats
path: root/lld/ELF/InputSection.cpp
diff options
context:
space:
mode:
authorFangrui Song <maskray@google.com>2019-04-22 03:10:40 +0000
committerFangrui Song <maskray@google.com>2019-04-22 03:10:40 +0000
commitbc4b159bb1121ed9e1c00df35a4f5dd5712de8de (patch)
tree591072d2a422da89a52897c0241aeb7ba0095ff3 /lld/ELF/InputSection.cpp
parent1233c15be59160eb48bec08327db012bc3f2aedf (diff)
downloadbcm5719-llvm-bc4b159bb1121ed9e1c00df35a4f5dd5712de8de.tar.gz
bcm5719-llvm-bc4b159bb1121ed9e1c00df35a4f5dd5712de8de.zip
[ELF][X86] Allow R_386_TLS_LDO_32 and R_X86_64_DTPOFF{32,64} to preemptable local-dynamic symbols
Summary: Fixes PR35242. A simplified reproduce: thread_local int i; int f() { return i; } % {g++,clang++} -fPIC -shared -ftls-model=local-dynamic -fuse-ld=lld a.cc ld.lld: error: can't create dynamic relocation R_X86_64_DTPOFF32 against symbol: i in readonly segment; recompile object files with -fPIC or pass '-Wl,-z,notext' to allow text relocations in the output In isStaticLinkTimeConstant(), Syn.IsPreemptible is true, so it is not seen as a constant. The error is then issued in processRelocAux(). A symbol of the local-dynamic TLS model cannot be preempted but it can preempt symbols of the global-dynamic TLS model in other DSOs. So it makes some sense that the variable is not static. This patch fixes the linking error by changing getRelExpr() on R_386_TLS_LDO_32 and R_X86_64_DTPOFF{32,64} from R_ABS to R_DTPREL. R_PPC64_DTPREL_* and R_MIPS_TLS_DTPREL_* need similar fixes, but they are not handled in this patch. As a bonus, we use `if (Expr == R_ABS && !Config->Shared)` to find ld-to-le opportunities. R_ABS is overloaded here for such STT_TLS symbols. A dedicated R_DTPREL is clearer. Differential Revision: https://reviews.llvm.org/D60945 llvm-svn: 358870
Diffstat (limited to 'lld/ELF/InputSection.cpp')
-rw-r--r--lld/ELF/InputSection.cpp4
1 files changed, 3 insertions, 1 deletions
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index a32015f4b14..060374ad6d4 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -616,6 +616,8 @@ static uint64_t getRelocTargetVA(const InputFile *File, RelType Type, int64_t A,
case R_RELAX_TLS_LD_TO_LE_ABS:
case R_RELAX_GOT_PC_NOPIC:
return Sym.getVA(A);
+ case R_DTPREL:
+ return Sym.getVA(A);
case R_ADDEND:
return A;
case R_ARM_SBREL:
@@ -806,7 +808,7 @@ void InputSection::relocateNonAlloc(uint8_t *Buf, ArrayRef<RelTy> Rels) {
if (Expr == R_NONE)
continue;
- if (Expr != R_ABS) {
+ if (Expr != R_ABS && Expr != R_DTPREL) {
std::string Msg = getLocation<ELFT>(Offset) +
": has non-ABS relocation " + toString(Type) +
" against symbol '" + toString(Sym) + "'";
OpenPOWER on IntegriCloud