summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM64/ARM64Subtarget.cpp
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-04-02 14:39:11 +0000
committerTim Northover <tnorthover@apple.com>2014-04-02 14:39:11 +0000
commit6d69168ffd197e2ce3f9145a4de5b8479b57b6b8 (patch)
tree4599872844aa0cd3f02836c6d1c8baa6ad913ef4 /llvm/lib/Target/ARM64/ARM64Subtarget.cpp
parent0d80f70530790881a5e4f513f113b94bc6596093 (diff)
downloadbcm5719-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.cpp29
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;
}
OpenPOWER on IntegriCloud