diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2013-04-17 21:18:16 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2013-04-17 21:18:16 +0000 |
commit | df39be6cb4eb44011db3d3e86f8fe463f81ce127 (patch) | |
tree | a008e657a29cef0e9c842f58d4eebb9bd45aba2b /include/llvm | |
parent | 53c9def43359f9b908565b28340e461ce5463009 (diff) | |
download | external_llvm-df39be6cb4eb44011db3d3e86f8fe463f81ce127.zip external_llvm-df39be6cb4eb44011db3d3e86f8fe463f81ce127.tar.gz external_llvm-df39be6cb4eb44011db3d3e86f8fe463f81ce127.tar.bz2 |
Add support for subsections to the ELF assembler. Fixes PR8717.
Differential Revision: http://llvm-reviews.chandlerc.com/D598
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179725 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm')
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 23 | ||||
-rw-r--r-- | include/llvm/MC/MCELFStreamer.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectStreamer.h | 10 | ||||
-rw-r--r-- | include/llvm/MC/MCSection.h | 4 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionCOFF.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionELF.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCSectionMachO.h | 3 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 48 |
8 files changed, 64 insertions, 33 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 32df38b..38a70f0 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -82,7 +82,7 @@ private: /// @} protected: - MCFragment(FragmentType _Kind, MCSectionData *_Parent); + MCFragment(FragmentType _Kind, MCSectionData *_Parent = 0); public: // Only for sentinel. @@ -92,6 +92,7 @@ public: FragmentType getKind() const { return Kind; } MCSectionData *getParent() const { return Parent; } + void setParent(MCSectionData *Value) { Parent = Value; } MCSymbolData *getAtom() const { return Atom; } void setAtom(MCSymbolData *Value) { Atom = Value; } @@ -132,7 +133,7 @@ class MCEncodedFragment : public MCFragment { uint8_t BundlePadding; public: - MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD) + MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0) : MCFragment(FType, SD), BundlePadding(0) { } @@ -347,7 +348,7 @@ class MCAlignFragment : public MCFragment { public: MCAlignFragment(unsigned _Alignment, int64_t _Value, unsigned _ValueSize, - unsigned _MaxBytesToEmit, MCSectionData *SD) + unsigned _MaxBytesToEmit, MCSectionData *SD = 0) : MCFragment(FT_Align, SD), Alignment(_Alignment), Value(_Value),ValueSize(_ValueSize), MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {} @@ -388,7 +389,7 @@ class MCFillFragment : public MCFragment { public: MCFillFragment(int64_t _Value, unsigned _ValueSize, uint64_t _Size, - MCSectionData *SD) + MCSectionData *SD = 0) : MCFragment(FT_Fill, SD), Value(_Value), ValueSize(_ValueSize), Size(_Size) { assert((!ValueSize || (Size % ValueSize) == 0) && @@ -421,7 +422,7 @@ class MCOrgFragment : public MCFragment { int8_t Value; public: - MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD) + MCOrgFragment(const MCExpr &_Offset, int8_t _Value, MCSectionData *SD = 0) : MCFragment(FT_Org, SD), Offset(&_Offset), Value(_Value) {} @@ -450,7 +451,7 @@ class MCLEBFragment : public MCFragment { SmallString<8> Contents; public: - MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD) + MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD = 0) : MCFragment(FT_LEB, SD), Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } @@ -486,7 +487,7 @@ class MCDwarfLineAddrFragment : public MCFragment { public: MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta, - MCSectionData *SD) + MCSectionData *SD = 0) : MCFragment(FT_Dwarf, SD), LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); } @@ -517,7 +518,7 @@ class MCDwarfCallFrameFragment : public MCFragment { SmallString<8> Contents; public: - MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD) + MCDwarfCallFrameFragment(const MCExpr &_AddrDelta, MCSectionData *SD = 0) : MCFragment(FT_DwarfFrame, SD), AddrDelta(&_AddrDelta) { Contents.push_back(0); } @@ -589,6 +590,10 @@ private: /// it. unsigned HasInstructions : 1; + /// Mapping from subsection number to insertion point for subsection numbers + /// below that number. + SmallVector<std::pair<unsigned, MCFragment *>, 1> SubsectionFragmentMap; + /// @} public: @@ -632,6 +637,8 @@ public: bool empty() const { return Fragments.empty(); } + iterator getSubsectionInsertionPoint(unsigned Subsection); + bool isBundleLocked() const { return BundleLockState != NotBundleLocked; } diff --git a/include/llvm/MC/MCELFStreamer.h b/include/llvm/MC/MCELFStreamer.h index 6fb2d22..55c05b0 100644 --- a/include/llvm/MC/MCELFStreamer.h +++ b/include/llvm/MC/MCELFStreamer.h @@ -50,7 +50,8 @@ public: virtual void InitSections(); virtual void InitToTextSection(); - virtual void ChangeSection(const MCSection *Section); + virtual void ChangeSection(const MCSection *Section, + const MCExpr *Subsection); virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitDebugLabel(MCSymbol *Symbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index f06c49f..22a2839 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCOBJECTSTREAMER_H #define LLVM_MC_MCOBJECTSTREAMER_H +#include "llvm/MC/MCAssembler.h" #include "llvm/MC/MCStreamer.h" namespace llvm { @@ -32,6 +33,7 @@ class raw_ostream; class MCObjectStreamer : public MCStreamer { MCAssembler *Assembler; MCSectionData *CurSectionData; + MCSectionData::iterator CurInsertionPoint; virtual void EmitInstToData(const MCInst &Inst) = 0; virtual void EmitCFIStartProcImpl(MCDwarfFrameInfo &Frame); @@ -56,6 +58,11 @@ protected: MCFragment *getCurrentFragment() const; + void insert(MCFragment *F) const { + CurSectionData->getFragmentList().insert(CurInsertionPoint, F); + F->setParent(CurSectionData); + } + /// Get a data fragment to write into, creating a new one if the current /// fragment is not a data fragment. MCDataFragment *getOrCreateDataFragment() const; @@ -76,7 +83,8 @@ public: virtual void EmitULEB128Value(const MCExpr *Value); virtual void EmitSLEB128Value(const MCExpr *Value); virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - virtual void ChangeSection(const MCSection *Section); + virtual void ChangeSection(const MCSection *Section, + const MCExpr *Subsection); virtual void EmitInstruction(const MCInst &Inst); /// \brief Emit an instruction to a special fragment, because this instruction diff --git a/include/llvm/MC/MCSection.h b/include/llvm/MC/MCSection.h index e575424..de2678a 100644 --- a/include/llvm/MC/MCSection.h +++ b/include/llvm/MC/MCSection.h @@ -20,6 +20,7 @@ namespace llvm { class MCAsmInfo; + class MCExpr; class raw_ostream; /// MCSection - Instances of this class represent a uniqued identifier for a @@ -48,7 +49,8 @@ namespace llvm { SectionVariant getVariant() const { return Variant; } virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const = 0; + raw_ostream &OS, + const MCExpr *Subsection) const = 0; // Convenience routines to get label names for the beginning/end of a // section. diff --git a/include/llvm/MC/MCSectionCOFF.h b/include/llvm/MC/MCSectionCOFF.h index 07c4714..50e33a5 100644 --- a/include/llvm/MC/MCSectionCOFF.h +++ b/include/llvm/MC/MCSectionCOFF.h @@ -60,7 +60,8 @@ namespace llvm { int getSelection () const { return Selection; } virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const; + raw_ostream &OS, + const MCExpr *Subsection) const; virtual bool UseCodeAlign() const; virtual bool isVirtualSection() const; diff --git a/include/llvm/MC/MCSectionELF.h b/include/llvm/MC/MCSectionELF.h index 4b8b849..5979915 100644 --- a/include/llvm/MC/MCSectionELF.h +++ b/include/llvm/MC/MCSectionELF.h @@ -70,7 +70,8 @@ public: const MCSymbol *getGroup() const { return Group; } void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const; + raw_ostream &OS, + const MCExpr *Subsection) const; virtual bool UseCodeAlign() const; virtual bool isVirtualSection() const; diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index 898f571..b68bd85 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -175,7 +175,8 @@ public: unsigned &StubSize); // Out. virtual void PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const; + raw_ostream &OS, + const MCExpr *Subsection) const; virtual bool UseCodeAlign() const; virtual bool isVirtualSection() const; diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index a069a2b..2cab481 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -37,6 +37,8 @@ namespace llvm { class raw_ostream; class formatted_raw_ostream; + typedef std::pair<const MCSection *, const MCExpr *> MCSectionSubPair; + /// MCStreamer - Streaming machine code generation interface. This interface /// is intended to provide a programatic interface that is very similar to the /// level that an assembler .s file provides. It has callbacks to emit bytes, @@ -86,8 +88,7 @@ namespace llvm { /// SectionStack - This is stack of current and previous section /// values saved by PushSection. - SmallVector<std::pair<const MCSection *, - const MCSection *>, 4> SectionStack; + SmallVector<std::pair<MCSectionSubPair, MCSectionSubPair>, 4> SectionStack; bool AutoInitSections; @@ -174,25 +175,25 @@ namespace llvm { /// getCurrentSection - Return the current section that the streamer is /// emitting code to. - const MCSection *getCurrentSection() const { + MCSectionSubPair getCurrentSection() const { if (!SectionStack.empty()) return SectionStack.back().first; - return NULL; + return MCSectionSubPair(); } /// getPreviousSection - Return the previous section that the streamer is /// emitting code to. - const MCSection *getPreviousSection() const { + MCSectionSubPair getPreviousSection() const { if (!SectionStack.empty()) return SectionStack.back().second; - return NULL; + return MCSectionSubPair(); } /// ChangeSection - Update streamer for a new active section. /// /// This is called by PopSection and SwitchSection, if the current /// section changes. - virtual void ChangeSection(const MCSection *) = 0; + virtual void ChangeSection(const MCSection *, const MCExpr *) = 0; /// pushSection - Save the current and previous section on the /// section stack. @@ -208,11 +209,19 @@ namespace llvm { bool PopSection() { if (SectionStack.size() <= 1) return false; - const MCSection *oldSection = SectionStack.pop_back_val().first; - const MCSection *curSection = SectionStack.back().first; + MCSectionSubPair oldSection = SectionStack.pop_back_val().first; + MCSectionSubPair curSection = SectionStack.back().first; if (oldSection != curSection) - ChangeSection(curSection); + ChangeSection(curSection.first, curSection.second); + return true; + } + + bool SubSection(const MCExpr *Subsection) { + if (SectionStack.empty()) + return false; + + SwitchSection(SectionStack.back().first.first, Subsection); return true; } @@ -220,25 +229,26 @@ namespace llvm { /// @p Section. This is required to update CurSection. /// /// This corresponds to assembler directives like .section, .text, etc. - void SwitchSection(const MCSection *Section) { + void SwitchSection(const MCSection *Section, const MCExpr *Subsection = 0) { assert(Section && "Cannot switch to a null section!"); - const MCSection *curSection = SectionStack.back().first; + MCSectionSubPair curSection = SectionStack.back().first; SectionStack.back().second = curSection; - if (Section != curSection) { - SectionStack.back().first = Section; - ChangeSection(Section); + if (MCSectionSubPair(Section, Subsection) != curSection) { + SectionStack.back().first = MCSectionSubPair(Section, Subsection); + ChangeSection(Section, Subsection); } } /// SwitchSectionNoChange - Set the current section where code is being /// emitted to @p Section. This is required to update CurSection. This /// version does not call ChangeSection. - void SwitchSectionNoChange(const MCSection *Section) { + void SwitchSectionNoChange(const MCSection *Section, + const MCExpr *Subsection = 0) { assert(Section && "Cannot switch to a null section!"); - const MCSection *curSection = SectionStack.back().first; + MCSectionSubPair curSection = SectionStack.back().first; SectionStack.back().second = curSection; - if (Section != curSection) - SectionStack.back().first = Section; + if (MCSectionSubPair(Section, Subsection) != curSection) + SectionStack.back().first = MCSectionSubPair(Section, Subsection); } /// Initialize the streamer. |