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/MCContext.h" 150b57cec5SDimitry Andric #include "llvm/MC/MCFixup.h" 160b57cec5SDimitry Andric #include "llvm/MC/MCSection.h" 17*0fca6ea1SDimitry Andric #include "llvm/MC/MCSectionMachO.h" 180b57cec5SDimitry Andric #include "llvm/MC/MCSymbol.h" 190b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 200b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 210b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 220b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 230b57cec5SDimitry Andric #include <cassert> 240b57cec5SDimitry Andric #include <cstdint> 250b57cec5SDimitry Andric #include <utility> 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric using namespace llvm; 280b57cec5SDimitry Andric 29*0fca6ea1SDimitry Andric MCFragment::MCFragment(FragmentType Kind, bool HasInstructions) 30*0fca6ea1SDimitry Andric : Kind(Kind), HasInstructions(HasInstructions), LinkerRelaxable(false) {} 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric void MCFragment::destroy() { 330b57cec5SDimitry Andric switch (Kind) { 340b57cec5SDimitry Andric case FT_Align: 35*0fca6ea1SDimitry Andric cast<MCAlignFragment>(this)->~MCAlignFragment(); 360b57cec5SDimitry Andric return; 370b57cec5SDimitry Andric case FT_Data: 38*0fca6ea1SDimitry Andric cast<MCDataFragment>(this)->~MCDataFragment(); 390b57cec5SDimitry Andric return; 400b57cec5SDimitry Andric case FT_CompactEncodedInst: 41*0fca6ea1SDimitry Andric cast<MCCompactEncodedInstFragment>(this)->~MCCompactEncodedInstFragment(); 420b57cec5SDimitry Andric return; 430b57cec5SDimitry Andric case FT_Fill: 44*0fca6ea1SDimitry Andric cast<MCFillFragment>(this)->~MCFillFragment(); 450b57cec5SDimitry Andric return; 46e8d8bef9SDimitry Andric case FT_Nops: 47*0fca6ea1SDimitry Andric cast<MCNopsFragment>(this)->~MCNopsFragment(); 48e8d8bef9SDimitry Andric return; 490b57cec5SDimitry Andric case FT_Relaxable: 50*0fca6ea1SDimitry Andric cast<MCRelaxableFragment>(this)->~MCRelaxableFragment(); 510b57cec5SDimitry Andric return; 520b57cec5SDimitry Andric case FT_Org: 53*0fca6ea1SDimitry Andric cast<MCOrgFragment>(this)->~MCOrgFragment(); 540b57cec5SDimitry Andric return; 550b57cec5SDimitry Andric case FT_Dwarf: 56*0fca6ea1SDimitry Andric cast<MCDwarfLineAddrFragment>(this)->~MCDwarfLineAddrFragment(); 570b57cec5SDimitry Andric return; 580b57cec5SDimitry Andric case FT_DwarfFrame: 59*0fca6ea1SDimitry Andric cast<MCDwarfCallFrameFragment>(this)->~MCDwarfCallFrameFragment(); 600b57cec5SDimitry Andric return; 610b57cec5SDimitry Andric case FT_LEB: 62*0fca6ea1SDimitry Andric cast<MCLEBFragment>(this)->~MCLEBFragment(); 630b57cec5SDimitry Andric return; 64480093f4SDimitry Andric case FT_BoundaryAlign: 65*0fca6ea1SDimitry Andric cast<MCBoundaryAlignFragment>(this)->~MCBoundaryAlignFragment(); 660b57cec5SDimitry Andric return; 670b57cec5SDimitry Andric case FT_SymbolId: 68*0fca6ea1SDimitry Andric cast<MCSymbolIdFragment>(this)->~MCSymbolIdFragment(); 690b57cec5SDimitry Andric return; 700b57cec5SDimitry Andric case FT_CVInlineLines: 71*0fca6ea1SDimitry Andric cast<MCCVInlineLineTableFragment>(this)->~MCCVInlineLineTableFragment(); 720b57cec5SDimitry Andric return; 730b57cec5SDimitry Andric case FT_CVDefRange: 74*0fca6ea1SDimitry Andric cast<MCCVDefRangeFragment>(this)->~MCCVDefRangeFragment(); 750b57cec5SDimitry Andric return; 76e8d8bef9SDimitry Andric case FT_PseudoProbe: 77*0fca6ea1SDimitry Andric cast<MCPseudoProbeAddrFragment>(this)->~MCPseudoProbeAddrFragment(); 78e8d8bef9SDimitry Andric return; 790b57cec5SDimitry Andric case FT_Dummy: 80*0fca6ea1SDimitry Andric cast<MCDummyFragment>(this)->~MCDummyFragment(); 810b57cec5SDimitry Andric return; 820b57cec5SDimitry Andric } 830b57cec5SDimitry Andric } 840b57cec5SDimitry Andric 85*0fca6ea1SDimitry Andric const MCSymbol *MCFragment::getAtom() const { 86*0fca6ea1SDimitry Andric return cast<MCSectionMachO>(Parent)->getAtom(LayoutOrder); 87*0fca6ea1SDimitry Andric } 88*0fca6ea1SDimitry Andric 890b57cec5SDimitry Andric // Debugging methods 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric namespace llvm { 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) { 940b57cec5SDimitry Andric OS << "<MCFixup" << " Offset:" << AF.getOffset() 950b57cec5SDimitry Andric << " Value:" << *AF.getValue() 960b57cec5SDimitry Andric << " Kind:" << AF.getKind() << ">"; 970b57cec5SDimitry Andric return OS; 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric } // end namespace llvm 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 1030b57cec5SDimitry Andric LLVM_DUMP_METHOD void MCFragment::dump() const { 1040b57cec5SDimitry Andric raw_ostream &OS = errs(); 1050b57cec5SDimitry Andric 1060b57cec5SDimitry Andric OS << "<"; 1070b57cec5SDimitry Andric switch (getKind()) { 1080b57cec5SDimitry Andric case MCFragment::FT_Align: OS << "MCAlignFragment"; break; 1090b57cec5SDimitry Andric case MCFragment::FT_Data: OS << "MCDataFragment"; break; 1100b57cec5SDimitry Andric case MCFragment::FT_CompactEncodedInst: 1110b57cec5SDimitry Andric OS << "MCCompactEncodedInstFragment"; break; 1120b57cec5SDimitry Andric case MCFragment::FT_Fill: OS << "MCFillFragment"; break; 113e8d8bef9SDimitry Andric case MCFragment::FT_Nops: 114e8d8bef9SDimitry Andric OS << "MCFNopsFragment"; 115e8d8bef9SDimitry Andric break; 1160b57cec5SDimitry Andric case MCFragment::FT_Relaxable: OS << "MCRelaxableFragment"; break; 1170b57cec5SDimitry Andric case MCFragment::FT_Org: OS << "MCOrgFragment"; break; 1180b57cec5SDimitry Andric case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break; 1190b57cec5SDimitry Andric case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break; 1200b57cec5SDimitry Andric case MCFragment::FT_LEB: OS << "MCLEBFragment"; break; 121480093f4SDimitry Andric case MCFragment::FT_BoundaryAlign: OS<<"MCBoundaryAlignFragment"; break; 1220b57cec5SDimitry Andric case MCFragment::FT_SymbolId: OS << "MCSymbolIdFragment"; break; 1230b57cec5SDimitry Andric case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break; 1240b57cec5SDimitry Andric case MCFragment::FT_CVDefRange: OS << "MCCVDefRangeTableFragment"; break; 125e8d8bef9SDimitry Andric case MCFragment::FT_PseudoProbe: 126e8d8bef9SDimitry Andric OS << "MCPseudoProbe"; 127e8d8bef9SDimitry Andric break; 1280b57cec5SDimitry Andric case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break; 1290b57cec5SDimitry Andric } 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric OS << "<MCFragment " << (const void *)this << " LayoutOrder:" << LayoutOrder 1320b57cec5SDimitry Andric << " Offset:" << Offset << " HasInstructions:" << hasInstructions(); 133480093f4SDimitry Andric if (const auto *EF = dyn_cast<MCEncodedFragment>(this)) 1340b57cec5SDimitry Andric OS << " BundlePadding:" << static_cast<unsigned>(EF->getBundlePadding()); 1350b57cec5SDimitry Andric OS << ">"; 1360b57cec5SDimitry Andric 1370b57cec5SDimitry Andric switch (getKind()) { 1380b57cec5SDimitry Andric case MCFragment::FT_Align: { 139480093f4SDimitry Andric const auto *AF = cast<MCAlignFragment>(this); 1400b57cec5SDimitry Andric if (AF->hasEmitNops()) 1410b57cec5SDimitry Andric OS << " (emit nops)"; 1420b57cec5SDimitry Andric OS << "\n "; 14381ad6265SDimitry Andric OS << " Alignment:" << AF->getAlignment().value() 1440b57cec5SDimitry Andric << " Value:" << AF->getValue() << " ValueSize:" << AF->getValueSize() 1450b57cec5SDimitry Andric << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">"; 1460b57cec5SDimitry Andric break; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric case MCFragment::FT_Data: { 149480093f4SDimitry Andric const auto *DF = cast<MCDataFragment>(this); 1500b57cec5SDimitry Andric OS << "\n "; 1510b57cec5SDimitry Andric OS << " Contents:["; 1520b57cec5SDimitry Andric const SmallVectorImpl<char> &Contents = DF->getContents(); 1530b57cec5SDimitry Andric for (unsigned i = 0, e = Contents.size(); i != e; ++i) { 1540b57cec5SDimitry Andric if (i) OS << ","; 1550b57cec5SDimitry Andric OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 1560b57cec5SDimitry Andric } 1570b57cec5SDimitry Andric OS << "] (" << Contents.size() << " bytes)"; 1580b57cec5SDimitry Andric 1590b57cec5SDimitry Andric if (DF->fixup_begin() != DF->fixup_end()) { 1600b57cec5SDimitry Andric OS << ",\n "; 1610b57cec5SDimitry Andric OS << " Fixups:["; 1620b57cec5SDimitry Andric for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(), 1630b57cec5SDimitry Andric ie = DF->fixup_end(); it != ie; ++it) { 1640b57cec5SDimitry Andric if (it != DF->fixup_begin()) OS << ",\n "; 1650b57cec5SDimitry Andric OS << *it; 1660b57cec5SDimitry Andric } 1670b57cec5SDimitry Andric OS << "]"; 1680b57cec5SDimitry Andric } 1690b57cec5SDimitry Andric break; 1700b57cec5SDimitry Andric } 1710b57cec5SDimitry Andric case MCFragment::FT_CompactEncodedInst: { 172480093f4SDimitry Andric const auto *CEIF = 1730b57cec5SDimitry Andric cast<MCCompactEncodedInstFragment>(this); 1740b57cec5SDimitry Andric OS << "\n "; 1750b57cec5SDimitry Andric OS << " Contents:["; 1760b57cec5SDimitry Andric const SmallVectorImpl<char> &Contents = CEIF->getContents(); 1770b57cec5SDimitry Andric for (unsigned i = 0, e = Contents.size(); i != e; ++i) { 1780b57cec5SDimitry Andric if (i) OS << ","; 1790b57cec5SDimitry Andric OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF); 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric OS << "] (" << Contents.size() << " bytes)"; 1820b57cec5SDimitry Andric break; 1830b57cec5SDimitry Andric } 1840b57cec5SDimitry Andric case MCFragment::FT_Fill: { 185480093f4SDimitry Andric const auto *FF = cast<MCFillFragment>(this); 1860b57cec5SDimitry Andric OS << " Value:" << static_cast<unsigned>(FF->getValue()) 1870b57cec5SDimitry Andric << " ValueSize:" << static_cast<unsigned>(FF->getValueSize()) 1880b57cec5SDimitry Andric << " NumValues:" << FF->getNumValues(); 1890b57cec5SDimitry Andric break; 1900b57cec5SDimitry Andric } 191e8d8bef9SDimitry Andric case MCFragment::FT_Nops: { 192e8d8bef9SDimitry Andric const auto *NF = cast<MCNopsFragment>(this); 193e8d8bef9SDimitry Andric OS << " NumBytes:" << NF->getNumBytes() 194e8d8bef9SDimitry Andric << " ControlledNopLength:" << NF->getControlledNopLength(); 195e8d8bef9SDimitry Andric break; 196e8d8bef9SDimitry Andric } 1970b57cec5SDimitry Andric case MCFragment::FT_Relaxable: { 198480093f4SDimitry Andric const auto *F = cast<MCRelaxableFragment>(this); 1990b57cec5SDimitry Andric OS << "\n "; 2000b57cec5SDimitry Andric OS << " Inst:"; 2010b57cec5SDimitry Andric F->getInst().dump_pretty(OS); 2025ffd83dbSDimitry Andric OS << " (" << F->getContents().size() << " bytes)"; 2030b57cec5SDimitry Andric break; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric case MCFragment::FT_Org: { 206480093f4SDimitry Andric const auto *OF = cast<MCOrgFragment>(this); 2070b57cec5SDimitry Andric OS << "\n "; 2080b57cec5SDimitry Andric OS << " Offset:" << OF->getOffset() 2090b57cec5SDimitry Andric << " Value:" << static_cast<unsigned>(OF->getValue()); 2100b57cec5SDimitry Andric break; 2110b57cec5SDimitry Andric } 2120b57cec5SDimitry Andric case MCFragment::FT_Dwarf: { 213480093f4SDimitry Andric const auto *OF = cast<MCDwarfLineAddrFragment>(this); 2140b57cec5SDimitry Andric OS << "\n "; 2150b57cec5SDimitry Andric OS << " AddrDelta:" << OF->getAddrDelta() 2160b57cec5SDimitry Andric << " LineDelta:" << OF->getLineDelta(); 2170b57cec5SDimitry Andric break; 2180b57cec5SDimitry Andric } 2190b57cec5SDimitry Andric case MCFragment::FT_DwarfFrame: { 220480093f4SDimitry Andric const auto *CF = cast<MCDwarfCallFrameFragment>(this); 2210b57cec5SDimitry Andric OS << "\n "; 2220b57cec5SDimitry Andric OS << " AddrDelta:" << CF->getAddrDelta(); 2230b57cec5SDimitry Andric break; 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric case MCFragment::FT_LEB: { 226480093f4SDimitry Andric const auto *LF = cast<MCLEBFragment>(this); 2270b57cec5SDimitry Andric OS << "\n "; 2280b57cec5SDimitry Andric OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned(); 2290b57cec5SDimitry Andric break; 2300b57cec5SDimitry Andric } 231480093f4SDimitry Andric case MCFragment::FT_BoundaryAlign: { 232480093f4SDimitry Andric const auto *BF = cast<MCBoundaryAlignFragment>(this); 2330b57cec5SDimitry Andric OS << "\n "; 234480093f4SDimitry Andric OS << " BoundarySize:" << BF->getAlignment().value() 2355ffd83dbSDimitry Andric << " LastFragment:" << BF->getLastFragment() 236480093f4SDimitry Andric << " Size:" << BF->getSize(); 2370b57cec5SDimitry Andric break; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric case MCFragment::FT_SymbolId: { 240480093f4SDimitry Andric const auto *F = cast<MCSymbolIdFragment>(this); 2410b57cec5SDimitry Andric OS << "\n "; 2420b57cec5SDimitry Andric OS << " Sym:" << F->getSymbol(); 2430b57cec5SDimitry Andric break; 2440b57cec5SDimitry Andric } 2450b57cec5SDimitry Andric case MCFragment::FT_CVInlineLines: { 2460b57cec5SDimitry Andric const auto *F = cast<MCCVInlineLineTableFragment>(this); 2470b57cec5SDimitry Andric OS << "\n "; 2480b57cec5SDimitry Andric OS << " Sym:" << *F->getFnStartSym(); 2490b57cec5SDimitry Andric break; 2500b57cec5SDimitry Andric } 2510b57cec5SDimitry Andric case MCFragment::FT_CVDefRange: { 2520b57cec5SDimitry Andric const auto *F = cast<MCCVDefRangeFragment>(this); 2530b57cec5SDimitry Andric OS << "\n "; 2540b57cec5SDimitry Andric for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd : 2550b57cec5SDimitry Andric F->getRanges()) { 2560b57cec5SDimitry Andric OS << " RangeStart:" << RangeStartEnd.first; 2570b57cec5SDimitry Andric OS << " RangeEnd:" << RangeStartEnd.second; 2580b57cec5SDimitry Andric } 2590b57cec5SDimitry Andric break; 2600b57cec5SDimitry Andric } 261e8d8bef9SDimitry Andric case MCFragment::FT_PseudoProbe: { 262e8d8bef9SDimitry Andric const auto *OF = cast<MCPseudoProbeAddrFragment>(this); 263e8d8bef9SDimitry Andric OS << "\n "; 264e8d8bef9SDimitry Andric OS << " AddrDelta:" << OF->getAddrDelta(); 265e8d8bef9SDimitry Andric break; 266e8d8bef9SDimitry Andric } 2670b57cec5SDimitry Andric case MCFragment::FT_Dummy: 2680b57cec5SDimitry Andric break; 2690b57cec5SDimitry Andric } 2700b57cec5SDimitry Andric OS << ">"; 2710b57cec5SDimitry Andric } 2720b57cec5SDimitry Andric #endif 273