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"
17using namespace llvm;
18using namespace dwarf;
19
20void 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
28AArch64_MachoTargetObjectFile::AArch64_MachoTargetObjectFile() {
29  SupportGOTPCRelWithOffset = false;
30}
31
32const MCExpr *AArch64_MachoTargetObjectFile::getTTypeGlobalReference(
33    const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
34    MachineModuleInfo *MMI, MCStreamer &Streamer) const {
35  // On Darwin, we can reference dwarf symbols with foo@GOT-., which
36  // is an indirect pc-relative reference. The default implementation
37  // won't reference using the GOT, so we need this target-specific
38  // version.
39  if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) {
40    const MCSymbol *Sym = TM.getSymbol(GV);
41    const MCExpr *Res =
42        MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, getContext());
43    MCSymbol *PCSym = getContext().createTempSymbol();
44    Streamer.emitLabel(PCSym);
45    const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext());
46    return MCBinaryExpr::createSub(Res, PC, getContext());
47  }
48
49  return TargetLoweringObjectFileMachO::getTTypeGlobalReference(
50      GV, Encoding, TM, MMI, Streamer);
51}
52
53MCSymbol *AArch64_MachoTargetObjectFile::getCFIPersonalitySymbol(
54    const GlobalValue *GV, const TargetMachine &TM,
55    MachineModuleInfo *MMI) const {
56  return TM.getSymbol(GV);
57}
58
59const MCExpr *AArch64_MachoTargetObjectFile::getIndirectSymViaGOTPCRel(
60    const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
61    int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
62  assert((Offset+MV.getConstant() == 0) &&
63         "Arch64 does not support GOT PC rel with extra offset");
64  // On ARM64 Darwin, we can reference symbols with foo@GOT-., which
65  // is an indirect pc-relative reference.
66  const MCExpr *Res =
67      MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, getContext());
68  MCSymbol *PCSym = getContext().createTempSymbol();
69  Streamer.emitLabel(PCSym);
70  const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext());
71  return MCBinaryExpr::createSub(Res, PC, getContext());
72}
73
74void AArch64_MachoTargetObjectFile::getNameWithPrefix(
75    SmallVectorImpl<char> &OutName, const GlobalValue *GV,
76    const TargetMachine &TM) const {
77  // AArch64 does not use section-relative relocations so any global symbol must
78  // be accessed via at least a linker-private symbol.
79  getMangler().getNameWithPrefix(OutName, GV, /* CannotUsePrivateLabel */ true);
80}
81