1249259Sdim//===-- AArch64TargetObjectFile.cpp - AArch64 Object Info -----------------===//
2249259Sdim//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6249259Sdim//
7249259Sdim//===----------------------------------------------------------------------===//
8249259Sdim
9249259Sdim#include "AArch64TargetObjectFile.h"
10276479Sdim#include "AArch64TargetMachine.h"
11321369Sdim#include "llvm/BinaryFormat/Dwarf.h"
12276479Sdim#include "llvm/IR/Mangler.h"
13276479Sdim#include "llvm/MC/MCContext.h"
14276479Sdim#include "llvm/MC/MCExpr.h"
15276479Sdim#include "llvm/MC/MCStreamer.h"
16288943Sdim#include "llvm/MC/MCValue.h"
17249259Sdimusing namespace llvm;
18276479Sdimusing namespace dwarf;
19249259Sdim
20276479Sdimvoid AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,
21276479Sdim                                             const TargetMachine &TM) {
22249259Sdim  TargetLoweringObjectFileELF::Initialize(Ctx, TM);
23249259Sdim  InitializeELF(TM.Options.UseInitArray);
24344779Sdim  // AARCH64 ELF ABI does not define static relocation type for TLS offset
25344779Sdim  // within a module.  Do not generate AT_location for TLS variables.
26344779Sdim  SupportDebugThreadLocalLocation = false;
27249259Sdim}
28265925Sdim
29288943SdimAArch64_MachoTargetObjectFile::AArch64_MachoTargetObjectFile()
30288943Sdim  : TargetLoweringObjectFileMachO() {
31288943Sdim  SupportGOTPCRelWithOffset = false;
32288943Sdim}
33288943Sdim
34276479Sdimconst MCExpr *AArch64_MachoTargetObjectFile::getTTypeGlobalReference(
35314564Sdim    const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,
36314564Sdim    MachineModuleInfo *MMI, MCStreamer &Streamer) const {
37276479Sdim  // On Darwin, we can reference dwarf symbols with foo@GOT-., which
38276479Sdim  // is an indirect pc-relative reference. The default implementation
39276479Sdim  // won't reference using the GOT, so we need this target-specific
40276479Sdim  // version.
41276479Sdim  if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) {
42314564Sdim    const MCSymbol *Sym = TM.getSymbol(GV);
43276479Sdim    const MCExpr *Res =
44288943Sdim        MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, getContext());
45288943Sdim    MCSymbol *PCSym = getContext().createTempSymbol();
46276479Sdim    Streamer.EmitLabel(PCSym);
47288943Sdim    const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext());
48288943Sdim    return MCBinaryExpr::createSub(Res, PC, getContext());
49276479Sdim  }
50276479Sdim
51276479Sdim  return TargetLoweringObjectFileMachO::getTTypeGlobalReference(
52314564Sdim      GV, Encoding, TM, MMI, Streamer);
53265925Sdim}
54276479Sdim
55276479SdimMCSymbol *AArch64_MachoTargetObjectFile::getCFIPersonalitySymbol(
56314564Sdim    const GlobalValue *GV, const TargetMachine &TM,
57276479Sdim    MachineModuleInfo *MMI) const {
58314564Sdim  return TM.getSymbol(GV);
59276479Sdim}
60288943Sdim
61288943Sdimconst MCExpr *AArch64_MachoTargetObjectFile::getIndirectSymViaGOTPCRel(
62360784Sdim    const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,
63360784Sdim    int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {
64288943Sdim  assert((Offset+MV.getConstant() == 0) &&
65288943Sdim         "Arch64 does not support GOT PC rel with extra offset");
66288943Sdim  // On ARM64 Darwin, we can reference symbols with foo@GOT-., which
67288943Sdim  // is an indirect pc-relative reference.
68288943Sdim  const MCExpr *Res =
69288943Sdim      MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_GOT, getContext());
70288943Sdim  MCSymbol *PCSym = getContext().createTempSymbol();
71288943Sdim  Streamer.EmitLabel(PCSym);
72288943Sdim  const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext());
73288943Sdim  return MCBinaryExpr::createSub(Res, PC, getContext());
74288943Sdim}
75321369Sdim
76321369Sdimvoid AArch64_MachoTargetObjectFile::getNameWithPrefix(
77321369Sdim    SmallVectorImpl<char> &OutName, const GlobalValue *GV,
78321369Sdim    const TargetMachine &TM) const {
79321369Sdim  // AArch64 does not use section-relative relocations so any global symbol must
80321369Sdim  // be accessed via at least a linker-private symbol.
81321369Sdim  getMangler().getNameWithPrefix(OutName, GV, /* CannotUsePrivateLabel */ true);
82321369Sdim}
83