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