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