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/MCAsmLayout.h"
15 #include "llvm/MC/MCAssembler.h"
16 #include "llvm/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCFixup.h"
19 #include "llvm/MC/MCSection.h"
20 #include "llvm/MC/MCSymbol.h"
21 #include "llvm/MC/MCValue.h"
22 #include "llvm/Support/Casting.h"
23 #include "llvm/Support/Compiler.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/raw_ostream.h"
32 MCAsmLayout::MCAsmLayout(MCAssembler
&Asm
) : Assembler(Asm
) {
33 // Compute the section layout order. Virtual sections must go last.
34 for (MCSection
&Sec
: Asm
)
35 if (!Sec
.isVirtualSection())
36 SectionOrder
.push_back(&Sec
);
37 for (MCSection
&Sec
: Asm
)
38 if (Sec
.isVirtualSection())
39 SectionOrder
.push_back(&Sec
);
42 bool MCAsmLayout::isFragmentValid(const MCFragment
*F
) const {
43 const MCSection
*Sec
= F
->getParent();
44 const MCFragment
*LastValid
= LastValidFragment
.lookup(Sec
);
47 assert(LastValid
->getParent() == Sec
);
48 return F
->getLayoutOrder() <= LastValid
->getLayoutOrder();
51 void MCAsmLayout::invalidateFragmentsFrom(MCFragment
*F
) {
52 // If this fragment wasn't already valid, we don't need to do anything.
53 if (!isFragmentValid(F
))
56 // Otherwise, reset the last valid fragment to the previous fragment
57 // (if this is the first fragment, it will be NULL).
58 LastValidFragment
[F
->getParent()] = F
->getPrevNode();
61 void MCAsmLayout::ensureValid(const MCFragment
*F
) const {
62 MCSection
*Sec
= F
->getParent();
63 MCSection::iterator I
;
64 if (MCFragment
*Cur
= LastValidFragment
[Sec
])
65 I
= ++MCSection::iterator(Cur
);
69 // Advance the layout position until the fragment is valid.
70 while (!isFragmentValid(F
)) {
71 assert(I
!= Sec
->end() && "Layout bookkeeping error");
72 const_cast<MCAsmLayout
*>(this)->layoutFragment(&*I
);
77 uint64_t MCAsmLayout::getFragmentOffset(const MCFragment
*F
) const {
79 assert(F
->Offset
!= ~UINT64_C(0) && "Address not set!");
83 // Simple getSymbolOffset helper for the non-variable case.
84 static bool getLabelOffset(const MCAsmLayout
&Layout
, const MCSymbol
&S
,
85 bool ReportError
, uint64_t &Val
) {
86 if (!S
.getFragment()) {
88 report_fatal_error("unable to evaluate offset to undefined symbol '" +
92 Val
= Layout
.getFragmentOffset(S
.getFragment()) + S
.getOffset();
96 static bool getSymbolOffsetImpl(const MCAsmLayout
&Layout
, const MCSymbol
&S
,
97 bool ReportError
, uint64_t &Val
) {
99 return getLabelOffset(Layout
, S
, ReportError
, Val
);
101 // If SD is a variable, evaluate it.
103 if (!S
.getVariableValue()->evaluateAsValue(Target
, Layout
))
104 report_fatal_error("unable to evaluate offset for variable '" +
107 uint64_t Offset
= Target
.getConstant();
109 const MCSymbolRefExpr
*A
= Target
.getSymA();
112 if (!getLabelOffset(Layout
, A
->getSymbol(), ReportError
, ValA
))
117 const MCSymbolRefExpr
*B
= Target
.getSymB();
120 if (!getLabelOffset(Layout
, B
->getSymbol(), ReportError
, ValB
))
129 bool MCAsmLayout::getSymbolOffset(const MCSymbol
&S
, uint64_t &Val
) const {
130 return getSymbolOffsetImpl(*this, S
, false, Val
);
133 uint64_t MCAsmLayout::getSymbolOffset(const MCSymbol
&S
) const {
135 getSymbolOffsetImpl(*this, S
, true, Val
);
139 const MCSymbol
*MCAsmLayout::getBaseSymbol(const MCSymbol
&Symbol
) const {
140 if (!Symbol
.isVariable())
143 const MCExpr
*Expr
= Symbol
.getVariableValue();
145 if (!Expr
->evaluateAsValue(Value
, *this)) {
146 Assembler
.getContext().reportError(
147 Expr
->getLoc(), "expression could not be evaluated");
151 const MCSymbolRefExpr
*RefB
= Value
.getSymB();
153 Assembler
.getContext().reportError(
154 Expr
->getLoc(), Twine("symbol '") + RefB
->getSymbol().getName() +
155 "' could not be evaluated in a subtraction expression");
159 const MCSymbolRefExpr
*A
= Value
.getSymA();
163 const MCSymbol
&ASym
= A
->getSymbol();
164 const MCAssembler
&Asm
= getAssembler();
165 if (ASym
.isCommon()) {
166 Asm
.getContext().reportError(Expr
->getLoc(),
167 "Common symbol '" + ASym
.getName() +
168 "' cannot be used in assignment expr");
175 uint64_t MCAsmLayout::getSectionAddressSize(const MCSection
*Sec
) const {
176 // The size is the last fragment's end offset.
177 const MCFragment
&F
= Sec
->getFragmentList().back();
178 return getFragmentOffset(&F
) + getAssembler().computeFragmentSize(*this, F
);
181 uint64_t MCAsmLayout::getSectionFileSize(const MCSection
*Sec
) const {
182 // Virtual sections have no file size.
183 if (Sec
->isVirtualSection())
186 // Otherwise, the file size is the same as the address space size.
187 return getSectionAddressSize(Sec
);
190 uint64_t llvm::computeBundlePadding(const MCAssembler
&Assembler
,
191 const MCEncodedFragment
*F
,
192 uint64_t FOffset
, uint64_t FSize
) {
193 uint64_t BundleSize
= Assembler
.getBundleAlignSize();
194 assert(BundleSize
> 0 &&
195 "computeBundlePadding should only be called if bundling is enabled");
196 uint64_t BundleMask
= BundleSize
- 1;
197 uint64_t OffsetInBundle
= FOffset
& BundleMask
;
198 uint64_t EndOfFragment
= OffsetInBundle
+ FSize
;
200 // There are two kinds of bundling restrictions:
202 // 1) For alignToBundleEnd(), add padding to ensure that the fragment will
203 // *end* on a bundle boundary.
204 // 2) Otherwise, check if the fragment would cross a bundle boundary. If it
205 // would, add padding until the end of the bundle so that the fragment
206 // will start in a new one.
207 if (F
->alignToBundleEnd()) {
208 // Three possibilities here:
210 // A) The fragment just happens to end at a bundle boundary, so we're good.
211 // B) The fragment ends before the current bundle boundary: pad it just
212 // enough to reach the boundary.
213 // C) The fragment ends after the current bundle boundary: pad it until it
214 // reaches the end of the next bundle boundary.
216 // Note: this code could be made shorter with some modulo trickery, but it's
217 // intentionally kept in its more explicit form for simplicity.
218 if (EndOfFragment
== BundleSize
)
220 else if (EndOfFragment
< BundleSize
)
221 return BundleSize
- EndOfFragment
;
222 else { // EndOfFragment > BundleSize
223 return 2 * BundleSize
- EndOfFragment
;
225 } else if (OffsetInBundle
> 0 && EndOfFragment
> BundleSize
)
226 return BundleSize
- OffsetInBundle
;
233 void ilist_alloc_traits
<MCFragment
>::deleteNode(MCFragment
*V
) { V
->destroy(); }
235 MCFragment::~MCFragment() = default;
237 MCFragment::MCFragment(FragmentType Kind
, bool HasInstructions
,
239 : Kind(Kind
), HasInstructions(HasInstructions
), LayoutOrder(0),
240 Parent(Parent
), Atom(nullptr), Offset(~UINT64_C(0)) {
241 if (Parent
&& !isDummy())
242 Parent
->getFragmentList().push_back(this);
245 void MCFragment::destroy() {
246 // First check if we are the sentinal.
247 if (Kind
== FragmentType(~0)) {
254 delete cast
<MCAlignFragment
>(this);
257 delete cast
<MCDataFragment
>(this);
259 case FT_CompactEncodedInst
:
260 delete cast
<MCCompactEncodedInstFragment
>(this);
263 delete cast
<MCFillFragment
>(this);
266 delete cast
<MCRelaxableFragment
>(this);
269 delete cast
<MCOrgFragment
>(this);
272 delete cast
<MCDwarfLineAddrFragment
>(this);
275 delete cast
<MCDwarfCallFrameFragment
>(this);
278 delete cast
<MCLEBFragment
>(this);
281 delete cast
<MCPaddingFragment
>(this);
284 delete cast
<MCSymbolIdFragment
>(this);
286 case FT_CVInlineLines
:
287 delete cast
<MCCVInlineLineTableFragment
>(this);
290 delete cast
<MCCVDefRangeFragment
>(this);
293 delete cast
<MCDummyFragment
>(this);
302 raw_ostream
&operator<<(raw_ostream
&OS
, const MCFixup
&AF
) {
303 OS
<< "<MCFixup" << " Offset:" << AF
.getOffset()
304 << " Value:" << *AF
.getValue()
305 << " Kind:" << AF
.getKind() << ">";
309 } // end namespace llvm
311 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
312 LLVM_DUMP_METHOD
void MCFragment::dump() const {
313 raw_ostream
&OS
= errs();
317 case MCFragment::FT_Align
: OS
<< "MCAlignFragment"; break;
318 case MCFragment::FT_Data
: OS
<< "MCDataFragment"; break;
319 case MCFragment::FT_CompactEncodedInst
:
320 OS
<< "MCCompactEncodedInstFragment"; break;
321 case MCFragment::FT_Fill
: OS
<< "MCFillFragment"; break;
322 case MCFragment::FT_Relaxable
: OS
<< "MCRelaxableFragment"; break;
323 case MCFragment::FT_Org
: OS
<< "MCOrgFragment"; break;
324 case MCFragment::FT_Dwarf
: OS
<< "MCDwarfFragment"; break;
325 case MCFragment::FT_DwarfFrame
: OS
<< "MCDwarfCallFrameFragment"; break;
326 case MCFragment::FT_LEB
: OS
<< "MCLEBFragment"; break;
327 case MCFragment::FT_Padding
: OS
<< "MCPaddingFragment"; break;
328 case MCFragment::FT_SymbolId
: OS
<< "MCSymbolIdFragment"; break;
329 case MCFragment::FT_CVInlineLines
: OS
<< "MCCVInlineLineTableFragment"; break;
330 case MCFragment::FT_CVDefRange
: OS
<< "MCCVDefRangeTableFragment"; break;
331 case MCFragment::FT_Dummy
: OS
<< "MCDummyFragment"; break;
334 OS
<< "<MCFragment " << (const void *)this << " LayoutOrder:" << LayoutOrder
335 << " Offset:" << Offset
<< " HasInstructions:" << hasInstructions();
336 if (const MCEncodedFragment
*EF
= dyn_cast
<MCEncodedFragment
>(this))
337 OS
<< " BundlePadding:" << static_cast<unsigned>(EF
->getBundlePadding());
341 case MCFragment::FT_Align
: {
342 const MCAlignFragment
*AF
= cast
<MCAlignFragment
>(this);
343 if (AF
->hasEmitNops())
344 OS
<< " (emit nops)";
346 OS
<< " Alignment:" << AF
->getAlignment()
347 << " Value:" << AF
->getValue() << " ValueSize:" << AF
->getValueSize()
348 << " MaxBytesToEmit:" << AF
->getMaxBytesToEmit() << ">";
351 case MCFragment::FT_Data
: {
352 const MCDataFragment
*DF
= cast
<MCDataFragment
>(this);
355 const SmallVectorImpl
<char> &Contents
= DF
->getContents();
356 for (unsigned i
= 0, e
= Contents
.size(); i
!= e
; ++i
) {
358 OS
<< hexdigit((Contents
[i
] >> 4) & 0xF) << hexdigit(Contents
[i
] & 0xF);
360 OS
<< "] (" << Contents
.size() << " bytes)";
362 if (DF
->fixup_begin() != DF
->fixup_end()) {
365 for (MCDataFragment::const_fixup_iterator it
= DF
->fixup_begin(),
366 ie
= DF
->fixup_end(); it
!= ie
; ++it
) {
367 if (it
!= DF
->fixup_begin()) OS
<< ",\n ";
374 case MCFragment::FT_CompactEncodedInst
: {
375 const MCCompactEncodedInstFragment
*CEIF
=
376 cast
<MCCompactEncodedInstFragment
>(this);
379 const SmallVectorImpl
<char> &Contents
= CEIF
->getContents();
380 for (unsigned i
= 0, e
= Contents
.size(); i
!= e
; ++i
) {
382 OS
<< hexdigit((Contents
[i
] >> 4) & 0xF) << hexdigit(Contents
[i
] & 0xF);
384 OS
<< "] (" << Contents
.size() << " bytes)";
387 case MCFragment::FT_Fill
: {
388 const MCFillFragment
*FF
= cast
<MCFillFragment
>(this);
389 OS
<< " Value:" << static_cast<unsigned>(FF
->getValue())
390 << " ValueSize:" << static_cast<unsigned>(FF
->getValueSize())
391 << " NumValues:" << FF
->getNumValues();
394 case MCFragment::FT_Relaxable
: {
395 const MCRelaxableFragment
*F
= cast
<MCRelaxableFragment
>(this);
398 F
->getInst().dump_pretty(OS
);
401 case MCFragment::FT_Org
: {
402 const MCOrgFragment
*OF
= cast
<MCOrgFragment
>(this);
404 OS
<< " Offset:" << OF
->getOffset()
405 << " Value:" << static_cast<unsigned>(OF
->getValue());
408 case MCFragment::FT_Dwarf
: {
409 const MCDwarfLineAddrFragment
*OF
= cast
<MCDwarfLineAddrFragment
>(this);
411 OS
<< " AddrDelta:" << OF
->getAddrDelta()
412 << " LineDelta:" << OF
->getLineDelta();
415 case MCFragment::FT_DwarfFrame
: {
416 const MCDwarfCallFrameFragment
*CF
= cast
<MCDwarfCallFrameFragment
>(this);
418 OS
<< " AddrDelta:" << CF
->getAddrDelta();
421 case MCFragment::FT_LEB
: {
422 const MCLEBFragment
*LF
= cast
<MCLEBFragment
>(this);
424 OS
<< " Value:" << LF
->getValue() << " Signed:" << LF
->isSigned();
427 case MCFragment::FT_Padding
: {
428 const MCPaddingFragment
*F
= cast
<MCPaddingFragment
>(this);
430 OS
<< " PaddingPoliciesMask:" << F
->getPaddingPoliciesMask()
431 << " IsInsertionPoint:" << F
->isInsertionPoint()
432 << " Size:" << F
->getSize();
435 F
->getInst().dump_pretty(OS
);
436 OS
<< " InstSize:" << F
->getInstSize();
440 case MCFragment::FT_SymbolId
: {
441 const MCSymbolIdFragment
*F
= cast
<MCSymbolIdFragment
>(this);
443 OS
<< " Sym:" << F
->getSymbol();
446 case MCFragment::FT_CVInlineLines
: {
447 const auto *F
= cast
<MCCVInlineLineTableFragment
>(this);
449 OS
<< " Sym:" << *F
->getFnStartSym();
452 case MCFragment::FT_CVDefRange
: {
453 const auto *F
= cast
<MCCVDefRangeFragment
>(this);
455 for (std::pair
<const MCSymbol
*, const MCSymbol
*> RangeStartEnd
:
457 OS
<< " RangeStart:" << RangeStartEnd
.first
;
458 OS
<< " RangeEnd:" << RangeStartEnd
.second
;
462 case MCFragment::FT_Dummy
: