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/raw_ostream.h"
27 MCFragment::MCFragment(FragmentType Kind
, bool HasInstructions
)
28 : Kind(Kind
), HasInstructions(HasInstructions
), AlignToBundleEnd(false),
29 LinkerRelaxable(false), AllowAutoPadding(false) {}
31 void MCFragment::destroy() {
34 cast
<MCAlignFragment
>(this)->~MCAlignFragment();
37 cast
<MCDataFragment
>(this)->~MCDataFragment();
40 cast
<MCFillFragment
>(this)->~MCFillFragment();
43 cast
<MCNopsFragment
>(this)->~MCNopsFragment();
46 cast
<MCRelaxableFragment
>(this)->~MCRelaxableFragment();
49 cast
<MCOrgFragment
>(this)->~MCOrgFragment();
52 cast
<MCDwarfLineAddrFragment
>(this)->~MCDwarfLineAddrFragment();
55 cast
<MCDwarfCallFrameFragment
>(this)->~MCDwarfCallFrameFragment();
58 cast
<MCLEBFragment
>(this)->~MCLEBFragment();
60 case FT_BoundaryAlign
:
61 cast
<MCBoundaryAlignFragment
>(this)->~MCBoundaryAlignFragment();
64 cast
<MCSymbolIdFragment
>(this)->~MCSymbolIdFragment();
66 case FT_CVInlineLines
:
67 cast
<MCCVInlineLineTableFragment
>(this)->~MCCVInlineLineTableFragment();
70 cast
<MCCVDefRangeFragment
>(this)->~MCCVDefRangeFragment();
73 cast
<MCPseudoProbeAddrFragment
>(this)->~MCPseudoProbeAddrFragment();
76 cast
<MCDummyFragment
>(this)->~MCDummyFragment();
81 const MCSymbol
*MCFragment::getAtom() const {
82 return cast
<MCSectionMachO
>(Parent
)->getAtom(LayoutOrder
);
89 raw_ostream
&operator<<(raw_ostream
&OS
, const MCFixup
&AF
) {
90 OS
<< "<MCFixup" << " Offset:" << AF
.getOffset()
91 << " Value:" << *AF
.getValue()
92 << " Kind:" << AF
.getKind() << ">";
96 } // end namespace llvm
98 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
99 LLVM_DUMP_METHOD
void MCFragment::dump() const {
100 raw_ostream
&OS
= errs();
104 case MCFragment::FT_Align
: OS
<< "MCAlignFragment"; break;
105 case MCFragment::FT_Data
: OS
<< "MCDataFragment"; break;
106 case MCFragment::FT_Fill
: OS
<< "MCFillFragment"; break;
107 case MCFragment::FT_Nops
:
108 OS
<< "MCFNopsFragment";
110 case MCFragment::FT_Relaxable
: OS
<< "MCRelaxableFragment"; break;
111 case MCFragment::FT_Org
: OS
<< "MCOrgFragment"; break;
112 case MCFragment::FT_Dwarf
: OS
<< "MCDwarfFragment"; break;
113 case MCFragment::FT_DwarfFrame
: OS
<< "MCDwarfCallFrameFragment"; break;
114 case MCFragment::FT_LEB
: OS
<< "MCLEBFragment"; break;
115 case MCFragment::FT_BoundaryAlign
: OS
<<"MCBoundaryAlignFragment"; break;
116 case MCFragment::FT_SymbolId
: OS
<< "MCSymbolIdFragment"; break;
117 case MCFragment::FT_CVInlineLines
: OS
<< "MCCVInlineLineTableFragment"; break;
118 case MCFragment::FT_CVDefRange
: OS
<< "MCCVDefRangeTableFragment"; break;
119 case MCFragment::FT_PseudoProbe
:
120 OS
<< "MCPseudoProbe";
122 case MCFragment::FT_Dummy
: OS
<< "MCDummyFragment"; break;
125 OS
<< "<MCFragment " << (const void *)this << " LayoutOrder:" << LayoutOrder
126 << " Offset:" << Offset
<< " HasInstructions:" << hasInstructions();
127 if (const auto *EF
= dyn_cast
<MCEncodedFragment
>(this))
128 OS
<< " BundlePadding:" << static_cast<unsigned>(EF
->getBundlePadding());
132 case MCFragment::FT_Align
: {
133 const auto *AF
= cast
<MCAlignFragment
>(this);
134 if (AF
->hasEmitNops())
135 OS
<< " (emit nops)";
137 OS
<< " Alignment:" << AF
->getAlignment().value()
138 << " Value:" << AF
->getValue() << " ValueSize:" << AF
->getValueSize()
139 << " MaxBytesToEmit:" << AF
->getMaxBytesToEmit() << ">";
142 case MCFragment::FT_Data
: {
143 const auto *DF
= cast
<MCDataFragment
>(this);
146 const SmallVectorImpl
<char> &Contents
= DF
->getContents();
147 for (unsigned i
= 0, e
= Contents
.size(); i
!= e
; ++i
) {
149 OS
<< hexdigit((Contents
[i
] >> 4) & 0xF) << hexdigit(Contents
[i
] & 0xF);
151 OS
<< "] (" << Contents
.size() << " bytes)";
153 if (DF
->fixup_begin() != DF
->fixup_end()) {
156 for (MCDataFragment::const_fixup_iterator it
= DF
->fixup_begin(),
157 ie
= DF
->fixup_end(); it
!= ie
; ++it
) {
158 if (it
!= DF
->fixup_begin()) OS
<< ",\n ";
165 case MCFragment::FT_Fill
: {
166 const auto *FF
= cast
<MCFillFragment
>(this);
167 OS
<< " Value:" << static_cast<unsigned>(FF
->getValue())
168 << " ValueSize:" << static_cast<unsigned>(FF
->getValueSize())
169 << " NumValues:" << FF
->getNumValues();
172 case MCFragment::FT_Nops
: {
173 const auto *NF
= cast
<MCNopsFragment
>(this);
174 OS
<< " NumBytes:" << NF
->getNumBytes()
175 << " ControlledNopLength:" << NF
->getControlledNopLength();
178 case MCFragment::FT_Relaxable
: {
179 const auto *F
= cast
<MCRelaxableFragment
>(this);
182 F
->getInst().dump_pretty(OS
);
183 OS
<< " (" << F
->getContents().size() << " bytes)";
186 case MCFragment::FT_Org
: {
187 const auto *OF
= cast
<MCOrgFragment
>(this);
189 OS
<< " Offset:" << OF
->getOffset()
190 << " Value:" << static_cast<unsigned>(OF
->getValue());
193 case MCFragment::FT_Dwarf
: {
194 const auto *OF
= cast
<MCDwarfLineAddrFragment
>(this);
196 OS
<< " AddrDelta:" << OF
->getAddrDelta()
197 << " LineDelta:" << OF
->getLineDelta();
200 case MCFragment::FT_DwarfFrame
: {
201 const auto *CF
= cast
<MCDwarfCallFrameFragment
>(this);
203 OS
<< " AddrDelta:" << CF
->getAddrDelta();
206 case MCFragment::FT_LEB
: {
207 const auto *LF
= cast
<MCLEBFragment
>(this);
209 OS
<< " Value:" << LF
->getValue() << " Signed:" << LF
->isSigned();
212 case MCFragment::FT_BoundaryAlign
: {
213 const auto *BF
= cast
<MCBoundaryAlignFragment
>(this);
215 OS
<< " BoundarySize:" << BF
->getAlignment().value()
216 << " LastFragment:" << BF
->getLastFragment()
217 << " Size:" << BF
->getSize();
220 case MCFragment::FT_SymbolId
: {
221 const auto *F
= cast
<MCSymbolIdFragment
>(this);
223 OS
<< " Sym:" << F
->getSymbol();
226 case MCFragment::FT_CVInlineLines
: {
227 const auto *F
= cast
<MCCVInlineLineTableFragment
>(this);
229 OS
<< " Sym:" << *F
->getFnStartSym();
232 case MCFragment::FT_CVDefRange
: {
233 const auto *F
= cast
<MCCVDefRangeFragment
>(this);
235 for (std::pair
<const MCSymbol
*, const MCSymbol
*> RangeStartEnd
:
237 OS
<< " RangeStart:" << RangeStartEnd
.first
;
238 OS
<< " RangeEnd:" << RangeStartEnd
.second
;
242 case MCFragment::FT_PseudoProbe
: {
243 const auto *OF
= cast
<MCPseudoProbeAddrFragment
>(this);
245 OS
<< " AddrDelta:" << OF
->getAddrDelta();
248 case MCFragment::FT_Dummy
: