brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.8 KiB · 85de2d5 Raw
189 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "AArch64TargetObjectFile.h"10#include "AArch64TargetMachine.h"11#include "MCTargetDesc/AArch64MCAsmInfo.h"12#include "MCTargetDesc/AArch64TargetStreamer.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/MCSectionELF.h"20#include "llvm/MC/MCStreamer.h"21#include "llvm/MC/MCValue.h"22using namespace llvm;23using namespace dwarf;24 25void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx,26                                             const TargetMachine &TM) {27  TargetLoweringObjectFileELF::Initialize(Ctx, TM);28  PLTRelativeSpecifier = AArch64::S_PLT;29  SupportIndirectSymViaGOTPCRel = true;30 31  // AARCH64 ELF ABI does not define static relocation type for TLS offset32  // within a module.  Do not generate AT_location for TLS variables.33  SupportDebugThreadLocalLocation = false;34 35  // Make sure the implicitly created empty .text section has the36  // SHF_AARCH64_PURECODE flag set if the "+execute-only" target feature is37  // present.38  if (TM.getMCSubtargetInfo()->hasFeature(AArch64::FeatureExecuteOnly)) {39    auto *Text = static_cast<MCSectionELF *>(TextSection);40    Text->setFlags(Text->getFlags() | ELF::SHF_AARCH64_PURECODE);41  }42}43 44void AArch64_ELFTargetObjectFile::emitPersonalityValueImpl(45    MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym,46    const MachineModuleInfo *MMI) const {47  if (!MMI->getObjFileInfo<MachineModuleInfoELF>().hasSignedPersonality()) {48    TargetLoweringObjectFileELF::emitPersonalityValueImpl(Streamer, DL, Sym,49                                                          MMI);50    return;51  }52  auto *TS = static_cast<AArch64TargetStreamer *>(Streamer.getTargetStreamer());53  // The value is ptrauth_string_discriminator("personality")54  constexpr uint16_t Discriminator = 0x7EAD;55  TS->emitAuthValue(MCSymbolRefExpr::create(Sym, getContext()), Discriminator,56                    AArch64PACKey::IA, /*HasAddressDiversity=*/true);57}58 59const MCExpr *AArch64_ELFTargetObjectFile::getIndirectSymViaGOTPCRel(60    const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,61    int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {62  int64_t FinalOffset = Offset + MV.getConstant();63  const MCExpr *Res =64      MCSymbolRefExpr::create(Sym, AArch64::S_GOTPCREL, getContext());65  const MCExpr *Off = MCConstantExpr::create(FinalOffset, getContext());66  return MCBinaryExpr::createAdd(Res, Off, getContext());67}68 69AArch64_MachoTargetObjectFile::AArch64_MachoTargetObjectFile() {70  SupportGOTPCRelWithOffset = false;71}72 73const MCExpr *AArch64_MachoTargetObjectFile::getTTypeGlobalReference(74    const GlobalValue *GV, unsigned Encoding, const TargetMachine &TM,75    MachineModuleInfo *MMI, MCStreamer &Streamer) const {76  // On Darwin, we can reference dwarf symbols with foo@GOT-., which77  // is an indirect pc-relative reference. The default implementation78  // won't reference using the GOT, so we need this target-specific79  // version.80  if (Encoding & (DW_EH_PE_indirect | DW_EH_PE_pcrel)) {81    const MCSymbol *Sym = TM.getSymbol(GV);82    const MCExpr *Res =83        MCSymbolRefExpr::create(Sym, AArch64::S_MACHO_GOT, getContext());84    MCSymbol *PCSym = getContext().createTempSymbol();85    Streamer.emitLabel(PCSym);86    const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext());87    return MCBinaryExpr::createSub(Res, PC, getContext());88  }89 90  return TargetLoweringObjectFileMachO::getTTypeGlobalReference(91      GV, Encoding, TM, MMI, Streamer);92}93 94MCSymbol *AArch64_MachoTargetObjectFile::getCFIPersonalitySymbol(95    const GlobalValue *GV, const TargetMachine &TM,96    MachineModuleInfo *MMI) const {97  return TM.getSymbol(GV);98}99 100const MCExpr *AArch64_MachoTargetObjectFile::getIndirectSymViaGOTPCRel(101    const GlobalValue *GV, const MCSymbol *Sym, const MCValue &MV,102    int64_t Offset, MachineModuleInfo *MMI, MCStreamer &Streamer) const {103  assert((Offset+MV.getConstant() == 0) &&104         "Arch64 does not support GOT PC rel with extra offset");105  // On ARM64 Darwin, we can reference symbols with foo@GOT-., which106  // is an indirect pc-relative reference.107  const MCExpr *Res =108      MCSymbolRefExpr::create(Sym, AArch64::S_MACHO_GOT, getContext());109  MCSymbol *PCSym = getContext().createTempSymbol();110  Streamer.emitLabel(PCSym);111  const MCExpr *PC = MCSymbolRefExpr::create(PCSym, getContext());112  return MCBinaryExpr::createSub(Res, PC, getContext());113}114 115void AArch64_MachoTargetObjectFile::getNameWithPrefix(116    SmallVectorImpl<char> &OutName, const GlobalValue *GV,117    const TargetMachine &TM) const {118  // AArch64 does not use section-relative relocations so any global symbol must119  // be accessed via at least a linker-private symbol.120  getMangler().getNameWithPrefix(OutName, GV, /* CannotUsePrivateLabel */ true);121}122 123template <typename MachineModuleInfoTarget>124static MCSymbol *getAuthPtrSlotSymbolHelper(125    MCContext &Ctx, const TargetMachine &TM, MachineModuleInfo *MMI,126    MachineModuleInfoTarget &TargetMMI, const MCSymbol *RawSym,127    AArch64PACKey::ID Key, uint16_t Discriminator) {128  const DataLayout &DL = MMI->getModule()->getDataLayout();129 130  MCSymbol *StubSym = Ctx.getOrCreateSymbol(131      DL.getLinkerPrivateGlobalPrefix() + RawSym->getName() +132      Twine("$auth_ptr$") + AArch64PACKeyIDToString(Key) + Twine('$') +133      Twine(Discriminator));134 135  const MCExpr *&StubAuthPtrRef = TargetMMI.getAuthPtrStubEntry(StubSym);136 137  if (StubAuthPtrRef)138    return StubSym;139 140  const MCExpr *Sym = MCSymbolRefExpr::create(RawSym, Ctx);141 142  StubAuthPtrRef =143      AArch64AuthMCExpr::create(Sym, Discriminator, Key,144                                /*HasAddressDiversity=*/false, Ctx);145  return StubSym;146}147 148MCSymbol *AArch64_ELFTargetObjectFile::getAuthPtrSlotSymbol(149    const TargetMachine &TM, MachineModuleInfo *MMI, const MCSymbol *RawSym,150    AArch64PACKey::ID Key, uint16_t Discriminator) const {151  auto &ELFMMI = MMI->getObjFileInfo<MachineModuleInfoELF>();152  return getAuthPtrSlotSymbolHelper(getContext(), TM, MMI, ELFMMI, RawSym, Key,153                                    Discriminator);154}155 156MCSymbol *AArch64_MachoTargetObjectFile::getAuthPtrSlotSymbol(157    const TargetMachine &TM, MachineModuleInfo *MMI, const MCSymbol *RawSym,158    AArch64PACKey::ID Key, uint16_t Discriminator) const {159  auto &MachOMMI = MMI->getObjFileInfo<MachineModuleInfoMachO>();160  return getAuthPtrSlotSymbolHelper(getContext(), TM, MMI, MachOMMI, RawSym,161                                    Key, Discriminator);162}163 164static bool isExecuteOnlyFunction(const GlobalObject *GO, SectionKind Kind,165                                  const TargetMachine &TM) {166  if (const Function *F = dyn_cast<Function>(GO))167    if (TM.getSubtarget<AArch64Subtarget>(*F).genExecuteOnly() && Kind.isText())168      return true;169  return false;170}171 172MCSection *AArch64_ELFTargetObjectFile::getExplicitSectionGlobal(173    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {174  // Set execute-only access for the explicit section175  if (isExecuteOnlyFunction(GO, Kind, TM))176    Kind = SectionKind::getExecuteOnly();177 178  return TargetLoweringObjectFileELF::getExplicitSectionGlobal(GO, Kind, TM);179}180 181MCSection *AArch64_ELFTargetObjectFile::SelectSectionForGlobal(182    const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {183  // Set execute-only access for the explicit section184  if (isExecuteOnlyFunction(GO, Kind, TM))185    Kind = SectionKind::getExecuteOnly();186 187  return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);188}189