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 "llvm/BinaryFormat/Dwarf.h" |
12 | #include "llvm/IR/Mangler.h" |
13 | #include "llvm/MC/MCContext.h" |
14 | #include "llvm/MC/MCExpr.h" |
15 | #include "llvm/MC/MCStreamer.h" |
16 | #include "llvm/MC/MCValue.h" |
17 | using namespace llvm; |
18 | using namespace dwarf; |
19 | |
20 | void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx, |
21 | const TargetMachine &TM) { |
22 | TargetLoweringObjectFileELF::Initialize(Ctx, TM); |
23 | // AARCH64 ELF ABI does not define static relocation type for TLS offset |
24 | // within a module. Do not generate AT_location for TLS variables. |
25 | SupportDebugThreadLocalLocation = false; |
26 | } |
27 | |
28 | const MCExpr *AArch64_ELFTargetObjectFile::getIndirectSymViaGOTPCRel( |
29 | const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, |
30 | int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
31 | int64_t FinalOffset = Offset + MV.getConstant(); |
32 | const MCExpr *Res = |
33 | MCSymbolRefExpr::create(Symbol: Sym, Kind: MCSymbolRefExpr::VK_GOTPCREL, Ctx&: getContext()); |
34 | const MCExpr *Off = MCConstantExpr::create(Value: FinalOffset, Ctx&: getContext()); |
35 | return MCBinaryExpr::createAdd(LHS: Res, RHS: Off, Ctx&: getContext()); |
36 | } |
37 | |
38 | AArch64_MachoTargetObjectFile::AArch64_MachoTargetObjectFile() { |
39 | SupportGOTPCRelWithOffset = false; |
40 | } |
41 | |
42 | const MCExpr *AArch64_MachoTargetObjectFile::getTTypeGlobalReference( |
43 | const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM, |
44 | MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
45 | // On Darwin, we can reference dwarf symbols with foo@GOT-., which |
46 | // is an indirect pc-relative reference. The default implementation |
47 | // won't reference using the GOT, so we need this target-specific |
48 | // version. |
49 | if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) { |
50 | const MCSymbol *Sym = TM.getSymbol(GV); |
51 | const MCExpr *Res = |
52 | MCSymbolRefExpr::create(Symbol: Sym, Kind: MCSymbolRefExpr::VK_GOT, Ctx&: getContext()); |
53 | MCSymbol *PCSym = getContext().createTempSymbol(); |
54 | Streamer.emitLabel(Symbol: PCSym); |
55 | const MCExpr *PC = MCSymbolRefExpr::create(Symbol: PCSym, Ctx&: getContext()); |
56 | return MCBinaryExpr::createSub(LHS: Res, RHS: PC, Ctx&: getContext()); |
57 | } |
58 | |
59 | return TargetLoweringObjectFileMachO::getTTypeGlobalReference( |
60 | GV, Encoding, TM, MMI, Streamer); |
61 | } |
62 | |
63 | MCSymbol *AArch64_MachoTargetObjectFile::getCFIPersonalitySymbol( |
64 | const GlobalValue *GV, const TargetMachine &TM, |
65 | MachineModuleInfo *MMI) const { |
66 | return TM.getSymbol(GV); |
67 | } |
68 | |
69 | const MCExpr *AArch64_MachoTargetObjectFile::getIndirectSymViaGOTPCRel( |
70 | const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV, |
71 | int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const { |
72 | assert((Offset+MV.getConstant() == 0) && |
73 | "Arch64 does not support GOT PC rel with extra offset" ); |
74 | // On ARM64 Darwin, we can reference symbols with foo@GOT-., which |
75 | // is an indirect pc-relative reference. |
76 | const MCExpr *Res = |
77 | MCSymbolRefExpr::create(Symbol: Sym, Kind: MCSymbolRefExpr::VK_GOT, Ctx&: getContext()); |
78 | MCSymbol *PCSym = getContext().createTempSymbol(); |
79 | Streamer.emitLabel(Symbol: PCSym); |
80 | const MCExpr *PC = MCSymbolRefExpr::create(Symbol: PCSym, Ctx&: getContext()); |
81 | return MCBinaryExpr::createSub(LHS: Res, RHS: PC, Ctx&: getContext()); |
82 | } |
83 | |
84 | void AArch64_MachoTargetObjectFile::getNameWithPrefix( |
85 | SmallVectorImpl<char> &OutName, const GlobalValue *GV, |
86 | const TargetMachine &TM) const { |
87 | // AArch64 does not use section-relative relocations so any global symbol must |
88 | // be accessed via at least a linker-private symbol. |
89 | getMangler().getNameWithPrefix(OutName, GV, /* CannotUsePrivateLabel */ true); |
90 | } |
91 | |