1 //===- lib/MC/MCFragment.cpp - Assembler Fragment Implementation ----------===//
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
7 //===----------------------------------------------------------------------===//
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"
29 MCFragment::MCFragment(FragmentType Kind
, bool HasInstructions
)
30 : Kind(Kind
), HasInstructions(HasInstructions
), LinkerRelaxable(false) {}
32 void MCFragment::destroy() {
35 cast
<MCAlignFragment
>(this)->~MCAlignFragment();
38 cast
<MCDataFragment
>(this)->~MCDataFragment();
40 case FT_CompactEncodedInst
:
41 cast
<MCCompactEncodedInstFragment
>(this)->~MCCompactEncodedInstFragment();
44 cast
<MCFillFragment
>(this)->~MCFillFragment();
47 cast
<MCNopsFragment
>(this)->~MCNopsFragment();
50 cast
<MCRelaxableFragment
>(this)->~MCRelaxableFragment();
53 cast
<MCOrgFragment
>(this)->~MCOrgFragment();
56 cast
<MCDwarfLineAddrFragment
>(this)->~MCDwarfLineAddrFragment();
59 cast
<MCDwarfCallFrameFragment
>(this)->~MCDwarfCallFrameFragment();
62 cast
<MCLEBFragment
>(this)->~MCLEBFragment();
64 case FT_BoundaryAlign
:
65 cast
<MCBoundaryAlignFragment
>(this)->~MCBoundaryAlignFragment();
68 cast
<MCSymbolIdFragment
>(this)->~MCSymbolIdFragment();
70 case FT_CVInlineLines
:
71 cast
<MCCVInlineLineTableFragment
>(this)->~MCCVInlineLineTableFragment();
74 cast
<MCCVDefRangeFragment
>(this)->~MCCVDefRangeFragment();
77 cast
<MCPseudoProbeAddrFragment
>(this)->~MCPseudoProbeAddrFragment();
80 cast
<MCDummyFragment
>(this)->~MCDummyFragment();
85 const MCSymbol
*MCFragment::getAtom() const {
86 return cast
<MCSectionMachO
>(Parent
)->getAtom(LayoutOrder
);
93 raw_ostream
&operator<<(raw_ostream
&OS
, const MCFixup
&AF
) {
94 OS
<< "<MCFixup" << " Offset:" << AF
.getOffset()
95 << " Value:" << *AF
.getValue()
96 << " Kind:" << AF
.getKind() << ">";
100 } // end namespace llvm
102 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
103 LLVM_DUMP_METHOD
void MCFragment::dump() const {
104 raw_ostream
&OS
= errs();
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";
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";
128 case MCFragment::FT_Dummy
: OS
<< "MCDummyFragment"; break;
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());
138 case MCFragment::FT_Align
: {
139 const auto *AF
= cast
<MCAlignFragment
>(this);
140 if (AF
->hasEmitNops())
141 OS
<< " (emit nops)";
143 OS
<< " Alignment:" << AF
->getAlignment().value()
144 << " Value:" << AF
->getValue() << " ValueSize:" << AF
->getValueSize()
145 << " MaxBytesToEmit:" << AF
->getMaxBytesToEmit() << ">";
148 case MCFragment::FT_Data
: {
149 const auto *DF
= cast
<MCDataFragment
>(this);
152 const SmallVectorImpl
<char> &Contents
= DF
->getContents();
153 for (unsigned i
= 0, e
= Contents
.size(); i
!= e
; ++i
) {
155 OS
<< hexdigit((Contents
[i
] >> 4) & 0xF) << hexdigit(Contents
[i
] & 0xF);
157 OS
<< "] (" << Contents
.size() << " bytes)";
159 if (DF
->fixup_begin() != DF
->fixup_end()) {
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 ";
171 case MCFragment::FT_CompactEncodedInst
: {
173 cast
<MCCompactEncodedInstFragment
>(this);
176 const SmallVectorImpl
<char> &Contents
= CEIF
->getContents();
177 for (unsigned i
= 0, e
= Contents
.size(); i
!= e
; ++i
) {
179 OS
<< hexdigit((Contents
[i
] >> 4) & 0xF) << hexdigit(Contents
[i
] & 0xF);
181 OS
<< "] (" << Contents
.size() << " bytes)";
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();
191 case MCFragment::FT_Nops
: {
192 const auto *NF
= cast
<MCNopsFragment
>(this);
193 OS
<< " NumBytes:" << NF
->getNumBytes()
194 << " ControlledNopLength:" << NF
->getControlledNopLength();
197 case MCFragment::FT_Relaxable
: {
198 const auto *F
= cast
<MCRelaxableFragment
>(this);
201 F
->getInst().dump_pretty(OS
);
202 OS
<< " (" << F
->getContents().size() << " bytes)";
205 case MCFragment::FT_Org
: {
206 const auto *OF
= cast
<MCOrgFragment
>(this);
208 OS
<< " Offset:" << OF
->getOffset()
209 << " Value:" << static_cast<unsigned>(OF
->getValue());
212 case MCFragment::FT_Dwarf
: {
213 const auto *OF
= cast
<MCDwarfLineAddrFragment
>(this);
215 OS
<< " AddrDelta:" << OF
->getAddrDelta()
216 << " LineDelta:" << OF
->getLineDelta();
219 case MCFragment::FT_DwarfFrame
: {
220 const auto *CF
= cast
<MCDwarfCallFrameFragment
>(this);
222 OS
<< " AddrDelta:" << CF
->getAddrDelta();
225 case MCFragment::FT_LEB
: {
226 const auto *LF
= cast
<MCLEBFragment
>(this);
228 OS
<< " Value:" << LF
->getValue() << " Signed:" << LF
->isSigned();
231 case MCFragment::FT_BoundaryAlign
: {
232 const auto *BF
= cast
<MCBoundaryAlignFragment
>(this);
234 OS
<< " BoundarySize:" << BF
->getAlignment().value()
235 << " LastFragment:" << BF
->getLastFragment()
236 << " Size:" << BF
->getSize();
239 case MCFragment::FT_SymbolId
: {
240 const auto *F
= cast
<MCSymbolIdFragment
>(this);
242 OS
<< " Sym:" << F
->getSymbol();
245 case MCFragment::FT_CVInlineLines
: {
246 const auto *F
= cast
<MCCVInlineLineTableFragment
>(this);
248 OS
<< " Sym:" << *F
->getFnStartSym();
251 case MCFragment::FT_CVDefRange
: {
252 const auto *F
= cast
<MCCVDefRangeFragment
>(this);
254 for (std::pair
<const MCSymbol
*, const MCSymbol
*> RangeStartEnd
:
256 OS
<< " RangeStart:" << RangeStartEnd
.first
;
257 OS
<< " RangeEnd:" << RangeStartEnd
.second
;
261 case MCFragment::FT_PseudoProbe
: {
262 const auto *OF
= cast
<MCPseudoProbeAddrFragment
>(this);
264 OS
<< " AddrDelta:" << OF
->getAddrDelta();
267 case MCFragment::FT_Dummy
: