brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 55ec4a6 Raw
145 lines · cpp
1//===- MCAsmBackend.cpp - Target MC Assembly Backend ----------------------===//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 "llvm/MC/MCAsmBackend.h"10#include "llvm/MC/MCAssembler.h"11#include "llvm/MC/MCContext.h"12#include "llvm/MC/MCDXContainerWriter.h"13#include "llvm/MC/MCELFObjectWriter.h"14#include "llvm/MC/MCGOFFObjectWriter.h"15#include "llvm/MC/MCMachObjectWriter.h"16#include "llvm/MC/MCObjectWriter.h"17#include "llvm/MC/MCSPIRVObjectWriter.h"18#include "llvm/MC/MCWasmObjectWriter.h"19#include "llvm/MC/MCWinCOFFObjectWriter.h"20#include "llvm/MC/MCXCOFFObjectWriter.h"21#include <cassert>22#include <cstddef>23#include <cstdint>24 25using namespace llvm;26 27MCAsmBackend::~MCAsmBackend() = default;28 29MCContext &MCAsmBackend::getContext() const { return Asm->getContext(); }30 31std::unique_ptr<MCObjectWriter>32MCAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {33  auto TW = createObjectTargetWriter();34  bool IsLE = Endian == llvm::endianness::little;35  switch (TW->getFormat()) {36  case Triple::MachO:37    return std::make_unique<MachObjectWriter>(38        cast<MCMachObjectTargetWriter>(std::move(TW)), OS, IsLE);39  case Triple::COFF:40    return createWinCOFFObjectWriter(41        cast<MCWinCOFFObjectTargetWriter>(std::move(TW)), OS);42  case Triple::ELF:43    return std::make_unique<ELFObjectWriter>(44        cast<MCELFObjectTargetWriter>(std::move(TW)), OS, IsLE);45  case Triple::SPIRV:46    return createSPIRVObjectWriter(47        cast<MCSPIRVObjectTargetWriter>(std::move(TW)), OS);48  case Triple::Wasm:49    return createWasmObjectWriter(cast<MCWasmObjectTargetWriter>(std::move(TW)),50                                  OS);51  case Triple::GOFF:52    return createGOFFObjectWriter(cast<MCGOFFObjectTargetWriter>(std::move(TW)),53                                  OS);54  case Triple::XCOFF:55    return createXCOFFObjectWriter(56        cast<MCXCOFFObjectTargetWriter>(std::move(TW)), OS);57  case Triple::DXContainer:58    return std::make_unique<DXContainerObjectWriter>(59        cast<MCDXContainerTargetWriter>(std::move(TW)), OS);60  default:61    llvm_unreachable("unexpected object format");62  }63}64 65std::unique_ptr<MCObjectWriter>66MCAsmBackend::createDwoObjectWriter(raw_pwrite_stream &OS,67                                    raw_pwrite_stream &DwoOS) const {68  auto TW = createObjectTargetWriter();69  switch (TW->getFormat()) {70  case Triple::COFF:71    return createWinCOFFDwoObjectWriter(72        cast<MCWinCOFFObjectTargetWriter>(std::move(TW)), OS, DwoOS);73  case Triple::ELF:74    return std::make_unique<ELFObjectWriter>(75        cast<MCELFObjectTargetWriter>(std::move(TW)), OS, DwoOS,76        Endian == llvm::endianness::little);77  case Triple::Wasm:78    return createWasmDwoObjectWriter(79        cast<MCWasmObjectTargetWriter>(std::move(TW)), OS, DwoOS);80  default:81    report_fatal_error("dwo only supported with COFF, ELF, and Wasm");82  }83}84 85std::optional<MCFixupKind> MCAsmBackend::getFixupKind(StringRef Name) const {86  return std::nullopt;87}88 89MCFixupKindInfo MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {90  // clang-format off91  static const MCFixupKindInfo Builtins[] = {92      {"FK_NONE", 0, 0, 0},93      {"FK_Data_1", 0, 8, 0},94      {"FK_Data_2", 0, 16, 0},95      {"FK_Data_4", 0, 32, 0},96      {"FK_Data_8", 0, 64, 0},97      {"FK_Data_leb128", 0, 0, 0},98      {"FK_SecRel_1", 0, 8, 0},99      {"FK_SecRel_2", 0, 16, 0},100      {"FK_SecRel_4", 0, 32, 0},101      {"FK_SecRel_8", 0, 64, 0},102  };103  // clang-format on104 105  assert(size_t(Kind - FK_NONE) < std::size(Builtins) && "Unknown fixup kind");106  return Builtins[Kind - FK_NONE];107}108 109bool MCAsmBackend::fixupNeedsRelaxationAdvanced(const MCFragment &,110                                                const MCFixup &Fixup,111                                                const MCValue &, uint64_t Value,112                                                bool Resolved) const {113  if (!Resolved)114    return true;115  return fixupNeedsRelaxation(Fixup, Value);116}117 118void MCAsmBackend::maybeAddReloc(const MCFragment &F, const MCFixup &Fixup,119                                 const MCValue &Target, uint64_t &Value,120                                 bool IsResolved) {121  if (!IsResolved)122    Asm->getWriter().recordRelocation(F, Fixup, Target, Value);123}124 125bool MCAsmBackend::isDarwinCanonicalPersonality(const MCSymbol *Sym) const {126  assert(getContext().isMachO());127  // Consider a NULL personality (ie., no personality encoding) to be canonical128  // because it's always at 0.129  if (!Sym)130    return true;131 132  StringRef name = Sym->getName();133  // XXX: We intentionally leave out "___gcc_personality_v0" because, despite134  // being system-defined like these two, it is not very commonly-used.135  // Reserving an empty slot for it seems silly.136  return name == "___gxx_personality_v0" || name == "___objc_personality_v0";137}138 139const MCSubtargetInfo *MCAsmBackend::getSubtargetInfo(const MCFragment &F) {140  const MCSubtargetInfo *STI = nullptr;141  STI = F.getSubtargetInfo();142  assert(!F.hasInstructions() || STI != nullptr);143  return STI;144}145