diff options
-rw-r--r-- | llvm/include/llvm/MC/MCAssembler.h | 232 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCELFStreamer.h | 2 | ||||
-rw-r--r-- | llvm/include/llvm/MC/MCSection.h | 12 | ||||
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 126 | ||||
-rw-r--r-- | llvm/lib/MC/MCELFStreamer.cpp | 2 |
5 files changed, 188 insertions, 186 deletions
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index 484f370515a..0642af837e7 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -49,7 +49,7 @@ class MCFragment : public ilist_node<MCFragment> { void operator=(const MCFragment &) = delete; public: - enum FragmentType { + enum FragmentType : uint8_t { FT_Align, FT_Data, FT_CompactEncodedInst, @@ -65,6 +65,18 @@ public: private: FragmentType Kind; +protected: + bool HasInstructions; + +private: + /// \brief Should this fragment be aligned to the end of a bundle? + bool AlignToBundleEnd; + + uint8_t BundlePadding; + + /// LayoutOrder - The layout order of this fragment. + unsigned LayoutOrder; + /// The data for the section this fragment is in. MCSection *Parent; @@ -81,18 +93,25 @@ private: /// initialized. uint64_t Offset; - /// LayoutOrder - The layout order of this fragment. - unsigned LayoutOrder; - /// @} protected: - MCFragment(FragmentType Kind, MCSection *Parent = nullptr); + MCFragment(FragmentType Kind, bool HasInstructions, + uint8_t BundlePadding, MCSection *Parent = nullptr); -public: - // Only for sentinel. + ~MCFragment(); +private: + + // This is a friend so that the sentinal can be created. + friend struct ilist_sentinel_traits<MCFragment>; MCFragment(); - virtual ~MCFragment(); + +public: + /// Destroys the current fragment. + /// + /// This must be used instead of delete as MCFragment is non-virtual. + /// This method will dispatch to the appropriate subclass. + void destroy(); FragmentType getKind() const { return Kind; } @@ -107,22 +126,22 @@ public: /// \brief Does this fragment have instructions emitted into it? By default /// this is false, but specific fragment types may set it to true. - virtual bool hasInstructions() const { return false; } + bool hasInstructions() const { return HasInstructions; } /// \brief Should this fragment be placed at the end of an aligned bundle? - virtual bool alignToBundleEnd() const { return false; } - virtual void setAlignToBundleEnd(bool V) {} + bool alignToBundleEnd() const { return AlignToBundleEnd; } + void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } /// \brief Get the padding size that must be inserted before this fragment. /// Used for bundling. By default, no padding is inserted. /// Note that padding size is restricted to 8 bits. This is an optimization /// to reduce the amount of space used for each fragment. In practice, larger /// padding should never be required. - virtual uint8_t getBundlePadding() const { return 0; } + uint8_t getBundlePadding() const { return BundlePadding; } /// \brief Set the padding size for this fragment. By default it's a no-op, /// and only some fragments have a meaningful implementation. - virtual void setBundlePadding(uint8_t N) {} + void setBundlePadding(uint8_t N) { BundlePadding = N; } void dump(); }; @@ -131,22 +150,12 @@ public: /// data. /// class MCEncodedFragment : public MCFragment { - virtual void anchor(); - - uint8_t BundlePadding; +protected: + MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions, + MCSection *Sec) + : MCFragment(FType, HasInstructions, 0, Sec) {} public: - MCEncodedFragment(MCFragment::FragmentType FType, MCSection *Sec = nullptr) - : MCFragment(FType, Sec), BundlePadding(0) {} - ~MCEncodedFragment() override; - - virtual SmallVectorImpl<char> &getContents() = 0; - virtual const SmallVectorImpl<char> &getContents() const = 0; - - uint8_t getBundlePadding() const override { return BundlePadding; } - - void setBundlePadding(uint8_t N) override { BundlePadding = N; } - static bool classof(const MCFragment *F) { MCFragment::FragmentType Kind = F->getKind(); switch (Kind) { @@ -161,28 +170,52 @@ public: }; /// Interface implemented by fragments that contain encoded instructions and/or -/// data and also have fixups registered. +/// data. /// -class MCEncodedFragmentWithFixups : public MCEncodedFragment { - void anchor() override; +template<unsigned ContentsSize> +class MCEncodedFragmentWithContents : public MCEncodedFragment { + SmallVector<char, ContentsSize> Contents; + +protected: + MCEncodedFragmentWithContents(MCFragment::FragmentType FType, + bool HasInstructions, + MCSection *Sec) + : MCEncodedFragment(FType, HasInstructions, Sec) {} public: - MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, - MCSection *Sec = nullptr) - : MCEncodedFragment(FType, Sec) {} + SmallVectorImpl<char> &getContents() { return Contents; } + const SmallVectorImpl<char> &getContents() const { return Contents; } +}; + +/// Interface implemented by fragments that contain encoded instructions and/or +/// data and also have fixups registered. +/// +template<unsigned ContentsSize, unsigned FixupsSize> +class MCEncodedFragmentWithFixups : + public MCEncodedFragmentWithContents<ContentsSize> { - ~MCEncodedFragmentWithFixups() override; + /// Fixups - The list of fixups in this fragment. + SmallVector<MCFixup, FixupsSize> Fixups; +protected: + MCEncodedFragmentWithFixups(MCFragment::FragmentType FType, + bool HasInstructions, + MCSection *Sec) + : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions, + Sec) {} + +public: typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator; typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator; - virtual SmallVectorImpl<MCFixup> &getFixups() = 0; - virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0; + SmallVectorImpl<MCFixup> &getFixups() { return Fixups; } + const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; } + + fixup_iterator fixup_begin() { return Fixups.begin(); } + const_fixup_iterator fixup_begin() const { return Fixups.begin(); } - virtual fixup_iterator fixup_begin() = 0; - virtual const_fixup_iterator fixup_begin() const = 0; - virtual fixup_iterator fixup_end() = 0; - virtual const_fixup_iterator fixup_end() const = 0; + fixup_iterator fixup_end() { return Fixups.end(); } + const_fixup_iterator fixup_end() const { return Fixups.end(); } static bool classof(const MCFragment *F) { MCFragment::FragmentType Kind = F->getKind(); @@ -192,43 +225,12 @@ public: /// Fragment for data and encoded instructions. /// -class MCDataFragment : public MCEncodedFragmentWithFixups { - void anchor() override; - - /// \brief Does this fragment contain encoded instructions anywhere in it? - bool HasInstructions; - - /// \brief Should this fragment be aligned to the end of a bundle? - bool AlignToBundleEnd; - - SmallVector<char, 32> Contents; - - /// Fixups - The list of fixups in this fragment. - SmallVector<MCFixup, 4> Fixups; - +class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> { public: MCDataFragment(MCSection *Sec = nullptr) - : MCEncodedFragmentWithFixups(FT_Data, Sec), HasInstructions(false), - AlignToBundleEnd(false) {} - - SmallVectorImpl<char> &getContents() override { return Contents; } - const SmallVectorImpl<char> &getContents() const override { return Contents; } - - SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; } + : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {} - const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; } - - bool hasInstructions() const override { return HasInstructions; } - virtual void setHasInstructions(bool V) { HasInstructions = V; } - - bool alignToBundleEnd() const override { return AlignToBundleEnd; } - void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; } - - fixup_iterator fixup_begin() override { return Fixups.begin(); } - const_fixup_iterator fixup_begin() const override { return Fixups.begin(); } - - fixup_iterator fixup_end() override { return Fixups.end(); } - const_fixup_iterator fixup_end() const override { return Fixups.end(); } + void setHasInstructions(bool V) { HasInstructions = V; } static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Data; @@ -240,27 +242,12 @@ public: /// it can be used instead of MCDataFragment and lead to lower memory /// consumption. /// -class MCCompactEncodedInstFragment : public MCEncodedFragment { - void anchor() override; - - /// \brief Should this fragment be aligned to the end of a bundle? - bool AlignToBundleEnd; - - SmallVector<char, 4> Contents; - +class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> { public: MCCompactEncodedInstFragment(MCSection *Sec = nullptr) - : MCEncodedFragment(FT_CompactEncodedInst, Sec), AlignToBundleEnd(false) { + : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) { } - bool hasInstructions() const override { return true; } - - SmallVectorImpl<char> &getContents() override { return Contents; } - const SmallVectorImpl<char> &getContents() const override { return Contents; } - - bool alignToBundleEnd() const override { return AlignToBundleEnd; } - void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; } - static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_CompactEncodedInst; } @@ -269,8 +256,7 @@ public: /// A relaxable fragment holds on to its MCInst, since it may need to be /// relaxed during the assembler layout and relaxation stage. /// -class MCRelaxableFragment : public MCEncodedFragmentWithFixups { - void anchor() override; +class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> { /// Inst - The instruction this is a fragment for. MCInst Inst; @@ -280,48 +266,32 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups { /// in the assembler are not seen here. const MCSubtargetInfo STI; - /// Contents - Binary data for the currently encoded instruction. - SmallVector<char, 8> Contents; - - /// Fixups - The list of fixups in this fragment. - SmallVector<MCFixup, 1> Fixups; - public: MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI, MCSection *Sec = nullptr) - : MCEncodedFragmentWithFixups(FT_Relaxable, Sec), Inst(Inst), STI(STI) {} - - SmallVectorImpl<char> &getContents() override { return Contents; } - const SmallVectorImpl<char> &getContents() const override { return Contents; } + : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec), + Inst(Inst), STI(STI) {} const MCInst &getInst() const { return Inst; } void setInst(const MCInst &Value) { Inst = Value; } const MCSubtargetInfo &getSubtargetInfo() { return STI; } - SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; } - - const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; } - - bool hasInstructions() const override { return true; } - - fixup_iterator fixup_begin() override { return Fixups.begin(); } - const_fixup_iterator fixup_begin() const override { return Fixups.begin(); } - - fixup_iterator fixup_end() override { return Fixups.end(); } - const_fixup_iterator fixup_end() const override { return Fixups.end(); } - static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Relaxable; } }; class MCAlignFragment : public MCFragment { - virtual void anchor(); /// Alignment - The alignment to ensure, in bytes. unsigned Alignment; + /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead + /// of using the provided value. The exact interpretation of this flag is + /// target dependent. + bool EmitNops : 1; + /// Value - Value to use for filling padding bytes. int64_t Value; @@ -332,16 +302,12 @@ class MCAlignFragment : public MCFragment { /// cannot be satisfied in this width then this fragment is ignored. unsigned MaxBytesToEmit; - /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead - /// of using the provided value. The exact interpretation of this flag is - /// target dependent. - bool EmitNops : 1; - public: MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize, unsigned MaxBytesToEmit, MCSection *Sec = nullptr) - : MCFragment(FT_Align, Sec), Alignment(Alignment), Value(Value), - ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit), EmitNops(false) {} + : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment), + EmitNops(false), Value(Value), + ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {} /// \name Accessors /// @{ @@ -365,7 +331,6 @@ public: }; class MCFillFragment : public MCFragment { - virtual void anchor(); /// Value - Value to use for filling bytes. int64_t Value; @@ -380,7 +345,7 @@ class MCFillFragment : public MCFragment { public: MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size, MCSection *Sec = nullptr) - : MCFragment(FT_Fill, Sec), Value(Value), ValueSize(ValueSize), + : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(ValueSize), Size(Size) { assert((!ValueSize || (Size % ValueSize) == 0) && "Fill size must be a multiple of the value size!"); @@ -403,7 +368,6 @@ public: }; class MCOrgFragment : public MCFragment { - virtual void anchor(); /// Offset - The offset this fragment should start at. const MCExpr *Offset; @@ -413,7 +377,7 @@ class MCOrgFragment : public MCFragment { public: MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSection *Sec = nullptr) - : MCFragment(FT_Org, Sec), Offset(&Offset), Value(Value) {} + : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value) {} /// \name Accessors /// @{ @@ -430,7 +394,6 @@ public: }; class MCLEBFragment : public MCFragment { - virtual void anchor(); /// Value - The value this fragment should contain. const MCExpr *Value; @@ -442,7 +405,7 @@ class MCLEBFragment : public MCFragment { public: MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr) - : MCFragment(FT_LEB, Sec), Value(&Value_), IsSigned(IsSigned_) { + : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } @@ -464,7 +427,6 @@ public: }; class MCDwarfLineAddrFragment : public MCFragment { - virtual void anchor(); /// LineDelta - the value of the difference between the two line numbers /// between two .loc dwarf directives. @@ -479,7 +441,8 @@ class MCDwarfLineAddrFragment : public MCFragment { public: MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta, MCSection *Sec = nullptr) - : MCFragment(FT_Dwarf, Sec), LineDelta(LineDelta), AddrDelta(&AddrDelta) { + : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta), + AddrDelta(&AddrDelta) { Contents.push_back(0); } @@ -501,7 +464,6 @@ public: }; class MCDwarfCallFrameFragment : public MCFragment { - virtual void anchor(); /// AddrDelta - The expression for the difference of the two symbols that /// make up the address delta between two .cfi_* dwarf directives. @@ -511,7 +473,7 @@ class MCDwarfCallFrameFragment : public MCFragment { public: MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr) - : MCFragment(FT_DwarfFrame, Sec), AddrDelta(&AddrDelta) { + : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) { Contents.push_back(0); } @@ -531,13 +493,11 @@ public: }; class MCSafeSEHFragment : public MCFragment { - virtual void anchor(); - const MCSymbol *Sym; public: MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr) - : MCFragment(FT_SafeSEH, Sec), Sym(Sym) {} + : MCFragment(FT_SafeSEH, false, 0, Sec), Sym(Sym) {} /// \name Accessors /// @{ diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h index 241db0dc9cd..a5b257f5958 100644 --- a/llvm/include/llvm/MC/MCELFStreamer.h +++ b/llvm/include/llvm/MC/MCELFStreamer.h @@ -93,7 +93,7 @@ private: void fixSymbolsInTLSFixups(const MCExpr *expr); /// \brief Merge the content of the fragment \p EF into the fragment \p DF. - void mergeFragment(MCDataFragment *, MCEncodedFragmentWithFixups *); + void mergeFragment(MCDataFragment *, MCDataFragment *); bool SeenIdent; diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h index 5f6e8ec1d50..2d0d4dfc591 100644 --- a/llvm/include/llvm/MC/MCSection.h +++ b/llvm/include/llvm/MC/MCSection.h @@ -31,6 +31,18 @@ class MCSection; class MCSymbol; class raw_ostream; +template<> +struct ilist_node_traits<MCFragment> { + MCFragment *createNode(const MCFragment &V); + static void deleteNode(MCFragment *V); + + void addNodeToList(MCFragment *) {} + void removeNodeFromList(MCFragment *) {} + void transferNodesFromList(ilist_node_traits & /*SrcTraits*/, + ilist_iterator<MCFragment> /*first*/, + ilist_iterator<MCFragment> /*last*/) {} +}; + /// Instances of this class represent a uniqued identifier for a section in the /// current translation unit. The MCContext class uniques and creates these. class MCSection { diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index df416710182..76be67cafc5 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -262,26 +262,64 @@ uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler, /* *** */ -MCFragment::MCFragment() : Kind(FragmentType(~0)) { +void ilist_node_traits<MCFragment>::deleteNode(MCFragment *V) { + V->destroy(); } -MCFragment::~MCFragment() { +MCFragment::MCFragment() : Kind(FragmentType(~0)), HasInstructions(false), + AlignToBundleEnd(false), BundlePadding(0) { } -MCFragment::MCFragment(FragmentType Kind, MCSection *Parent) - : Kind(Kind), Parent(Parent), Atom(nullptr), Offset(~UINT64_C(0)) { +MCFragment::~MCFragment() { } + +MCFragment::MCFragment(FragmentType Kind, bool HasInstructions, + uint8_t BundlePadding, MCSection *Parent) + : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false), + BundlePadding(BundlePadding), Parent(Parent), Atom(nullptr), + Offset(~UINT64_C(0)) { if (Parent) Parent->getFragmentList().push_back(this); } -/* *** */ - -MCEncodedFragment::~MCEncodedFragment() { -} - -/* *** */ +void MCFragment::destroy() { + // First check if we are the sentinal. + if (Kind == FragmentType(~0)) { + delete this; + return; + } -MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() { + switch (Kind) { + case FT_Align: + delete cast<MCAlignFragment>(this); + return; + case FT_Data: + delete cast<MCDataFragment>(this); + return; + case FT_CompactEncodedInst: + delete cast<MCCompactEncodedInstFragment>(this); + return; + case FT_Fill: + delete cast<MCFillFragment>(this); + return; + case FT_Relaxable: + delete cast<MCRelaxableFragment>(this); + return; + case FT_Org: + delete cast<MCOrgFragment>(this); + return; + case FT_Dwarf: + delete cast<MCDwarfLineAddrFragment>(this); + return; + case FT_DwarfFrame: + delete cast<MCDwarfCallFrameFragment>(this); + return; + case FT_LEB: + delete cast<MCLEBFragment>(this); + return; + case FT_SafeSEH: + delete cast<MCSafeSEHFragment>(this); + return; + } } /* *** */ @@ -454,9 +492,11 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const { switch (F.getKind()) { case MCFragment::FT_Data: + return cast<MCDataFragment>(F).getContents().size(); case MCFragment::FT_Relaxable: + return cast<MCRelaxableFragment>(F).getContents().size(); case MCFragment::FT_CompactEncodedInst: - return cast<MCEncodedFragment>(F).getContents().size(); + return cast<MCCompactEncodedInstFragment>(F).getContents().size(); case MCFragment::FT_Fill: return cast<MCFillFragment>(F).getSize(); @@ -562,13 +602,6 @@ void MCAsmLayout::layoutFragment(MCFragment *F) { } } -/// \brief Write the contents of a fragment to the given object writer. Expects -/// a MCEncodedFragment. -static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) { - const MCEncodedFragment &EF = cast<MCEncodedFragment>(F); - OW->writeBytes(EF.getContents()); -} - void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) { bool New = !Symbol.isRegistered(); if (Created) @@ -671,17 +704,17 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, case MCFragment::FT_Data: ++stats::EmittedDataFragments; - writeFragmentContents(F, OW); + OW->writeBytes(cast<MCDataFragment>(F).getContents()); break; case MCFragment::FT_Relaxable: ++stats::EmittedRelaxableFragments; - writeFragmentContents(F, OW); + OW->writeBytes(cast<MCRelaxableFragment>(F).getContents()); break; case MCFragment::FT_CompactEncodedInst: ++stats::EmittedCompactEncodedInstFragments; - writeFragmentContents(F, OW); + OW->writeBytes(cast<MCCompactEncodedInstFragment>(F).getContents()); break; case MCFragment::FT_Fill: { @@ -870,18 +903,29 @@ void MCAssembler::Finish() { for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) { for (MCSection::iterator it2 = it->begin(), ie2 = it->end(); it2 != ie2; ++it2) { - MCEncodedFragmentWithFixups *F = - dyn_cast<MCEncodedFragmentWithFixups>(it2); - if (F) { - for (MCEncodedFragmentWithFixups::fixup_iterator it3 = F->fixup_begin(), - ie3 = F->fixup_end(); it3 != ie3; ++it3) { - MCFixup &Fixup = *it3; - uint64_t FixedValue; - bool IsPCRel; - std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup); - getBackend().applyFixup(Fixup, F->getContents().data(), - F->getContents().size(), FixedValue, IsPCRel); - } + MCEncodedFragment *F = dyn_cast<MCEncodedFragment>(it2); + // Data and relaxable fragments both have fixups. So only process + // those here. + // FIXME: Is there a better way to do this? MCEncodedFragmentWithFixups + // being templated makes this tricky. + if (!F || isa<MCCompactEncodedInstFragment>(F)) + continue; + ArrayRef<MCFixup> Fixups; + MutableArrayRef<char> Contents; + if (auto *FragWithFixups = dyn_cast<MCDataFragment>(F)) { + Fixups = FragWithFixups->getFixups(); + Contents = FragWithFixups->getContents(); + } else if (auto *FragWithFixups = dyn_cast<MCRelaxableFragment>(F)) { + Fixups = FragWithFixups->getFixups(); + Contents = FragWithFixups->getContents(); + } else + llvm_unreachable("Unknow fragment with fixups!"); + for (const MCFixup &Fixup : Fixups) { + uint64_t FixedValue; + bool IsPCRel; + std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup); + getBackend().applyFixup(Fixup, Contents.data(), + Contents.size(), FixedValue, IsPCRel); } } } @@ -1218,17 +1262,3 @@ void MCAssembler::dump() { OS << "]>\n"; } #endif - -// anchors for MC*Fragment vtables -void MCEncodedFragment::anchor() { } -void MCEncodedFragmentWithFixups::anchor() { } -void MCDataFragment::anchor() { } -void MCCompactEncodedInstFragment::anchor() { } -void MCRelaxableFragment::anchor() { } -void MCAlignFragment::anchor() { } -void MCFillFragment::anchor() { } -void MCOrgFragment::anchor() { } -void MCLEBFragment::anchor() { } -void MCSafeSEHFragment::anchor() { } -void MCDwarfLineAddrFragment::anchor() { } -void MCDwarfCallFrameFragment::anchor() { } diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index e0f4a2ae16a..fe9ac21e17f 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -45,7 +45,7 @@ MCELFStreamer::~MCELFStreamer() { } void MCELFStreamer::mergeFragment(MCDataFragment *DF, - MCEncodedFragmentWithFixups *EF) { + MCDataFragment *EF) { MCAssembler &Assembler = getAssembler(); if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) { |