10b57cec5SDimitry Andric //===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h" 100b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 110b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h" 120b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 130b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 140b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h" 150b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCAsmBackend.h" 170b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCCodeEmitter.h" 190b57cec5SDimitry Andric #include "llvm/MC/MCCodeView.h" 200b57cec5SDimitry Andric #include "llvm/MC/MCContext.h" 210b57cec5SDimitry Andric #include "llvm/MC/MCDwarf.h" 220b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h" 230b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h" 240b57cec5SDimitry Andric #include "llvm/MC/MCFixupKindInfo.h" 250b57cec5SDimitry Andric #include "llvm/MC/MCFragment.h" 260b57cec5SDimitry Andric #include "llvm/MC/MCInst.h" 270b57cec5SDimitry Andric #include "llvm/MC/MCObjectWriter.h" 280b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 290b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 300b57cec5SDimitry Andric #include "llvm/MC/MCValue.h" 318bcb0991SDimitry Andric #include "llvm/Support/Alignment.h" 320b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 330b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 345ffd83dbSDimitry Andric #include "llvm/Support/EndianStream.h" 350b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 360b57cec5SDimitry Andric #include "llvm/Support/LEB128.h" 370b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 380b57cec5SDimitry Andric #include <cassert> 390b57cec5SDimitry Andric #include <cstdint> 400b57cec5SDimitry Andric #include <tuple> 410b57cec5SDimitry Andric #include <utility> 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric using namespace llvm; 440b57cec5SDimitry Andric 4581ad6265SDimitry Andric namespace llvm { 4681ad6265SDimitry Andric class MCSubtargetInfo; 4781ad6265SDimitry Andric } 4881ad6265SDimitry Andric 490b57cec5SDimitry Andric #define DEBUG_TYPE "assembler" 500b57cec5SDimitry Andric 510b57cec5SDimitry Andric namespace { 520b57cec5SDimitry Andric namespace stats { 530b57cec5SDimitry Andric 540b57cec5SDimitry Andric STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total"); 550b57cec5SDimitry Andric STATISTIC(EmittedRelaxableFragments, 560b57cec5SDimitry Andric "Number of emitted assembler fragments - relaxable"); 570b57cec5SDimitry Andric STATISTIC(EmittedDataFragments, 580b57cec5SDimitry Andric "Number of emitted assembler fragments - data"); 590b57cec5SDimitry Andric STATISTIC(EmittedCompactEncodedInstFragments, 600b57cec5SDimitry Andric "Number of emitted assembler fragments - compact encoded inst"); 610b57cec5SDimitry Andric STATISTIC(EmittedAlignFragments, 620b57cec5SDimitry Andric "Number of emitted assembler fragments - align"); 630b57cec5SDimitry Andric STATISTIC(EmittedFillFragments, 640b57cec5SDimitry Andric "Number of emitted assembler fragments - fill"); 65e8d8bef9SDimitry Andric STATISTIC(EmittedNopsFragments, "Number of emitted assembler fragments - nops"); 66e8d8bef9SDimitry Andric STATISTIC(EmittedOrgFragments, "Number of emitted assembler fragments - org"); 670b57cec5SDimitry Andric STATISTIC(evaluateFixup, "Number of evaluated fixups"); 680b57cec5SDimitry Andric STATISTIC(ObjectBytes, "Number of emitted object file bytes"); 690b57cec5SDimitry Andric STATISTIC(RelaxationSteps, "Number of assembler layout and relaxation steps"); 700b57cec5SDimitry Andric STATISTIC(RelaxedInstructions, "Number of relaxed instructions"); 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric } // end namespace stats 730b57cec5SDimitry Andric } // end anonymous namespace 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric // FIXME FIXME FIXME: There are number of places in this file where we convert 760b57cec5SDimitry Andric // what is a 64-bit assembler value used for computation into a value in the 770b57cec5SDimitry Andric // object file, which may truncate it. We should detect that truncation where 780b57cec5SDimitry Andric // invalid and report errors back. 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /* *** */ 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric MCAssembler::MCAssembler(MCContext &Context, 830b57cec5SDimitry Andric std::unique_ptr<MCAsmBackend> Backend, 840b57cec5SDimitry Andric std::unique_ptr<MCCodeEmitter> Emitter, 850b57cec5SDimitry Andric std::unique_ptr<MCObjectWriter> Writer) 860b57cec5SDimitry Andric : Context(Context), Backend(std::move(Backend)), 870fca6ea1SDimitry Andric Emitter(std::move(Emitter)), Writer(std::move(Writer)) {} 880b57cec5SDimitry Andric 890b57cec5SDimitry Andric void MCAssembler::reset() { 900fca6ea1SDimitry Andric RelaxAll = false; 910b57cec5SDimitry Andric Sections.clear(); 920b57cec5SDimitry Andric Symbols.clear(); 930b57cec5SDimitry Andric ThumbFuncs.clear(); 940b57cec5SDimitry Andric BundleAlignSize = 0; 950b57cec5SDimitry Andric 960b57cec5SDimitry Andric // reset objects owned by us 970b57cec5SDimitry Andric if (getBackendPtr()) 980b57cec5SDimitry Andric getBackendPtr()->reset(); 990b57cec5SDimitry Andric if (getEmitterPtr()) 1000b57cec5SDimitry Andric getEmitterPtr()->reset(); 1010fca6ea1SDimitry Andric if (Writer) 1020fca6ea1SDimitry Andric Writer->reset(); 1030b57cec5SDimitry Andric } 1040b57cec5SDimitry Andric 1050b57cec5SDimitry Andric bool MCAssembler::registerSection(MCSection &Section) { 1060b57cec5SDimitry Andric if (Section.isRegistered()) 1070b57cec5SDimitry Andric return false; 1080fca6ea1SDimitry Andric assert(Section.curFragList()->Head && "allocInitialFragment not called"); 1090b57cec5SDimitry Andric Sections.push_back(&Section); 1100b57cec5SDimitry Andric Section.setIsRegistered(true); 1110b57cec5SDimitry Andric return true; 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric bool MCAssembler::isThumbFunc(const MCSymbol *Symbol) const { 1150b57cec5SDimitry Andric if (ThumbFuncs.count(Symbol)) 1160b57cec5SDimitry Andric return true; 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric if (!Symbol->isVariable()) 1190b57cec5SDimitry Andric return false; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric const MCExpr *Expr = Symbol->getVariableValue(); 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric MCValue V; 1240b57cec5SDimitry Andric if (!Expr->evaluateAsRelocatable(V, nullptr, nullptr)) 1250b57cec5SDimitry Andric return false; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric if (V.getSymB() || V.getRefKind() != MCSymbolRefExpr::VK_None) 1280b57cec5SDimitry Andric return false; 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric const MCSymbolRefExpr *Ref = V.getSymA(); 1310b57cec5SDimitry Andric if (!Ref) 1320b57cec5SDimitry Andric return false; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric if (Ref->getKind() != MCSymbolRefExpr::VK_None) 1350b57cec5SDimitry Andric return false; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric const MCSymbol &Sym = Ref->getSymbol(); 1380b57cec5SDimitry Andric if (!isThumbFunc(&Sym)) 1390b57cec5SDimitry Andric return false; 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric ThumbFuncs.insert(Symbol); // Cache it. 1420b57cec5SDimitry Andric return true; 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric 1450fca6ea1SDimitry Andric bool MCAssembler::evaluateFixup(const MCFixup &Fixup, const MCFragment *DF, 1460fca6ea1SDimitry Andric MCValue &Target, const MCSubtargetInfo *STI, 1470fca6ea1SDimitry Andric uint64_t &Value, bool &WasForced) const { 1480b57cec5SDimitry Andric ++stats::evaluateFixup; 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric // FIXME: This code has some duplication with recordRelocation. We should 1510b57cec5SDimitry Andric // probably merge the two into a single callback that tries to evaluate a 1520b57cec5SDimitry Andric // fixup and records a relocation if one is needed. 1530b57cec5SDimitry Andric 1540b57cec5SDimitry Andric // On error claim to have completely evaluated the fixup, to prevent any 1550b57cec5SDimitry Andric // further processing from being done. 1560b57cec5SDimitry Andric const MCExpr *Expr = Fixup.getValue(); 1570b57cec5SDimitry Andric MCContext &Ctx = getContext(); 1580b57cec5SDimitry Andric Value = 0; 1590b57cec5SDimitry Andric WasForced = false; 1600fca6ea1SDimitry Andric if (!Expr->evaluateAsRelocatable(Target, this, &Fixup)) { 1610b57cec5SDimitry Andric Ctx.reportError(Fixup.getLoc(), "expected relocatable expression"); 1620b57cec5SDimitry Andric return true; 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 1650b57cec5SDimitry Andric if (RefB->getKind() != MCSymbolRefExpr::VK_None) { 1660b57cec5SDimitry Andric Ctx.reportError(Fixup.getLoc(), 1670b57cec5SDimitry Andric "unsupported subtraction of qualified symbol"); 1680b57cec5SDimitry Andric return true; 1690b57cec5SDimitry Andric } 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric assert(getBackendPtr() && "Expected assembler backend"); 17355e4f9d5SDimitry Andric bool IsTarget = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags & 17455e4f9d5SDimitry Andric MCFixupKindInfo::FKF_IsTarget; 17555e4f9d5SDimitry Andric 17655e4f9d5SDimitry Andric if (IsTarget) 1770fca6ea1SDimitry Andric return getBackend().evaluateTargetFixup(*this, Fixup, DF, Target, STI, 1780fca6ea1SDimitry Andric Value, WasForced); 17955e4f9d5SDimitry Andric 18021054a9bSDimitry Andric unsigned FixupFlags = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags; 1810b57cec5SDimitry Andric bool IsPCRel = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags & 1820b57cec5SDimitry Andric MCFixupKindInfo::FKF_IsPCRel; 1830b57cec5SDimitry Andric 1840b57cec5SDimitry Andric bool IsResolved = false; 1850b57cec5SDimitry Andric if (IsPCRel) { 1860b57cec5SDimitry Andric if (Target.getSymB()) { 1870b57cec5SDimitry Andric IsResolved = false; 1880b57cec5SDimitry Andric } else if (!Target.getSymA()) { 1890b57cec5SDimitry Andric IsResolved = false; 1900b57cec5SDimitry Andric } else { 1910b57cec5SDimitry Andric const MCSymbolRefExpr *A = Target.getSymA(); 1920b57cec5SDimitry Andric const MCSymbol &SA = A->getSymbol(); 1930b57cec5SDimitry Andric if (A->getKind() != MCSymbolRefExpr::VK_None || SA.isUndefined()) { 1940b57cec5SDimitry Andric IsResolved = false; 1950fca6ea1SDimitry Andric } else { 19621054a9bSDimitry Andric IsResolved = (FixupFlags & MCFixupKindInfo::FKF_Constant) || 1970fca6ea1SDimitry Andric getWriter().isSymbolRefDifferenceFullyResolvedImpl( 1980b57cec5SDimitry Andric *this, SA, *DF, false, true); 1990b57cec5SDimitry Andric } 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric } else { 2020b57cec5SDimitry Andric IsResolved = Target.isAbsolute(); 2030b57cec5SDimitry Andric } 2040b57cec5SDimitry Andric 2050b57cec5SDimitry Andric Value = Target.getConstant(); 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric if (const MCSymbolRefExpr *A = Target.getSymA()) { 2080b57cec5SDimitry Andric const MCSymbol &Sym = A->getSymbol(); 2090b57cec5SDimitry Andric if (Sym.isDefined()) 2100fca6ea1SDimitry Andric Value += getSymbolOffset(Sym); 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric if (const MCSymbolRefExpr *B = Target.getSymB()) { 2130b57cec5SDimitry Andric const MCSymbol &Sym = B->getSymbol(); 2140b57cec5SDimitry Andric if (Sym.isDefined()) 2150fca6ea1SDimitry Andric Value -= getSymbolOffset(Sym); 2160b57cec5SDimitry Andric } 2170b57cec5SDimitry Andric 2180b57cec5SDimitry Andric bool ShouldAlignPC = getBackend().getFixupKindInfo(Fixup.getKind()).Flags & 2190b57cec5SDimitry Andric MCFixupKindInfo::FKF_IsAlignedDownTo32Bits; 2200b57cec5SDimitry Andric assert((ShouldAlignPC ? IsPCRel : true) && 2210b57cec5SDimitry Andric "FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!"); 2220b57cec5SDimitry Andric 2230b57cec5SDimitry Andric if (IsPCRel) { 2240fca6ea1SDimitry Andric uint64_t Offset = getFragmentOffset(*DF) + Fixup.getOffset(); 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric // A number of ARM fixups in Thumb mode require that the effective PC 2270b57cec5SDimitry Andric // address be determined as the 32-bit aligned version of the actual offset. 2280b57cec5SDimitry Andric if (ShouldAlignPC) Offset &= ~0x3; 2290b57cec5SDimitry Andric Value -= Offset; 2300b57cec5SDimitry Andric } 2310b57cec5SDimitry Andric 2320b57cec5SDimitry Andric // Let the backend force a relocation if needed. 2335f757f3fSDimitry Andric if (IsResolved && 2345f757f3fSDimitry Andric getBackend().shouldForceRelocation(*this, Fixup, Target, STI)) { 2350b57cec5SDimitry Andric IsResolved = false; 2360b57cec5SDimitry Andric WasForced = true; 2370b57cec5SDimitry Andric } 2380b57cec5SDimitry Andric 23906c3fb27SDimitry Andric // A linker relaxation target may emit ADD/SUB relocations for A-B+C. Let 24006c3fb27SDimitry Andric // recordRelocation handle non-VK_None cases like A@plt-B+C. 24106c3fb27SDimitry Andric if (!IsResolved && Target.getSymA() && Target.getSymB() && 24206c3fb27SDimitry Andric Target.getSymA()->getKind() == MCSymbolRefExpr::VK_None && 2430fca6ea1SDimitry Andric getBackend().handleAddSubRelocations(*this, *DF, Fixup, Target, Value)) 24406c3fb27SDimitry Andric return true; 24506c3fb27SDimitry Andric 2460b57cec5SDimitry Andric return IsResolved; 2470b57cec5SDimitry Andric } 2480b57cec5SDimitry Andric 2490fca6ea1SDimitry Andric uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const { 2500b57cec5SDimitry Andric assert(getBackendPtr() && "Requires assembler backend"); 2510b57cec5SDimitry Andric switch (F.getKind()) { 2520b57cec5SDimitry Andric case MCFragment::FT_Data: 2530b57cec5SDimitry Andric return cast<MCDataFragment>(F).getContents().size(); 2540b57cec5SDimitry Andric case MCFragment::FT_Relaxable: 2550b57cec5SDimitry Andric return cast<MCRelaxableFragment>(F).getContents().size(); 2560b57cec5SDimitry Andric case MCFragment::FT_CompactEncodedInst: 2570b57cec5SDimitry Andric return cast<MCCompactEncodedInstFragment>(F).getContents().size(); 2580b57cec5SDimitry Andric case MCFragment::FT_Fill: { 2590b57cec5SDimitry Andric auto &FF = cast<MCFillFragment>(F); 2600b57cec5SDimitry Andric int64_t NumValues = 0; 2610fca6ea1SDimitry Andric if (!FF.getNumValues().evaluateKnownAbsolute(NumValues, *this)) { 2620b57cec5SDimitry Andric getContext().reportError(FF.getLoc(), 2630b57cec5SDimitry Andric "expected assembly-time absolute expression"); 2640b57cec5SDimitry Andric return 0; 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric int64_t Size = NumValues * FF.getValueSize(); 2670b57cec5SDimitry Andric if (Size < 0) { 2680b57cec5SDimitry Andric getContext().reportError(FF.getLoc(), "invalid number of bytes"); 2690b57cec5SDimitry Andric return 0; 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric return Size; 2720b57cec5SDimitry Andric } 2730b57cec5SDimitry Andric 274e8d8bef9SDimitry Andric case MCFragment::FT_Nops: 275e8d8bef9SDimitry Andric return cast<MCNopsFragment>(F).getNumBytes(); 276e8d8bef9SDimitry Andric 2770b57cec5SDimitry Andric case MCFragment::FT_LEB: 2780b57cec5SDimitry Andric return cast<MCLEBFragment>(F).getContents().size(); 2790b57cec5SDimitry Andric 280480093f4SDimitry Andric case MCFragment::FT_BoundaryAlign: 281480093f4SDimitry Andric return cast<MCBoundaryAlignFragment>(F).getSize(); 2820b57cec5SDimitry Andric 2830b57cec5SDimitry Andric case MCFragment::FT_SymbolId: 2840b57cec5SDimitry Andric return 4; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric case MCFragment::FT_Align: { 2870b57cec5SDimitry Andric const MCAlignFragment &AF = cast<MCAlignFragment>(F); 2880fca6ea1SDimitry Andric unsigned Offset = getFragmentOffset(AF); 28981ad6265SDimitry Andric unsigned Size = offsetToAlignment(Offset, AF.getAlignment()); 2900b57cec5SDimitry Andric 2910b57cec5SDimitry Andric // Insert extra Nops for code alignment if the target define 2920b57cec5SDimitry Andric // shouldInsertExtraNopBytesForCodeAlign target hook. 29381ad6265SDimitry Andric if (AF.getParent()->useCodeAlign() && AF.hasEmitNops() && 2940b57cec5SDimitry Andric getBackend().shouldInsertExtraNopBytesForCodeAlign(AF, Size)) 2950b57cec5SDimitry Andric return Size; 2960b57cec5SDimitry Andric 2970b57cec5SDimitry Andric // If we are padding with nops, force the padding to be larger than the 2980b57cec5SDimitry Andric // minimum nop size. 2990b57cec5SDimitry Andric if (Size > 0 && AF.hasEmitNops()) { 3000b57cec5SDimitry Andric while (Size % getBackend().getMinimumNopSize()) 30181ad6265SDimitry Andric Size += AF.getAlignment().value(); 3020b57cec5SDimitry Andric } 3030b57cec5SDimitry Andric if (Size > AF.getMaxBytesToEmit()) 3040b57cec5SDimitry Andric return 0; 3050b57cec5SDimitry Andric return Size; 3060b57cec5SDimitry Andric } 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric case MCFragment::FT_Org: { 3090b57cec5SDimitry Andric const MCOrgFragment &OF = cast<MCOrgFragment>(F); 3100b57cec5SDimitry Andric MCValue Value; 3110fca6ea1SDimitry Andric if (!OF.getOffset().evaluateAsValue(Value, *this)) { 3120b57cec5SDimitry Andric getContext().reportError(OF.getLoc(), 3130b57cec5SDimitry Andric "expected assembly-time absolute expression"); 3140b57cec5SDimitry Andric return 0; 3150b57cec5SDimitry Andric } 3160b57cec5SDimitry Andric 3170fca6ea1SDimitry Andric uint64_t FragmentOffset = getFragmentOffset(OF); 3180b57cec5SDimitry Andric int64_t TargetLocation = Value.getConstant(); 3190b57cec5SDimitry Andric if (const MCSymbolRefExpr *A = Value.getSymA()) { 3200b57cec5SDimitry Andric uint64_t Val; 3210fca6ea1SDimitry Andric if (!getSymbolOffset(A->getSymbol(), Val)) { 3220b57cec5SDimitry Andric getContext().reportError(OF.getLoc(), "expected absolute expression"); 3230b57cec5SDimitry Andric return 0; 3240b57cec5SDimitry Andric } 3250b57cec5SDimitry Andric TargetLocation += Val; 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric int64_t Size = TargetLocation - FragmentOffset; 3280b57cec5SDimitry Andric if (Size < 0 || Size >= 0x40000000) { 3290b57cec5SDimitry Andric getContext().reportError( 3300b57cec5SDimitry Andric OF.getLoc(), "invalid .org offset '" + Twine(TargetLocation) + 3310b57cec5SDimitry Andric "' (at offset '" + Twine(FragmentOffset) + "')"); 3320b57cec5SDimitry Andric return 0; 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric return Size; 3350b57cec5SDimitry Andric } 3360b57cec5SDimitry Andric 3370b57cec5SDimitry Andric case MCFragment::FT_Dwarf: 3380b57cec5SDimitry Andric return cast<MCDwarfLineAddrFragment>(F).getContents().size(); 3390b57cec5SDimitry Andric case MCFragment::FT_DwarfFrame: 3400b57cec5SDimitry Andric return cast<MCDwarfCallFrameFragment>(F).getContents().size(); 3410b57cec5SDimitry Andric case MCFragment::FT_CVInlineLines: 3420b57cec5SDimitry Andric return cast<MCCVInlineLineTableFragment>(F).getContents().size(); 3430b57cec5SDimitry Andric case MCFragment::FT_CVDefRange: 3440b57cec5SDimitry Andric return cast<MCCVDefRangeFragment>(F).getContents().size(); 345e8d8bef9SDimitry Andric case MCFragment::FT_PseudoProbe: 346e8d8bef9SDimitry Andric return cast<MCPseudoProbeAddrFragment>(F).getContents().size(); 3470b57cec5SDimitry Andric case MCFragment::FT_Dummy: 3480b57cec5SDimitry Andric llvm_unreachable("Should not have been added"); 3490b57cec5SDimitry Andric } 3500b57cec5SDimitry Andric 3510b57cec5SDimitry Andric llvm_unreachable("invalid fragment kind"); 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric 3540fca6ea1SDimitry Andric // Compute the amount of padding required before the fragment \p F to 3550fca6ea1SDimitry Andric // obey bundling restrictions, where \p FOffset is the fragment's offset in 3560fca6ea1SDimitry Andric // its section and \p FSize is the fragment's size. 3570fca6ea1SDimitry Andric static uint64_t computeBundlePadding(unsigned BundleSize, 3580fca6ea1SDimitry Andric const MCEncodedFragment *F, 3590fca6ea1SDimitry Andric uint64_t FOffset, uint64_t FSize) { 3600fca6ea1SDimitry Andric uint64_t OffsetInBundle = FOffset & (BundleSize - 1); 3610fca6ea1SDimitry Andric uint64_t EndOfFragment = OffsetInBundle + FSize; 3620b57cec5SDimitry Andric 3630fca6ea1SDimitry Andric // There are two kinds of bundling restrictions: 3640fca6ea1SDimitry Andric // 3650fca6ea1SDimitry Andric // 1) For alignToBundleEnd(), add padding to ensure that the fragment will 3660fca6ea1SDimitry Andric // *end* on a bundle boundary. 3670fca6ea1SDimitry Andric // 2) Otherwise, check if the fragment would cross a bundle boundary. If it 3680fca6ea1SDimitry Andric // would, add padding until the end of the bundle so that the fragment 3690fca6ea1SDimitry Andric // will start in a new one. 3700fca6ea1SDimitry Andric if (F->alignToBundleEnd()) { 3710fca6ea1SDimitry Andric // Three possibilities here: 3720fca6ea1SDimitry Andric // 3730fca6ea1SDimitry Andric // A) The fragment just happens to end at a bundle boundary, so we're good. 3740fca6ea1SDimitry Andric // B) The fragment ends before the current bundle boundary: pad it just 3750fca6ea1SDimitry Andric // enough to reach the boundary. 3760fca6ea1SDimitry Andric // C) The fragment ends after the current bundle boundary: pad it until it 3770fca6ea1SDimitry Andric // reaches the end of the next bundle boundary. 3780fca6ea1SDimitry Andric // 3790fca6ea1SDimitry Andric // Note: this code could be made shorter with some modulo trickery, but it's 3800fca6ea1SDimitry Andric // intentionally kept in its more explicit form for simplicity. 3810fca6ea1SDimitry Andric if (EndOfFragment == BundleSize) 3820fca6ea1SDimitry Andric return 0; 3830fca6ea1SDimitry Andric else if (EndOfFragment < BundleSize) 3840fca6ea1SDimitry Andric return BundleSize - EndOfFragment; 3850fca6ea1SDimitry Andric else { // EndOfFragment > BundleSize 3860fca6ea1SDimitry Andric return 2 * BundleSize - EndOfFragment; 3870fca6ea1SDimitry Andric } 3880fca6ea1SDimitry Andric } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize) 3890fca6ea1SDimitry Andric return BundleSize - OffsetInBundle; 3900b57cec5SDimitry Andric else 3910fca6ea1SDimitry Andric return 0; 3920fca6ea1SDimitry Andric } 3930b57cec5SDimitry Andric 3940fca6ea1SDimitry Andric void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const { 3950b57cec5SDimitry Andric // If bundling is enabled and this fragment has instructions in it, it has to 3960b57cec5SDimitry Andric // obey the bundling restrictions. With padding, we'll have: 3970b57cec5SDimitry Andric // 3980b57cec5SDimitry Andric // 3990b57cec5SDimitry Andric // BundlePadding 4000b57cec5SDimitry Andric // ||| 4010b57cec5SDimitry Andric // ------------------------------------- 4020b57cec5SDimitry Andric // Prev |##########| F | 4030b57cec5SDimitry Andric // ------------------------------------- 4040b57cec5SDimitry Andric // ^ 4050b57cec5SDimitry Andric // | 4060b57cec5SDimitry Andric // F->Offset 4070b57cec5SDimitry Andric // 4080b57cec5SDimitry Andric // The fragment's offset will point to after the padding, and its computed 4090b57cec5SDimitry Andric // size won't include the padding. 4100b57cec5SDimitry Andric // 4110b57cec5SDimitry Andric // ".align N" is an example of a directive that introduces multiple 4120b57cec5SDimitry Andric // fragments. We could add a special case to handle ".align N" by emitting 4130b57cec5SDimitry Andric // within-fragment padding (which would produce less padding when N is less 4140b57cec5SDimitry Andric // than the bundle size), but for now we don't. 4150b57cec5SDimitry Andric // 4160b57cec5SDimitry Andric assert(isa<MCEncodedFragment>(F) && 4170b57cec5SDimitry Andric "Only MCEncodedFragment implementations have instructions"); 4180b57cec5SDimitry Andric MCEncodedFragment *EF = cast<MCEncodedFragment>(F); 4190fca6ea1SDimitry Andric uint64_t FSize = computeFragmentSize(*EF); 4200b57cec5SDimitry Andric 4210fca6ea1SDimitry Andric if (FSize > getBundleAlignSize()) 4220b57cec5SDimitry Andric report_fatal_error("Fragment can't be larger than a bundle size"); 4230b57cec5SDimitry Andric 4240b57cec5SDimitry Andric uint64_t RequiredBundlePadding = 4250fca6ea1SDimitry Andric computeBundlePadding(getBundleAlignSize(), EF, EF->Offset, FSize); 4260b57cec5SDimitry Andric if (RequiredBundlePadding > UINT8_MAX) 4270b57cec5SDimitry Andric report_fatal_error("Padding cannot exceed 255 bytes"); 4280b57cec5SDimitry Andric EF->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding)); 4290b57cec5SDimitry Andric EF->Offset += RequiredBundlePadding; 4300fca6ea1SDimitry Andric if (auto *DF = dyn_cast_or_null<MCDataFragment>(Prev)) 4310fca6ea1SDimitry Andric if (DF->getContents().empty()) 4320fca6ea1SDimitry Andric DF->Offset = EF->Offset; 4330b57cec5SDimitry Andric } 4340fca6ea1SDimitry Andric 435*52418fc2SDimitry Andric void MCAssembler::ensureValid(MCSection &Sec) const { 436*52418fc2SDimitry Andric if (Sec.hasLayout()) 437*52418fc2SDimitry Andric return; 438*52418fc2SDimitry Andric Sec.setHasLayout(true); 439*52418fc2SDimitry Andric MCFragment *Prev = nullptr; 440*52418fc2SDimitry Andric uint64_t Offset = 0; 441*52418fc2SDimitry Andric for (MCFragment &F : Sec) { 442*52418fc2SDimitry Andric F.Offset = Offset; 443*52418fc2SDimitry Andric if (isBundlingEnabled() && F.hasInstructions()) { 444*52418fc2SDimitry Andric layoutBundle(Prev, &F); 445*52418fc2SDimitry Andric Offset = F.Offset; 446*52418fc2SDimitry Andric } 447*52418fc2SDimitry Andric Offset += computeFragmentSize(F); 448*52418fc2SDimitry Andric Prev = &F; 449*52418fc2SDimitry Andric } 450*52418fc2SDimitry Andric } 451*52418fc2SDimitry Andric 452*52418fc2SDimitry Andric uint64_t MCAssembler::getFragmentOffset(const MCFragment &F) const { 453*52418fc2SDimitry Andric ensureValid(*F.getParent()); 454*52418fc2SDimitry Andric return F.Offset; 455*52418fc2SDimitry Andric } 456*52418fc2SDimitry Andric 4570fca6ea1SDimitry Andric // Simple getSymbolOffset helper for the non-variable case. 4580fca6ea1SDimitry Andric static bool getLabelOffset(const MCAssembler &Asm, const MCSymbol &S, 4590fca6ea1SDimitry Andric bool ReportError, uint64_t &Val) { 4600fca6ea1SDimitry Andric if (!S.getFragment()) { 4610fca6ea1SDimitry Andric if (ReportError) 4620fca6ea1SDimitry Andric report_fatal_error("unable to evaluate offset to undefined symbol '" + 4630fca6ea1SDimitry Andric S.getName() + "'"); 4640fca6ea1SDimitry Andric return false; 4650fca6ea1SDimitry Andric } 4660fca6ea1SDimitry Andric Val = Asm.getFragmentOffset(*S.getFragment()) + S.getOffset(); 4670fca6ea1SDimitry Andric return true; 4680fca6ea1SDimitry Andric } 4690fca6ea1SDimitry Andric 4700fca6ea1SDimitry Andric static bool getSymbolOffsetImpl(const MCAssembler &Asm, const MCSymbol &S, 4710fca6ea1SDimitry Andric bool ReportError, uint64_t &Val) { 4720fca6ea1SDimitry Andric if (!S.isVariable()) 4730fca6ea1SDimitry Andric return getLabelOffset(Asm, S, ReportError, Val); 4740fca6ea1SDimitry Andric 4750fca6ea1SDimitry Andric // If SD is a variable, evaluate it. 4760fca6ea1SDimitry Andric MCValue Target; 4770fca6ea1SDimitry Andric if (!S.getVariableValue()->evaluateAsValue(Target, Asm)) 4780fca6ea1SDimitry Andric report_fatal_error("unable to evaluate offset for variable '" + 4790fca6ea1SDimitry Andric S.getName() + "'"); 4800fca6ea1SDimitry Andric 4810fca6ea1SDimitry Andric uint64_t Offset = Target.getConstant(); 4820fca6ea1SDimitry Andric 4830fca6ea1SDimitry Andric const MCSymbolRefExpr *A = Target.getSymA(); 4840fca6ea1SDimitry Andric if (A) { 4850fca6ea1SDimitry Andric uint64_t ValA; 4860fca6ea1SDimitry Andric // FIXME: On most platforms, `Target`'s component symbols are labels from 4870fca6ea1SDimitry Andric // having been simplified during evaluation, but on Mach-O they can be 4880fca6ea1SDimitry Andric // variables due to PR19203. This, and the line below for `B` can be 4890fca6ea1SDimitry Andric // restored to call `getLabelOffset` when PR19203 is fixed. 4900fca6ea1SDimitry Andric if (!getSymbolOffsetImpl(Asm, A->getSymbol(), ReportError, ValA)) 4910fca6ea1SDimitry Andric return false; 4920fca6ea1SDimitry Andric Offset += ValA; 4930fca6ea1SDimitry Andric } 4940fca6ea1SDimitry Andric 4950fca6ea1SDimitry Andric const MCSymbolRefExpr *B = Target.getSymB(); 4960fca6ea1SDimitry Andric if (B) { 4970fca6ea1SDimitry Andric uint64_t ValB; 4980fca6ea1SDimitry Andric if (!getSymbolOffsetImpl(Asm, B->getSymbol(), ReportError, ValB)) 4990fca6ea1SDimitry Andric return false; 5000fca6ea1SDimitry Andric Offset -= ValB; 5010fca6ea1SDimitry Andric } 5020fca6ea1SDimitry Andric 5030fca6ea1SDimitry Andric Val = Offset; 5040fca6ea1SDimitry Andric return true; 5050fca6ea1SDimitry Andric } 5060fca6ea1SDimitry Andric 5070fca6ea1SDimitry Andric bool MCAssembler::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const { 5080fca6ea1SDimitry Andric return getSymbolOffsetImpl(*this, S, false, Val); 5090fca6ea1SDimitry Andric } 5100fca6ea1SDimitry Andric 5110fca6ea1SDimitry Andric uint64_t MCAssembler::getSymbolOffset(const MCSymbol &S) const { 5120fca6ea1SDimitry Andric uint64_t Val; 5130fca6ea1SDimitry Andric getSymbolOffsetImpl(*this, S, true, Val); 5140fca6ea1SDimitry Andric return Val; 5150fca6ea1SDimitry Andric } 5160fca6ea1SDimitry Andric 5170fca6ea1SDimitry Andric const MCSymbol *MCAssembler::getBaseSymbol(const MCSymbol &Symbol) const { 5180fca6ea1SDimitry Andric assert(HasLayout); 5190fca6ea1SDimitry Andric if (!Symbol.isVariable()) 5200fca6ea1SDimitry Andric return &Symbol; 5210fca6ea1SDimitry Andric 5220fca6ea1SDimitry Andric const MCExpr *Expr = Symbol.getVariableValue(); 5230fca6ea1SDimitry Andric MCValue Value; 5240fca6ea1SDimitry Andric if (!Expr->evaluateAsValue(Value, *this)) { 5250fca6ea1SDimitry Andric getContext().reportError(Expr->getLoc(), 5260fca6ea1SDimitry Andric "expression could not be evaluated"); 5270fca6ea1SDimitry Andric return nullptr; 5280fca6ea1SDimitry Andric } 5290fca6ea1SDimitry Andric 5300fca6ea1SDimitry Andric const MCSymbolRefExpr *RefB = Value.getSymB(); 5310fca6ea1SDimitry Andric if (RefB) { 5320fca6ea1SDimitry Andric getContext().reportError( 5330fca6ea1SDimitry Andric Expr->getLoc(), 5340fca6ea1SDimitry Andric Twine("symbol '") + RefB->getSymbol().getName() + 5350fca6ea1SDimitry Andric "' could not be evaluated in a subtraction expression"); 5360fca6ea1SDimitry Andric return nullptr; 5370fca6ea1SDimitry Andric } 5380fca6ea1SDimitry Andric 5390fca6ea1SDimitry Andric const MCSymbolRefExpr *A = Value.getSymA(); 5400fca6ea1SDimitry Andric if (!A) 5410fca6ea1SDimitry Andric return nullptr; 5420fca6ea1SDimitry Andric 5430fca6ea1SDimitry Andric const MCSymbol &ASym = A->getSymbol(); 5440fca6ea1SDimitry Andric if (ASym.isCommon()) { 5450fca6ea1SDimitry Andric getContext().reportError(Expr->getLoc(), 5460fca6ea1SDimitry Andric "Common symbol '" + ASym.getName() + 5470fca6ea1SDimitry Andric "' cannot be used in assignment expr"); 5480fca6ea1SDimitry Andric return nullptr; 5490fca6ea1SDimitry Andric } 5500fca6ea1SDimitry Andric 5510fca6ea1SDimitry Andric return &ASym; 5520fca6ea1SDimitry Andric } 5530fca6ea1SDimitry Andric 5540fca6ea1SDimitry Andric uint64_t MCAssembler::getSectionAddressSize(const MCSection &Sec) const { 5550fca6ea1SDimitry Andric assert(HasLayout); 5560fca6ea1SDimitry Andric // The size is the last fragment's end offset. 5570fca6ea1SDimitry Andric const MCFragment &F = *Sec.curFragList()->Tail; 5580fca6ea1SDimitry Andric return getFragmentOffset(F) + computeFragmentSize(F); 5590fca6ea1SDimitry Andric } 5600fca6ea1SDimitry Andric 5610fca6ea1SDimitry Andric uint64_t MCAssembler::getSectionFileSize(const MCSection &Sec) const { 5620fca6ea1SDimitry Andric // Virtual sections have no file size. 5630fca6ea1SDimitry Andric if (Sec.isVirtualSection()) 5640fca6ea1SDimitry Andric return 0; 5650fca6ea1SDimitry Andric return getSectionAddressSize(Sec); 5660b57cec5SDimitry Andric } 5670b57cec5SDimitry Andric 56806c3fb27SDimitry Andric bool MCAssembler::registerSymbol(const MCSymbol &Symbol) { 56906c3fb27SDimitry Andric bool Changed = !Symbol.isRegistered(); 57006c3fb27SDimitry Andric if (Changed) { 5710b57cec5SDimitry Andric Symbol.setIsRegistered(true); 5720b57cec5SDimitry Andric Symbols.push_back(&Symbol); 5730b57cec5SDimitry Andric } 57406c3fb27SDimitry Andric return Changed; 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric void MCAssembler::writeFragmentPadding(raw_ostream &OS, 5780b57cec5SDimitry Andric const MCEncodedFragment &EF, 5790b57cec5SDimitry Andric uint64_t FSize) const { 5800b57cec5SDimitry Andric assert(getBackendPtr() && "Expected assembler backend"); 5810b57cec5SDimitry Andric // Should NOP padding be written out before this fragment? 5820b57cec5SDimitry Andric unsigned BundlePadding = EF.getBundlePadding(); 5830b57cec5SDimitry Andric if (BundlePadding > 0) { 5840b57cec5SDimitry Andric assert(isBundlingEnabled() && 5850b57cec5SDimitry Andric "Writing bundle padding with disabled bundling"); 5860b57cec5SDimitry Andric assert(EF.hasInstructions() && 5870b57cec5SDimitry Andric "Writing bundle padding for a fragment without instructions"); 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize); 590349cc55cSDimitry Andric const MCSubtargetInfo *STI = EF.getSubtargetInfo(); 5910b57cec5SDimitry Andric if (EF.alignToBundleEnd() && TotalLength > getBundleAlignSize()) { 5920b57cec5SDimitry Andric // If the padding itself crosses a bundle boundary, it must be emitted 5930b57cec5SDimitry Andric // in 2 pieces, since even nop instructions must not cross boundaries. 5940b57cec5SDimitry Andric // v--------------v <- BundleAlignSize 5950b57cec5SDimitry Andric // v---------v <- BundlePadding 5960b57cec5SDimitry Andric // ---------------------------- 5970b57cec5SDimitry Andric // | Prev |####|####| F | 5980b57cec5SDimitry Andric // ---------------------------- 5990b57cec5SDimitry Andric // ^-------------------^ <- TotalLength 6000b57cec5SDimitry Andric unsigned DistanceToBoundary = TotalLength - getBundleAlignSize(); 601349cc55cSDimitry Andric if (!getBackend().writeNopData(OS, DistanceToBoundary, STI)) 6020b57cec5SDimitry Andric report_fatal_error("unable to write NOP sequence of " + 6030b57cec5SDimitry Andric Twine(DistanceToBoundary) + " bytes"); 6040b57cec5SDimitry Andric BundlePadding -= DistanceToBoundary; 6050b57cec5SDimitry Andric } 606349cc55cSDimitry Andric if (!getBackend().writeNopData(OS, BundlePadding, STI)) 6070b57cec5SDimitry Andric report_fatal_error("unable to write NOP sequence of " + 6080b57cec5SDimitry Andric Twine(BundlePadding) + " bytes"); 6090b57cec5SDimitry Andric } 6100b57cec5SDimitry Andric } 6110b57cec5SDimitry Andric 6120b57cec5SDimitry Andric /// Write the fragment \p F to the output file. 6130b57cec5SDimitry Andric static void writeFragment(raw_ostream &OS, const MCAssembler &Asm, 6140fca6ea1SDimitry Andric const MCFragment &F) { 6150b57cec5SDimitry Andric // FIXME: Embed in fragments instead? 6160fca6ea1SDimitry Andric uint64_t FragmentSize = Asm.computeFragmentSize(F); 6170b57cec5SDimitry Andric 6185f757f3fSDimitry Andric llvm::endianness Endian = Asm.getBackend().Endian; 6190b57cec5SDimitry Andric 6200b57cec5SDimitry Andric if (const MCEncodedFragment *EF = dyn_cast<MCEncodedFragment>(&F)) 6210b57cec5SDimitry Andric Asm.writeFragmentPadding(OS, *EF, FragmentSize); 6220b57cec5SDimitry Andric 6230b57cec5SDimitry Andric // This variable (and its dummy usage) is to participate in the assert at 6240b57cec5SDimitry Andric // the end of the function. 6250b57cec5SDimitry Andric uint64_t Start = OS.tell(); 6260b57cec5SDimitry Andric (void) Start; 6270b57cec5SDimitry Andric 6280b57cec5SDimitry Andric ++stats::EmittedFragments; 6290b57cec5SDimitry Andric 6300b57cec5SDimitry Andric switch (F.getKind()) { 6310b57cec5SDimitry Andric case MCFragment::FT_Align: { 6320b57cec5SDimitry Andric ++stats::EmittedAlignFragments; 6330b57cec5SDimitry Andric const MCAlignFragment &AF = cast<MCAlignFragment>(F); 6340b57cec5SDimitry Andric assert(AF.getValueSize() && "Invalid virtual align in concrete fragment!"); 6350b57cec5SDimitry Andric 6360b57cec5SDimitry Andric uint64_t Count = FragmentSize / AF.getValueSize(); 6370b57cec5SDimitry Andric 6380b57cec5SDimitry Andric // FIXME: This error shouldn't actually occur (the front end should emit 6390b57cec5SDimitry Andric // multiple .align directives to enforce the semantics it wants), but is 6400b57cec5SDimitry Andric // severe enough that we want to report it. How to handle this? 6410b57cec5SDimitry Andric if (Count * AF.getValueSize() != FragmentSize) 6420b57cec5SDimitry Andric report_fatal_error("undefined .align directive, value size '" + 6430b57cec5SDimitry Andric Twine(AF.getValueSize()) + 6440b57cec5SDimitry Andric "' is not a divisor of padding size '" + 6450b57cec5SDimitry Andric Twine(FragmentSize) + "'"); 6460b57cec5SDimitry Andric 6470b57cec5SDimitry Andric // See if we are aligning with nops, and if so do that first to try to fill 6480b57cec5SDimitry Andric // the Count bytes. Then if that did not fill any bytes or there are any 6490b57cec5SDimitry Andric // bytes left to fill use the Value and ValueSize to fill the rest. 6500b57cec5SDimitry Andric // If we are aligning with nops, ask that target to emit the right data. 6510b57cec5SDimitry Andric if (AF.hasEmitNops()) { 652349cc55cSDimitry Andric if (!Asm.getBackend().writeNopData(OS, Count, AF.getSubtargetInfo())) 6530b57cec5SDimitry Andric report_fatal_error("unable to write nop sequence of " + 6540b57cec5SDimitry Andric Twine(Count) + " bytes"); 6550b57cec5SDimitry Andric break; 6560b57cec5SDimitry Andric } 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric // Otherwise, write out in multiples of the value size. 6590b57cec5SDimitry Andric for (uint64_t i = 0; i != Count; ++i) { 6600b57cec5SDimitry Andric switch (AF.getValueSize()) { 6610b57cec5SDimitry Andric default: llvm_unreachable("Invalid size!"); 6620b57cec5SDimitry Andric case 1: OS << char(AF.getValue()); break; 6630b57cec5SDimitry Andric case 2: 6640b57cec5SDimitry Andric support::endian::write<uint16_t>(OS, AF.getValue(), Endian); 6650b57cec5SDimitry Andric break; 6660b57cec5SDimitry Andric case 4: 6670b57cec5SDimitry Andric support::endian::write<uint32_t>(OS, AF.getValue(), Endian); 6680b57cec5SDimitry Andric break; 6690b57cec5SDimitry Andric case 8: 6700b57cec5SDimitry Andric support::endian::write<uint64_t>(OS, AF.getValue(), Endian); 6710b57cec5SDimitry Andric break; 6720b57cec5SDimitry Andric } 6730b57cec5SDimitry Andric } 6740b57cec5SDimitry Andric break; 6750b57cec5SDimitry Andric } 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric case MCFragment::FT_Data: 6780b57cec5SDimitry Andric ++stats::EmittedDataFragments; 6790b57cec5SDimitry Andric OS << cast<MCDataFragment>(F).getContents(); 6800b57cec5SDimitry Andric break; 6810b57cec5SDimitry Andric 6820b57cec5SDimitry Andric case MCFragment::FT_Relaxable: 6830b57cec5SDimitry Andric ++stats::EmittedRelaxableFragments; 6840b57cec5SDimitry Andric OS << cast<MCRelaxableFragment>(F).getContents(); 6850b57cec5SDimitry Andric break; 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric case MCFragment::FT_CompactEncodedInst: 6880b57cec5SDimitry Andric ++stats::EmittedCompactEncodedInstFragments; 6890b57cec5SDimitry Andric OS << cast<MCCompactEncodedInstFragment>(F).getContents(); 6900b57cec5SDimitry Andric break; 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric case MCFragment::FT_Fill: { 6930b57cec5SDimitry Andric ++stats::EmittedFillFragments; 6940b57cec5SDimitry Andric const MCFillFragment &FF = cast<MCFillFragment>(F); 6950b57cec5SDimitry Andric uint64_t V = FF.getValue(); 6960b57cec5SDimitry Andric unsigned VSize = FF.getValueSize(); 6970b57cec5SDimitry Andric const unsigned MaxChunkSize = 16; 6980b57cec5SDimitry Andric char Data[MaxChunkSize]; 699480093f4SDimitry Andric assert(0 < VSize && VSize <= MaxChunkSize && "Illegal fragment fill size"); 7000b57cec5SDimitry Andric // Duplicate V into Data as byte vector to reduce number of 7010b57cec5SDimitry Andric // writes done. As such, do endian conversion here. 7020b57cec5SDimitry Andric for (unsigned I = 0; I != VSize; ++I) { 7035f757f3fSDimitry Andric unsigned index = Endian == llvm::endianness::little ? I : (VSize - I - 1); 7040b57cec5SDimitry Andric Data[I] = uint8_t(V >> (index * 8)); 7050b57cec5SDimitry Andric } 7060b57cec5SDimitry Andric for (unsigned I = VSize; I < MaxChunkSize; ++I) 7070b57cec5SDimitry Andric Data[I] = Data[I - VSize]; 7080b57cec5SDimitry Andric 7090b57cec5SDimitry Andric // Set to largest multiple of VSize in Data. 7100b57cec5SDimitry Andric const unsigned NumPerChunk = MaxChunkSize / VSize; 7110b57cec5SDimitry Andric // Set ChunkSize to largest multiple of VSize in Data 7120b57cec5SDimitry Andric const unsigned ChunkSize = VSize * NumPerChunk; 7130b57cec5SDimitry Andric 7140b57cec5SDimitry Andric // Do copies by chunk. 7150b57cec5SDimitry Andric StringRef Ref(Data, ChunkSize); 7160b57cec5SDimitry Andric for (uint64_t I = 0, E = FragmentSize / ChunkSize; I != E; ++I) 7170b57cec5SDimitry Andric OS << Ref; 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric // do remainder if needed. 7200b57cec5SDimitry Andric unsigned TrailingCount = FragmentSize % ChunkSize; 7210b57cec5SDimitry Andric if (TrailingCount) 7220b57cec5SDimitry Andric OS.write(Data, TrailingCount); 7230b57cec5SDimitry Andric break; 7240b57cec5SDimitry Andric } 7250b57cec5SDimitry Andric 726e8d8bef9SDimitry Andric case MCFragment::FT_Nops: { 727e8d8bef9SDimitry Andric ++stats::EmittedNopsFragments; 728e8d8bef9SDimitry Andric const MCNopsFragment &NF = cast<MCNopsFragment>(F); 729349cc55cSDimitry Andric 730e8d8bef9SDimitry Andric int64_t NumBytes = NF.getNumBytes(); 731e8d8bef9SDimitry Andric int64_t ControlledNopLength = NF.getControlledNopLength(); 732349cc55cSDimitry Andric int64_t MaximumNopLength = 733349cc55cSDimitry Andric Asm.getBackend().getMaximumNopSize(*NF.getSubtargetInfo()); 734e8d8bef9SDimitry Andric 735e8d8bef9SDimitry Andric assert(NumBytes > 0 && "Expected positive NOPs fragment size"); 736e8d8bef9SDimitry Andric assert(ControlledNopLength >= 0 && "Expected non-negative NOP size"); 737e8d8bef9SDimitry Andric 738e8d8bef9SDimitry Andric if (ControlledNopLength > MaximumNopLength) { 739e8d8bef9SDimitry Andric Asm.getContext().reportError(NF.getLoc(), 740e8d8bef9SDimitry Andric "illegal NOP size " + 741e8d8bef9SDimitry Andric std::to_string(ControlledNopLength) + 742e8d8bef9SDimitry Andric ". (expected within [0, " + 743e8d8bef9SDimitry Andric std::to_string(MaximumNopLength) + "])"); 744e8d8bef9SDimitry Andric // Clamp the NOP length as reportError does not stop the execution 745e8d8bef9SDimitry Andric // immediately. 746e8d8bef9SDimitry Andric ControlledNopLength = MaximumNopLength; 747e8d8bef9SDimitry Andric } 748e8d8bef9SDimitry Andric 749e8d8bef9SDimitry Andric // Use maximum value if the size of each NOP is not specified 750e8d8bef9SDimitry Andric if (!ControlledNopLength) 751e8d8bef9SDimitry Andric ControlledNopLength = MaximumNopLength; 752e8d8bef9SDimitry Andric 753e8d8bef9SDimitry Andric while (NumBytes) { 754e8d8bef9SDimitry Andric uint64_t NumBytesToEmit = 755e8d8bef9SDimitry Andric (uint64_t)std::min(NumBytes, ControlledNopLength); 756e8d8bef9SDimitry Andric assert(NumBytesToEmit && "try to emit empty NOP instruction"); 757349cc55cSDimitry Andric if (!Asm.getBackend().writeNopData(OS, NumBytesToEmit, 758349cc55cSDimitry Andric NF.getSubtargetInfo())) { 759e8d8bef9SDimitry Andric report_fatal_error("unable to write nop sequence of the remaining " + 760e8d8bef9SDimitry Andric Twine(NumBytesToEmit) + " bytes"); 761e8d8bef9SDimitry Andric break; 762e8d8bef9SDimitry Andric } 763e8d8bef9SDimitry Andric NumBytes -= NumBytesToEmit; 764e8d8bef9SDimitry Andric } 765e8d8bef9SDimitry Andric break; 766e8d8bef9SDimitry Andric } 767e8d8bef9SDimitry Andric 7680b57cec5SDimitry Andric case MCFragment::FT_LEB: { 7690b57cec5SDimitry Andric const MCLEBFragment &LF = cast<MCLEBFragment>(F); 7700b57cec5SDimitry Andric OS << LF.getContents(); 7710b57cec5SDimitry Andric break; 7720b57cec5SDimitry Andric } 7730b57cec5SDimitry Andric 774480093f4SDimitry Andric case MCFragment::FT_BoundaryAlign: { 775349cc55cSDimitry Andric const MCBoundaryAlignFragment &BF = cast<MCBoundaryAlignFragment>(F); 776349cc55cSDimitry Andric if (!Asm.getBackend().writeNopData(OS, FragmentSize, BF.getSubtargetInfo())) 7770b57cec5SDimitry Andric report_fatal_error("unable to write nop sequence of " + 7780b57cec5SDimitry Andric Twine(FragmentSize) + " bytes"); 7790b57cec5SDimitry Andric break; 7800b57cec5SDimitry Andric } 7810b57cec5SDimitry Andric 7820b57cec5SDimitry Andric case MCFragment::FT_SymbolId: { 7830b57cec5SDimitry Andric const MCSymbolIdFragment &SF = cast<MCSymbolIdFragment>(F); 7840b57cec5SDimitry Andric support::endian::write<uint32_t>(OS, SF.getSymbol()->getIndex(), Endian); 7850b57cec5SDimitry Andric break; 7860b57cec5SDimitry Andric } 7870b57cec5SDimitry Andric 7880b57cec5SDimitry Andric case MCFragment::FT_Org: { 7890b57cec5SDimitry Andric ++stats::EmittedOrgFragments; 7900b57cec5SDimitry Andric const MCOrgFragment &OF = cast<MCOrgFragment>(F); 7910b57cec5SDimitry Andric 7920b57cec5SDimitry Andric for (uint64_t i = 0, e = FragmentSize; i != e; ++i) 7930b57cec5SDimitry Andric OS << char(OF.getValue()); 7940b57cec5SDimitry Andric 7950b57cec5SDimitry Andric break; 7960b57cec5SDimitry Andric } 7970b57cec5SDimitry Andric 7980b57cec5SDimitry Andric case MCFragment::FT_Dwarf: { 7990b57cec5SDimitry Andric const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F); 8000b57cec5SDimitry Andric OS << OF.getContents(); 8010b57cec5SDimitry Andric break; 8020b57cec5SDimitry Andric } 8030b57cec5SDimitry Andric case MCFragment::FT_DwarfFrame: { 8040b57cec5SDimitry Andric const MCDwarfCallFrameFragment &CF = cast<MCDwarfCallFrameFragment>(F); 8050b57cec5SDimitry Andric OS << CF.getContents(); 8060b57cec5SDimitry Andric break; 8070b57cec5SDimitry Andric } 8080b57cec5SDimitry Andric case MCFragment::FT_CVInlineLines: { 8090b57cec5SDimitry Andric const auto &OF = cast<MCCVInlineLineTableFragment>(F); 8100b57cec5SDimitry Andric OS << OF.getContents(); 8110b57cec5SDimitry Andric break; 8120b57cec5SDimitry Andric } 8130b57cec5SDimitry Andric case MCFragment::FT_CVDefRange: { 8140b57cec5SDimitry Andric const auto &DRF = cast<MCCVDefRangeFragment>(F); 8150b57cec5SDimitry Andric OS << DRF.getContents(); 8160b57cec5SDimitry Andric break; 8170b57cec5SDimitry Andric } 818e8d8bef9SDimitry Andric case MCFragment::FT_PseudoProbe: { 819e8d8bef9SDimitry Andric const MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(F); 820e8d8bef9SDimitry Andric OS << PF.getContents(); 821e8d8bef9SDimitry Andric break; 822e8d8bef9SDimitry Andric } 8230b57cec5SDimitry Andric case MCFragment::FT_Dummy: 8240b57cec5SDimitry Andric llvm_unreachable("Should not have been added"); 8250b57cec5SDimitry Andric } 8260b57cec5SDimitry Andric 8270b57cec5SDimitry Andric assert(OS.tell() - Start == FragmentSize && 8280b57cec5SDimitry Andric "The stream should advance by fragment size"); 8290b57cec5SDimitry Andric } 8300b57cec5SDimitry Andric 8310fca6ea1SDimitry Andric void MCAssembler::writeSectionData(raw_ostream &OS, 8320fca6ea1SDimitry Andric const MCSection *Sec) const { 8330b57cec5SDimitry Andric assert(getBackendPtr() && "Expected assembler backend"); 8340b57cec5SDimitry Andric 8350b57cec5SDimitry Andric // Ignore virtual sections. 8360b57cec5SDimitry Andric if (Sec->isVirtualSection()) { 8370fca6ea1SDimitry Andric assert(getSectionFileSize(*Sec) == 0 && "Invalid size for section!"); 8380b57cec5SDimitry Andric 8390b57cec5SDimitry Andric // Check that contents are only things legal inside a virtual section. 8400b57cec5SDimitry Andric for (const MCFragment &F : *Sec) { 8410b57cec5SDimitry Andric switch (F.getKind()) { 8420b57cec5SDimitry Andric default: llvm_unreachable("Invalid fragment in virtual section!"); 8430b57cec5SDimitry Andric case MCFragment::FT_Data: { 8440b57cec5SDimitry Andric // Check that we aren't trying to write a non-zero contents (or fixups) 8450b57cec5SDimitry Andric // into a virtual section. This is to support clients which use standard 8460b57cec5SDimitry Andric // directives to fill the contents of virtual sections. 8470b57cec5SDimitry Andric const MCDataFragment &DF = cast<MCDataFragment>(F); 8480b57cec5SDimitry Andric if (DF.fixup_begin() != DF.fixup_end()) 8495ffd83dbSDimitry Andric getContext().reportError(SMLoc(), Sec->getVirtualSectionKind() + 8505ffd83dbSDimitry Andric " section '" + Sec->getName() + 8515ffd83dbSDimitry Andric "' cannot have fixups"); 8520b57cec5SDimitry Andric for (unsigned i = 0, e = DF.getContents().size(); i != e; ++i) 8530b57cec5SDimitry Andric if (DF.getContents()[i]) { 8545ffd83dbSDimitry Andric getContext().reportError(SMLoc(), 8555ffd83dbSDimitry Andric Sec->getVirtualSectionKind() + 8565ffd83dbSDimitry Andric " section '" + Sec->getName() + 8575ffd83dbSDimitry Andric "' cannot have non-zero initializers"); 8585ffd83dbSDimitry Andric break; 8590b57cec5SDimitry Andric } 8600b57cec5SDimitry Andric break; 8610b57cec5SDimitry Andric } 8620b57cec5SDimitry Andric case MCFragment::FT_Align: 8630b57cec5SDimitry Andric // Check that we aren't trying to write a non-zero value into a virtual 8640b57cec5SDimitry Andric // section. 8650b57cec5SDimitry Andric assert((cast<MCAlignFragment>(F).getValueSize() == 0 || 8660b57cec5SDimitry Andric cast<MCAlignFragment>(F).getValue() == 0) && 8670b57cec5SDimitry Andric "Invalid align in virtual section!"); 8680b57cec5SDimitry Andric break; 8690b57cec5SDimitry Andric case MCFragment::FT_Fill: 8700b57cec5SDimitry Andric assert((cast<MCFillFragment>(F).getValue() == 0) && 8710b57cec5SDimitry Andric "Invalid fill in virtual section!"); 8720b57cec5SDimitry Andric break; 873e8d8bef9SDimitry Andric case MCFragment::FT_Org: 874e8d8bef9SDimitry Andric break; 8750b57cec5SDimitry Andric } 8760b57cec5SDimitry Andric } 8770b57cec5SDimitry Andric 8780b57cec5SDimitry Andric return; 8790b57cec5SDimitry Andric } 8800b57cec5SDimitry Andric 8810b57cec5SDimitry Andric uint64_t Start = OS.tell(); 8820b57cec5SDimitry Andric (void)Start; 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric for (const MCFragment &F : *Sec) 8850fca6ea1SDimitry Andric writeFragment(OS, *this, F); 8860b57cec5SDimitry Andric 887e8d8bef9SDimitry Andric assert(getContext().hadError() || 8880fca6ea1SDimitry Andric OS.tell() - Start == getSectionAddressSize(*Sec)); 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric std::tuple<MCValue, uint64_t, bool> 8920fca6ea1SDimitry Andric MCAssembler::handleFixup(MCFragment &F, const MCFixup &Fixup, 8930fca6ea1SDimitry Andric const MCSubtargetInfo *STI) { 8940b57cec5SDimitry Andric // Evaluate the fixup. 8950b57cec5SDimitry Andric MCValue Target; 8960b57cec5SDimitry Andric uint64_t FixedValue; 8970b57cec5SDimitry Andric bool WasForced; 8985f757f3fSDimitry Andric bool IsResolved = 8990fca6ea1SDimitry Andric evaluateFixup(Fixup, &F, Target, STI, FixedValue, WasForced); 9000b57cec5SDimitry Andric if (!IsResolved) { 9010b57cec5SDimitry Andric // The fixup was unresolved, we need a relocation. Inform the object 9020b57cec5SDimitry Andric // writer of the relocation, and give it an opportunity to adjust the 9030b57cec5SDimitry Andric // fixup value if need be. 9040fca6ea1SDimitry Andric getWriter().recordRelocation(*this, &F, Fixup, Target, FixedValue); 9050b57cec5SDimitry Andric } 9060b57cec5SDimitry Andric return std::make_tuple(Target, FixedValue, IsResolved); 9070b57cec5SDimitry Andric } 9080b57cec5SDimitry Andric 9090fca6ea1SDimitry Andric void MCAssembler::layout() { 9100b57cec5SDimitry Andric assert(getBackendPtr() && "Expected assembler backend"); 9110b57cec5SDimitry Andric DEBUG_WITH_TYPE("mc-dump", { 9120b57cec5SDimitry Andric errs() << "assembler backend - pre-layout\n--\n"; 9130b57cec5SDimitry Andric dump(); }); 9140b57cec5SDimitry Andric 9150fca6ea1SDimitry Andric // Assign section ordinals. 9160b57cec5SDimitry Andric unsigned SectionIndex = 0; 9170b57cec5SDimitry Andric for (MCSection &Sec : *this) { 9180b57cec5SDimitry Andric Sec.setOrdinal(SectionIndex++); 9190b57cec5SDimitry Andric 9200fca6ea1SDimitry Andric // Chain together fragments from all subsections. 9210fca6ea1SDimitry Andric if (Sec.Subsections.size() > 1) { 9220fca6ea1SDimitry Andric MCDummyFragment Dummy; 9230fca6ea1SDimitry Andric MCFragment *Tail = &Dummy; 9240fca6ea1SDimitry Andric for (auto &[_, List] : Sec.Subsections) { 9250fca6ea1SDimitry Andric assert(List.Head); 9260fca6ea1SDimitry Andric Tail->Next = List.Head; 9270fca6ea1SDimitry Andric Tail = List.Tail; 9280fca6ea1SDimitry Andric } 9290fca6ea1SDimitry Andric Sec.Subsections.clear(); 9300fca6ea1SDimitry Andric Sec.Subsections.push_back({0u, {Dummy.getNext(), Tail}}); 9310fca6ea1SDimitry Andric Sec.CurFragList = &Sec.Subsections[0].second; 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric unsigned FragmentIndex = 0; 9340fca6ea1SDimitry Andric for (MCFragment &Frag : Sec) 9350b57cec5SDimitry Andric Frag.setLayoutOrder(FragmentIndex++); 9360b57cec5SDimitry Andric } 9370fca6ea1SDimitry Andric } 9380b57cec5SDimitry Andric 9390b57cec5SDimitry Andric // Layout until everything fits. 9400fca6ea1SDimitry Andric this->HasLayout = true; 9410fca6ea1SDimitry Andric while (layoutOnce()) { 942*52418fc2SDimitry Andric if (getContext().hadError()) 943*52418fc2SDimitry Andric return; 944*52418fc2SDimitry Andric // Size of fragments in one section can depend on the size of fragments in 945*52418fc2SDimitry Andric // another. If any fragment has changed size, we have to re-layout (and 946*52418fc2SDimitry Andric // as a result possibly further relax) all. 947*52418fc2SDimitry Andric for (MCSection &Sec : *this) 948*52418fc2SDimitry Andric Sec.setHasLayout(false); 9495ffd83dbSDimitry Andric } 9500b57cec5SDimitry Andric 9510b57cec5SDimitry Andric DEBUG_WITH_TYPE("mc-dump", { 9520b57cec5SDimitry Andric errs() << "assembler backend - post-relaxation\n--\n"; 9530b57cec5SDimitry Andric dump(); }); 9540b57cec5SDimitry Andric 955*52418fc2SDimitry Andric // Finalize the layout, including fragment lowering. 956*52418fc2SDimitry Andric getBackend().finishLayout(*this); 9570b57cec5SDimitry Andric 9580b57cec5SDimitry Andric DEBUG_WITH_TYPE("mc-dump", { 9590b57cec5SDimitry Andric errs() << "assembler backend - final-layout\n--\n"; 9600b57cec5SDimitry Andric dump(); }); 9610b57cec5SDimitry Andric 9620b57cec5SDimitry Andric // Allow the object writer a chance to perform post-layout binding (for 9630b57cec5SDimitry Andric // example, to set the index fields in the symbol data). 9640fca6ea1SDimitry Andric getWriter().executePostLayoutBinding(*this); 9650b57cec5SDimitry Andric 9660b57cec5SDimitry Andric // Evaluate and apply the fixups, generating relocation entries as necessary. 9670b57cec5SDimitry Andric for (MCSection &Sec : *this) { 9680b57cec5SDimitry Andric for (MCFragment &Frag : Sec) { 9690b57cec5SDimitry Andric ArrayRef<MCFixup> Fixups; 9700b57cec5SDimitry Andric MutableArrayRef<char> Contents; 9710b57cec5SDimitry Andric const MCSubtargetInfo *STI = nullptr; 9725ffd83dbSDimitry Andric 9735ffd83dbSDimitry Andric // Process MCAlignFragment and MCEncodedFragmentWithFixups here. 9745ffd83dbSDimitry Andric switch (Frag.getKind()) { 9755ffd83dbSDimitry Andric default: 9765ffd83dbSDimitry Andric continue; 9775ffd83dbSDimitry Andric case MCFragment::FT_Align: { 9785ffd83dbSDimitry Andric MCAlignFragment &AF = cast<MCAlignFragment>(Frag); 9790b57cec5SDimitry Andric // Insert fixup type for code alignment if the target define 9800b57cec5SDimitry Andric // shouldInsertFixupForCodeAlign target hook. 98181ad6265SDimitry Andric if (Sec.useCodeAlign() && AF.hasEmitNops()) 9820fca6ea1SDimitry Andric getBackend().shouldInsertFixupForCodeAlign(*this, AF); 9830b57cec5SDimitry Andric continue; 9845ffd83dbSDimitry Andric } 9855ffd83dbSDimitry Andric case MCFragment::FT_Data: { 9865ffd83dbSDimitry Andric MCDataFragment &DF = cast<MCDataFragment>(Frag); 9875ffd83dbSDimitry Andric Fixups = DF.getFixups(); 9885ffd83dbSDimitry Andric Contents = DF.getContents(); 9895ffd83dbSDimitry Andric STI = DF.getSubtargetInfo(); 9905ffd83dbSDimitry Andric assert(!DF.hasInstructions() || STI != nullptr); 9915ffd83dbSDimitry Andric break; 9925ffd83dbSDimitry Andric } 9935ffd83dbSDimitry Andric case MCFragment::FT_Relaxable: { 9945ffd83dbSDimitry Andric MCRelaxableFragment &RF = cast<MCRelaxableFragment>(Frag); 9955ffd83dbSDimitry Andric Fixups = RF.getFixups(); 9965ffd83dbSDimitry Andric Contents = RF.getContents(); 9975ffd83dbSDimitry Andric STI = RF.getSubtargetInfo(); 9985ffd83dbSDimitry Andric assert(!RF.hasInstructions() || STI != nullptr); 9995ffd83dbSDimitry Andric break; 10005ffd83dbSDimitry Andric } 10015ffd83dbSDimitry Andric case MCFragment::FT_CVDefRange: { 10025ffd83dbSDimitry Andric MCCVDefRangeFragment &CF = cast<MCCVDefRangeFragment>(Frag); 10035ffd83dbSDimitry Andric Fixups = CF.getFixups(); 10045ffd83dbSDimitry Andric Contents = CF.getContents(); 10055ffd83dbSDimitry Andric break; 10065ffd83dbSDimitry Andric } 10075ffd83dbSDimitry Andric case MCFragment::FT_Dwarf: { 10085ffd83dbSDimitry Andric MCDwarfLineAddrFragment &DF = cast<MCDwarfLineAddrFragment>(Frag); 10095ffd83dbSDimitry Andric Fixups = DF.getFixups(); 10105ffd83dbSDimitry Andric Contents = DF.getContents(); 10115ffd83dbSDimitry Andric break; 10125ffd83dbSDimitry Andric } 10135ffd83dbSDimitry Andric case MCFragment::FT_DwarfFrame: { 10145ffd83dbSDimitry Andric MCDwarfCallFrameFragment &DF = cast<MCDwarfCallFrameFragment>(Frag); 10155ffd83dbSDimitry Andric Fixups = DF.getFixups(); 10165ffd83dbSDimitry Andric Contents = DF.getContents(); 10175ffd83dbSDimitry Andric break; 10185ffd83dbSDimitry Andric } 10195f757f3fSDimitry Andric case MCFragment::FT_LEB: { 10205f757f3fSDimitry Andric auto &LF = cast<MCLEBFragment>(Frag); 10215f757f3fSDimitry Andric Fixups = LF.getFixups(); 10225f757f3fSDimitry Andric Contents = LF.getContents(); 10235f757f3fSDimitry Andric break; 10245f757f3fSDimitry Andric } 1025e8d8bef9SDimitry Andric case MCFragment::FT_PseudoProbe: { 1026e8d8bef9SDimitry Andric MCPseudoProbeAddrFragment &PF = cast<MCPseudoProbeAddrFragment>(Frag); 1027e8d8bef9SDimitry Andric Fixups = PF.getFixups(); 1028e8d8bef9SDimitry Andric Contents = PF.getContents(); 1029e8d8bef9SDimitry Andric break; 1030e8d8bef9SDimitry Andric } 10315ffd83dbSDimitry Andric } 10320b57cec5SDimitry Andric for (const MCFixup &Fixup : Fixups) { 10330b57cec5SDimitry Andric uint64_t FixedValue; 10340b57cec5SDimitry Andric bool IsResolved; 10350b57cec5SDimitry Andric MCValue Target; 10360b57cec5SDimitry Andric std::tie(Target, FixedValue, IsResolved) = 10370fca6ea1SDimitry Andric handleFixup(Frag, Fixup, STI); 10380b57cec5SDimitry Andric getBackend().applyFixup(*this, Fixup, Target, Contents, FixedValue, 10390b57cec5SDimitry Andric IsResolved, STI); 10400b57cec5SDimitry Andric } 10410b57cec5SDimitry Andric } 10420b57cec5SDimitry Andric } 10430b57cec5SDimitry Andric } 10440b57cec5SDimitry Andric 10450b57cec5SDimitry Andric void MCAssembler::Finish() { 10460fca6ea1SDimitry Andric layout(); 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric // Write the object file. 10490fca6ea1SDimitry Andric stats::ObjectBytes += getWriter().writeObject(*this); 10500fca6ea1SDimitry Andric 10510fca6ea1SDimitry Andric HasLayout = false; 10520b57cec5SDimitry Andric } 10530b57cec5SDimitry Andric 10540b57cec5SDimitry Andric bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, 10550fca6ea1SDimitry Andric const MCRelaxableFragment *DF) const { 10560b57cec5SDimitry Andric assert(getBackendPtr() && "Expected assembler backend"); 10570b57cec5SDimitry Andric MCValue Target; 10580b57cec5SDimitry Andric uint64_t Value; 10590b57cec5SDimitry Andric bool WasForced; 10600fca6ea1SDimitry Andric bool Resolved = evaluateFixup(Fixup, DF, Target, DF->getSubtargetInfo(), 10610fca6ea1SDimitry Andric Value, WasForced); 10620b57cec5SDimitry Andric if (Target.getSymA() && 10630b57cec5SDimitry Andric Target.getSymA()->getKind() == MCSymbolRefExpr::VK_X86_ABS8 && 10640b57cec5SDimitry Andric Fixup.getKind() == FK_Data_1) 10650b57cec5SDimitry Andric return false; 10660fca6ea1SDimitry Andric return getBackend().fixupNeedsRelaxationAdvanced(*this, Fixup, Resolved, 10670fca6ea1SDimitry Andric Value, DF, WasForced); 10680b57cec5SDimitry Andric } 10690b57cec5SDimitry Andric 10700fca6ea1SDimitry Andric bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F) const { 10710b57cec5SDimitry Andric assert(getBackendPtr() && "Expected assembler backend"); 10720b57cec5SDimitry Andric // If this inst doesn't ever need relaxation, ignore it. This occurs when we 10730b57cec5SDimitry Andric // are intentionally pushing out inst fragments, or because we relaxed a 10740b57cec5SDimitry Andric // previous instruction to one that doesn't need relaxation. 10750b57cec5SDimitry Andric if (!getBackend().mayNeedRelaxation(F->getInst(), *F->getSubtargetInfo())) 10760b57cec5SDimitry Andric return false; 10770b57cec5SDimitry Andric 10780b57cec5SDimitry Andric for (const MCFixup &Fixup : F->getFixups()) 10790fca6ea1SDimitry Andric if (fixupNeedsRelaxation(Fixup, F)) 10800b57cec5SDimitry Andric return true; 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric return false; 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric 10850fca6ea1SDimitry Andric bool MCAssembler::relaxInstruction(MCRelaxableFragment &F) { 10860b57cec5SDimitry Andric assert(getEmitterPtr() && 10870b57cec5SDimitry Andric "Expected CodeEmitter defined for relaxInstruction"); 10880fca6ea1SDimitry Andric if (!fragmentNeedsRelaxation(&F)) 10890b57cec5SDimitry Andric return false; 10900b57cec5SDimitry Andric 10910b57cec5SDimitry Andric ++stats::RelaxedInstructions; 10920b57cec5SDimitry Andric 10930b57cec5SDimitry Andric // FIXME-PERF: We could immediately lower out instructions if we can tell 10940b57cec5SDimitry Andric // they are fully resolved, to avoid retesting on later passes. 10950b57cec5SDimitry Andric 10960b57cec5SDimitry Andric // Relax the fragment. 10970b57cec5SDimitry Andric 10985ffd83dbSDimitry Andric MCInst Relaxed = F.getInst(); 10995ffd83dbSDimitry Andric getBackend().relaxInstruction(Relaxed, *F.getSubtargetInfo()); 11000b57cec5SDimitry Andric 11010b57cec5SDimitry Andric // Encode the new instruction. 11020b57cec5SDimitry Andric F.setInst(Relaxed); 110306c3fb27SDimitry Andric F.getFixups().clear(); 110406c3fb27SDimitry Andric F.getContents().clear(); 110506c3fb27SDimitry Andric getEmitter().encodeInstruction(Relaxed, F.getContents(), F.getFixups(), 110606c3fb27SDimitry Andric *F.getSubtargetInfo()); 11070b57cec5SDimitry Andric return true; 11080b57cec5SDimitry Andric } 11090b57cec5SDimitry Andric 11100fca6ea1SDimitry Andric bool MCAssembler::relaxLEB(MCLEBFragment &LF) { 11115f757f3fSDimitry Andric const unsigned OldSize = static_cast<unsigned>(LF.getContents().size()); 11125f757f3fSDimitry Andric unsigned PadTo = OldSize; 11130b57cec5SDimitry Andric int64_t Value; 11145f757f3fSDimitry Andric SmallVectorImpl<char> &Data = LF.getContents(); 11155f757f3fSDimitry Andric LF.getFixups().clear(); 11165f757f3fSDimitry Andric // Use evaluateKnownAbsolute for Mach-O as a hack: .subsections_via_symbols 11175f757f3fSDimitry Andric // requires that .uleb128 A-B is foldable where A and B reside in different 11185f757f3fSDimitry Andric // fragments. This is used by __gcc_except_table. 11190fca6ea1SDimitry Andric bool Abs = getWriter().getSubsectionsViaSymbols() 11200fca6ea1SDimitry Andric ? LF.getValue().evaluateKnownAbsolute(Value, *this) 11210fca6ea1SDimitry Andric : LF.getValue().evaluateAsAbsolute(Value, *this); 11225f757f3fSDimitry Andric if (!Abs) { 11231db9f3b2SDimitry Andric bool Relaxed, UseZeroPad; 11240fca6ea1SDimitry Andric std::tie(Relaxed, UseZeroPad) = getBackend().relaxLEB128(*this, LF, Value); 11251db9f3b2SDimitry Andric if (!Relaxed) { 11265f757f3fSDimitry Andric getContext().reportError(LF.getValue().getLoc(), 11275f757f3fSDimitry Andric Twine(LF.isSigned() ? ".s" : ".u") + 11285f757f3fSDimitry Andric "leb128 expression is not absolute"); 11295f757f3fSDimitry Andric LF.setValue(MCConstantExpr::create(0, Context)); 11305f757f3fSDimitry Andric } 11315f757f3fSDimitry Andric uint8_t Tmp[10]; // maximum size: ceil(64/7) 11325f757f3fSDimitry Andric PadTo = std::max(PadTo, encodeULEB128(uint64_t(Value), Tmp)); 11331db9f3b2SDimitry Andric if (UseZeroPad) 11341db9f3b2SDimitry Andric Value = 0; 11355f757f3fSDimitry Andric } 11360b57cec5SDimitry Andric Data.clear(); 11370b57cec5SDimitry Andric raw_svector_ostream OSE(Data); 11380b57cec5SDimitry Andric // The compiler can generate EH table assembly that is impossible to assemble 11390b57cec5SDimitry Andric // without either adding padding to an LEB fragment or adding extra padding 11400b57cec5SDimitry Andric // to a later alignment fragment. To accommodate such tables, relaxation can 11410b57cec5SDimitry Andric // only increase an LEB fragment size here, not decrease it. See PR35809. 11420b57cec5SDimitry Andric if (LF.isSigned()) 11435f757f3fSDimitry Andric encodeSLEB128(Value, OSE, PadTo); 11440b57cec5SDimitry Andric else 11455f757f3fSDimitry Andric encodeULEB128(Value, OSE, PadTo); 11460b57cec5SDimitry Andric return OldSize != LF.getContents().size(); 11470b57cec5SDimitry Andric } 11480b57cec5SDimitry Andric 1149480093f4SDimitry Andric /// Check if the branch crosses the boundary. 1150480093f4SDimitry Andric /// 1151480093f4SDimitry Andric /// \param StartAddr start address of the fused/unfused branch. 1152480093f4SDimitry Andric /// \param Size size of the fused/unfused branch. 1153480093f4SDimitry Andric /// \param BoundaryAlignment alignment requirement of the branch. 1154480093f4SDimitry Andric /// \returns true if the branch cross the boundary. 1155480093f4SDimitry Andric static bool mayCrossBoundary(uint64_t StartAddr, uint64_t Size, 1156480093f4SDimitry Andric Align BoundaryAlignment) { 1157480093f4SDimitry Andric uint64_t EndAddr = StartAddr + Size; 1158480093f4SDimitry Andric return (StartAddr >> Log2(BoundaryAlignment)) != 1159480093f4SDimitry Andric ((EndAddr - 1) >> Log2(BoundaryAlignment)); 1160480093f4SDimitry Andric } 1161480093f4SDimitry Andric 1162480093f4SDimitry Andric /// Check if the branch is against the boundary. 1163480093f4SDimitry Andric /// 1164480093f4SDimitry Andric /// \param StartAddr start address of the fused/unfused branch. 1165480093f4SDimitry Andric /// \param Size size of the fused/unfused branch. 1166480093f4SDimitry Andric /// \param BoundaryAlignment alignment requirement of the branch. 1167480093f4SDimitry Andric /// \returns true if the branch is against the boundary. 1168480093f4SDimitry Andric static bool isAgainstBoundary(uint64_t StartAddr, uint64_t Size, 1169480093f4SDimitry Andric Align BoundaryAlignment) { 1170480093f4SDimitry Andric uint64_t EndAddr = StartAddr + Size; 1171480093f4SDimitry Andric return (EndAddr & (BoundaryAlignment.value() - 1)) == 0; 1172480093f4SDimitry Andric } 1173480093f4SDimitry Andric 1174480093f4SDimitry Andric /// Check if the branch needs padding. 1175480093f4SDimitry Andric /// 1176480093f4SDimitry Andric /// \param StartAddr start address of the fused/unfused branch. 1177480093f4SDimitry Andric /// \param Size size of the fused/unfused branch. 1178480093f4SDimitry Andric /// \param BoundaryAlignment alignment requirement of the branch. 1179480093f4SDimitry Andric /// \returns true if the branch needs padding. 1180480093f4SDimitry Andric static bool needPadding(uint64_t StartAddr, uint64_t Size, 1181480093f4SDimitry Andric Align BoundaryAlignment) { 1182480093f4SDimitry Andric return mayCrossBoundary(StartAddr, Size, BoundaryAlignment) || 1183480093f4SDimitry Andric isAgainstBoundary(StartAddr, Size, BoundaryAlignment); 1184480093f4SDimitry Andric } 1185480093f4SDimitry Andric 11860fca6ea1SDimitry Andric bool MCAssembler::relaxBoundaryAlign(MCBoundaryAlignFragment &BF) { 11875ffd83dbSDimitry Andric // BoundaryAlignFragment that doesn't need to align any fragment should not be 11885ffd83dbSDimitry Andric // relaxed. 11895ffd83dbSDimitry Andric if (!BF.getLastFragment()) 1190480093f4SDimitry Andric return false; 1191480093f4SDimitry Andric 11920fca6ea1SDimitry Andric uint64_t AlignedOffset = getFragmentOffset(BF); 1193480093f4SDimitry Andric uint64_t AlignedSize = 0; 11940fca6ea1SDimitry Andric for (const MCFragment *F = BF.getNext();; F = F->getNext()) { 11950fca6ea1SDimitry Andric AlignedSize += computeFragmentSize(*F); 11960fca6ea1SDimitry Andric if (F == BF.getLastFragment()) 11970fca6ea1SDimitry Andric break; 11980fca6ea1SDimitry Andric } 11995ffd83dbSDimitry Andric 1200480093f4SDimitry Andric Align BoundaryAlignment = BF.getAlignment(); 1201480093f4SDimitry Andric uint64_t NewSize = needPadding(AlignedOffset, AlignedSize, BoundaryAlignment) 1202480093f4SDimitry Andric ? offsetToAlignment(AlignedOffset, BoundaryAlignment) 1203480093f4SDimitry Andric : 0U; 12045ffd83dbSDimitry Andric if (NewSize == BF.getSize()) 1205480093f4SDimitry Andric return false; 1206480093f4SDimitry Andric BF.setSize(NewSize); 1207480093f4SDimitry Andric return true; 1208480093f4SDimitry Andric } 1209480093f4SDimitry Andric 12100fca6ea1SDimitry Andric bool MCAssembler::relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF) { 1211fe6060f1SDimitry Andric bool WasRelaxed; 12120fca6ea1SDimitry Andric if (getBackend().relaxDwarfLineAddr(*this, DF, WasRelaxed)) 1213fe6060f1SDimitry Andric return WasRelaxed; 1214fe6060f1SDimitry Andric 12150fca6ea1SDimitry Andric MCContext &Context = getContext(); 12160b57cec5SDimitry Andric uint64_t OldSize = DF.getContents().size(); 12170b57cec5SDimitry Andric int64_t AddrDelta; 12180fca6ea1SDimitry Andric bool Abs = DF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this); 12190b57cec5SDimitry Andric assert(Abs && "We created a line delta with an invalid expression"); 12200b57cec5SDimitry Andric (void)Abs; 12210b57cec5SDimitry Andric int64_t LineDelta; 12220b57cec5SDimitry Andric LineDelta = DF.getLineDelta(); 12230b57cec5SDimitry Andric SmallVectorImpl<char> &Data = DF.getContents(); 12240b57cec5SDimitry Andric Data.clear(); 12250b57cec5SDimitry Andric DF.getFixups().clear(); 12260b57cec5SDimitry Andric 122706c3fb27SDimitry Andric MCDwarfLineAddr::encode(Context, getDWARFLinetableParams(), LineDelta, 122806c3fb27SDimitry Andric AddrDelta, Data); 12290b57cec5SDimitry Andric return OldSize != Data.size(); 12300b57cec5SDimitry Andric } 12310b57cec5SDimitry Andric 12320fca6ea1SDimitry Andric bool MCAssembler::relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF) { 1233fe6060f1SDimitry Andric bool WasRelaxed; 12340fca6ea1SDimitry Andric if (getBackend().relaxDwarfCFA(*this, DF, WasRelaxed)) 1235fe6060f1SDimitry Andric return WasRelaxed; 1236fe6060f1SDimitry Andric 12370fca6ea1SDimitry Andric MCContext &Context = getContext(); 123806c3fb27SDimitry Andric int64_t Value; 12390fca6ea1SDimitry Andric bool Abs = DF.getAddrDelta().evaluateAsAbsolute(Value, *this); 124006c3fb27SDimitry Andric if (!Abs) { 124106c3fb27SDimitry Andric getContext().reportError(DF.getAddrDelta().getLoc(), 124206c3fb27SDimitry Andric "invalid CFI advance_loc expression"); 124306c3fb27SDimitry Andric DF.setAddrDelta(MCConstantExpr::create(0, Context)); 124406c3fb27SDimitry Andric return false; 124506c3fb27SDimitry Andric } 124606c3fb27SDimitry Andric 12470b57cec5SDimitry Andric SmallVectorImpl<char> &Data = DF.getContents(); 124806c3fb27SDimitry Andric uint64_t OldSize = Data.size(); 12490b57cec5SDimitry Andric Data.clear(); 12500b57cec5SDimitry Andric DF.getFixups().clear(); 12510b57cec5SDimitry Andric 125206c3fb27SDimitry Andric MCDwarfFrameEmitter::encodeAdvanceLoc(Context, Value, Data); 12530b57cec5SDimitry Andric return OldSize != Data.size(); 12540b57cec5SDimitry Andric } 12550b57cec5SDimitry Andric 12560fca6ea1SDimitry Andric bool MCAssembler::relaxCVInlineLineTable(MCCVInlineLineTableFragment &F) { 12570b57cec5SDimitry Andric unsigned OldSize = F.getContents().size(); 12580fca6ea1SDimitry Andric getContext().getCVContext().encodeInlineLineTable(*this, F); 12590b57cec5SDimitry Andric return OldSize != F.getContents().size(); 12600b57cec5SDimitry Andric } 12610b57cec5SDimitry Andric 12620fca6ea1SDimitry Andric bool MCAssembler::relaxCVDefRange(MCCVDefRangeFragment &F) { 12630b57cec5SDimitry Andric unsigned OldSize = F.getContents().size(); 12640fca6ea1SDimitry Andric getContext().getCVContext().encodeDefRange(*this, F); 12650b57cec5SDimitry Andric return OldSize != F.getContents().size(); 12660b57cec5SDimitry Andric } 12670b57cec5SDimitry Andric 12680fca6ea1SDimitry Andric bool MCAssembler::relaxPseudoProbeAddr(MCPseudoProbeAddrFragment &PF) { 1269e8d8bef9SDimitry Andric uint64_t OldSize = PF.getContents().size(); 1270e8d8bef9SDimitry Andric int64_t AddrDelta; 12710fca6ea1SDimitry Andric bool Abs = PF.getAddrDelta().evaluateKnownAbsolute(AddrDelta, *this); 1272e8d8bef9SDimitry Andric assert(Abs && "We created a pseudo probe with an invalid expression"); 1273e8d8bef9SDimitry Andric (void)Abs; 1274e8d8bef9SDimitry Andric SmallVectorImpl<char> &Data = PF.getContents(); 1275e8d8bef9SDimitry Andric Data.clear(); 1276e8d8bef9SDimitry Andric raw_svector_ostream OSE(Data); 1277e8d8bef9SDimitry Andric PF.getFixups().clear(); 1278e8d8bef9SDimitry Andric 1279e8d8bef9SDimitry Andric // AddrDelta is a signed integer 1280e8d8bef9SDimitry Andric encodeSLEB128(AddrDelta, OSE, OldSize); 1281e8d8bef9SDimitry Andric return OldSize != Data.size(); 1282e8d8bef9SDimitry Andric } 1283e8d8bef9SDimitry Andric 12840fca6ea1SDimitry Andric bool MCAssembler::relaxFragment(MCFragment &F) { 12855ffd83dbSDimitry Andric switch(F.getKind()) { 12865ffd83dbSDimitry Andric default: 12875ffd83dbSDimitry Andric return false; 12885ffd83dbSDimitry Andric case MCFragment::FT_Relaxable: 12895ffd83dbSDimitry Andric assert(!getRelaxAll() && 12905ffd83dbSDimitry Andric "Did not expect a MCRelaxableFragment in RelaxAll mode"); 12910fca6ea1SDimitry Andric return relaxInstruction(cast<MCRelaxableFragment>(F)); 12925ffd83dbSDimitry Andric case MCFragment::FT_Dwarf: 12930fca6ea1SDimitry Andric return relaxDwarfLineAddr(cast<MCDwarfLineAddrFragment>(F)); 12945ffd83dbSDimitry Andric case MCFragment::FT_DwarfFrame: 12950fca6ea1SDimitry Andric return relaxDwarfCallFrameFragment(cast<MCDwarfCallFrameFragment>(F)); 12965ffd83dbSDimitry Andric case MCFragment::FT_LEB: 12970fca6ea1SDimitry Andric return relaxLEB(cast<MCLEBFragment>(F)); 12985ffd83dbSDimitry Andric case MCFragment::FT_BoundaryAlign: 12990fca6ea1SDimitry Andric return relaxBoundaryAlign(cast<MCBoundaryAlignFragment>(F)); 13005ffd83dbSDimitry Andric case MCFragment::FT_CVInlineLines: 13010fca6ea1SDimitry Andric return relaxCVInlineLineTable(cast<MCCVInlineLineTableFragment>(F)); 13025ffd83dbSDimitry Andric case MCFragment::FT_CVDefRange: 13030fca6ea1SDimitry Andric return relaxCVDefRange(cast<MCCVDefRangeFragment>(F)); 1304e8d8bef9SDimitry Andric case MCFragment::FT_PseudoProbe: 13050fca6ea1SDimitry Andric return relaxPseudoProbeAddr(cast<MCPseudoProbeAddrFragment>(F)); 13065ffd83dbSDimitry Andric } 13075ffd83dbSDimitry Andric } 13085ffd83dbSDimitry Andric 13090fca6ea1SDimitry Andric bool MCAssembler::layoutOnce() { 13100b57cec5SDimitry Andric ++stats::RelaxationSteps; 13110b57cec5SDimitry Andric 13120fca6ea1SDimitry Andric bool Changed = false; 1313*52418fc2SDimitry Andric for (MCSection &Sec : *this) 1314*52418fc2SDimitry Andric for (MCFragment &Frag : Sec) 1315*52418fc2SDimitry Andric if (relaxFragment(Frag)) 13160fca6ea1SDimitry Andric Changed = true; 1317*52418fc2SDimitry Andric return Changed; 13180b57cec5SDimitry Andric } 13190b57cec5SDimitry Andric 13200b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 13210b57cec5SDimitry Andric LLVM_DUMP_METHOD void MCAssembler::dump() const{ 13220b57cec5SDimitry Andric raw_ostream &OS = errs(); 13230b57cec5SDimitry Andric 13240b57cec5SDimitry Andric OS << "<MCAssembler\n"; 13250b57cec5SDimitry Andric OS << " Sections:[\n "; 13260fca6ea1SDimitry Andric bool First = true; 13270fca6ea1SDimitry Andric for (const MCSection &Sec : *this) { 13280fca6ea1SDimitry Andric if (First) 13290fca6ea1SDimitry Andric First = false; 13300fca6ea1SDimitry Andric else 13310fca6ea1SDimitry Andric OS << ",\n "; 13320fca6ea1SDimitry Andric Sec.dump(); 13330b57cec5SDimitry Andric } 13340b57cec5SDimitry Andric OS << "],\n"; 13350b57cec5SDimitry Andric OS << " Symbols:["; 13360b57cec5SDimitry Andric 13370fca6ea1SDimitry Andric First = true; 13380fca6ea1SDimitry Andric for (const MCSymbol &Sym : symbols()) { 13390fca6ea1SDimitry Andric if (First) 13400fca6ea1SDimitry Andric First = false; 13410fca6ea1SDimitry Andric else 13420fca6ea1SDimitry Andric OS << ",\n "; 13430b57cec5SDimitry Andric OS << "("; 13440fca6ea1SDimitry Andric Sym.dump(); 13450fca6ea1SDimitry Andric OS << ", Index:" << Sym.getIndex() << ", "; 13460b57cec5SDimitry Andric OS << ")"; 13470b57cec5SDimitry Andric } 13480b57cec5SDimitry Andric OS << "]>\n"; 13490b57cec5SDimitry Andric } 13500b57cec5SDimitry Andric #endif 1351