xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCFragment.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
1 //===- lib/MC/MCFragment.cpp - Assembler Fragment Implementation ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/ADT/SmallVector.h"
10 #include "llvm/ADT/StringExtras.h"
11 #include "llvm/ADT/Twine.h"
12 #include "llvm/Config/llvm-config.h"
13 #include "llvm/MC/MCContext.h"
14 #include "llvm/MC/MCFixup.h"
15 #include "llvm/MC/MCSection.h"
16 #include "llvm/MC/MCSectionMachO.h"
17 #include "llvm/MC/MCSymbol.h"
18 #include "llvm/Support/Casting.h"
19 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include <cassert>
22 #include <type_traits>
23 #include <utility>
24 
25 using namespace llvm;
26 
27 static_assert(std::is_trivially_destructible_v<MCDataFragment>,
28               "fragment classes must be trivially destructible");
29 
MCFragment(FragmentType Kind,bool HasInstructions)30 MCFragment::MCFragment(FragmentType Kind, bool HasInstructions)
31     : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false),
32       LinkerRelaxable(false), AllowAutoPadding(false) {}
33 
getAtom() const34 const MCSymbol *MCFragment::getAtom() const {
35   return cast<MCSectionMachO>(Parent)->getAtom(LayoutOrder);
36 }
37 
38 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const39 LLVM_DUMP_METHOD void MCFragment::dump() const {
40   raw_ostream &OS = errs();
41 
42   OS << Offset << ' ';
43   switch (getKind()) {
44     // clang-format off
45   case MCFragment::FT_Align:         OS << "Align"; break;
46   case MCFragment::FT_Data:          OS << "Data"; break;
47   case MCFragment::FT_Fill:          OS << "Fill"; break;
48   case MCFragment::FT_Nops:          OS << "Nops"; break;
49   case MCFragment::FT_Relaxable:     OS << "Relaxable"; break;
50   case MCFragment::FT_Org:           OS << "Org"; break;
51   case MCFragment::FT_Dwarf:         OS << "Dwarf"; break;
52   case MCFragment::FT_DwarfFrame:    OS << "DwarfCallFrame"; break;
53   case MCFragment::FT_LEB:           OS << "LEB"; break;
54   case MCFragment::FT_BoundaryAlign: OS<<"BoundaryAlign"; break;
55   case MCFragment::FT_SymbolId:      OS << "SymbolId"; break;
56   case MCFragment::FT_CVInlineLines: OS << "CVInlineLineTable"; break;
57   case MCFragment::FT_CVDefRange:    OS << "CVDefRangeTable"; break;
58   case MCFragment::FT_PseudoProbe:   OS << "PseudoProbe"; break;
59     // clang-format on
60   }
61 
62   if (const auto *EF = dyn_cast<MCEncodedFragment>(this))
63     if (auto Pad = static_cast<unsigned>(EF->getBundlePadding()))
64       OS << " BundlePadding:" << Pad;
65 
66   auto printFixups = [&](llvm::ArrayRef<MCFixup> Fixups) {
67     if (Fixups.empty())
68       return;
69     for (auto [I, F] : llvm::enumerate(Fixups)) {
70       OS << "\n  Fixup @" << F.getOffset() << " Value:";
71       F.getValue()->print(OS, nullptr);
72       OS << " Kind:" << F.getKind();
73       if (F.isLinkerRelaxable())
74         OS << " LinkerRelaxable";
75     }
76   };
77 
78   switch (getKind()) {
79   case MCFragment::FT_Align: {
80     const auto *AF = cast<MCAlignFragment>(this);
81     OS << " Align:" << AF->getAlignment().value() << " Fill:" << AF->getFill()
82        << " FillLen:" << unsigned(AF->getFillLen())
83        << " MaxBytesToEmit:" << AF->getMaxBytesToEmit();
84     if (AF->hasEmitNops())
85       OS << " Nops";
86     break;
87   }
88   case MCFragment::FT_Data:  {
89     const auto *F = cast<MCDataFragment>(this);
90     if (F->isLinkerRelaxable())
91       OS << " LinkerRelaxable";
92     auto Contents = F->getContents();
93     OS << " Size:" << Contents.size() << " [";
94     for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
95       if (i) OS << ",";
96       OS << format("%02x", uint8_t(Contents[i]));
97     }
98     OS << ']';
99     printFixups(F->getFixups());
100     break;
101   }
102   case MCFragment::FT_Fill:  {
103     const auto *FF = cast<MCFillFragment>(this);
104     OS << " Value:" << static_cast<unsigned>(FF->getValue())
105        << " ValueSize:" << static_cast<unsigned>(FF->getValueSize())
106        << " NumValues:";
107     FF->getNumValues().print(OS, nullptr);
108     break;
109   }
110   case MCFragment::FT_Nops: {
111     const auto *NF = cast<MCNopsFragment>(this);
112     OS << " NumBytes:" << NF->getNumBytes()
113        << " ControlledNopLength:" << NF->getControlledNopLength();
114     break;
115   }
116   case MCFragment::FT_Relaxable:  {
117     const auto *F = cast<MCRelaxableFragment>(this);
118     if (F->isLinkerRelaxable())
119       OS << " LinkerRelaxable";
120     OS << " Size:" << F->getContents().size() << ' ';
121     F->getInst().dump_pretty(OS);
122     printFixups(F->getFixups());
123     break;
124   }
125   case MCFragment::FT_Org:  {
126     const auto *OF = cast<MCOrgFragment>(this);
127     OS << " Offset:";
128     OF->getOffset().print(OS, nullptr);
129     OS << " Value:" << static_cast<unsigned>(OF->getValue());
130     break;
131   }
132   case MCFragment::FT_Dwarf:  {
133     const auto *OF = cast<MCDwarfLineAddrFragment>(this);
134     OS << " AddrDelta:";
135     OF->getAddrDelta().print(OS, nullptr);
136     OS << " LineDelta:" << OF->getLineDelta();
137     break;
138   }
139   case MCFragment::FT_DwarfFrame:  {
140     const auto *CF = cast<MCDwarfCallFrameFragment>(this);
141     OS << " AddrDelta:";
142     CF->getAddrDelta().print(OS, nullptr);
143     break;
144   }
145   case MCFragment::FT_LEB: {
146     const auto *LF = cast<MCLEBFragment>(this);
147     OS << " Value:";
148     LF->getValue().print(OS, nullptr);
149     OS << " Signed:" << LF->isSigned();
150     break;
151   }
152   case MCFragment::FT_BoundaryAlign: {
153     const auto *BF = cast<MCBoundaryAlignFragment>(this);
154     OS << " BoundarySize:" << BF->getAlignment().value()
155        << " LastFragment:" << BF->getLastFragment()
156        << " Size:" << BF->getSize();
157     break;
158   }
159   case MCFragment::FT_SymbolId: {
160     const auto *F = cast<MCSymbolIdFragment>(this);
161     OS << " Sym:" << F->getSymbol();
162     break;
163   }
164   case MCFragment::FT_CVInlineLines: {
165     const auto *F = cast<MCCVInlineLineTableFragment>(this);
166     OS << " Sym:" << *F->getFnStartSym();
167     break;
168   }
169   case MCFragment::FT_CVDefRange: {
170     const auto *F = cast<MCCVDefRangeFragment>(this);
171     OS << "\n   ";
172     for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd :
173          F->getRanges()) {
174       OS << " RangeStart:" << RangeStartEnd.first;
175       OS << " RangeEnd:" << RangeStartEnd.second;
176     }
177     break;
178   }
179   case MCFragment::FT_PseudoProbe: {
180     const auto *OF = cast<MCPseudoProbeAddrFragment>(this);
181     OS << " AddrDelta:";
182     OF->getAddrDelta().print(OS, nullptr);
183     break;
184   }
185   }
186 }
187 #endif
188