diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-09-15 21:48:40 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-09-15 21:48:40 +0000 |
commit | d80781b98b771d370730ab7c630018f23e202b57 (patch) | |
tree | 96ca95a60f4eb1c0694f785f29529a6e7c21f3b9 /lib/MC | |
parent | 06f264e504d75f0426eea55b9f9e36c780d8a4fc (diff) |
Add a InitSections method to the streamer interface.
The ELF implementation now creates text, data and bss to match the gnu as
behavior.
The text streamer still has the old MachO specific behavior since
the testsuite checks that it will error when a directive is given
before a setting the current section for example.
A nice benefit is that -n is not required anymore when producing
ELF files.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114027 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 8 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 2 | ||||
-rw-r--r-- | lib/MC/MCELFStreamer.cpp | 33 | ||||
-rw-r--r-- | lib/MC/MCLoggingStreamer.cpp | 4 | ||||
-rw-r--r-- | lib/MC/MCMachOStreamer.cpp | 8 | ||||
-rw-r--r-- | lib/MC/MCNullStreamer.cpp | 3 | ||||
-rw-r--r-- | lib/MC/MCParser/AsmParser.cpp | 6 | ||||
-rw-r--r-- | lib/MC/MCParser/ELFAsmParser.cpp | 14 | ||||
-rw-r--r-- | lib/MC/WinCOFFStreamer.cpp | 4 |
9 files changed, 73 insertions, 9 deletions
diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index 1cc8fb0b54..efde8aa350 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -100,6 +100,14 @@ public: virtual void SwitchSection(const MCSection *Section); + virtual void InitSections() { + // FIXME, this is MachO specific, but the testsuite + // expects this. + SwitchSection(getContext().getMachOSection("__TEXT", "__text", + MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + 0, SectionKind::getText())); + } + virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 8db1536d2d..bb1249950c 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -739,7 +739,7 @@ void MCAssembler::Finish(MCObjectWriter *Writer) { // Create dummy fragments to eliminate any empty sections, this simplifies // layout. if (it->getFragmentList().empty()) - new MCFillFragment(0, 1, 0, it); + new MCDataFragment(it); it->setOrdinal(SectionIndex++); } diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 6490cc7a82..deb1a0de20 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -46,6 +46,7 @@ public: /// @name MCStreamer Interface /// @{ + virtual void InitSections(); virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); @@ -109,10 +110,42 @@ public: virtual void Finish(); /// @} + void SetSection(StringRef Section, unsigned Type, unsigned Flags, + SectionKind Kind) { + SwitchSection(getContext().getELFSection(Section, Type, Flags, Kind)); + } + + void SetSectionData() { + SetSection(".data", MCSectionELF::SHT_PROGBITS, + MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC, + SectionKind::getDataRel()); + EmitCodeAlignment(4, 0); + } + void SetSectionText() { + SetSection(".text", MCSectionELF::SHT_PROGBITS, + MCSectionELF::SHF_EXECINSTR | + MCSectionELF::SHF_ALLOC, SectionKind::getText()); + EmitCodeAlignment(4, 0); + } + void SetSectionBss() { + SetSection(".bss", MCSectionELF::SHT_NOBITS, + MCSectionELF::SHF_WRITE | + MCSectionELF::SHF_ALLOC, SectionKind::getBSS()); + EmitCodeAlignment(4, 0); + } }; } // end anonymous namespace. +void MCELFStreamer::InitSections() { + // This emulates the same behavior of GNU as. This makes it easier + // to compare the output as the major sections are in the same order. + SetSectionText(); + SetSectionData(); + SetSectionBss(); + SetSectionText(); +} + void MCELFStreamer::EmitLabel(MCSymbol *Symbol) { assert(Symbol->isUndefined() && "Cannot define a symbol twice!"); diff --git a/lib/MC/MCLoggingStreamer.cpp b/lib/MC/MCLoggingStreamer.cpp index b96040abd0..879afa44c5 100644 --- a/lib/MC/MCLoggingStreamer.cpp +++ b/lib/MC/MCLoggingStreamer.cpp @@ -54,6 +54,10 @@ public: return Child->SwitchSection(Section); } + virtual void InitSections() { + LogCall("InitSections"); + } + virtual void EmitLabel(MCSymbol *Symbol) { LogCall("EmitLabel"); return Child->EmitLabel(Symbol); diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 671874df2c..cd6fd50933 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -46,6 +46,7 @@ public: /// @name MCStreamer Interface /// @{ + virtual void InitSections(); virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); @@ -110,6 +111,13 @@ public: } // end anonymous namespace. +void MCMachOStreamer::InitSections() { + SwitchSection(getContext().getMachOSection("__TEXT", "__text", + MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, + 0, SectionKind::getText())); + +} + void MCMachOStreamer::EmitLabel(MCSymbol *Symbol) { // TODO: This is almost exactly the same as WinCOFFStreamer. Consider merging // into MCObjectStreamer. diff --git a/lib/MC/MCNullStreamer.cpp b/lib/MC/MCNullStreamer.cpp index f7a2f20ca4..b2db410c11 100644 --- a/lib/MC/MCNullStreamer.cpp +++ b/lib/MC/MCNullStreamer.cpp @@ -25,6 +25,9 @@ namespace { /// @name MCStreamer Interface /// @{ + virtual void InitSections() { + } + virtual void SwitchSection(const MCSection *Section) { PrevSection = CurSection; CurSection = Section; diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 5ef6f682bf..b3ffed846d 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -365,12 +365,8 @@ const AsmToken &AsmParser::Lex() { bool AsmParser::Run(bool NoInitialTextSection, bool NoFinalize) { // Create the initial section, if requested. - // - // FIXME: Target hook & command line option for initial section. if (!NoInitialTextSection) - Out.SwitchSection(Ctx.getMachOSection("__TEXT", "__text", - MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS, - 0, SectionKind::getText())); + Out.InitSections(); // Prime the lexer. Lex(); diff --git a/lib/MC/MCParser/ELFAsmParser.cpp b/lib/MC/MCParser/ELFAsmParser.cpp index 38288d78b0..ddf988faa6 100644 --- a/lib/MC/MCParser/ELFAsmParser.cpp +++ b/lib/MC/MCParser/ELFAsmParser.cpp @@ -51,20 +51,28 @@ public: AddDirectiveHandler<&ELFAsmParser::ParseDirectivePrevious>(".previous"); } + // FIXME: Part of this logic is duplicated in the MCELFStreamer. What is + // the best way for us to get access to it? bool ParseSectionDirectiveData(StringRef, SMLoc) { - return ParseSectionSwitch(".data", MCSectionELF::SHT_PROGBITS, + bool ret = ParseSectionSwitch(".data", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_WRITE |MCSectionELF::SHF_ALLOC, SectionKind::getDataRel()); + getStreamer().EmitCodeAlignment(4, 0); + return ret; } bool ParseSectionDirectiveText(StringRef, SMLoc) { - return ParseSectionSwitch(".text", MCSectionELF::SHT_PROGBITS, + bool ret = ParseSectionSwitch(".text", MCSectionELF::SHT_PROGBITS, MCSectionELF::SHF_EXECINSTR | MCSectionELF::SHF_ALLOC, SectionKind::getText()); + getStreamer().EmitCodeAlignment(4, 0); + return ret; } bool ParseSectionDirectiveBSS(StringRef, SMLoc) { - return ParseSectionSwitch(".bss", MCSectionELF::SHT_NOBITS, + bool ret = ParseSectionSwitch(".bss", MCSectionELF::SHT_NOBITS, MCSectionELF::SHF_WRITE | MCSectionELF::SHF_ALLOC, SectionKind::getBSS()); + getStreamer().EmitCodeAlignment(4, 0); + return ret; } bool ParseSectionDirectiveRoData(StringRef, SMLoc) { return ParseSectionSwitch(".rodata", MCSectionELF::SHT_PROGBITS, diff --git a/lib/MC/WinCOFFStreamer.cpp b/lib/MC/WinCOFFStreamer.cpp index 8a194bff21..faecfcbe33 100644 --- a/lib/MC/WinCOFFStreamer.cpp +++ b/lib/MC/WinCOFFStreamer.cpp @@ -48,6 +48,7 @@ public: // MCStreamer interface + virtual void InitSections(); virtual void EmitLabel(MCSymbol *Symbol); virtual void EmitAssemblerFlag(MCAssemblerFlag Flag); virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value); @@ -126,6 +127,9 @@ void WinCOFFStreamer::AddCommonSymbol(MCSymbol *Symbol, uint64_t Size, // MCStreamer interface +void WinCOFFStreamer::InitSections() { +} + void WinCOFFStreamer::EmitLabel(MCSymbol *Symbol) { // TODO: This is copied almost exactly from the MachOStreamer. Consider // merging into MCObjectStreamer? |