1 | //===-- AArch64TargetObjectFile.cpp - AArch64 Object Info -----------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "AArch64TargetObjectFile.h" |
10 | #include "AArch64TargetMachine.h" |
11 | #include "MCTargetDesc/AArch64MCExpr.h" |
12 | #include "llvm/ADT/StringExtras.h" |
13 | #include "llvm/BinaryFormat/Dwarf.h" |
14 | #include "llvm/CodeGen/MachineModuleInfoImpls.h" |
15 | #include "llvm/IR/Mangler.h" |
16 | #include "llvm/IR/Module.h" |
17 | #include "llvm/MC/MCContext.h" |
18 | #include "llvm/MC/MCExpr.h" |
19 | #include "llvm/MC/MCStreamer.h" |
20 | #include "llvm/MC/MCValue.h" |
21 | using namespace llvm; |
22 | using namespace dwarf; |
23 | |
24 | void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx, |
25 | const TargetMachine &TM) { |
26 | TargetLoweringObjectFileELF::Initialize(Ctx, TM); |
27 | // AARCH64 ELF ABI does not define static relocation type for TLS offset |
28 | // within a module. Do not generate AT_location for TLS variables. |
29 | SupportDebugThreadLocalLocation = false; |
30 | } |
31 | |
32 | const MCExpr *AArch64_ELFTargetObjectFile::getIndirectSymViaGOTPCRel( |
33 | const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, |
34 | int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
35 | int64_t FinalOffset = Offset + MV.getConstant(); |
36 | const MCExpr *Res = |
37 | MCSymbolRefExpr::create(Symbol: Sym, Kind: MCSymbolRefExpr::VK_GOTPCREL, Ctx&: getContext()); |
38 | const MCExpr *Off = MCConstantExpr::create(Value: FinalOffset, Ctx&: getContext()); |
39 | return MCBinaryExpr::createAdd(LHS: Res, RHS: Off, Ctx&: getContext()); |
40 | } |
41 | |
42 | AArch64_MachoTargetObjectFile::AArch64_MachoTargetObjectFile() { |
43 | SupportGOTPCRelWithOffset = false; |
44 | } |
45 | |
46 | const MCExpr *AArch64_MachoTargetObjectFile::getTTypeGlobalReference( |
47 | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
48 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
49 | // On Darwin, we can reference dwarf symbols with foo@GOT-., which |
50 | // is an indirect pc-relative reference. The default implementation |
51 | // won't reference using the GOT, so we need this target-specific |
52 | // version. |
53 | if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) { |
54 | const MCSymbol *Sym = TM.getSymbol(GV); |
55 | const MCExpr *Res = |
56 | MCSymbolRefExpr::create(Symbol: Sym, Kind: MCSymbolRefExpr::VK_GOT, Ctx&: getContext()); |
57 | MCSymbol *PCSym = getContext().createTempSymbol(); |
58 | Streamer.emitLabel(Symbol: PCSym); |
59 | const MCExpr *PC = MCSymbolRefExpr::create(Symbol: PCSym, Ctx&: getContext()); |
60 | return MCBinaryExpr::createSub(LHS: Res, RHS: PC, Ctx&: getContext()); |
61 | } |
62 | |
63 | return TargetLoweringObjectFileMachO::getTTypeGlobalReference( |
64 | GV, Encoding, TM, MMI, Streamer); |
65 | } |
66 | |
67 | MCSymbol *AArch64_MachoTargetObjectFile::getCFIPersonalitySymbol( |
68 | const GlobalValue *GV, const TargetMachine &TM, |
69 | MachineModuleInfo *MMI) const { |
70 | return TM.getSymbol(GV); |
71 | } |
72 | |
73 | const MCExpr *AArch64_MachoTargetObjectFile::getIndirectSymViaGOTPCRel( |
74 | const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, |
75 | int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
76 | assert((Offset+MV.getConstant() == 0) && |
77 | "Arch64 does not support GOT PC rel with extra offset" ); |
78 | // On ARM64 Darwin, we can reference symbols with foo@GOT-., which |
79 | // is an indirect pc-relative reference. |
80 | const MCExpr *Res = |
81 | MCSymbolRefExpr::create(Symbol: Sym, Kind: MCSymbolRefExpr::VK_GOT, Ctx&: getContext()); |
82 | MCSymbol *PCSym = getContext().createTempSymbol(); |
83 | Streamer.emitLabel(Symbol: PCSym); |
84 | const MCExpr *PC = MCSymbolRefExpr::create(Symbol: PCSym, Ctx&: getContext()); |
85 | return MCBinaryExpr::createSub(LHS: Res, RHS: PC, Ctx&: getContext()); |
86 | } |
87 | |
88 | void AArch64_MachoTargetObjectFile::getNameWithPrefix( |
89 | SmallVectorImpl<char> &OutName, const GlobalValue *GV, |
90 | const TargetMachine &TM) const { |
91 | // AArch64 does not use section-relative relocations so any global symbol must |
92 | // be accessed via at least a linker-private symbol. |
93 | getMangler().getNameWithPrefix(OutName, GV, /* CannotUsePrivateLabel */ true); |
94 | } |
95 | |
96 | template <typename MachineModuleInfoTarget> |
97 | static MCSymbol *getAuthPtrSlotSymbolHelper( |
98 | MCContext &Ctx, const TargetMachine &TM, MachineModuleInfo *MMI, |
99 | MachineModuleInfoTarget &TargetMMI, const MCSymbol *RawSym, |
100 | AArch64PACKey::ID Key, uint16_t Discriminator) { |
101 | const DataLayout &DL = MMI->getModule()->getDataLayout(); |
102 | |
103 | MCSymbol *StubSym = Ctx.getOrCreateSymbol( |
104 | Name: DL.getLinkerPrivateGlobalPrefix() + RawSym->getName() + |
105 | Twine("$auth_ptr$" ) + AArch64PACKeyIDToString(KeyID: Key) + Twine('$') + |
106 | Twine(Discriminator)); |
107 | |
108 | const MCExpr *&StubAuthPtrRef = TargetMMI.getAuthPtrStubEntry(StubSym); |
109 | |
110 | if (StubAuthPtrRef) |
111 | return StubSym; |
112 | |
113 | const MCExpr *Sym = MCSymbolRefExpr::create(Symbol: RawSym, Ctx); |
114 | |
115 | StubAuthPtrRef = |
116 | AArch64AuthMCExpr::create(Expr: Sym, Discriminator, Key, |
117 | /*HasAddressDiversity=*/false, Ctx); |
118 | return StubSym; |
119 | } |
120 | |
121 | MCSymbol *AArch64_ELFTargetObjectFile::getAuthPtrSlotSymbol( |
122 | const TargetMachine &TM, MachineModuleInfo *MMI, const MCSymbol *RawSym, |
123 | AArch64PACKey::ID Key, uint16_t Discriminator) const { |
124 | auto &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>(); |
125 | return getAuthPtrSlotSymbolHelper(Ctx&: getContext(), TM, MMI, TargetMMI&: ELFMMI, RawSym, Key, |
126 | Discriminator); |
127 | } |
128 | |
129 | MCSymbol *AArch64_MachoTargetObjectFile::getAuthPtrSlotSymbol( |
130 | const TargetMachine &TM, MachineModuleInfo *MMI, const MCSymbol *RawSym, |
131 | AArch64PACKey::ID Key, uint16_t Discriminator) const { |
132 | auto &MachOMMI = MMI->getObjFileInfo<MachineModuleInfoMachO>(); |
133 | return getAuthPtrSlotSymbolHelper(Ctx&: getContext(), TM, MMI, TargetMMI&: MachOMMI, RawSym, |
134 | Key, Discriminator); |
135 | } |
136 | |