summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2017-08-11 20:49:27 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2017-08-11 20:49:27 +0000
commitb8956a70d3486556b93ea5d5074d340866f16f88 (patch)
treee06f3a521dc14bd5266e7efff266078b5401b9bb /llvm/lib
parentf6822c869c70718573deaeb374337ba869341a42 (diff)
downloadbcm5719-llvm-b8956a70d3486556b93ea5d5074d340866f16f88.tar.gz
bcm5719-llvm-b8956a70d3486556b93ea5d5074d340866f16f88.zip
Fix access to undefined weak symbols in pic code
When the access to a weak symbol is not a call, the access has to be able to produce the value 0 at runtime. We were sometimes producing code sequences where that was not possible if the code was leaded more than 4g away from 0. llvm-svn: 310756
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86Subtarget.cpp18
1 files changed, 17 insertions, 1 deletions
diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp
index 493084f795f..1b02b88c187 100644
--- a/llvm/lib/Target/X86/X86Subtarget.cpp
+++ b/llvm/lib/Target/X86/X86Subtarget.cpp
@@ -99,6 +99,22 @@ X86Subtarget::classifyLocalReference(const GlobalValue *GV) const {
return X86II::MO_GOTOFF;
}
+static bool shouldAssumeGlobalReferenceLocal(const X86Subtarget *ST,
+ const TargetMachine &TM,
+ const Module &M,
+ const GlobalValue *GV) {
+ if (!TM.shouldAssumeDSOLocal(M, GV))
+ return false;
+ // A weak reference can end up being 0. If the code can be more that 4g away
+ // from zero and we are using the small code model we have to treat it as non
+ // local.
+ if (GV && GV->hasExternalWeakLinkage() &&
+ TM.getCodeModel() == CodeModel::Small && TM.isPositionIndependent() &&
+ ST->is64Bit() && ST->isTargetELF())
+ return false;
+ return true;
+}
+
unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,
const Module &M) const {
// Large model never uses stubs.
@@ -118,7 +134,7 @@ unsigned char X86Subtarget::classifyGlobalReference(const GlobalValue *GV,
}
}
- if (TM.shouldAssumeDSOLocal(M, GV))
+ if (shouldAssumeGlobalReferenceLocal(this, TM, M, GV))
return classifyLocalReference(GV);
if (isTargetCOFF())
OpenPOWER on IntegriCloud