diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2011-02-16 01:08:29 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2011-02-16 01:08:29 +0000 |
commit | 7768a9dce14431018133cd586f5c8ce3e057f069 (patch) | |
tree | 96d6d88654a2520802874c021b320394bfe2e1ff /lib/MC | |
parent | e32effb02f28025bcbb1eb6b673f46f8d072627b (diff) |
Add support for pushsection and popsection. Patch by Joerg Sonnenberger.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@125629 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 20 | ||||
-rw-r--r-- | lib/MC/MCELFStreamer.cpp | 8 | ||||
-rw-r--r-- | lib/MC/MCLoggingStreamer.cpp | 7 | ||||
-rw-r--r-- | lib/MC/MCMachOStreamer.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCNullStreamer.cpp | 8 | ||||
-rw-r--r-- | lib/MC/MCObjectStreamer.cpp | 11 | ||||
-rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 30 | ||||
-rw-r--r-- | lib/MC/MCPureStreamer.cpp | 4 | ||||
-rw-r--r-- | lib/MC/MCStreamer.cpp | 5 |
9 files changed, 53 insertions, 42 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 6aabfe188a..8d0698216f 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -107,7 +107,7 @@ public: /// @name MCStreamer Interface /// @{ - virtual void SwitchSection(const MCSection *Section); + virtual void ChangeSection(const MCSection *Section); virtual void InitSections() { // FIXME, this is MachO specific, but the testsuite @@ -254,23 +254,19 @@ static inline int64_t truncateToSize(int64_t Value, unsigned Bytes) { return Value & ((uint64_t) (int64_t) -1 >> (64 - Bytes * 8)); } -void MCAsmStreamer::SwitchSection(const MCSection *Section) { +void MCAsmStreamer::ChangeSection(const MCSection *Section) { assert(Section && "Cannot switch to a null section!"); - if (Section != CurSection) { - PrevSection = CurSection; - CurSection = Section; - Section->PrintSwitchToSection(MAI, OS); - } + Section->PrintSwitchToSection(MAI, OS); } void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); - assert(CurSection && "Cannot emit before setting section!"); + assert(getCurrentSection() && "Cannot emit before setting section!"); OS << *Symbol << MAI.getLabelSuffix(); EmitEOL(); - Symbol->setSection(*CurSection); + Symbol->setSection(*getCurrentSection()); } void MCAsmStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) { @@ -486,7 +482,7 @@ static void PrintQuotedString(StringRef Data, raw_ostream &OS) { void MCAsmStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { - assert(CurSection && "Cannot emit contents before setting section!"); + assert(getCurrentSection() && "Cannot emit contents before setting section!"); if (Data.empty()) return; if (Data.size() == 1) { @@ -517,7 +513,7 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size, void MCAsmStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, bool isPCRel, unsigned AddrSpace) { - assert(CurSection && "Cannot emit contents before setting section!"); + assert(getCurrentSection() && "Cannot emit contents before setting section!"); assert(!isPCRel && "Cannot emit pc relative relocations!"); const char *Directive = 0; switch (Size) { @@ -864,7 +860,7 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst) { } void MCAsmStreamer::EmitInstruction(const MCInst &Inst) { - assert(CurSection && "Cannot emit contents before setting section!"); + assert(getCurrentSection() && "Cannot emit contents before setting section!"); if (!UseLoc) MCLineEntry::Make(this, getCurrentSection()); diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index ac31057065..e49074da39 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -80,12 +80,12 @@ public: /// @{ virtual void InitSections(); + virtual void ChangeSection(const MCSection *Section); virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); virtual void EmitThumbFunc(MCSymbol *Func); virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol); - virtual void SwitchSection(const MCSection *Section); virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute); virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) { assert(0 && "ELF doesn't support this directive"); @@ -222,11 +222,11 @@ void MCELFStreamer::EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { Symbol->setVariableValue(AddValueSymbols(Value)); } -void MCELFStreamer::SwitchSection(const MCSection *Section) { +void MCELFStreamer::ChangeSection(const MCSection *Section) { const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup(); if (Grp) getAssembler().getOrCreateSymbolData(*Grp); - this->MCObjectStreamer::SwitchSection(Section); + this->MCObjectStreamer::ChangeSection(Section); } void MCELFStreamer::EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) { @@ -411,7 +411,7 @@ void MCELFStreamer::EmitCodeAlignment(unsigned ByteAlignment, // entry in the module's symbol table (the first being the null symbol). void MCELFStreamer::EmitFileDirective(StringRef Filename) { MCSymbol *Symbol = getAssembler().getContext().GetOrCreateSymbol(Filename); - Symbol->setSection(*CurSection); + Symbol->setSection(*getCurrentSection()); Symbol->setAbsolute(); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); diff --git a/lib/MC/MCLoggingStreamer.cpp b/lib/MC/MCLoggingStreamer.cpp index d947481383..012c7f62f8 100644 --- a/lib/MC/MCLoggingStreamer.cpp +++ b/lib/MC/MCLoggingStreamer.cpp @@ -48,10 +48,9 @@ public: return Child->AddBlankLine(); } - virtual void SwitchSection(const MCSection *Section) { - CurSection = Section; - LogCall("SwitchSection"); - return Child->SwitchSection(Section); + virtual void ChangeSection(const MCSection *Section) { + LogCall("ChangeSection"); + return Child->ChangeSection(Section); } virtual void InitSections() { diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 7e1cda25b6..d1f9f5cd56 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -105,7 +105,7 @@ void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); // isSymbolLinkerVisible uses the section. - Symbol->setSection(*CurSection); + Symbol->setSection(*getCurrentSection()); // We have to create a new fragment if this is an atom defining symbol, // fragments cannot span atoms. if (getAssembler().isSymbolLinkerVisible(*Symbol)) diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index b9393ffd2e..08ddf01d1a 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -28,15 +28,13 @@ namespace { virtual void InitSections() { } - virtual void SwitchSection(const MCSection *Section) { - PrevSection = CurSection; - CurSection = Section; + virtual void ChangeSection(const MCSection *Section) { } virtual void EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); - assert(CurSection && "Cannot emit before setting section!"); - Symbol->setSection(*CurSection); + assert(getCurrentSection() && "Cannot emit before setting section!"); + Symbol->setSection(*getCurrentSection()); } virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {} diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index ecd7257c70..035826690c 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -101,9 +101,9 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, void MCObjectStreamer::EmitLabel(MCSymbol *Symbol) { assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); - assert(CurSection && "Cannot emit before setting section!"); + assert(getCurrentSection() && "Cannot emit before setting section!"); - Symbol->setSection(*CurSection); + Symbol->setSection(*getCurrentSection()); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); @@ -142,14 +142,9 @@ void MCObjectStreamer::EmitWeakReference(MCSymbol *Alias, report_fatal_error("This file format doesn't support weak aliases."); } -void MCObjectStreamer::SwitchSection(const MCSection *Section) { +void MCObjectStreamer::ChangeSection(const MCSection *Section) { assert(Section && "Cannot switch to a null section!"); - // If already in this section, then this is a noop. - if (Section == CurSection) return; - - PrevSection = CurSection; - CurSection = Section; CurSectionData = &getAssembler().getOrCreateSectionData(*Section); } diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 7b88ea2d1d..bfaf36a451 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -49,6 +49,8 @@ public: AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveDataRelRoLocal>(".data.rel.ro.local"); AddDirectiveHandler<&ELFAsmParser::ParseSectionDirectiveEhFrame>(".eh_frame"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSection>(".section"); + AddDirectiveHandler<&ELFAsmParser::ParseDirectivePushSection>(".pushsection"); + AddDirectiveHandler<&ELFAsmParser::ParseDirectivePopSection>(".popsection"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveSize>(".size"); AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); AddDirectiveHandler<&ELFAsmParser::ParseDirectiveType>(".type"); @@ -115,6 +117,8 @@ public: ELF::SHF_WRITE, SectionKind::getDataRel()); } + bool ParseDirectivePushSection(StringRef, SMLoc); + bool ParseDirectivePopSection(StringRef, SMLoc); bool ParseDirectiveSection(StringRef, SMLoc); bool ParseDirectiveSize(StringRef, SMLoc); bool ParseDirectivePrevious(StringRef, SMLoc); @@ -253,6 +257,23 @@ static int parseSectionFlags(StringRef flagsStr) { return flags; } +bool ELFAsmParser::ParseDirectivePushSection(StringRef s, SMLoc loc) { + getStreamer().PushSection(); + + if (ParseDirectiveSection(s, loc)) { + getStreamer().PopSection(); + return true; + } + + return false; +} + +bool ELFAsmParser::ParseDirectivePopSection(StringRef, SMLoc) { + if (!getStreamer().PopSection()) + return TokError(".popsection without corresponding .pushsection"); + return false; +} + // FIXME: This is a work in progress. bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { StringRef SectionName; @@ -364,8 +385,9 @@ bool ELFAsmParser::ParseDirectiveSection(StringRef, SMLoc) { bool ELFAsmParser::ParseDirectivePrevious(StringRef DirName, SMLoc) { const MCSection *PreviousSection = getStreamer().getPreviousSection(); - if (PreviousSection != NULL) - getStreamer().SwitchSection(PreviousSection); + if (PreviousSection == NULL) + return TokError(".previous without corresponding .section"); + getStreamer().SwitchSection(PreviousSection); return false; } @@ -427,7 +449,6 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { Lex(); - const MCSection *OldSection = getStreamer().getCurrentSection(); const MCSection *Comment = getContext().getELFSection(".comment", ELF::SHT_PROGBITS, ELF::SHF_MERGE | @@ -437,13 +458,14 @@ bool ELFAsmParser::ParseDirectiveIdent(StringRef, SMLoc) { static bool First = true; + getStreamer().PushSection(); getStreamer().SwitchSection(Comment); if (First) getStreamer().EmitIntValue(0, 1); First = false; getStreamer().EmitBytes(Data, 0); getStreamer().EmitIntValue(0, 1); - getStreamer().SwitchSection(OldSection); + getStreamer().PopSection(); return false; } diff --git a/lib/MC/MCPureStreamer.cpp b/lib/MC/MCPureStreamer.cpp index 5341844f74..6098e6b8f3 100644 --- a/lib/MC/MCPureStreamer.cpp +++ b/lib/MC/MCPureStreamer.cpp @@ -113,9 +113,9 @@ void MCPureStreamer::InitSections() { void MCPureStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); assert(!Symbol->isVariable() && "Cannot emit a variable symbol!"); - assert(CurSection && "Cannot emit before setting section!"); + assert(getCurrentSection() && "Cannot emit before setting section!"); - Symbol->setSection(*CurSection); + Symbol->setSection(*getCurrentSection()); MCSymbolData &SD = getAssembler().getOrCreateSymbolData(*Symbol); diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 1cb5165e6d..3dcdba1313 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -19,8 +19,9 @@ #include <cstdlib> using namespace llvm; -MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx), CurSection(0), - PrevSection(0) { +MCStreamer::MCStreamer(MCContext &Ctx) : Context(Ctx) { + PrevSectionStack.push_back(NULL); + CurSectionStack.push_back(NULL); } MCStreamer::~MCStreamer() { |