Path: blob/main/contrib/llvm-project/llvm/lib/MC/MCAsmBackend.cpp
35233 views
//===- MCAsmBackend.cpp - Target MC Assembly Backend ----------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/MC/MCAsmBackend.h"9#include "llvm/MC/MCAssembler.h"10#include "llvm/MC/MCDXContainerWriter.h"11#include "llvm/MC/MCELFObjectWriter.h"12#include "llvm/MC/MCFixupKindInfo.h"13#include "llvm/MC/MCGOFFObjectWriter.h"14#include "llvm/MC/MCMachObjectWriter.h"15#include "llvm/MC/MCObjectWriter.h"16#include "llvm/MC/MCSPIRVObjectWriter.h"17#include "llvm/MC/MCWasmObjectWriter.h"18#include "llvm/MC/MCWinCOFFObjectWriter.h"19#include "llvm/MC/MCXCOFFObjectWriter.h"20#include <cassert>21#include <cstddef>22#include <cstdint>2324using namespace llvm;2526MCAsmBackend::MCAsmBackend(llvm::endianness Endian, unsigned RelaxFixupKind)27: Endian(Endian), RelaxFixupKind(RelaxFixupKind) {}2829MCAsmBackend::~MCAsmBackend() = default;3031std::unique_ptr<MCObjectWriter>32MCAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {33auto TW = createObjectTargetWriter();34bool IsLE = Endian == llvm::endianness::little;35switch (TW->getFormat()) {36case Triple::MachO:37return createMachObjectWriter(cast<MCMachObjectTargetWriter>(std::move(TW)),38OS, IsLE);39case Triple::COFF:40return createWinCOFFObjectWriter(41cast<MCWinCOFFObjectTargetWriter>(std::move(TW)), OS);42case Triple::ELF:43return std::make_unique<ELFObjectWriter>(44cast<MCELFObjectTargetWriter>(std::move(TW)), OS, IsLE);45case Triple::SPIRV:46return createSPIRVObjectWriter(47cast<MCSPIRVObjectTargetWriter>(std::move(TW)), OS);48case Triple::Wasm:49return createWasmObjectWriter(cast<MCWasmObjectTargetWriter>(std::move(TW)),50OS);51case Triple::GOFF:52return createGOFFObjectWriter(cast<MCGOFFObjectTargetWriter>(std::move(TW)),53OS);54case Triple::XCOFF:55return createXCOFFObjectWriter(56cast<MCXCOFFObjectTargetWriter>(std::move(TW)), OS);57case Triple::DXContainer:58return createDXContainerObjectWriter(59cast<MCDXContainerTargetWriter>(std::move(TW)), OS);60default:61llvm_unreachable("unexpected object format");62}63}6465std::unique_ptr<MCObjectWriter>66MCAsmBackend::createDwoObjectWriter(raw_pwrite_stream &OS,67raw_pwrite_stream &DwoOS) const {68auto TW = createObjectTargetWriter();69switch (TW->getFormat()) {70case Triple::COFF:71return createWinCOFFDwoObjectWriter(72cast<MCWinCOFFObjectTargetWriter>(std::move(TW)), OS, DwoOS);73case Triple::ELF:74return std::make_unique<ELFObjectWriter>(75cast<MCELFObjectTargetWriter>(std::move(TW)), OS, DwoOS,76Endian == llvm::endianness::little);77case Triple::Wasm:78return createWasmDwoObjectWriter(79cast<MCWasmObjectTargetWriter>(std::move(TW)), OS, DwoOS);80default:81report_fatal_error("dwo only supported with COFF, ELF, and Wasm");82}83}8485std::optional<MCFixupKind> MCAsmBackend::getFixupKind(StringRef Name) const {86return std::nullopt;87}8889const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {90static const MCFixupKindInfo Builtins[] = {91{"FK_NONE", 0, 0, 0},92{"FK_Data_1", 0, 8, 0},93{"FK_Data_2", 0, 16, 0},94{"FK_Data_4", 0, 32, 0},95{"FK_Data_8", 0, 64, 0},96{"FK_Data_leb128", 0, 0, 0},97{"FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel},98{"FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel},99{"FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel},100{"FK_PCRel_8", 0, 64, MCFixupKindInfo::FKF_IsPCRel},101{"FK_GPRel_1", 0, 8, 0},102{"FK_GPRel_2", 0, 16, 0},103{"FK_GPRel_4", 0, 32, 0},104{"FK_GPRel_8", 0, 64, 0},105{"FK_DTPRel_4", 0, 32, 0},106{"FK_DTPRel_8", 0, 64, 0},107{"FK_TPRel_4", 0, 32, 0},108{"FK_TPRel_8", 0, 64, 0},109{"FK_SecRel_1", 0, 8, 0},110{"FK_SecRel_2", 0, 16, 0},111{"FK_SecRel_4", 0, 32, 0},112{"FK_SecRel_8", 0, 64, 0},113};114115assert((size_t)Kind <= std::size(Builtins) && "Unknown fixup kind");116return Builtins[Kind];117}118119bool MCAsmBackend::fixupNeedsRelaxationAdvanced(const MCAssembler &Asm,120const MCFixup &Fixup,121bool Resolved, uint64_t Value,122const MCRelaxableFragment *DF,123const bool WasForced) const {124if (!Resolved)125return true;126return fixupNeedsRelaxation(Fixup, Value);127}128129bool MCAsmBackend::isDarwinCanonicalPersonality(const MCSymbol *Sym) const {130// Consider a NULL personality (ie., no personality encoding) to be canonical131// because it's always at 0.132if (!Sym)133return true;134135if (!Sym->isMachO())136llvm_unreachable("Expected MachO symbols only");137138StringRef name = Sym->getName();139// XXX: We intentionally leave out "___gcc_personality_v0" because, despite140// being system-defined like these two, it is not very commonly-used.141// Reserving an empty slot for it seems silly.142return name == "___gxx_personality_v0" || name == "___objc_personality_v0";143}144145146