From 6db8a9f3fabefeb00163295f0611d09134651f3f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 2 Dec 2010 03:09:06 +0000 Subject: [PATCH] The sections that the ELF object writer has to create are very simple and contain only data. Handle them specially instead of using AddSectionToTheEnd. This moves a hack from the generic assembler to the elf writer. It is also a bit faster and should make other improvements easier. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120683 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCAssembler.h | 5 ++- lib/MC/ELFObjectWriter.cpp | 68 ++++++++++++++++++++++++----------- lib/MC/MCAssembler.cpp | 20 ----------- 3 files changed, 50 insertions(+), 43 deletions(-) diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 06ac92e5665..4f3223f5db3 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -481,6 +481,8 @@ public: unsigned getLayoutOrder() const { return LayoutOrder; } void setLayoutOrder(unsigned Value) { LayoutOrder = Value; } + uint64_t getAddress() const { return Address; } + /// @name Fragment Access /// @{ @@ -757,9 +759,6 @@ public: void WriteSectionData(const MCSectionData *Section, const MCAsmLayout &Layout, MCObjectWriter *OW) const; - void AddSectionToTheEnd(const MCObjectWriter &Writer, MCSectionData &SD, - MCAsmLayout &Layout); - public: /// Construct a new assembler instance. /// diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 67907c7d8bf..b84f593a95c 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -982,8 +982,6 @@ void ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, MCDataFragment *F = new MCDataFragment(&RelaSD); WriteRelocationsFragment(Asm, F, &SD); - - Asm.AddSectionToTheEnd(*this, RelaSD, Layout); } } @@ -1091,14 +1089,11 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, MCDataFragment *ShndxF = NULL; if (NeedsSymtabShndx) { ShndxF = new MCDataFragment(SymtabShndxSD); - Asm.AddSectionToTheEnd(*this, *SymtabShndxSD, Layout); } WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); - Asm.AddSectionToTheEnd(*this, SymtabSD, Layout); F = new MCDataFragment(&StrtabSD); F->getContents().append(StringTable.begin(), StringTable.end()); - Asm.AddSectionToTheEnd(*this, StrtabSD, Layout); F = new MCDataFragment(&ShstrtabSD); @@ -1130,8 +1125,6 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, F->getContents() += Name; F->getContents() += '\x00'; } - - Asm.AddSectionToTheEnd(*this, ShstrtabSD, Layout); } bool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, @@ -1220,13 +1213,6 @@ void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm, MCDataFragment *F = new MCDataFragment(&Data); String32(*F, NumGroups + Index); } - - for (RevGroupMapTy::const_iterator i = RevGroupMap.begin(), - e = RevGroupMap.end(); i != e; ++i) { - const MCSectionELF *Group = i->second; - MCSectionData &Data = Asm.getOrCreateSectionData(*Group); - Asm.AddSectionToTheEnd(*this, Data, Layout); - } } void ELFObjectWriter::WriteSection(MCAssembler &Asm, @@ -1299,6 +1285,45 @@ void ELFObjectWriter::WriteSection(MCAssembler &Asm, Alignment, Section.getEntrySize()); } +static bool IsELFMetaDataSection(const MCSectionData &SD) { + return SD.getAddress() == ~UINT64_C(0) && + !SD.getSection().isVirtualSection(); +} + +static uint64_t DataSectionSize(const MCSectionData &SD) { + uint64_t Ret = 0; + for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; + ++i) { + const MCFragment &F = *i; + assert(F.getKind() == MCFragment::FT_Data); + Ret += cast(F).getContents().size(); + } + return Ret; +} + +static uint64_t GetSectionFileSize(const MCAsmLayout &Layout, + const MCSectionData &SD) { + if (IsELFMetaDataSection(SD)) + return DataSectionSize(SD); + return Layout.getSectionFileSize(&SD); +} + +static uint64_t GetSectionSize(const MCAsmLayout &Layout, + const MCSectionData &SD) { + if (IsELFMetaDataSection(SD)) + return DataSectionSize(SD); + return Layout.getSectionSize(&SD); +} + +static void WriteDataSectionData(ELFObjectWriter *W, const MCSectionData &SD) { + for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; + ++i) { + const MCFragment &F = *i; + assert(F.getKind() == MCFragment::FT_Data); + W->WriteBytes(cast(F).getContents().str()); + } +} + void ELFObjectWriter::WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { GroupMapTy GroupMap; @@ -1342,9 +1367,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); // Get the size of the section in the output file (including padding). - uint64_t Size = Layout.getSectionFileSize(&SD); - - FileOff += Size; + FileOff += GetSectionFileSize(Layout, SD); } FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); @@ -1368,9 +1391,12 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, // Remember the offset into the file for this section. SectionOffsetMap[&Section] = FileOff; - FileOff += Layout.getSectionFileSize(&SD); + FileOff += GetSectionFileSize(Layout, SD); - Asm.WriteSectionData(&SD, Layout, this); + if (IsELFMetaDataSection(SD)) + WriteDataSectionData(this, SD); + else + Asm.WriteSectionData(&SD, Layout, this); } uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); @@ -1396,8 +1422,10 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, else GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]); + uint64_t Size = GetSectionSize(Layout, SD); + WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, - SectionOffsetMap[&Section], Layout.getSectionSize(&SD), + SectionOffsetMap[&Section], Size, SD.getAlignment(), Section); } } diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 168b62073f7..86bdca1c21f 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -618,26 +618,6 @@ void MCAssembler::WriteSectionData(const MCSectionData *SD, assert(OW->getStream().tell() - Start == Layout.getSectionFileSize(SD)); } -void MCAssembler::AddSectionToTheEnd(const MCObjectWriter &Writer, - MCSectionData &SD, MCAsmLayout &Layout) { - // Create dummy fragments and assign section ordinals. - unsigned SectionIndex = size(); - SD.setOrdinal(SectionIndex); - - // Assign layout order indices to sections and fragments. - const MCFragment &Last = *Layout.getSectionOrder().back()->rbegin(); - unsigned FragmentIndex = Last.getLayoutOrder() + 1; - - SD.setLayoutOrder(Layout.getSectionOrder().size()); - for (MCSectionData::iterator it2 = SD.begin(), - ie2 = SD.end(); it2 != ie2; ++it2) { - it2->setLayoutOrder(FragmentIndex++); - } - Layout.getSectionOrder().push_back(&SD); - - Layout.LayoutSection(&SD); -} - void MCAssembler::Finish(MCObjectWriter *Writer) { DEBUG_WITH_TYPE("mc-dump", { llvm::errs() << "assembler backend - pre-layout\n--\n";