diff options
author | Tim Northover <tnorthover@apple.com> | 2014-04-02 14:39:11 +0000 |
---|---|---|
committer | Tim Northover <tnorthover@apple.com> | 2014-04-02 14:39:11 +0000 |
commit | 6d69168ffd197e2ce3f9145a4de5b8479b57b6b8 (patch) | |
tree | 4599872844aa0cd3f02836c6d1c8baa6ad913ef4 /llvm/lib/Target/ARM64/ARM64Subtarget.cpp | |
parent | 0d80f70530790881a5e4f513f113b94bc6596093 (diff) | |
download | bcm5719-llvm-6d69168ffd197e2ce3f9145a4de5b8479b57b6b8.tar.gz bcm5719-llvm-6d69168ffd197e2ce3f9145a4de5b8479b57b6b8.zip |
ARM64: use GOT for weak symbols & PIC.
Weak symbols cannot use the small code model's usual ADRP sequences since the
instruction simply may not be able to encode a value of 0.
This redirects them to use the GOT, which hopefully linkers are able to cope
with even in the static relocation model.
llvm-svn: 205426
Diffstat (limited to 'llvm/lib/Target/ARM64/ARM64Subtarget.cpp')
-rw-r--r-- | llvm/lib/Target/ARM64/ARM64Subtarget.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/llvm/lib/Target/ARM64/ARM64Subtarget.cpp b/llvm/lib/Target/ARM64/ARM64Subtarget.cpp index c28c26b0eaf..14b54443dc9 100644 --- a/llvm/lib/Target/ARM64/ARM64Subtarget.cpp +++ b/llvm/lib/Target/ARM64/ARM64Subtarget.cpp @@ -50,16 +50,33 @@ ARM64Subtarget::ClassifyGlobalReference(const GlobalValue *GV, if (GV->isDeclaration() && !GV->isMaterializable()) isDecl = true; - // If symbol visibility is hidden, the extra load is not needed if - // the symbol is definitely defined in the current translation unit. - if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility() && - (isDecl || GV->isWeakForLinker())) + // MachO large model always goes via a GOT, simply to get a single 8-byte + // absolute relocation on all global addresses. + if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) return ARM64II::MO_GOT; - if (TM.getCodeModel() == CodeModel::Large && isTargetMachO()) + // The small code mode's direct accesses use ADRP, which cannot necessarily + // produce the value 0 (if the code is above 4GB). Therefore they must use the + // GOT. + if (TM.getCodeModel() == CodeModel::Small && GV->isWeakForLinker() && isDecl) return ARM64II::MO_GOT; - // FIXME: this will fail on static ELF for weak symbols. + // If symbol visibility is hidden, the extra load is not needed if + // the symbol is definitely defined in the current translation unit. + + // The handling of non-hidden symbols in PIC mode is rather target-dependent: + // + On MachO, if the symbol is defined in this module the GOT can be + // skipped. + // + On ELF, the R_AARCH64_COPY relocation means that even symbols actually + // defined could end up in unexpected places. Use a GOT. + if (TM.getRelocationModel() != Reloc::Static && GV->hasDefaultVisibility()) { + if (isTargetMachO()) + return (isDecl || GV->isWeakForLinker()) ? ARM64II::MO_GOT + : ARM64II::MO_NO_FLAG; + else + return ARM64II::MO_GOT; + } + return ARM64II::MO_NO_FLAG; } |