aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2013-04-17 21:18:16 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2013-04-17 21:18:16 +0000
commitdf39be6cb4eb44011db3d3e86f8fe463f81ce127 (patch)
treea008e657a29cef0e9c842f58d4eebb9bd45aba2b /include/llvm
parent53c9def43359f9b908565b28340e461ce5463009 (diff)
downloadexternal_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.h23
-rw-r--r--include/llvm/MC/MCELFStreamer.h3
-rw-r--r--include/llvm/MC/MCObjectStreamer.h10
-rw-r--r--include/llvm/MC/MCSection.h4
-rw-r--r--include/llvm/MC/MCSectionCOFF.h3
-rw-r--r--include/llvm/MC/MCSectionELF.h3
-rw-r--r--include/llvm/MC/MCSectionMachO.h3
-rw-r--r--include/llvm/MC/MCStreamer.h48
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.