aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-12-02 03:09:06 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-12-02 03:09:06 +0000
commit6db8a9f3fabefeb00163295f0611d09134651f3f (patch)
treedca6d4004a208d63caaec83d13f42f863f40edaa
parent052008bc3d288b44eae5c2e9abe8d78ffd891e2a (diff)
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
-rw-r--r--include/llvm/MC/MCAssembler.h5
-rw-r--r--lib/MC/ELFObjectWriter.cpp68
-rw-r--r--lib/MC/MCAssembler.cpp20
3 files changed, 50 insertions, 43 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 06ac92e566..4f3223f5db 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 67907c7d8b..b84f593a95 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<MCDataFragment>(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<MCDataFragment>(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 168b62073f..86bdca1c21 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";