summaryrefslogtreecommitdiff
path: root/lib/MC/ELFObjectWriter.cpp
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2011-03-20 18:44:20 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2011-03-20 18:44:20 +0000
commit7c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9 (patch)
tree805831560fd2335ffc166f53d3852bacd28e9c67 /lib/MC/ELFObjectWriter.cpp
parenta201c4c2e604a519665ca55dc49e913628444ddb (diff)
downloadllvm-7c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9.tar.gz
llvm-7c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9.tar.bz2
llvm-7c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9.tar.xz
Write the section table and the section data in the same order that
gun as does. This makes it a lot easier to compare the output of both as the addresses are now a lot closer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127972 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/ELFObjectWriter.cpp')
-rw-r--r--lib/MC/ELFObjectWriter.cpp289
1 files changed, 196 insertions, 93 deletions
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 3492cbc55d..e44d8c5344 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -500,7 +500,8 @@ bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature,
}
void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
- SectionIndexMapTy &SectionIndexMap) {
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap) {
unsigned Index = 1;
for (MCAssembler::iterator it = Asm.begin(),
ie = Asm.end(); it != ie; ++it) {
@@ -515,15 +516,21 @@ void ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm,
ie = Asm.end(); it != ie; ++it) {
const MCSectionELF &Section =
static_cast<const MCSectionELF &>(it->getSection());
- if (Section.getType() == ELF::SHT_GROUP)
+ if (Section.getType() == ELF::SHT_GROUP ||
+ Section.getType() == ELF::SHT_REL ||
+ Section.getType() == ELF::SHT_RELA)
continue;
SectionIndexMap[&Section] = Index++;
+ const MCSectionELF *RelSection = RelMap.lookup(&Section);
+ if (RelSection)
+ SectionIndexMap[RelSection] = Index++;
}
}
void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
const SectionIndexMapTy &SectionIndexMap,
- RevGroupMapTy RevGroupMap) {
+ RevGroupMapTy RevGroupMap,
+ unsigned NumRegularSections) {
// FIXME: Is this the correct place to do this?
if (NeedsGOT) {
llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_";
@@ -533,9 +540,6 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
MCELF::SetBinding(Data, ELF::STB_GLOBAL);
}
- // Build section lookup table.
- int NumRegularSections = Asm.size();
-
// Index 0 is always the empty string.
StringMap<uint64_t> StringIndexMap;
StringTable += '\x00';
@@ -636,11 +640,16 @@ void ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm,
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
}
-void ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
- const MCSectionData &SD) {
- if (!Relocations[&SD].empty()) {
+void ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm,
+ MCAsmLayout &Layout,
+ RelMapTy &RelMap) {
+ for (MCAssembler::const_iterator it = Asm.begin(),
+ ie = Asm.end(); it != ie; ++it) {
+ const MCSectionData &SD = *it;
+ if (Relocations[&SD].empty())
+ continue;
+
MCContext &Ctx = Asm.getContext();
- const MCSectionELF *RelaSection;
const MCSectionELF &Section =
static_cast<const MCSectionELF&>(SD.getSection());
@@ -654,17 +663,32 @@ void ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout,
else
EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
- RelaSection = Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
- ELF::SHT_RELA : ELF::SHT_REL, 0,
- SectionKind::getReadOnly(),
- EntrySize, "");
+ const MCSectionELF *RelaSection =
+ Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ?
+ ELF::SHT_RELA : ELF::SHT_REL, 0,
+ SectionKind::getReadOnly(),
+ EntrySize, "");
+ RelMap[&Section] = RelaSection;
+ Asm.getOrCreateSectionData(*RelaSection);
+ }
+}
+
+void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout,
+ const RelMapTy &RelMap) {
+ for (MCAssembler::const_iterator it = Asm.begin(),
+ ie = Asm.end(); it != ie; ++it) {
+ const MCSectionData &SD = *it;
+ const MCSectionELF &Section =
+ static_cast<const MCSectionELF&>(SD.getSection());
+ const MCSectionELF *RelaSection = RelMap.lookup(&Section);
+ if (!RelaSection)
+ continue;
MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection);
RelaSD.setAlignment(is64Bit() ? 8 : 4);
MCDataFragment *F = new MCDataFragment(&RelaSD);
-
- WriteRelocationsFragment(Asm, F, &SD);
+ WriteRelocationsFragment(Asm, F, &*it);
}
}
@@ -726,7 +750,8 @@ void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm,
void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
MCAsmLayout &Layout,
- const SectionIndexMapTy &SectionIndexMap) {
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap) {
MCContext &Ctx = Asm.getContext();
MCDataFragment *F;
@@ -738,7 +763,6 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
SectionKind::getReadOnly());
MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection);
ShstrtabSD.setAlignment(1);
- ShstrtabIndex = Asm.size();
const MCSectionELF *SymtabSection =
Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0,
@@ -746,7 +770,6 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
EntrySize, "");
MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection);
SymtabSD.setAlignment(is64Bit() ? 8 : 4);
- SymbolTableIndex = Asm.size();
MCSectionData *SymtabShndxSD = NULL;
@@ -758,14 +781,17 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
SymtabShndxSD->setAlignment(4);
}
- const MCSection *StrtabSection;
+ const MCSectionELF *StrtabSection;
StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0,
SectionKind::getReadOnly());
MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection);
StrtabSD.setAlignment(1);
- StringTableIndex = Asm.size();
- WriteRelocations(Asm, Layout);
+ ComputeIndexMap(Asm, SectionIndexMap, RelMap);
+
+ ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection);
+ SymbolTableIndex = SectionIndexMap.lookup(SymtabSection);
+ StringTableIndex = SectionIndexMap.lookup(StrtabSection);
// Symbol table
F = new MCDataFragment(&SymtabSD);
@@ -813,7 +839,9 @@ void ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm,
void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
MCAsmLayout &Layout,
GroupMapTy &GroupMap,
- RevGroupMapTy &RevGroupMap) {
+ RevGroupMapTy &RevGroupMap,
+ SectionIndexMapTy &SectionIndexMap,
+ const RelMapTy &RelMap) {
// Create the .note.GNU-stack section if needed.
MCContext &Ctx = Asm.getContext();
if (Asm.getNoExecStack()) {
@@ -844,11 +872,11 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
GroupMap[Group] = SignatureSymbol;
}
+ ComputeIndexMap(Asm, SectionIndexMap, RelMap);
+
// Add sections to the groups
- unsigned Index = 1;
- unsigned NumGroups = RevGroupMap.size();
for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
- it != ie; ++it, ++Index) {
+ it != ie; ++it) {
const MCSectionELF &Section =
static_cast<const MCSectionELF&>(it->getSection());
if (!(Section.getFlags() & ELF::SHF_GROUP))
@@ -857,7 +885,8 @@ void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
// FIXME: we could use the previous fragment
MCDataFragment *F = new MCDataFragment(&Data);
- String32(*F, NumGroups + Index);
+ unsigned Index = SectionIndexMap.lookup(&Section);
+ String32(*F, Index);
}
}
@@ -966,13 +995,98 @@ uint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout,
return Layout.getSectionAddressSize(&SD);
}
-void ELFObjectWriter::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::WriteDataSectionData(MCAssembler &Asm,
+ const MCAsmLayout &Layout,
+ const MCSectionELF &Section) {
+ uint64_t FileOff = OS.tell();
+ const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
+
+ uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
+ WriteZeros(Padding);
+ FileOff += Padding;
+
+ FileOff += GetSectionFileSize(Layout, SD);
+
+ if (IsELFMetaDataSection(SD)) {
+ for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e;
+ ++i) {
+ const MCFragment &F = *i;
+ assert(F.getKind() == MCFragment::FT_Data);
+ WriteBytes(cast<MCDataFragment>(F).getContents().str());
+ }
+ } else {
+ Asm.WriteSectionData(&SD, Layout);
+ }
+}
+
+void ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm,
+ const GroupMapTy &GroupMap,
+ const MCAsmLayout &Layout,
+ const SectionIndexMapTy &SectionIndexMap,
+ const SectionOffsetMapTy &SectionOffsetMap) {
+ const unsigned NumSections = Asm.size() + 1;
+
+ std::vector<const MCSectionELF*> Sections;
+ Sections.resize(NumSections - 1);
+
+ for (SectionIndexMapTy::const_iterator i=
+ SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
+ const std::pair<const MCSectionELF*, uint32_t> &p = *i;
+ Sections[p.second - 1] = p.first;
+ }
+
+ // Null section first.
+ uint64_t FirstSectionSize =
+ NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
+ uint32_t FirstSectionLink =
+ ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
+ WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
+
+ for (unsigned i = 0; i < NumSections - 1; ++i) {
+ const MCSectionELF &Section = *Sections[i];
+ const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
+ uint32_t GroupSymbolIndex;
+ if (Section.getType() != ELF::SHT_GROUP)
+ GroupSymbolIndex = 0;
+ else
+ GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm,
+ GroupMap.lookup(&Section));
+
+ uint64_t Size = GetSectionAddressSize(Layout, SD);
+
+ WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
+ SectionOffsetMap.lookup(&Section), Size,
+ SD.getAlignment(), Section);
+ }
+}
+
+void ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm,
+ std::vector<const MCSectionELF*> &Sections) {
+ for (MCAssembler::iterator it = Asm.begin(),
+ ie = Asm.end(); it != ie; ++it) {
+ const MCSectionELF &Section =
+ static_cast<const MCSectionELF &>(it->getSection());
+ if (Section.getType() == ELF::SHT_GROUP)
+ Sections.push_back(&Section);
+ }
+
+ for (MCAssembler::iterator it = Asm.begin(),
+ ie = Asm.end(); it != ie; ++it) {
+ const MCSectionELF &Section =
+ static_cast<const MCSectionELF &>(it->getSection());
+ if (Section.getType() != ELF::SHT_GROUP &&
+ Section.getType() != ELF::SHT_REL &&
+ Section.getType() != ELF::SHT_RELA)
+ Sections.push_back(&Section);
+ }
+
+ for (MCAssembler::iterator it = Asm.begin(),
+ ie = Asm.end(); it != ie; ++it) {
+ const MCSectionELF &Section =
+ static_cast<const MCSectionELF &>(it->getSection());
+ if (Section.getType() == ELF::SHT_REL ||
+ Section.getType() == ELF::SHT_RELA)
+ Sections.push_back(&Section);
}
}
@@ -980,107 +1094,96 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
GroupMapTy GroupMap;
RevGroupMapTy RevGroupMap;
- CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
- RevGroupMap);
-
SectionIndexMapTy SectionIndexMap;
- ComputeIndexMap(Asm, SectionIndexMap);
+ unsigned NumUserSections = Asm.size();
+
+ DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap;
+ CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
+
+ const unsigned NumUserAndRelocSections = Asm.size();
+ CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
+ RevGroupMap, SectionIndexMap, RelMap);
+ const unsigned AllSections = Asm.size();
+ const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections;
+
+ unsigned NumRegularSections = NumUserSections + NumIndexedSections;
// Compute symbol table information.
- ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap);
+ ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections);
+
+
+ WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap);
CreateMetadataSections(const_cast<MCAssembler&>(Asm),
const_cast<MCAsmLayout&>(Layout),
- SectionIndexMap);
-
- // Update to include the metadata sections.
- ComputeIndexMap(Asm, SectionIndexMap);
+ SectionIndexMap,
+ RelMap);
- // Add 1 for the null section.
- unsigned NumSections = Asm.size() + 1;
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) :
sizeof(ELF::Elf32_Ehdr);
uint64_t FileOff = HeaderSize;
std::vector<const MCSectionELF*> Sections;
- Sections.resize(NumSections);
-
- for (SectionIndexMapTy::const_iterator i=
- SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) {
- const std::pair<const MCSectionELF*, uint32_t> &p = *i;
- Sections[p.second] = p.first;
- }
-
- for (unsigned i = 1; i < NumSections; ++i) {
+ ComputeSectionOrder(Asm, Sections);
+ unsigned NumSections = Sections.size();
+ SectionOffsetMapTy SectionOffsetMap;
+ for (unsigned i = 0; i < NumRegularSections + 1; ++i) {
const MCSectionELF &Section = *Sections[i];
const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
+ // Remember the offset into the file for this section.
+ SectionOffsetMap[&Section] = FileOff;
+
// Get the size of the section in the output file (including padding).
FileOff += GetSectionFileSize(Layout, SD);
}
FileOff = RoundUpToAlignment(FileOff, NaturalAlignment);
- // Write out the ELF header ...
- WriteHeader(FileOff - HeaderSize, NumSections);
-
- FileOff = HeaderSize;
+ const unsigned SectionHeaderOffset = FileOff - HeaderSize;
- // ... then all of the sections ...
- DenseMap<const MCSection*, uint64_t> SectionOffsetMap;
+ uint64_t SectionHeaderEntrySize = is64Bit() ?
+ sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr);
+ FileOff += (NumSections + 1) * SectionHeaderEntrySize;
- for (unsigned i = 1; i < NumSections; ++i) {
+ for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) {
const MCSectionELF &Section = *Sections[i];
const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
- uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment());
- WriteZeros(Padding);
- FileOff += Padding;
+ FileOff = RoundUpToAlignment(FileOff, SD.getAlignment());
// Remember the offset into the file for this section.
SectionOffsetMap[&Section] = FileOff;
+ // Get the size of the section in the output file (including padding).
FileOff += GetSectionFileSize(Layout, SD);
-
- if (IsELFMetaDataSection(SD))
- WriteDataSectionData(this, SD);
- else
- Asm.WriteSectionData(&SD, Layout);
}
+ // Write out the ELF header ...
+ WriteHeader(SectionHeaderOffset, NumSections + 1);
+
+ // ... then the regular sections ...
+ // + because of .shstrtab
+ for (unsigned i = 0; i < NumRegularSections + 1; ++i)
+ WriteDataSectionData(Asm, Layout, *Sections[i]);
+
+ FileOff = OS.tell();
uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment);
WriteZeros(Padding);
- FileOff += Padding;
- // ... and then the section header table.
- // Should we align the section header table?
- //
- // Null section first.
- uint64_t FirstSectionSize =
- NumSections >= ELF::SHN_LORESERVE ? NumSections : 0;
- uint32_t FirstSectionLink =
- ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0;
- WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0);
+ // ... then the section header table ...
+ WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap,
+ SectionOffsetMap);
- for (unsigned i = 1; i < NumSections; ++i) {
- const MCSectionELF &Section = *Sections[i];
- const MCSectionData &SD = Asm.getOrCreateSectionData(Section);
- uint32_t GroupSymbolIndex;
- if (Section.getType() != ELF::SHT_GROUP)
- GroupSymbolIndex = 0;
- else
- GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]);
-
- uint64_t Size = GetSectionAddressSize(Layout, SD);
+ FileOff = OS.tell();
- WriteSection(Asm, SectionIndexMap, GroupSymbolIndex,
- SectionOffsetMap[&Section], Size,
- SD.getAlignment(), Section);
- }
+ // ... and then the remainting sections ...
+ for (unsigned i = NumRegularSections + 1; i < NumSections; ++i)
+ WriteDataSectionData(Asm, Layout, *Sections[i]);
}
bool