diff options
| author | Rafael Espindola <rafael.espindola@gmail.com> | 2017-08-11 20:49:27 +0000 |
|---|---|---|
| committer | Rafael Espindola <rafael.espindola@gmail.com> | 2017-08-11 20:49:27 +0000 |
| commit | b8956a70d3486556b93ea5d5074d340866f16f88 (patch) | |
| tree | e06f3a521dc14bd5266e7efff266078b5401b9bb /llvm/lib | |
| parent | f6822c869c70718573deaeb374337ba869341a42 (diff) | |
| download | bcm5719-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.cpp | 18 |
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()) |

