xref: /freebsd-src/contrib/llvm-project/llvm/lib/MC/MCFragment.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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