xref: /llvm-project/llvm/lib/MC/MCFragment.cpp (revision fb7028237bac1dccd328b6c3150e50e222a0879b)
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/MC/MCFragment.h"
10 #include "llvm/ADT/SmallVector.h"
11 #include "llvm/ADT/StringExtras.h"
12 #include "llvm/ADT/Twine.h"
13 #include "llvm/Config/llvm-config.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCFixup.h"
16 #include "llvm/MC/MCSection.h"
17 #include "llvm/MC/MCSectionMachO.h"
18 #include "llvm/MC/MCSymbol.h"
19 #include "llvm/Support/Casting.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include <cassert>
24 #include <cstdint>
25 #include <utility>
26 
27 using namespace llvm;
28 
29 MCFragment::MCFragment(FragmentType Kind, bool HasInstructions)
30     : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false),
31       LinkerRelaxable(false), AllowAutoPadding(false) {}
32 
33 void MCFragment::destroy() {
34   switch (Kind) {
35     case FT_Align:
36       cast<MCAlignFragment>(this)->~MCAlignFragment();
37       return;
38     case FT_Data:
39       cast<MCDataFragment>(this)->~MCDataFragment();
40       return;
41     case FT_Fill:
42       cast<MCFillFragment>(this)->~MCFillFragment();
43       return;
44     case FT_Nops:
45       cast<MCNopsFragment>(this)->~MCNopsFragment();
46       return;
47     case FT_Relaxable:
48       cast<MCRelaxableFragment>(this)->~MCRelaxableFragment();
49       return;
50     case FT_Org:
51       cast<MCOrgFragment>(this)->~MCOrgFragment();
52       return;
53     case FT_Dwarf:
54       cast<MCDwarfLineAddrFragment>(this)->~MCDwarfLineAddrFragment();
55       return;
56     case FT_DwarfFrame:
57       cast<MCDwarfCallFrameFragment>(this)->~MCDwarfCallFrameFragment();
58       return;
59     case FT_LEB:
60       cast<MCLEBFragment>(this)->~MCLEBFragment();
61       return;
62     case FT_BoundaryAlign:
63       cast<MCBoundaryAlignFragment>(this)->~MCBoundaryAlignFragment();
64       return;
65     case FT_SymbolId:
66       cast<MCSymbolIdFragment>(this)->~MCSymbolIdFragment();
67       return;
68     case FT_CVInlineLines:
69       cast<MCCVInlineLineTableFragment>(this)->~MCCVInlineLineTableFragment();
70       return;
71     case FT_CVDefRange:
72       cast<MCCVDefRangeFragment>(this)->~MCCVDefRangeFragment();
73       return;
74     case FT_PseudoProbe:
75       cast<MCPseudoProbeAddrFragment>(this)->~MCPseudoProbeAddrFragment();
76       return;
77     case FT_Dummy:
78       cast<MCDummyFragment>(this)->~MCDummyFragment();
79       return;
80   }
81 }
82 
83 const MCSymbol *MCFragment::getAtom() const {
84   return cast<MCSectionMachO>(Parent)->getAtom(LayoutOrder);
85 }
86 
87 // Debugging methods
88 
89 namespace llvm {
90 
91 raw_ostream &operator<<(raw_ostream &OS, const MCFixup &AF) {
92   OS << "<MCFixup" << " Offset:" << AF.getOffset()
93      << " Value:" << *AF.getValue()
94      << " Kind:" << AF.getKind() << ">";
95   return OS;
96 }
97 
98 } // end namespace llvm
99 
100 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
101 LLVM_DUMP_METHOD void MCFragment::dump() const {
102   raw_ostream &OS = errs();
103 
104   OS << "<";
105   switch (getKind()) {
106   case MCFragment::FT_Align: OS << "MCAlignFragment"; break;
107   case MCFragment::FT_Data:  OS << "MCDataFragment"; break;
108   case MCFragment::FT_Fill:  OS << "MCFillFragment"; break;
109   case MCFragment::FT_Nops:
110     OS << "MCFNopsFragment";
111     break;
112   case MCFragment::FT_Relaxable:  OS << "MCRelaxableFragment"; break;
113   case MCFragment::FT_Org:   OS << "MCOrgFragment"; break;
114   case MCFragment::FT_Dwarf: OS << "MCDwarfFragment"; break;
115   case MCFragment::FT_DwarfFrame: OS << "MCDwarfCallFrameFragment"; break;
116   case MCFragment::FT_LEB:   OS << "MCLEBFragment"; break;
117   case MCFragment::FT_BoundaryAlign: OS<<"MCBoundaryAlignFragment"; break;
118   case MCFragment::FT_SymbolId:    OS << "MCSymbolIdFragment"; break;
119   case MCFragment::FT_CVInlineLines: OS << "MCCVInlineLineTableFragment"; break;
120   case MCFragment::FT_CVDefRange: OS << "MCCVDefRangeTableFragment"; break;
121   case MCFragment::FT_PseudoProbe:
122     OS << "MCPseudoProbe";
123     break;
124   case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break;
125   }
126 
127   OS << "<MCFragment " << (const void *)this << " LayoutOrder:" << LayoutOrder
128      << " Offset:" << Offset << " HasInstructions:" << hasInstructions();
129   if (const auto *EF = dyn_cast<MCEncodedFragment>(this))
130     OS << " BundlePadding:" << static_cast<unsigned>(EF->getBundlePadding());
131   OS << ">";
132 
133   switch (getKind()) {
134   case MCFragment::FT_Align: {
135     const auto *AF = cast<MCAlignFragment>(this);
136     if (AF->hasEmitNops())
137       OS << " (emit nops)";
138     OS << "\n       ";
139     OS << " Alignment:" << AF->getAlignment().value()
140        << " Value:" << AF->getValue() << " ValueSize:" << AF->getValueSize()
141        << " MaxBytesToEmit:" << AF->getMaxBytesToEmit() << ">";
142     break;
143   }
144   case MCFragment::FT_Data:  {
145     const auto *DF = cast<MCDataFragment>(this);
146     OS << "\n       ";
147     OS << " Contents:[";
148     const SmallVectorImpl<char> &Contents = DF->getContents();
149     for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
150       if (i) OS << ",";
151       OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
152     }
153     OS << "] (" << Contents.size() << " bytes)";
154 
155     if (DF->fixup_begin() != DF->fixup_end()) {
156       OS << ",\n       ";
157       OS << " Fixups:[";
158       for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(),
159              ie = DF->fixup_end(); it != ie; ++it) {
160         if (it != DF->fixup_begin()) OS << ",\n                ";
161         OS << *it;
162       }
163       OS << "]";
164     }
165     break;
166   }
167   case MCFragment::FT_Fill:  {
168     const auto *FF = cast<MCFillFragment>(this);
169     OS << " Value:" << static_cast<unsigned>(FF->getValue())
170        << " ValueSize:" << static_cast<unsigned>(FF->getValueSize())
171        << " NumValues:" << FF->getNumValues();
172     break;
173   }
174   case MCFragment::FT_Nops: {
175     const auto *NF = cast<MCNopsFragment>(this);
176     OS << " NumBytes:" << NF->getNumBytes()
177        << " ControlledNopLength:" << NF->getControlledNopLength();
178     break;
179   }
180   case MCFragment::FT_Relaxable:  {
181     const auto *F = cast<MCRelaxableFragment>(this);
182     OS << "\n       ";
183     OS << " Inst:";
184     F->getInst().dump_pretty(OS);
185     OS << " (" << F->getContents().size() << " bytes)";
186     break;
187   }
188   case MCFragment::FT_Org:  {
189     const auto *OF = cast<MCOrgFragment>(this);
190     OS << "\n       ";
191     OS << " Offset:" << OF->getOffset()
192        << " Value:" << static_cast<unsigned>(OF->getValue());
193     break;
194   }
195   case MCFragment::FT_Dwarf:  {
196     const auto *OF = cast<MCDwarfLineAddrFragment>(this);
197     OS << "\n       ";
198     OS << " AddrDelta:" << OF->getAddrDelta()
199        << " LineDelta:" << OF->getLineDelta();
200     break;
201   }
202   case MCFragment::FT_DwarfFrame:  {
203     const auto *CF = cast<MCDwarfCallFrameFragment>(this);
204     OS << "\n       ";
205     OS << " AddrDelta:" << CF->getAddrDelta();
206     break;
207   }
208   case MCFragment::FT_LEB: {
209     const auto *LF = cast<MCLEBFragment>(this);
210     OS << "\n       ";
211     OS << " Value:" << LF->getValue() << " Signed:" << LF->isSigned();
212     break;
213   }
214   case MCFragment::FT_BoundaryAlign: {
215     const auto *BF = cast<MCBoundaryAlignFragment>(this);
216     OS << "\n       ";
217     OS << " BoundarySize:" << BF->getAlignment().value()
218        << " LastFragment:" << BF->getLastFragment()
219        << " Size:" << BF->getSize();
220     break;
221   }
222   case MCFragment::FT_SymbolId: {
223     const auto *F = cast<MCSymbolIdFragment>(this);
224     OS << "\n       ";
225     OS << " Sym:" << F->getSymbol();
226     break;
227   }
228   case MCFragment::FT_CVInlineLines: {
229     const auto *F = cast<MCCVInlineLineTableFragment>(this);
230     OS << "\n       ";
231     OS << " Sym:" << *F->getFnStartSym();
232     break;
233   }
234   case MCFragment::FT_CVDefRange: {
235     const auto *F = cast<MCCVDefRangeFragment>(this);
236     OS << "\n       ";
237     for (std::pair<const MCSymbol *, const MCSymbol *> RangeStartEnd :
238          F->getRanges()) {
239       OS << " RangeStart:" << RangeStartEnd.first;
240       OS << " RangeEnd:" << RangeStartEnd.second;
241     }
242     break;
243   }
244   case MCFragment::FT_PseudoProbe: {
245     const auto *OF = cast<MCPseudoProbeAddrFragment>(this);
246     OS << "\n       ";
247     OS << " AddrDelta:" << OF->getAddrDelta();
248     break;
249   }
250   case MCFragment::FT_Dummy:
251     break;
252   }
253   OS << ">";
254 }
255 #endif
256