10b57cec5SDimitry Andric //===- lib/MC/MCFragment.cpp - Assembler Fragment 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/MCFragment.h"
100b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
110b57cec5SDimitry Andric #include "llvm/ADT/StringExtras.h"
120b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
130b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
140b57cec5SDimitry Andric #include "llvm/MC/MCAsmLayout.h"
150b57cec5SDimitry Andric #include "llvm/MC/MCAssembler.h"
160b57cec5SDimitry Andric #include "llvm/MC/MCContext.h"
170b57cec5SDimitry Andric #include "llvm/MC/MCExpr.h"
180b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h"
190b57cec5SDimitry Andric #include "llvm/MC/MCSection.h"
200b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h"
210b57cec5SDimitry Andric #include "llvm/MC/MCValue.h"
220b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
230b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
240b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
250b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
260b57cec5SDimitry Andric #include <cassert>
270b57cec5SDimitry Andric #include <cstdint>
280b57cec5SDimitry Andric #include <utility>
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric using namespace llvm;
310b57cec5SDimitry Andric 
MCAsmLayout(MCAssembler & Asm)320b57cec5SDimitry Andric MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) {
330b57cec5SDimitry Andric   // Compute the section layout order. Virtual sections must go last.
340b57cec5SDimitry Andric   for (MCSection &Sec : Asm)
350b57cec5SDimitry Andric     if (!Sec.isVirtualSection())
360b57cec5SDimitry Andric       SectionOrder.push_back(&Sec);
370b57cec5SDimitry Andric   for (MCSection &Sec : Asm)
380b57cec5SDimitry Andric     if (Sec.isVirtualSection())
390b57cec5SDimitry Andric       SectionOrder.push_back(&Sec);
400b57cec5SDimitry Andric }
410b57cec5SDimitry Andric 
isFragmentValid(const MCFragment * F) const420b57cec5SDimitry Andric bool MCAsmLayout::isFragmentValid(const MCFragment *F) const {
430b57cec5SDimitry Andric   const MCSection *Sec = F->getParent();
440b57cec5SDimitry Andric   const MCFragment *LastValid = LastValidFragment.lookup(Sec);
450b57cec5SDimitry Andric   if (!LastValid)
460b57cec5SDimitry Andric     return false;
470b57cec5SDimitry Andric   assert(LastValid->getParent() == Sec);
480b57cec5SDimitry Andric   return F->getLayoutOrder() <= LastValid->getLayoutOrder();
490b57cec5SDimitry Andric }
500b57cec5SDimitry Andric 
canGetFragmentOffset(const MCFragment * F) const515ffd83dbSDimitry Andric bool MCAsmLayout::canGetFragmentOffset(const MCFragment *F) const {
525ffd83dbSDimitry Andric   MCSection *Sec = F->getParent();
535ffd83dbSDimitry Andric   MCSection::iterator I;
545ffd83dbSDimitry Andric   if (MCFragment *LastValid = LastValidFragment[Sec]) {
555ffd83dbSDimitry Andric     // Fragment already valid, offset is available.
565ffd83dbSDimitry Andric     if (F->getLayoutOrder() <= LastValid->getLayoutOrder())
575ffd83dbSDimitry Andric       return true;
585ffd83dbSDimitry Andric     I = ++MCSection::iterator(LastValid);
595ffd83dbSDimitry Andric   } else
605ffd83dbSDimitry Andric     I = Sec->begin();
615ffd83dbSDimitry Andric 
625ffd83dbSDimitry Andric   // A fragment ordered before F is currently being laid out.
635ffd83dbSDimitry Andric   const MCFragment *FirstInvalidFragment = &*I;
645ffd83dbSDimitry Andric   if (FirstInvalidFragment->IsBeingLaidOut)
655ffd83dbSDimitry Andric     return false;
665ffd83dbSDimitry Andric 
675ffd83dbSDimitry Andric   return true;
685ffd83dbSDimitry Andric }
695ffd83dbSDimitry Andric 
invalidateFragmentsFrom(MCFragment * F)700b57cec5SDimitry Andric void MCAsmLayout::invalidateFragmentsFrom(MCFragment *F) {
710b57cec5SDimitry Andric   // If this fragment wasn't already valid, we don't need to do anything.
720b57cec5SDimitry Andric   if (!isFragmentValid(F))
730b57cec5SDimitry Andric     return;
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric   // Otherwise, reset the last valid fragment to the previous fragment
760b57cec5SDimitry Andric   // (if this is the first fragment, it will be NULL).
770b57cec5SDimitry Andric   LastValidFragment[F->getParent()] = F->getPrevNode();
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric 
ensureValid(const MCFragment * F) const800b57cec5SDimitry Andric void MCAsmLayout::ensureValid(const MCFragment *F) const {
810b57cec5SDimitry Andric   MCSection *Sec = F->getParent();
820b57cec5SDimitry Andric   MCSection::iterator I;
830b57cec5SDimitry Andric   if (MCFragment *Cur = LastValidFragment[Sec])
840b57cec5SDimitry Andric     I = ++MCSection::iterator(Cur);
850b57cec5SDimitry Andric   else
860b57cec5SDimitry Andric     I = Sec->begin();
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric   // Advance the layout position until the fragment is valid.
890b57cec5SDimitry Andric   while (!isFragmentValid(F)) {
900b57cec5SDimitry Andric     assert(I != Sec->end() && "Layout bookkeeping error");
910b57cec5SDimitry Andric     const_cast<MCAsmLayout *>(this)->layoutFragment(&*I);
920b57cec5SDimitry Andric     ++I;
930b57cec5SDimitry Andric   }
940b57cec5SDimitry Andric }
950b57cec5SDimitry Andric 
getFragmentOffset(const MCFragment * F) const960b57cec5SDimitry Andric uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const {
970b57cec5SDimitry Andric   ensureValid(F);
980b57cec5SDimitry Andric   assert(F->Offset != ~UINT64_C(0) && "Address not set!");
990b57cec5SDimitry Andric   return F->Offset;
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric // Simple getSymbolOffset helper for the non-variable case.
getLabelOffset(const MCAsmLayout & Layout,const MCSymbol & S,bool ReportError,uint64_t & Val)1030b57cec5SDimitry Andric static bool getLabelOffset(const MCAsmLayout &Layout, const MCSymbol &S,
1040b57cec5SDimitry Andric                            bool ReportError, uint64_t &Val) {
1050b57cec5SDimitry Andric   if (!S.getFragment()) {
1060b57cec5SDimitry Andric     if (ReportError)
1070b57cec5SDimitry Andric       report_fatal_error("unable to evaluate offset to undefined symbol '" +
1080b57cec5SDimitry Andric                          S.getName() + "'");
1090b57cec5SDimitry Andric     return false;
1100b57cec5SDimitry Andric   }
1110b57cec5SDimitry Andric   Val = Layout.getFragmentOffset(S.getFragment()) + S.getOffset();
1120b57cec5SDimitry Andric   return true;
1130b57cec5SDimitry Andric }
1140b57cec5SDimitry Andric 
getSymbolOffsetImpl(const MCAsmLayout & Layout,const MCSymbol & S,bool ReportError,uint64_t & Val)1150b57cec5SDimitry Andric static bool getSymbolOffsetImpl(const MCAsmLayout &Layout, const MCSymbol &S,
1160b57cec5SDimitry Andric                                 bool ReportError, uint64_t &Val) {
1170b57cec5SDimitry Andric   if (!S.isVariable())
1180b57cec5SDimitry Andric     return getLabelOffset(Layout, S, ReportError, Val);
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric   // If SD is a variable, evaluate it.
1210b57cec5SDimitry Andric   MCValue Target;
1220b57cec5SDimitry Andric   if (!S.getVariableValue()->evaluateAsValue(Target, Layout))
1230b57cec5SDimitry Andric     report_fatal_error("unable to evaluate offset for variable '" +
1240b57cec5SDimitry Andric                        S.getName() + "'");
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   uint64_t Offset = Target.getConstant();
1270b57cec5SDimitry Andric 
1280b57cec5SDimitry Andric   const MCSymbolRefExpr *A = Target.getSymA();
1290b57cec5SDimitry Andric   if (A) {
1300b57cec5SDimitry Andric     uint64_t ValA;
131349cc55cSDimitry Andric     // FIXME: On most platforms, `Target`'s component symbols are labels from
132349cc55cSDimitry Andric     // having been simplified during evaluation, but on Mach-O they can be
133349cc55cSDimitry Andric     // variables due to PR19203. This, and the line below for `B` can be
134349cc55cSDimitry Andric     // restored to call `getLabelOffset` when PR19203 is fixed.
135349cc55cSDimitry Andric     if (!getSymbolOffsetImpl(Layout, A->getSymbol(), ReportError, ValA))
1360b57cec5SDimitry Andric       return false;
1370b57cec5SDimitry Andric     Offset += ValA;
1380b57cec5SDimitry Andric   }
1390b57cec5SDimitry Andric 
1400b57cec5SDimitry Andric   const MCSymbolRefExpr *B = Target.getSymB();
1410b57cec5SDimitry Andric   if (B) {
1420b57cec5SDimitry Andric     uint64_t ValB;
143349cc55cSDimitry Andric     if (!getSymbolOffsetImpl(Layout, B->getSymbol(), ReportError, ValB))
1440b57cec5SDimitry Andric       return false;
1450b57cec5SDimitry Andric     Offset -= ValB;
1460b57cec5SDimitry Andric   }
1470b57cec5SDimitry Andric 
1480b57cec5SDimitry Andric   Val = Offset;
1490b57cec5SDimitry Andric   return true;
1500b57cec5SDimitry Andric }
1510b57cec5SDimitry Andric 
getSymbolOffset(const MCSymbol & S,uint64_t & Val) const1520b57cec5SDimitry Andric bool MCAsmLayout::getSymbolOffset(const MCSymbol &S, uint64_t &Val) const {
1530b57cec5SDimitry Andric   return getSymbolOffsetImpl(*this, S, false, Val);
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
getSymbolOffset(const MCSymbol & S) const1560b57cec5SDimitry Andric uint64_t MCAsmLayout::getSymbolOffset(const MCSymbol &S) const {
1570b57cec5SDimitry Andric   uint64_t Val;
1580b57cec5SDimitry Andric   getSymbolOffsetImpl(*this, S, true, Val);
1590b57cec5SDimitry Andric   return Val;
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
getBaseSymbol(const MCSymbol & Symbol) const1620b57cec5SDimitry Andric const MCSymbol *MCAsmLayout::getBaseSymbol(const MCSymbol &Symbol) const {
1630b57cec5SDimitry Andric   if (!Symbol.isVariable())
1640b57cec5SDimitry Andric     return &Symbol;
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   const MCExpr *Expr = Symbol.getVariableValue();
1670b57cec5SDimitry Andric   MCValue Value;
1680b57cec5SDimitry Andric   if (!Expr->evaluateAsValue(Value, *this)) {
1690b57cec5SDimitry Andric     Assembler.getContext().reportError(
1700b57cec5SDimitry Andric         Expr->getLoc(), "expression could not be evaluated");
1710b57cec5SDimitry Andric     return nullptr;
1720b57cec5SDimitry Andric   }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric   const MCSymbolRefExpr *RefB = Value.getSymB();
1750b57cec5SDimitry Andric   if (RefB) {
1760b57cec5SDimitry Andric     Assembler.getContext().reportError(
1770b57cec5SDimitry Andric         Expr->getLoc(), Twine("symbol '") + RefB->getSymbol().getName() +
1780b57cec5SDimitry Andric                      "' could not be evaluated in a subtraction expression");
1790b57cec5SDimitry Andric     return nullptr;
1800b57cec5SDimitry Andric   }
1810b57cec5SDimitry Andric 
1820b57cec5SDimitry Andric   const MCSymbolRefExpr *A = Value.getSymA();
1830b57cec5SDimitry Andric   if (!A)
1840b57cec5SDimitry Andric     return nullptr;
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric   const MCSymbol &ASym = A->getSymbol();
1870b57cec5SDimitry Andric   const MCAssembler &Asm = getAssembler();
1880b57cec5SDimitry Andric   if (ASym.isCommon()) {
1890b57cec5SDimitry Andric     Asm.getContext().reportError(Expr->getLoc(),
1900b57cec5SDimitry Andric                                  "Common symbol '" + ASym.getName() +
1910b57cec5SDimitry Andric                                      "' cannot be used in assignment expr");
1920b57cec5SDimitry Andric     return nullptr;
1930b57cec5SDimitry Andric   }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   return &ASym;
1960b57cec5SDimitry Andric }
1970b57cec5SDimitry Andric 
getSectionAddressSize(const MCSection * Sec) const1980b57cec5SDimitry Andric uint64_t MCAsmLayout::getSectionAddressSize(const MCSection *Sec) const {
1990b57cec5SDimitry Andric   // The size is the last fragment's end offset.
2000b57cec5SDimitry Andric   const MCFragment &F = Sec->getFragmentList().back();
2010b57cec5SDimitry Andric   return getFragmentOffset(&F) + getAssembler().computeFragmentSize(*this, F);
2020b57cec5SDimitry Andric }
2030b57cec5SDimitry Andric 
getSectionFileSize(const MCSection * Sec) const2040b57cec5SDimitry Andric uint64_t MCAsmLayout::getSectionFileSize(const MCSection *Sec) const {
2050b57cec5SDimitry Andric   // Virtual sections have no file size.
2060b57cec5SDimitry Andric   if (Sec->isVirtualSection())
2070b57cec5SDimitry Andric     return 0;
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric   // Otherwise, the file size is the same as the address space size.
2100b57cec5SDimitry Andric   return getSectionAddressSize(Sec);
2110b57cec5SDimitry Andric }
2120b57cec5SDimitry Andric 
computeBundlePadding(const MCAssembler & Assembler,const MCEncodedFragment * F,uint64_t FOffset,uint64_t FSize)2130b57cec5SDimitry Andric uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
2140b57cec5SDimitry Andric                                     const MCEncodedFragment *F,
2150b57cec5SDimitry Andric                                     uint64_t FOffset, uint64_t FSize) {
2160b57cec5SDimitry Andric   uint64_t BundleSize = Assembler.getBundleAlignSize();
2170b57cec5SDimitry Andric   assert(BundleSize > 0 &&
2180b57cec5SDimitry Andric          "computeBundlePadding should only be called if bundling is enabled");
2190b57cec5SDimitry Andric   uint64_t BundleMask = BundleSize - 1;
2200b57cec5SDimitry Andric   uint64_t OffsetInBundle = FOffset & BundleMask;
2210b57cec5SDimitry Andric   uint64_t EndOfFragment = OffsetInBundle + FSize;
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric   // There are two kinds of bundling restrictions:
2240b57cec5SDimitry Andric   //
2250b57cec5SDimitry Andric   // 1) For alignToBundleEnd(), add padding to ensure that the fragment will
2260b57cec5SDimitry Andric   //    *end* on a bundle boundary.
2270b57cec5SDimitry Andric   // 2) Otherwise, check if the fragment would cross a bundle boundary. If it
2280b57cec5SDimitry Andric   //    would, add padding until the end of the bundle so that the fragment
2290b57cec5SDimitry Andric   //    will start in a new one.
2300b57cec5SDimitry Andric   if (F->alignToBundleEnd()) {
2310b57cec5SDimitry Andric     // Three possibilities here:
2320b57cec5SDimitry Andric     //
2330b57cec5SDimitry Andric     // A) The fragment just happens to end at a bundle boundary, so we're good.
2340b57cec5SDimitry Andric     // B) The fragment ends before the current bundle boundary: pad it just
2350b57cec5SDimitry Andric     //    enough to reach the boundary.
2360b57cec5SDimitry Andric     // C) The fragment ends after the current bundle boundary: pad it until it
2370b57cec5SDimitry Andric     //    reaches the end of the next bundle boundary.
2380b57cec5SDimitry Andric     //
2390b57cec5SDimitry Andric     // Note: this code could be made shorter with some modulo trickery, but it's
2400b57cec5SDimitry Andric     // intentionally kept in its more explicit form for simplicity.
2410b57cec5SDimitry Andric     if (EndOfFragment == BundleSize)
2420b57cec5SDimitry Andric       return 0;
2430b57cec5SDimitry Andric     else if (EndOfFragment < BundleSize)
2440b57cec5SDimitry Andric       return BundleSize - EndOfFragment;
2450b57cec5SDimitry Andric     else { // EndOfFragment > BundleSize
2460b57cec5SDimitry Andric       return 2 * BundleSize - EndOfFragment;
2470b57cec5SDimitry Andric     }
2480b57cec5SDimitry Andric   } else if (OffsetInBundle > 0 && EndOfFragment > BundleSize)
2490b57cec5SDimitry Andric     return BundleSize - OffsetInBundle;
2500b57cec5SDimitry Andric   else
2510b57cec5SDimitry Andric     return 0;
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric /* *** */
2550b57cec5SDimitry Andric 
deleteNode(MCFragment * V)2560b57cec5SDimitry Andric void ilist_alloc_traits<MCFragment>::deleteNode(MCFragment *V) { V->destroy(); }
2570b57cec5SDimitry Andric 
MCFragment(FragmentType Kind,bool HasInstructions,MCSection * Parent)2580b57cec5SDimitry Andric MCFragment::MCFragment(FragmentType Kind, bool HasInstructions,
2590b57cec5SDimitry Andric                        MCSection *Parent)
260480093f4SDimitry Andric     : Parent(Parent), Atom(nullptr), Offset(~UINT64_C(0)), LayoutOrder(0),
2615ffd83dbSDimitry Andric       Kind(Kind), IsBeingLaidOut(false), HasInstructions(HasInstructions) {
262480093f4SDimitry Andric   if (Parent && !isa<MCDummyFragment>(*this))
2630b57cec5SDimitry Andric     Parent->getFragmentList().push_back(this);
2640b57cec5SDimitry Andric }
2650b57cec5SDimitry Andric 
destroy()2660b57cec5SDimitry Andric void MCFragment::destroy() {
2677a6dacacSDimitry Andric   // First check if we are the sentinel.
2680b57cec5SDimitry Andric   if (Kind == FragmentType(~0)) {
2690b57cec5SDimitry Andric     delete this;
2700b57cec5SDimitry Andric     return;
2710b57cec5SDimitry Andric   }
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   switch (Kind) {
2740b57cec5SDimitry Andric     case FT_Align:
2750b57cec5SDimitry Andric       delete cast<MCAlignFragment>(this);
2760b57cec5SDimitry Andric       return;
2770b57cec5SDimitry Andric     case FT_Data:
2780b57cec5SDimitry Andric       delete cast<MCDataFragment>(this);
2790b57cec5SDimitry Andric       return;
2800b57cec5SDimitry Andric     case FT_CompactEncodedInst:
2810b57cec5SDimitry Andric       delete cast<MCCompactEncodedInstFragment>(this);
2820b57cec5SDimitry Andric       return;
2830b57cec5SDimitry Andric     case FT_Fill:
2840b57cec5SDimitry Andric       delete cast<MCFillFragment>(this);
2850b57cec5SDimitry Andric       return;
286e8d8bef9SDimitry Andric     case FT_Nops:
287e8d8bef9SDimitry Andric       delete cast<MCNopsFragment>(this);
288e8d8bef9SDimitry Andric       return;
2890b57cec5SDimitry Andric     case FT_Relaxable:
2900b57cec5SDimitry Andric       delete cast<MCRelaxableFragment>(this);
2910b57cec5SDimitry Andric       return;
2920b57cec5SDimitry Andric     case FT_Org:
2930b57cec5SDimitry Andric       delete cast<MCOrgFragment>(this);
2940b57cec5SDimitry Andric       return;
2950b57cec5SDimitry Andric     case FT_Dwarf:
2960b57cec5SDimitry Andric       delete cast<MCDwarfLineAddrFragment>(this);
2970b57cec5SDimitry Andric       return;
2980b57cec5SDimitry Andric     case FT_DwarfFrame:
2990b57cec5SDimitry Andric       delete cast<MCDwarfCallFrameFragment>(this);
3000b57cec5SDimitry Andric       return;
3010b57cec5SDimitry Andric     case FT_LEB:
3020b57cec5SDimitry Andric       delete cast<MCLEBFragment>(this);
3030b57cec5SDimitry Andric       return;
304480093f4SDimitry Andric     case FT_BoundaryAlign:
305480093f4SDimitry Andric       delete cast<MCBoundaryAlignFragment>(this);
3060b57cec5SDimitry Andric       return;
3070b57cec5SDimitry Andric     case FT_SymbolId:
3080b57cec5SDimitry Andric       delete cast<MCSymbolIdFragment>(this);
3090b57cec5SDimitry Andric       return;
3100b57cec5SDimitry Andric     case FT_CVInlineLines:
3110b57cec5SDimitry Andric       delete cast<MCCVInlineLineTableFragment>(this);
3120b57cec5SDimitry Andric       return;
3130b57cec5SDimitry Andric     case FT_CVDefRange:
3140b57cec5SDimitry Andric       delete cast<MCCVDefRangeFragment>(this);
3150b57cec5SDimitry Andric       return;
316e8d8bef9SDimitry Andric     case FT_PseudoProbe:
317e8d8bef9SDimitry Andric       delete cast<MCPseudoProbeAddrFragment>(this);
318e8d8bef9SDimitry Andric       return;
3190b57cec5SDimitry Andric     case FT_Dummy:
3200b57cec5SDimitry Andric       delete cast<MCDummyFragment>(this);
3210b57cec5SDimitry Andric       return;
3220b57cec5SDimitry Andric   }
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric // Debugging methods
3260b57cec5SDimitry Andric 
3270b57cec5SDimitry Andric namespace llvm {
3280b57cec5SDimitry Andric 
operator <<(raw_ostream & OS,const MCFixup & AF)3290b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) {
3300b57cec5SDimitry Andric   OS << "<MCFixup" << " Offset:" << AF.getOffset()
3310b57cec5SDimitry Andric      << " Value:" << *AF.getValue()
3320b57cec5SDimitry Andric      << " Kind:" << AF.getKind() << ">";
3330b57cec5SDimitry Andric   return OS;
3340b57cec5SDimitry Andric }
3350b57cec5SDimitry Andric 
3360b57cec5SDimitry Andric } // end namespace llvm
3370b57cec5SDimitry Andric 
3380b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const3390b57cec5SDimitry Andric LLVM_DUMP_METHOD void MCFragment::dump() const {
3400b57cec5SDimitry Andric   raw_ostream &OS = errs();
3410b57cec5SDimitry Andric 
3420b57cec5SDimitry Andric   OS << "<";
3430b57cec5SDimitry Andric   switch (getKind()) {
3440b57cec5SDimitry Andric   case MCFragment::FT_Align: OS << "MCAlignFragment"; break;
3450b57cec5SDimitry Andric   case MCFragment::FT_Data:  OS << "MCDataFragment"; break;
3460b57cec5SDimitry Andric   case MCFragment::FT_CompactEncodedInst:
3470b57cec5SDimitry Andric     OS << "MCCompactEncodedInstFragment"; break;
3480b57cec5SDimitry Andric   case MCFragment::FT_Fill:  OS << "MCFillFragment"; break;
349e8d8bef9SDimitry Andric   case MCFragment::FT_Nops:
350e8d8bef9SDimitry Andric     OS << "MCFNopsFragment";
351e8d8bef9SDimitry Andric     break;
3520b57cec5SDimitry Andric   case MCFragment::FT_Relaxable:  OS << "MCRelaxableFragment"; break;
3530b57cec5SDimitry Andric   case MCFragment::FT_Org:   OS << "MCOrgFragment"; break;
3540b57cec5SDimitry Andric   case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
3550b57cec5SDimitry Andric   case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break;
3560b57cec5SDimitry Andric   case MCFragment::FT_LEB:   OS << "MCLEBFragment"; break;
357480093f4SDimitry Andric   case MCFragment::FT_BoundaryAlign: OS<<"MCBoundaryAlignFragment"; break;
3580b57cec5SDimitry Andric   case MCFragment::FT_SymbolId:    OS << "MCSymbolIdFragment"; break;
3590b57cec5SDimitry Andric   case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break;
3600b57cec5SDimitry Andric   case MCFragment::FT_CVDefRange: OS << "MCCVDefRangeTableFragment"; break;
361e8d8bef9SDimitry Andric   case MCFragment::FT_PseudoProbe:
362e8d8bef9SDimitry Andric     OS << "MCPseudoProbe";
363e8d8bef9SDimitry Andric     break;
3640b57cec5SDimitry Andric   case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break;
3650b57cec5SDimitry Andric   }
3660b57cec5SDimitry Andric 
3670b57cec5SDimitry Andric   OS << "<MCFragment " << (const void *)this << " LayoutOrder:" << LayoutOrder
3680b57cec5SDimitry Andric      << " Offset:" << Offset << " HasInstructions:" << hasInstructions();
369480093f4SDimitry Andric   if (const auto *EF = dyn_cast<MCEncodedFragment>(this))
3700b57cec5SDimitry Andric     OS << " BundlePadding:" << static_cast<unsigned>(EF->getBundlePadding());
3710b57cec5SDimitry Andric   OS << ">";
3720b57cec5SDimitry Andric 
3730b57cec5SDimitry Andric   switch (getKind()) {
3740b57cec5SDimitry Andric   case MCFragment::FT_Align: {
375480093f4SDimitry Andric     const auto *AF = cast<MCAlignFragment>(this);
3760b57cec5SDimitry Andric     if (AF->hasEmitNops())
3770b57cec5SDimitry Andric       OS << " (emit nops)";
3780b57cec5SDimitry Andric     OS << "\n       ";
37981ad6265SDimitry Andric     OS << " Alignment:" << AF->getAlignment().value()
3800b57cec5SDimitry Andric        << " Value:" << AF->getValue() << " ValueSize:" << AF->getValueSize()
3810b57cec5SDimitry Andric        << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">";
3820b57cec5SDimitry Andric     break;
3830b57cec5SDimitry Andric   }
3840b57cec5SDimitry Andric   case MCFragment::FT_Data:  {
385480093f4SDimitry Andric     const auto *DF = cast<MCDataFragment>(this);
3860b57cec5SDimitry Andric     OS << "\n       ";
3870b57cec5SDimitry Andric     OS << " Contents:[";
3880b57cec5SDimitry Andric     const SmallVectorImpl<char> &Contents = DF->getContents();
3890b57cec5SDimitry Andric     for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
3900b57cec5SDimitry Andric       if (i) OS << ",";
3910b57cec5SDimitry Andric       OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
3920b57cec5SDimitry Andric     }
3930b57cec5SDimitry Andric     OS << "] (" << Contents.size() << " bytes)";
3940b57cec5SDimitry Andric 
3950b57cec5SDimitry Andric     if (DF->fixup_begin() != DF->fixup_end()) {
3960b57cec5SDimitry Andric       OS << ",\n       ";
3970b57cec5SDimitry Andric       OS << " Fixups:[";
3980b57cec5SDimitry Andric       for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(),
3990b57cec5SDimitry Andric              ie = DF->fixup_end(); it != ie; ++it) {
4000b57cec5SDimitry Andric         if (it != DF->fixup_begin()) OS << ",\n                ";
4010b57cec5SDimitry Andric         OS << *it;
4020b57cec5SDimitry Andric       }
4030b57cec5SDimitry Andric       OS << "]";
4040b57cec5SDimitry Andric     }
4050b57cec5SDimitry Andric     break;
4060b57cec5SDimitry Andric   }
4070b57cec5SDimitry Andric   case MCFragment::FT_CompactEncodedInst: {
408480093f4SDimitry Andric     const auto *CEIF =
4090b57cec5SDimitry Andric       cast<MCCompactEncodedInstFragment>(this);
4100b57cec5SDimitry Andric     OS << "\n       ";
4110b57cec5SDimitry Andric     OS << " Contents:[";
4120b57cec5SDimitry Andric     const SmallVectorImpl<char> &Contents = CEIF->getContents();
4130b57cec5SDimitry Andric     for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
4140b57cec5SDimitry Andric       if (i) OS << ",";
4150b57cec5SDimitry Andric       OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
4160b57cec5SDimitry Andric     }
4170b57cec5SDimitry Andric     OS << "] (" << Contents.size() << " bytes)";
4180b57cec5SDimitry Andric     break;
4190b57cec5SDimitry Andric   }
4200b57cec5SDimitry Andric   case MCFragment::FT_Fill:  {
421480093f4SDimitry Andric     const auto *FF = cast<MCFillFragment>(this);
4220b57cec5SDimitry Andric     OS << " Value:" << static_cast<unsigned>(FF->getValue())
4230b57cec5SDimitry Andric        << " ValueSize:" << static_cast<unsigned>(FF->getValueSize())
4240b57cec5SDimitry Andric        << " NumValues:" << FF->getNumValues();
4250b57cec5SDimitry Andric     break;
4260b57cec5SDimitry Andric   }
427e8d8bef9SDimitry Andric   case MCFragment::FT_Nops: {
428e8d8bef9SDimitry Andric     const auto *NF = cast<MCNopsFragment>(this);
429e8d8bef9SDimitry Andric     OS << " NumBytes:" << NF->getNumBytes()
430e8d8bef9SDimitry Andric        << " ControlledNopLength:" << NF->getControlledNopLength();
431e8d8bef9SDimitry Andric     break;
432e8d8bef9SDimitry Andric   }
4330b57cec5SDimitry Andric   case MCFragment::FT_Relaxable:  {
434480093f4SDimitry Andric     const auto *F = cast<MCRelaxableFragment>(this);
4350b57cec5SDimitry Andric     OS << "\n       ";
4360b57cec5SDimitry Andric     OS << " Inst:";
4370b57cec5SDimitry Andric     F->getInst().dump_pretty(OS);
4385ffd83dbSDimitry Andric     OS << " (" << F->getContents().size() << " bytes)";
4390b57cec5SDimitry Andric     break;
4400b57cec5SDimitry Andric   }
4410b57cec5SDimitry Andric   case MCFragment::FT_Org:  {
442480093f4SDimitry Andric     const auto *OF = cast<MCOrgFragment>(this);
4430b57cec5SDimitry Andric     OS << "\n       ";
4440b57cec5SDimitry Andric     OS << " Offset:" << OF->getOffset()
4450b57cec5SDimitry Andric        << " Value:" << static_cast<unsigned>(OF->getValue());
4460b57cec5SDimitry Andric     break;
4470b57cec5SDimitry Andric   }
4480b57cec5SDimitry Andric   case MCFragment::FT_Dwarf:  {
449480093f4SDimitry Andric     const auto *OF = cast<MCDwarfLineAddrFragment>(this);
4500b57cec5SDimitry Andric     OS << "\n       ";
4510b57cec5SDimitry Andric     OS << " AddrDelta:" << OF->getAddrDelta()
4520b57cec5SDimitry Andric        << " LineDelta:" << OF->getLineDelta();
4530b57cec5SDimitry Andric     break;
4540b57cec5SDimitry Andric   }
4550b57cec5SDimitry Andric   case MCFragment::FT_DwarfFrame:  {
456480093f4SDimitry Andric     const auto *CF = cast<MCDwarfCallFrameFragment>(this);
4570b57cec5SDimitry Andric     OS << "\n       ";
4580b57cec5SDimitry Andric     OS << " AddrDelta:" << CF->getAddrDelta();
4590b57cec5SDimitry Andric     break;
4600b57cec5SDimitry Andric   }
4610b57cec5SDimitry Andric   case MCFragment::FT_LEB: {
462480093f4SDimitry Andric     const auto *LF = cast<MCLEBFragment>(this);
4630b57cec5SDimitry Andric     OS << "\n       ";
4640b57cec5SDimitry Andric     OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned();
4650b57cec5SDimitry Andric     break;
4660b57cec5SDimitry Andric   }
467480093f4SDimitry Andric   case MCFragment::FT_BoundaryAlign: {
468480093f4SDimitry Andric     const auto *BF = cast<MCBoundaryAlignFragment>(this);
4690b57cec5SDimitry Andric     OS << "\n       ";
470480093f4SDimitry Andric     OS << " BoundarySize:" << BF->getAlignment().value()
4715ffd83dbSDimitry Andric        << " LastFragment:" << BF->getLastFragment()
472480093f4SDimitry Andric        << " Size:" << BF->getSize();
4730b57cec5SDimitry Andric     break;
4740b57cec5SDimitry Andric   }
4750b57cec5SDimitry Andric   case MCFragment::FT_SymbolId: {
476480093f4SDimitry Andric     const auto *F = cast<MCSymbolIdFragment>(this);
4770b57cec5SDimitry Andric     OS << "\n       ";
4780b57cec5SDimitry Andric     OS << " Sym:" << F->getSymbol();
4790b57cec5SDimitry Andric     break;
4800b57cec5SDimitry Andric   }
4810b57cec5SDimitry Andric   case MCFragment::FT_CVInlineLines: {
4820b57cec5SDimitry Andric     const auto *F = cast<MCCVInlineLineTableFragment>(this);
4830b57cec5SDimitry Andric     OS << "\n       ";
4840b57cec5SDimitry Andric     OS << " Sym:" << *F->getFnStartSym();
4850b57cec5SDimitry Andric     break;
4860b57cec5SDimitry Andric   }
4870b57cec5SDimitry Andric   case MCFragment::FT_CVDefRange: {
4880b57cec5SDimitry Andric     const auto *F = cast<MCCVDefRangeFragment>(this);
4890b57cec5SDimitry Andric     OS << "\n       ";
4900b57cec5SDimitry Andric     for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd :
4910b57cec5SDimitry Andric          F->getRanges()) {
4920b57cec5SDimitry Andric       OS << " RangeStart:" << RangeStartEnd.first;
4930b57cec5SDimitry Andric       OS << " RangeEnd:" << RangeStartEnd.second;
4940b57cec5SDimitry Andric     }
4950b57cec5SDimitry Andric     break;
4960b57cec5SDimitry Andric   }
497e8d8bef9SDimitry Andric   case MCFragment::FT_PseudoProbe: {
498e8d8bef9SDimitry Andric     const auto *OF = cast<MCPseudoProbeAddrFragment>(this);
499e8d8bef9SDimitry Andric     OS << "\n       ";
500e8d8bef9SDimitry Andric     OS << " AddrDelta:" << OF->getAddrDelta();
501e8d8bef9SDimitry Andric     break;
502e8d8bef9SDimitry Andric   }
5030b57cec5SDimitry Andric   case MCFragment::FT_Dummy:
5040b57cec5SDimitry Andric     break;
5050b57cec5SDimitry Andric   }
5060b57cec5SDimitry Andric   OS << ">";
5070b57cec5SDimitry Andric }
5080b57cec5SDimitry Andric #endif
509