Path: blob/main/contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp
35234 views
//===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===//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/MCAssembler.h"9#include "llvm/ADT/ArrayRef.h"10#include "llvm/ADT/SmallString.h"11#include "llvm/ADT/SmallVector.h"12#include "llvm/ADT/Statistic.h"13#include "llvm/ADT/StringRef.h"14#include "llvm/ADT/Twine.h"15#include "llvm/MC/MCAsmBackend.h"16#include "llvm/MC/MCAsmInfo.h"17#include "llvm/MC/MCCodeEmitter.h"18#include "llvm/MC/MCCodeView.h"19#include "llvm/MC/MCContext.h"20#include "llvm/MC/MCDwarf.h"21#include "llvm/MC/MCExpr.h"22#include "llvm/MC/MCFixup.h"23#include "llvm/MC/MCFixupKindInfo.h"24#include "llvm/MC/MCFragment.h"25#include "llvm/MC/MCInst.h"26#include "llvm/MC/MCObjectWriter.h"27#include "llvm/MC/MCSection.h"28#include "llvm/MC/MCSymbol.h"29#include "llvm/MC/MCValue.h"30#include "llvm/Support/Alignment.h"31#include "llvm/Support/Casting.h"32#include "llvm/Support/Debug.h"33#include "llvm/Support/EndianStream.h"34#include "llvm/Support/ErrorHandling.h"35#include "llvm/Support/LEB128.h"36#include "llvm/Support/raw_ostream.h"37#include <cassert>38#include <cstdint>39#include <tuple>40#include <utility>4142using namespace llvm;4344namespace llvm {45class MCSubtargetInfo;46}4748#define DEBUG_TYPE "assembler"4950namespace {51namespace stats {5253STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total");54STATISTIC(EmittedRelaxableFragments,55"Number of emitted assembler fragments - relaxable");56STATISTIC(EmittedDataFragments,57"Number of emitted assembler fragments - data");58STATISTIC(EmittedCompactEncodedInstFragments,59"Number of emitted assembler fragments - compact encoded inst");60STATISTIC(EmittedAlignFragments,61"Number of emitted assembler fragments - align");62STATISTIC(EmittedFillFragments,63"Number of emitted assembler fragments - fill");64STATISTIC(EmittedNopsFragments, "Number of emitted assembler fragments - nops");65STATISTIC(EmittedOrgFragments, "Number of emitted assembler fragments - org");66STATISTIC(evaluateFixup, "Number of evaluated fixups");67STATISTIC(ObjectBytes, "Number of emitted object file bytes");68STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps");69STATISTIC(RelaxedInstructions, "Number of relaxed instructions");7071} // end namespace stats72} // end anonymous namespace7374// FIXME FIXME FIXME: There are number of places in this file where we convert75// what is a 64-bit assembler value used for computation into a value in the76// object file, which may truncate it. We should detect that truncation where77// invalid and report errors back.7879/* *** */8081MCAssembler::MCAssembler(MCContext &Context,82std::unique_ptr<MCAsmBackend> Backend,83std::unique_ptr<MCCodeEmitter> Emitter,84std::unique_ptr<MCObjectWriter> Writer)85: Context(Context), Backend(std::move(Backend)),86Emitter(std::move(Emitter)), Writer(std::move(Writer)) {}8788void MCAssembler::reset() {89RelaxAll = false;90Sections.clear();91Symbols.clear();92ThumbFuncs.clear();93BundleAlignSize = 0;9495// reset objects owned by us96if (getBackendPtr())97getBackendPtr()->reset();98if (getEmitterPtr())99getEmitterPtr()->reset();100if (Writer)101Writer->reset();102}103104bool MCAssembler::registerSection(MCSection &Section) {105if (Section.isRegistered())106return false;107assert(Section.curFragList()->Head && "allocInitialFragment not called");108Sections.push_back(&Section);109Section.setIsRegistered(true);110return true;111}112113bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const {114if (ThumbFuncs.count(Symbol))115return true;116117if (!Symbol->isVariable())118return false;119120const MCExpr *Expr = Symbol->getVariableValue();121122MCValue V;123if (!Expr->evaluateAsRelocatable(V, nullptr, nullptr))124return false;125126if (V.getSymB() || V.getRefKind() != MCSymbolRefExpr::VK_None)127return false;128129const MCSymbolRefExpr *Ref = V.getSymA();130if (!Ref)131return false;132133if (Ref->getKind() != MCSymbolRefExpr::VK_None)134return false;135136const MCSymbol &Sym = Ref->getSymbol();137if (!isThumbFunc(&Sym))138return false;139140ThumbFuncs.insert(Symbol); // Cache it.141return true;142}143144bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,145MCValue &Target, const MCSubtargetInfo *STI,146uint64_t &Value, bool &WasForced) const {147++stats::evaluateFixup;148149// FIXME: This code has some duplication with recordRelocation. We should150// probably merge the two into a single callback that tries to evaluate a151// fixup and records a relocation if one is needed.152153// On error claim to have completely evaluated the fixup, to prevent any154// further processing from being done.155const MCExpr *Expr = Fixup.getValue();156MCContext &Ctx = getContext();157Value = 0;158WasForced = false;159if (!Expr->evaluateAsRelocatable(Target, this, &Fixup)) {160Ctx.reportError(Fixup.getLoc(), "expected relocatable expression");161return true;162}163if (const MCSymbolRefExpr *RefB = Target.getSymB()) {164if (RefB->getKind() != MCSymbolRefExpr::VK_None) {165Ctx.reportError(Fixup.getLoc(),166"unsupported subtraction of qualified symbol");167return true;168}169}170171assert(getBackendPtr() && "Expected assembler backend");172bool IsTarget = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags &173MCFixupKindInfo::FKF_IsTarget;174175if (IsTarget)176return getBackend().evaluateTargetFixup(*this, Fixup, DF, Target, STI,177Value, WasForced);178179unsigned FixupFlags = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags;180bool IsPCRel = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags &181MCFixupKindInfo::FKF_IsPCRel;182183bool IsResolved = false;184if (IsPCRel) {185if (Target.getSymB()) {186IsResolved = false;187} else if (!Target.getSymA()) {188IsResolved = false;189} else {190const MCSymbolRefExpr *A = Target.getSymA();191const MCSymbol &SA = A->getSymbol();192if (A->getKind() != MCSymbolRefExpr::VK_None || SA.isUndefined()) {193IsResolved = false;194} else {195IsResolved = (FixupFlags & MCFixupKindInfo::FKF_Constant) ||196getWriter().isSymbolRefDifferenceFullyResolvedImpl(197*this, SA, *DF, false, true);198}199}200} else {201IsResolved = Target.isAbsolute();202}203204Value = Target.getConstant();205206if (const MCSymbolRefExpr *A = Target.getSymA()) {207const MCSymbol &Sym = A->getSymbol();208if (Sym.isDefined())209Value += getSymbolOffset(Sym);210}211if (const MCSymbolRefExpr *B = Target.getSymB()) {212const MCSymbol &Sym = B->getSymbol();213if (Sym.isDefined())214Value -= getSymbolOffset(Sym);215}216217bool ShouldAlignPC = getBackend().getFixupKindInfo(Fixup.getKind()).Flags &218MCFixupKindInfo::FKF_IsAlignedDownTo32Bits;219assert((ShouldAlignPC ? IsPCRel : true) &&220"FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!");221222if (IsPCRel) {223uint64_t Offset = getFragmentOffset(*DF) + Fixup.getOffset();224225// A number of ARM fixups in Thumb mode require that the effective PC226// address be determined as the 32-bit aligned version of the actual offset.227if (ShouldAlignPC) Offset &= ~0x3;228Value -= Offset;229}230231// Let the backend force a relocation if needed.232if (IsResolved &&233getBackend().shouldForceRelocation(*this, Fixup, Target, STI)) {234IsResolved = false;235WasForced = true;236}237238// A linker relaxation target may emit ADD/SUB relocations for A-B+C. Let239// recordRelocation handle non-VK_None cases like A@plt-B+C.240if (!IsResolved && Target.getSymA() && Target.getSymB() &&241Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None &&242getBackend().handleAddSubRelocations(*this, *DF, Fixup, Target, Value))243return true;244245return IsResolved;246}247248uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {249assert(getBackendPtr() && "Requires assembler backend");250switch (F.getKind()) {251case MCFragment::FT_Data:252return cast<MCDataFragment>(F).getContents().size();253case MCFragment::FT_Relaxable:254return cast<MCRelaxableFragment>(F).getContents().size();255case MCFragment::FT_CompactEncodedInst:256return cast<MCCompactEncodedInstFragment>(F).getContents().size();257case MCFragment::FT_Fill: {258auto &FF = cast<MCFillFragment>(F);259int64_t NumValues = 0;260if (!FF.getNumValues().evaluateKnownAbsolute(NumValues, *this)) {261getContext().reportError(FF.getLoc(),262"expected assembly-time absolute expression");263return 0;264}265int64_t Size = NumValues * FF.getValueSize();266if (Size < 0) {267getContext().reportError(FF.getLoc(), "invalid number of bytes");268return 0;269}270return Size;271}272273case MCFragment::FT_Nops:274return cast<MCNopsFragment>(F).getNumBytes();275276case MCFragment::FT_LEB:277return cast<MCLEBFragment>(F).getContents().size();278279case MCFragment::FT_BoundaryAlign:280return cast<MCBoundaryAlignFragment>(F).getSize();281282case MCFragment::FT_SymbolId:283return 4;284285case MCFragment::FT_Align: {286const MCAlignFragment &AF = cast<MCAlignFragment>(F);287unsigned Offset = getFragmentOffset(AF);288unsigned Size = offsetToAlignment(Offset, AF.getAlignment());289290// Insert extra Nops for code alignment if the target define291// shouldInsertExtraNopBytesForCodeAlign target hook.292if (AF.getParent()->useCodeAlign() && AF.hasEmitNops() &&293getBackend().shouldInsertExtraNopBytesForCodeAlign(AF, Size))294return Size;295296// If we are padding with nops, force the padding to be larger than the297// minimum nop size.298if (Size > 0 && AF.hasEmitNops()) {299while (Size % getBackend().getMinimumNopSize())300Size += AF.getAlignment().value();301}302if (Size > AF.getMaxBytesToEmit())303return 0;304return Size;305}306307case MCFragment::FT_Org: {308const MCOrgFragment &OF = cast<MCOrgFragment>(F);309MCValue Value;310if (!OF.getOffset().evaluateAsValue(Value, *this)) {311getContext().reportError(OF.getLoc(),312"expected assembly-time absolute expression");313return 0;314}315316uint64_t FragmentOffset = getFragmentOffset(OF);317int64_t TargetLocation = Value.getConstant();318if (const MCSymbolRefExpr *A = Value.getSymA()) {319uint64_t Val;320if (!getSymbolOffset(A->getSymbol(), Val)) {321getContext().reportError(OF.getLoc(), "expected absolute expression");322return 0;323}324TargetLocation += Val;325}326int64_t Size = TargetLocation - FragmentOffset;327if (Size < 0 || Size >= 0x40000000) {328getContext().reportError(329OF.getLoc(), "invalid .org offset '" + Twine(TargetLocation) +330"' (at offset '" + Twine(FragmentOffset) + "')");331return 0;332}333return Size;334}335336case MCFragment::FT_Dwarf:337return cast<MCDwarfLineAddrFragment>(F).getContents().size();338case MCFragment::FT_DwarfFrame:339return cast<MCDwarfCallFrameFragment>(F).getContents().size();340case MCFragment::FT_CVInlineLines:341return cast<MCCVInlineLineTableFragment>(F).getContents().size();342case MCFragment::FT_CVDefRange:343return cast<MCCVDefRangeFragment>(F).getContents().size();344case MCFragment::FT_PseudoProbe:345return cast<MCPseudoProbeAddrFragment>(F).getContents().size();346case MCFragment::FT_Dummy:347llvm_unreachable("Should not have been added");348}349350llvm_unreachable("invalid fragment kind");351}352353// Compute the amount of padding required before the fragment \p F to354// obey bundling restrictions, where \p FOffset is the fragment's offset in355// its section and \p FSize is the fragment's size.356static uint64_t computeBundlePadding(unsigned BundleSize,357const MCEncodedFragment *F,358uint64_t FOffset, uint64_t FSize) {359uint64_t OffsetInBundle = FOffset & (BundleSize - 1);360uint64_t EndOfFragment = OffsetInBundle + FSize;361362// There are two kinds of bundling restrictions:363//364// 1) For alignToBundleEnd(), add padding to ensure that the fragment will365// *end* on a bundle boundary.366// 2) Otherwise, check if the fragment would cross a bundle boundary. If it367// would, add padding until the end of the bundle so that the fragment368// will start in a new one.369if (F->alignToBundleEnd()) {370// Three possibilities here:371//372// A) The fragment just happens to end at a bundle boundary, so we're good.373// B) The fragment ends before the current bundle boundary: pad it just374// enough to reach the boundary.375// C) The fragment ends after the current bundle boundary: pad it until it376// reaches the end of the next bundle boundary.377//378// Note: this code could be made shorter with some modulo trickery, but it's379// intentionally kept in its more explicit form for simplicity.380if (EndOfFragment == BundleSize)381return 0;382else if (EndOfFragment < BundleSize)383return BundleSize - EndOfFragment;384else { // EndOfFragment > BundleSize385return 2 * BundleSize - EndOfFragment;386}387} else if (OffsetInBundle > 0 && EndOfFragment > BundleSize)388return BundleSize - OffsetInBundle;389else390return 0;391}392393void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const {394// If bundling is enabled and this fragment has instructions in it, it has to395// obey the bundling restrictions. With padding, we'll have:396//397//398// BundlePadding399// |||400// -------------------------------------401// Prev |##########| F |402// -------------------------------------403// ^404// |405// F->Offset406//407// The fragment's offset will point to after the padding, and its computed408// size won't include the padding.409//410// ".align N" is an example of a directive that introduces multiple411// fragments. We could add a special case to handle ".align N" by emitting412// within-fragment padding (which would produce less padding when N is less413// than the bundle size), but for now we don't.414//415assert(isa<MCEncodedFragment>(F) &&416"Only MCEncodedFragment implementations have instructions");417MCEncodedFragment *EF = cast<MCEncodedFragment>(F);418uint64_t FSize = computeFragmentSize(*EF);419420if (FSize > getBundleAlignSize())421report_fatal_error("Fragment can't be larger than a bundle size");422423uint64_t RequiredBundlePadding =424computeBundlePadding(getBundleAlignSize(), EF, EF->Offset, FSize);425if (RequiredBundlePadding > UINT8_MAX)426report_fatal_error("Padding cannot exceed 255 bytes");427EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));428EF->Offset += RequiredBundlePadding;429if (auto *DF = dyn_cast_or_null<MCDataFragment>(Prev))430if (DF->getContents().empty())431DF->Offset = EF->Offset;432}433434void MCAssembler::ensureValid(MCSection &Sec) const {435if (Sec.hasLayout())436return;437Sec.setHasLayout(true);438MCFragment *Prev = nullptr;439uint64_t Offset = 0;440for (MCFragment &F : Sec) {441F.Offset = Offset;442if (isBundlingEnabled() && F.hasInstructions()) {443layoutBundle(Prev, &F);444Offset = F.Offset;445}446Offset += computeFragmentSize(F);447Prev = &F;448}449}450451uint64_t MCAssembler::getFragmentOffset(const MCFragment &F) const {452ensureValid(*F.getParent());453return F.Offset;454}455456// Simple getSymbolOffset helper for the non-variable case.457static bool getLabelOffset(const MCAssembler &Asm, const MCSymbol &S,458bool ReportError, uint64_t &Val) {459if (!S.getFragment()) {460if (ReportError)461report_fatal_error("unable to evaluate offset to undefined symbol '" +462S.getName() + "'");463return false;464}465Val = Asm.getFragmentOffset(*S.getFragment()) + S.getOffset();466return true;467}468469static bool getSymbolOffsetImpl(const MCAssembler &Asm, const MCSymbol &S,470bool ReportError, uint64_t &Val) {471if (!S.isVariable())472return getLabelOffset(Asm, S, ReportError, Val);473474// If SD is a variable, evaluate it.475MCValue Target;476if (!S.getVariableValue()->evaluateAsValue(Target, Asm))477report_fatal_error("unable to evaluate offset for variable '" +478S.getName() + "'");479480uint64_t Offset = Target.getConstant();481482const MCSymbolRefExpr *A = Target.getSymA();483if (A) {484uint64_t ValA;485// FIXME: On most platforms, `Target`'s component symbols are labels from486// having been simplified during evaluation, but on Mach-O they can be487// variables due to PR19203. This, and the line below for `B` can be488// restored to call `getLabelOffset` when PR19203 is fixed.489if (!getSymbolOffsetImpl(Asm, A->getSymbol(), ReportError, ValA))490return false;491Offset += ValA;492}493494const MCSymbolRefExpr *B = Target.getSymB();495if (B) {496uint64_t ValB;497if (!getSymbolOffsetImpl(Asm, B->getSymbol(), ReportError, ValB))498return false;499Offset -= ValB;500}501502Val = Offset;503return true;504}505506bool MCAssembler::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const {507return getSymbolOffsetImpl(*this, S, false, Val);508}509510uint64_t MCAssembler::getSymbolOffset(const MCSymbol &S) const {511uint64_t Val;512getSymbolOffsetImpl(*this, S, true, Val);513return Val;514}515516const MCSymbol *MCAssembler::getBaseSymbol(const MCSymbol &Symbol) const {517assert(HasLayout);518if (!Symbol.isVariable())519return &Symbol;520521const MCExpr *Expr = Symbol.getVariableValue();522MCValue Value;523if (!Expr->evaluateAsValue(Value, *this)) {524getContext().reportError(Expr->getLoc(),525"expression could not be evaluated");526return nullptr;527}528529const MCSymbolRefExpr *RefB = Value.getSymB();530if (RefB) {531getContext().reportError(532Expr->getLoc(),533Twine("symbol '") + RefB->getSymbol().getName() +534"' could not be evaluated in a subtraction expression");535return nullptr;536}537538const MCSymbolRefExpr *A = Value.getSymA();539if (!A)540return nullptr;541542const MCSymbol &ASym = A->getSymbol();543if (ASym.isCommon()) {544getContext().reportError(Expr->getLoc(),545"Common symbol '" + ASym.getName() +546"' cannot be used in assignment expr");547return nullptr;548}549550return &ASym;551}552553uint64_t MCAssembler::getSectionAddressSize(const MCSection &Sec) const {554assert(HasLayout);555// The size is the last fragment's end offset.556const MCFragment &F = *Sec.curFragList()->Tail;557return getFragmentOffset(F) + computeFragmentSize(F);558}559560uint64_t MCAssembler::getSectionFileSize(const MCSection &Sec) const {561// Virtual sections have no file size.562if (Sec.isVirtualSection())563return 0;564return getSectionAddressSize(Sec);565}566567bool MCAssembler::registerSymbol(const MCSymbol &Symbol) {568bool Changed = !Symbol.isRegistered();569if (Changed) {570Symbol.setIsRegistered(true);571Symbols.push_back(&Symbol);572}573return Changed;574}575576void MCAssembler::writeFragmentPadding(raw_ostream &OS,577const MCEncodedFragment &EF,578uint64_t FSize) const {579assert(getBackendPtr() && "Expected assembler backend");580// Should NOP padding be written out before this fragment?581unsigned BundlePadding = EF.getBundlePadding();582if (BundlePadding > 0) {583assert(isBundlingEnabled() &&584"Writing bundle padding with disabled bundling");585assert(EF.hasInstructions() &&586"Writing bundle padding for a fragment without instructions");587588unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize);589const MCSubtargetInfo *STI = EF.getSubtargetInfo();590if (EF.alignToBundleEnd() && TotalLength > getBundleAlignSize()) {591// If the padding itself crosses a bundle boundary, it must be emitted592// in 2 pieces, since even nop instructions must not cross boundaries.593// v--------------v <- BundleAlignSize594// v---------v <- BundlePadding595// ----------------------------596// | Prev |####|####| F |597// ----------------------------598// ^-------------------^ <- TotalLength599unsigned DistanceToBoundary = TotalLength - getBundleAlignSize();600if (!getBackend().writeNopData(OS, DistanceToBoundary, STI))601report_fatal_error("unable to write NOP sequence of " +602Twine(DistanceToBoundary) + " bytes");603BundlePadding -= DistanceToBoundary;604}605if (!getBackend().writeNopData(OS, BundlePadding, STI))606report_fatal_error("unable to write NOP sequence of " +607Twine(BundlePadding) + " bytes");608}609}610611/// Write the fragment \p F to the output file.612static void writeFragment(raw_ostream &OS, const MCAssembler &Asm,613const MCFragment &F) {614// FIXME: Embed in fragments instead?615uint64_t FragmentSize = Asm.computeFragmentSize(F);616617llvm::endianness Endian = Asm.getBackend().Endian;618619if (const MCEncodedFragment *EF = dyn_cast<MCEncodedFragment>(&F))620Asm.writeFragmentPadding(OS, *EF, FragmentSize);621622// This variable (and its dummy usage) is to participate in the assert at623// the end of the function.624uint64_t Start = OS.tell();625(void) Start;626627++stats::EmittedFragments;628629switch (F.getKind()) {630case MCFragment::FT_Align: {631++stats::EmittedAlignFragments;632const MCAlignFragment &AF = cast<MCAlignFragment>(F);633assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!");634635uint64_t Count = FragmentSize / AF.getValueSize();636637// FIXME: This error shouldn't actually occur (the front end should emit638// multiple .align directives to enforce the semantics it wants), but is639// severe enough that we want to report it. How to handle this?640if (Count * AF.getValueSize() != FragmentSize)641report_fatal_error("undefined .align directive, value size '" +642Twine(AF.getValueSize()) +643"' is not a divisor of padding size '" +644Twine(FragmentSize) + "'");645646// See if we are aligning with nops, and if so do that first to try to fill647// the Count bytes. Then if that did not fill any bytes or there are any648// bytes left to fill use the Value and ValueSize to fill the rest.649// If we are aligning with nops, ask that target to emit the right data.650if (AF.hasEmitNops()) {651if (!Asm.getBackend().writeNopData(OS, Count, AF.getSubtargetInfo()))652report_fatal_error("unable to write nop sequence of " +653Twine(Count) + " bytes");654break;655}656657// Otherwise, write out in multiples of the value size.658for (uint64_t i = 0; i != Count; ++i) {659switch (AF.getValueSize()) {660default: llvm_unreachable("Invalid size!");661case 1: OS << char(AF.getValue()); break;662case 2:663support::endian::write<uint16_t>(OS, AF.getValue(), Endian);664break;665case 4:666support::endian::write<uint32_t>(OS, AF.getValue(), Endian);667break;668case 8:669support::endian::write<uint64_t>(OS, AF.getValue(), Endian);670break;671}672}673break;674}675676case MCFragment::FT_Data:677++stats::EmittedDataFragments;678OS << cast<MCDataFragment>(F).getContents();679break;680681case MCFragment::FT_Relaxable:682++stats::EmittedRelaxableFragments;683OS << cast<MCRelaxableFragment>(F).getContents();684break;685686case MCFragment::FT_CompactEncodedInst:687++stats::EmittedCompactEncodedInstFragments;688OS << cast<MCCompactEncodedInstFragment>(F).getContents();689break;690691case MCFragment::FT_Fill: {692++stats::EmittedFillFragments;693const MCFillFragment &FF = cast<MCFillFragment>(F);694uint64_t V = FF.getValue();695unsigned VSize = FF.getValueSize();696const unsigned MaxChunkSize = 16;697char Data[MaxChunkSize];698assert(0 < VSize && VSize <= MaxChunkSize && "Illegal fragment fill size");699// Duplicate V into Data as byte vector to reduce number of700// writes done. As such, do endian conversion here.701for (unsigned I = 0; I != VSize; ++I) {702unsigned index = Endian == llvm::endianness::little ? I : (VSize - I - 1);703Data[I] = uint8_t(V >> (index * 8));704}705for (unsigned I = VSize; I < MaxChunkSize; ++I)706Data[I] = Data[I - VSize];707708// Set to largest multiple of VSize in Data.709const unsigned NumPerChunk = MaxChunkSize / VSize;710// Set ChunkSize to largest multiple of VSize in Data711const unsigned ChunkSize = VSize * NumPerChunk;712713// Do copies by chunk.714StringRef Ref(Data, ChunkSize);715for (uint64_t I = 0, E = FragmentSize / ChunkSize; I != E; ++I)716OS << Ref;717718// do remainder if needed.719unsigned TrailingCount = FragmentSize % ChunkSize;720if (TrailingCount)721OS.write(Data, TrailingCount);722break;723}724725case MCFragment::FT_Nops: {726++stats::EmittedNopsFragments;727const MCNopsFragment &NF = cast<MCNopsFragment>(F);728729int64_t NumBytes = NF.getNumBytes();730int64_t ControlledNopLength = NF.getControlledNopLength();731int64_t MaximumNopLength =732Asm.getBackend().getMaximumNopSize(*NF.getSubtargetInfo());733734assert(NumBytes > 0 && "Expected positive NOPs fragment size");735assert(ControlledNopLength >= 0 && "Expected non-negative NOP size");736737if (ControlledNopLength > MaximumNopLength) {738Asm.getContext().reportError(NF.getLoc(),739"illegal NOP size " +740std::to_string(ControlledNopLength) +741". (expected within [0, " +742std::to_string(MaximumNopLength) + "])");743// Clamp the NOP length as reportError does not stop the execution744// immediately.745ControlledNopLength = MaximumNopLength;746}747748// Use maximum value if the size of each NOP is not specified749if (!ControlledNopLength)750ControlledNopLength = MaximumNopLength;751752while (NumBytes) {753uint64_t NumBytesToEmit =754(uint64_t)std::min(NumBytes, ControlledNopLength);755assert(NumBytesToEmit && "try to emit empty NOP instruction");756if (!Asm.getBackend().writeNopData(OS, NumBytesToEmit,757NF.getSubtargetInfo())) {758report_fatal_error("unable to write nop sequence of the remaining " +759Twine(NumBytesToEmit) + " bytes");760break;761}762NumBytes -= NumBytesToEmit;763}764break;765}766767case MCFragment::FT_LEB: {768const MCLEBFragment &LF = cast<MCLEBFragment>(F);769OS << LF.getContents();770break;771}772773case MCFragment::FT_BoundaryAlign: {774const MCBoundaryAlignFragment &BF = cast<MCBoundaryAlignFragment>(F);775if (!Asm.getBackend().writeNopData(OS, FragmentSize, BF.getSubtargetInfo()))776report_fatal_error("unable to write nop sequence of " +777Twine(FragmentSize) + " bytes");778break;779}780781case MCFragment::FT_SymbolId: {782const MCSymbolIdFragment &SF = cast<MCSymbolIdFragment>(F);783support::endian::write<uint32_t>(OS, SF.getSymbol()->getIndex(), Endian);784break;785}786787case MCFragment::FT_Org: {788++stats::EmittedOrgFragments;789const MCOrgFragment &OF = cast<MCOrgFragment>(F);790791for (uint64_t i = 0, e = FragmentSize; i != e; ++i)792OS << char(OF.getValue());793794break;795}796797case MCFragment::FT_Dwarf: {798const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F);799OS << OF.getContents();800break;801}802case MCFragment::FT_DwarfFrame: {803const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F);804OS << CF.getContents();805break;806}807case MCFragment::FT_CVInlineLines: {808const auto &OF = cast<MCCVInlineLineTableFragment>(F);809OS << OF.getContents();810break;811}812case MCFragment::FT_CVDefRange: {813const auto &DRF = cast<MCCVDefRangeFragment>(F);814OS << DRF.getContents();815break;816}817case MCFragment::FT_PseudoProbe: {818const MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(F);819OS << PF.getContents();820break;821}822case MCFragment::FT_Dummy:823llvm_unreachable("Should not have been added");824}825826assert(OS.tell() - Start == FragmentSize &&827"The stream should advance by fragment size");828}829830void MCAssembler::writeSectionData(raw_ostream &OS,831const MCSection *Sec) const {832assert(getBackendPtr() && "Expected assembler backend");833834// Ignore virtual sections.835if (Sec->isVirtualSection()) {836assert(getSectionFileSize(*Sec) == 0 && "Invalid size for section!");837838// Check that contents are only things legal inside a virtual section.839for (const MCFragment &F : *Sec) {840switch (F.getKind()) {841default: llvm_unreachable("Invalid fragment in virtual section!");842case MCFragment::FT_Data: {843// Check that we aren't trying to write a non-zero contents (or fixups)844// into a virtual section. This is to support clients which use standard845// directives to fill the contents of virtual sections.846const MCDataFragment &DF = cast<MCDataFragment>(F);847if (DF.fixup_begin() != DF.fixup_end())848getContext().reportError(SMLoc(), Sec->getVirtualSectionKind() +849" section '" + Sec->getName() +850"' cannot have fixups");851for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i)852if (DF.getContents()[i]) {853getContext().reportError(SMLoc(),854Sec->getVirtualSectionKind() +855" section '" + Sec->getName() +856"' cannot have non-zero initializers");857break;858}859break;860}861case MCFragment::FT_Align:862// Check that we aren't trying to write a non-zero value into a virtual863// section.864assert((cast<MCAlignFragment>(F).getValueSize() == 0 ||865cast<MCAlignFragment>(F).getValue() == 0) &&866"Invalid align in virtual section!");867break;868case MCFragment::FT_Fill:869assert((cast<MCFillFragment>(F).getValue() == 0) &&870"Invalid fill in virtual section!");871break;872case MCFragment::FT_Org:873break;874}875}876877return;878}879880uint64_t Start = OS.tell();881(void)Start;882883for (const MCFragment &F : *Sec)884writeFragment(OS, *this, F);885886assert(getContext().hadError() ||887OS.tell() - Start == getSectionAddressSize(*Sec));888}889890std::tuple<MCValue, uint64_t, bool>891MCAssembler::handleFixup(MCFragment &F, const MCFixup &Fixup,892const MCSubtargetInfo *STI) {893// Evaluate the fixup.894MCValue Target;895uint64_t FixedValue;896bool WasForced;897bool IsResolved =898evaluateFixup(Fixup, &F, Target, STI, FixedValue, WasForced);899if (!IsResolved) {900// The fixup was unresolved, we need a relocation. Inform the object901// writer of the relocation, and give it an opportunity to adjust the902// fixup value if need be.903getWriter().recordRelocation(*this, &F, Fixup, Target, FixedValue);904}905return std::make_tuple(Target, FixedValue, IsResolved);906}907908void MCAssembler::layout() {909assert(getBackendPtr() && "Expected assembler backend");910DEBUG_WITH_TYPE("mc-dump", {911errs() << "assembler backend - pre-layout\n--\n";912dump(); });913914// Assign section ordinals.915unsigned SectionIndex = 0;916for (MCSection &Sec : *this) {917Sec.setOrdinal(SectionIndex++);918919// Chain together fragments from all subsections.920if (Sec.Subsections.size() > 1) {921MCDummyFragment Dummy;922MCFragment *Tail = &Dummy;923for (auto &[_, List] : Sec.Subsections) {924assert(List.Head);925Tail->Next = List.Head;926Tail = List.Tail;927}928Sec.Subsections.clear();929Sec.Subsections.push_back({0u, {Dummy.getNext(), Tail}});930Sec.CurFragList = &Sec.Subsections[0].second;931932unsigned FragmentIndex = 0;933for (MCFragment &Frag : Sec)934Frag.setLayoutOrder(FragmentIndex++);935}936}937938// Layout until everything fits.939this->HasLayout = true;940while (layoutOnce()) {941if (getContext().hadError())942return;943// Size of fragments in one section can depend on the size of fragments in944// another. If any fragment has changed size, we have to re-layout (and945// as a result possibly further relax) all.946for (MCSection &Sec : *this)947Sec.setHasLayout(false);948}949950DEBUG_WITH_TYPE("mc-dump", {951errs() << "assembler backend - post-relaxation\n--\n";952dump(); });953954// Finalize the layout, including fragment lowering.955getBackend().finishLayout(*this);956957DEBUG_WITH_TYPE("mc-dump", {958errs() << "assembler backend - final-layout\n--\n";959dump(); });960961// Allow the object writer a chance to perform post-layout binding (for962// example, to set the index fields in the symbol data).963getWriter().executePostLayoutBinding(*this);964965// Evaluate and apply the fixups, generating relocation entries as necessary.966for (MCSection &Sec : *this) {967for (MCFragment &Frag : Sec) {968ArrayRef<MCFixup> Fixups;969MutableArrayRef<char> Contents;970const MCSubtargetInfo *STI = nullptr;971972// Process MCAlignFragment and MCEncodedFragmentWithFixups here.973switch (Frag.getKind()) {974default:975continue;976case MCFragment::FT_Align: {977MCAlignFragment &AF = cast<MCAlignFragment>(Frag);978// Insert fixup type for code alignment if the target define979// shouldInsertFixupForCodeAlign target hook.980if (Sec.useCodeAlign() && AF.hasEmitNops())981getBackend().shouldInsertFixupForCodeAlign(*this, AF);982continue;983}984case MCFragment::FT_Data: {985MCDataFragment &DF = cast<MCDataFragment>(Frag);986Fixups = DF.getFixups();987Contents = DF.getContents();988STI = DF.getSubtargetInfo();989assert(!DF.hasInstructions() || STI != nullptr);990break;991}992case MCFragment::FT_Relaxable: {993MCRelaxableFragment &RF = cast<MCRelaxableFragment>(Frag);994Fixups = RF.getFixups();995Contents = RF.getContents();996STI = RF.getSubtargetInfo();997assert(!RF.hasInstructions() || STI != nullptr);998break;999}1000case MCFragment::FT_CVDefRange: {1001MCCVDefRangeFragment &CF = cast<MCCVDefRangeFragment>(Frag);1002Fixups = CF.getFixups();1003Contents = CF.getContents();1004break;1005}1006case MCFragment::FT_Dwarf: {1007MCDwarfLineAddrFragment &DF = cast<MCDwarfLineAddrFragment>(Frag);1008Fixups = DF.getFixups();1009Contents = DF.getContents();1010break;1011}1012case MCFragment::FT_DwarfFrame: {1013MCDwarfCallFrameFragment &DF = cast<MCDwarfCallFrameFragment>(Frag);1014Fixups = DF.getFixups();1015Contents = DF.getContents();1016break;1017}1018case MCFragment::FT_LEB: {1019auto &LF = cast<MCLEBFragment>(Frag);1020Fixups = LF.getFixups();1021Contents = LF.getContents();1022break;1023}1024case MCFragment::FT_PseudoProbe: {1025MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(Frag);1026Fixups = PF.getFixups();1027Contents = PF.getContents();1028break;1029}1030}1031for (const MCFixup &Fixup : Fixups) {1032uint64_t FixedValue;1033bool IsResolved;1034MCValue Target;1035std::tie(Target, FixedValue, IsResolved) =1036handleFixup(Frag, Fixup, STI);1037getBackend().applyFixup(*this, Fixup, Target, Contents, FixedValue,1038IsResolved, STI);1039}1040}1041}1042}10431044void MCAssembler::Finish() {1045layout();10461047// Write the object file.1048stats::ObjectBytes += getWriter().writeObject(*this);10491050HasLayout = false;1051}10521053bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup,1054const MCRelaxableFragment *DF) const {1055assert(getBackendPtr() && "Expected assembler backend");1056MCValue Target;1057uint64_t Value;1058bool WasForced;1059bool Resolved = evaluateFixup(Fixup, DF, Target, DF->getSubtargetInfo(),1060Value, WasForced);1061if (Target.getSymA() &&1062Target.getSymA()->getKind() == MCSymbolRefExpr::VK_X86_ABS8 &&1063Fixup.getKind() == FK_Data_1)1064return false;1065return getBackend().fixupNeedsRelaxationAdvanced(*this, Fixup, Resolved,1066Value, DF, WasForced);1067}10681069bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F) const {1070assert(getBackendPtr() && "Expected assembler backend");1071// If this inst doesn't ever need relaxation, ignore it. This occurs when we1072// are intentionally pushing out inst fragments, or because we relaxed a1073// previous instruction to one that doesn't need relaxation.1074if (!getBackend().mayNeedRelaxation(F->getInst(), *F->getSubtargetInfo()))1075return false;10761077for (const MCFixup &Fixup : F->getFixups())1078if (fixupNeedsRelaxation(Fixup, F))1079return true;10801081return false;1082}10831084bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) {1085assert(getEmitterPtr() &&1086"Expected CodeEmitter defined for relaxInstruction");1087if (!fragmentNeedsRelaxation(&F))1088return false;10891090++stats::RelaxedInstructions;10911092// FIXME-PERF: We could immediately lower out instructions if we can tell1093// they are fully resolved, to avoid retesting on later passes.10941095// Relax the fragment.10961097MCInst Relaxed = F.getInst();1098getBackend().relaxInstruction(Relaxed, *F.getSubtargetInfo());10991100// Encode the new instruction.1101F.setInst(Relaxed);1102F.getFixups().clear();1103F.getContents().clear();1104getEmitter().encodeInstruction(Relaxed, F.getContents(), F.getFixups(),1105*F.getSubtargetInfo());1106return true;1107}11081109bool MCAssembler::relaxLEB(MCLEBFragment &LF) {1110const unsigned OldSize = static_cast<unsigned>(LF.getContents().size());1111unsigned PadTo = OldSize;1112int64_t Value;1113SmallVectorImpl<char> &Data = LF.getContents();1114LF.getFixups().clear();1115// Use evaluateKnownAbsolute for Mach-O as a hack: .subsections_via_symbols1116// requires that .uleb128 A-B is foldable where A and B reside in different1117// fragments. This is used by __gcc_except_table.1118bool Abs = getWriter().getSubsectionsViaSymbols()1119? LF.getValue().evaluateKnownAbsolute(Value, *this)1120: LF.getValue().evaluateAsAbsolute(Value, *this);1121if (!Abs) {1122bool Relaxed, UseZeroPad;1123std::tie(Relaxed, UseZeroPad) = getBackend().relaxLEB128(*this, LF, Value);1124if (!Relaxed) {1125getContext().reportError(LF.getValue().getLoc(),1126Twine(LF.isSigned() ? ".s" : ".u") +1127"leb128 expression is not absolute");1128LF.setValue(MCConstantExpr::create(0, Context));1129}1130uint8_t Tmp[10]; // maximum size: ceil(64/7)1131PadTo = std::max(PadTo, encodeULEB128(uint64_t(Value), Tmp));1132if (UseZeroPad)1133Value = 0;1134}1135Data.clear();1136raw_svector_ostream OSE(Data);1137// The compiler can generate EH table assembly that is impossible to assemble1138// without either adding padding to an LEB fragment or adding extra padding1139// to a later alignment fragment. To accommodate such tables, relaxation can1140// only increase an LEB fragment size here, not decrease it. See PR35809.1141if (LF.isSigned())1142encodeSLEB128(Value, OSE, PadTo);1143else1144encodeULEB128(Value, OSE, PadTo);1145return OldSize != LF.getContents().size();1146}11471148/// Check if the branch crosses the boundary.1149///1150/// \param StartAddr start address of the fused/unfused branch.1151/// \param Size size of the fused/unfused branch.1152/// \param BoundaryAlignment alignment requirement of the branch.1153/// \returns true if the branch cross the boundary.1154static bool mayCrossBoundary(uint64_t StartAddr, uint64_t Size,1155Align BoundaryAlignment) {1156uint64_t EndAddr = StartAddr + Size;1157return (StartAddr >> Log2(BoundaryAlignment)) !=1158((EndAddr - 1) >> Log2(BoundaryAlignment));1159}11601161/// Check if the branch is against the boundary.1162///1163/// \param StartAddr start address of the fused/unfused branch.1164/// \param Size size of the fused/unfused branch.1165/// \param BoundaryAlignment alignment requirement of the branch.1166/// \returns true if the branch is against the boundary.1167static bool isAgainstBoundary(uint64_t StartAddr, uint64_t Size,1168Align BoundaryAlignment) {1169uint64_t EndAddr = StartAddr + Size;1170return (EndAddr & (BoundaryAlignment.value() - 1)) == 0;1171}11721173/// Check if the branch needs padding.1174///1175/// \param StartAddr start address of the fused/unfused branch.1176/// \param Size size of the fused/unfused branch.1177/// \param BoundaryAlignment alignment requirement of the branch.1178/// \returns true if the branch needs padding.1179static bool needPadding(uint64_t StartAddr, uint64_t Size,1180Align BoundaryAlignment) {1181return mayCrossBoundary(StartAddr, Size, BoundaryAlignment) ||1182isAgainstBoundary(StartAddr, Size, BoundaryAlignment);1183}11841185bool MCAssembler::relaxBoundaryAlign(MCBoundaryAlignFragment &BF) {1186// BoundaryAlignFragment that doesn't need to align any fragment should not be1187// relaxed.1188if (!BF.getLastFragment())1189return false;11901191uint64_t AlignedOffset = getFragmentOffset(BF);1192uint64_t AlignedSize = 0;1193for (const MCFragment *F = BF.getNext();; F = F->getNext()) {1194AlignedSize += computeFragmentSize(*F);1195if (F == BF.getLastFragment())1196break;1197}11981199Align BoundaryAlignment = BF.getAlignment();1200uint64_t NewSize = needPadding(AlignedOffset, AlignedSize, BoundaryAlignment)1201? offsetToAlignment(AlignedOffset, BoundaryAlignment)1202: 0U;1203if (NewSize == BF.getSize())1204return false;1205BF.setSize(NewSize);1206return true;1207}12081209bool MCAssembler::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF) {1210bool WasRelaxed;1211if (getBackend().relaxDwarfLineAddr(*this, DF, WasRelaxed))1212return WasRelaxed;12131214MCContext &Context = getContext();1215uint64_t OldSize = DF.getContents().size();1216int64_t AddrDelta;1217bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);1218assert(Abs && "We created a line delta with an invalid expression");1219(void)Abs;1220int64_t LineDelta;1221LineDelta = DF.getLineDelta();1222SmallVectorImpl<char> &Data = DF.getContents();1223Data.clear();1224DF.getFixups().clear();12251226MCDwarfLineAddr::encode(Context, getDWARFLinetableParams(), LineDelta,1227AddrDelta, Data);1228return OldSize != Data.size();1229}12301231bool MCAssembler::relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF) {1232bool WasRelaxed;1233if (getBackend().relaxDwarfCFA(*this, DF, WasRelaxed))1234return WasRelaxed;12351236MCContext &Context = getContext();1237int64_t Value;1238bool Abs = DF.getAddrDelta().evaluateAsAbsolute(Value, *this);1239if (!Abs) {1240getContext().reportError(DF.getAddrDelta().getLoc(),1241"invalid CFI advance_loc expression");1242DF.setAddrDelta(MCConstantExpr::create(0, Context));1243return false;1244}12451246SmallVectorImpl<char> &Data = DF.getContents();1247uint64_t OldSize = Data.size();1248Data.clear();1249DF.getFixups().clear();12501251MCDwarfFrameEmitter::encodeAdvanceLoc(Context, Value, Data);1252return OldSize != Data.size();1253}12541255bool MCAssembler::relaxCVInlineLineTable(MCCVInlineLineTableFragment &F) {1256unsigned OldSize = F.getContents().size();1257getContext().getCVContext().encodeInlineLineTable(*this, F);1258return OldSize != F.getContents().size();1259}12601261bool MCAssembler::relaxCVDefRange(MCCVDefRangeFragment &F) {1262unsigned OldSize = F.getContents().size();1263getContext().getCVContext().encodeDefRange(*this, F);1264return OldSize != F.getContents().size();1265}12661267bool MCAssembler::relaxPseudoProbeAddr(MCPseudoProbeAddrFragment &PF) {1268uint64_t OldSize = PF.getContents().size();1269int64_t AddrDelta;1270bool Abs = PF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);1271assert(Abs && "We created a pseudo probe with an invalid expression");1272(void)Abs;1273SmallVectorImpl<char> &Data = PF.getContents();1274Data.clear();1275raw_svector_ostream OSE(Data);1276PF.getFixups().clear();12771278// AddrDelta is a signed integer1279encodeSLEB128(AddrDelta, OSE, OldSize);1280return OldSize != Data.size();1281}12821283bool MCAssembler::relaxFragment(MCFragment &F) {1284switch(F.getKind()) {1285default:1286return false;1287case MCFragment::FT_Relaxable:1288assert(!getRelaxAll() &&1289"Did not expect a MCRelaxableFragment in RelaxAll mode");1290return relaxInstruction(cast<MCRelaxableFragment>(F));1291case MCFragment::FT_Dwarf:1292return relaxDwarfLineAddr(cast<MCDwarfLineAddrFragment>(F));1293case MCFragment::FT_DwarfFrame:1294return relaxDwarfCallFrameFragment(cast<MCDwarfCallFrameFragment>(F));1295case MCFragment::FT_LEB:1296return relaxLEB(cast<MCLEBFragment>(F));1297case MCFragment::FT_BoundaryAlign:1298return relaxBoundaryAlign(cast<MCBoundaryAlignFragment>(F));1299case MCFragment::FT_CVInlineLines:1300return relaxCVInlineLineTable(cast<MCCVInlineLineTableFragment>(F));1301case MCFragment::FT_CVDefRange:1302return relaxCVDefRange(cast<MCCVDefRangeFragment>(F));1303case MCFragment::FT_PseudoProbe:1304return relaxPseudoProbeAddr(cast<MCPseudoProbeAddrFragment>(F));1305}1306}13071308bool MCAssembler::layoutOnce() {1309++stats::RelaxationSteps;13101311bool Changed = false;1312for (MCSection &Sec : *this)1313for (MCFragment &Frag : Sec)1314if (relaxFragment(Frag))1315Changed = true;1316return Changed;1317}13181319#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)1320LLVM_DUMP_METHOD void MCAssembler::dump() const{1321raw_ostream &OS = errs();13221323OS << "<MCAssembler\n";1324OS << " Sections:[\n ";1325bool First = true;1326for (const MCSection &Sec : *this) {1327if (First)1328First = false;1329else1330OS << ",\n ";1331Sec.dump();1332}1333OS << "],\n";1334OS << " Symbols:[";13351336First = true;1337for (const MCSymbol &Sym : symbols()) {1338if (First)1339First = false;1340else1341OS << ",\n ";1342OS << "(";1343Sym.dump();1344OS << ", Index:" << Sym.getIndex() << ", ";1345OS << ")";1346}1347OS << "]>\n";1348}1349#endif135013511352