xref: /freebsd-src/contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp (revision 52418fc2be8efa5172b90a3a9e617017173612c4)
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