mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-31 10:34:17 +00:00
Write sections mostly in one pass.
During ELF writing, there is no need to further relax the sections, so we should not be creating fragments. This patch avoids doing so in all cases but debug section compression (that is next). Also, the ELF format is fairly simple to write. We can do a single pass over the sections to write them out and compute the section header table. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@236235 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8c54c84ae7
commit
76e71bd66e
@ -78,10 +78,6 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolData &Data,
|
static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolData &Data,
|
||||||
bool Used, bool Renamed);
|
bool Used, bool Renamed);
|
||||||
static bool isLocal(const MCSymbolData &Data, bool isUsedInReloc);
|
static bool isLocal(const MCSymbolData &Data, bool isUsedInReloc);
|
||||||
static bool IsELFMetaDataSection(const MCSectionData &SD);
|
|
||||||
|
|
||||||
void writeDataSectionData(MCAssembler &Asm, const MCAsmLayout &Layout,
|
|
||||||
const MCSectionData &SD);
|
|
||||||
|
|
||||||
/// Helper struct for containing some precomputed information on symbols.
|
/// Helper struct for containing some precomputed information on symbols.
|
||||||
struct ELFSymbolData {
|
struct ELFSymbolData {
|
||||||
@ -193,7 +189,8 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
const MCAsmLayout &Layout);
|
const MCAsmLayout &Layout);
|
||||||
|
|
||||||
// Start and end offset of each section
|
// Start and end offset of each section
|
||||||
typedef std::vector<std::pair<uint64_t, uint64_t>> SectionOffsetsTy;
|
typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>
|
||||||
|
SectionOffsetsTy;
|
||||||
|
|
||||||
void WriteSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
|
void WriteSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||||
std::vector<const MCSectionELF *> &Sections,
|
std::vector<const MCSectionELF *> &Sections,
|
||||||
@ -224,33 +221,18 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
const SectionIndexMapTy &SectionIndexMap,
|
const SectionIndexMapTy &SectionIndexMap,
|
||||||
const RevGroupMapTy &RevGroupMap);
|
const RevGroupMapTy &RevGroupMap);
|
||||||
|
|
||||||
void maybeAddToGroup(MCAssembler &Asm,
|
const MCSectionELF *createRelocationSection(MCAssembler &Asm,
|
||||||
ArrayRef<const MCSectionELF *> Sections,
|
const MCSectionELF &Sec);
|
||||||
const RevGroupMapTy &RevGroupMap,
|
|
||||||
const MCSectionELF &Section, unsigned Index);
|
|
||||||
|
|
||||||
void computeIndexMap(MCAssembler &Asm,
|
|
||||||
std::vector<const MCSectionELF *> &Sections,
|
|
||||||
SectionIndexMapTy &SectionIndexMap,
|
|
||||||
const RevGroupMapTy &RevGroupMap);
|
|
||||||
|
|
||||||
void createRelocationSection(MCAssembler &Asm, const MCSectionELF &Sec);
|
|
||||||
|
|
||||||
void CompressDebugSections(MCAssembler &Asm, MCAsmLayout &Layout);
|
void CompressDebugSections(MCAssembler &Asm, MCAsmLayout &Layout);
|
||||||
|
|
||||||
void
|
const MCSectionELF *
|
||||||
createSectionHeaderStringTable(MCAssembler &Asm,
|
createSectionHeaderStringTable(MCAssembler &Asm,
|
||||||
std::vector<const MCSectionELF *> &Sections);
|
std::vector<const MCSectionELF *> &Sections);
|
||||||
void createStringTable(MCAssembler &Asm,
|
const MCSectionELF *
|
||||||
|
createStringTable(MCAssembler &Asm,
|
||||||
std::vector<const MCSectionELF *> &Sections);
|
std::vector<const MCSectionELF *> &Sections);
|
||||||
|
|
||||||
// Create the sections that show up in the symbol table. Currently
|
|
||||||
// those are the .note.GNU-stack section and the group sections.
|
|
||||||
void createIndexedSections(MCAssembler &Asm, const MCAsmLayout &Layout,
|
|
||||||
RevGroupMapTy &RevGroupMap,
|
|
||||||
std::vector<const MCSectionELF *> &Sections,
|
|
||||||
SectionIndexMapTy &SectionIndexMap);
|
|
||||||
|
|
||||||
void ExecutePostLayoutBinding(MCAssembler &Asm,
|
void ExecutePostLayoutBinding(MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout) override;
|
const MCAsmLayout &Layout) override;
|
||||||
|
|
||||||
@ -628,7 +610,7 @@ void ELFObjectWriter::WriteSymbolTable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t SecEnd = OS.tell();
|
uint64_t SecEnd = OS.tell();
|
||||||
SectionOffsets.push_back(std::make_pair(SecStart, SecEnd));
|
SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
|
||||||
|
|
||||||
ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
|
ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
|
||||||
if (ShndxIndexes.empty())
|
if (ShndxIndexes.empty())
|
||||||
@ -644,7 +626,7 @@ void ELFObjectWriter::WriteSymbolTable(
|
|||||||
for (uint32_t Index : ShndxIndexes)
|
for (uint32_t Index : ShndxIndexes)
|
||||||
write(Index);
|
write(Index);
|
||||||
SecEnd = OS.tell();
|
SecEnd = OS.tell();
|
||||||
SectionOffsets.push_back(std::make_pair(SecStart, SecEnd));
|
SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// It is always valid to create a relocation with a symbol. It is preferable
|
// It is always valid to create a relocation with a symbol. It is preferable
|
||||||
@ -948,37 +930,6 @@ bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELFObjectWriter::maybeAddToGroup(MCAssembler &Asm,
|
|
||||||
ArrayRef<const MCSectionELF *> Sections,
|
|
||||||
const RevGroupMapTy &RevGroupMap,
|
|
||||||
const MCSectionELF &Section,
|
|
||||||
unsigned Index) {
|
|
||||||
const MCSymbol *Sym = Section.getGroup();
|
|
||||||
if (!Sym)
|
|
||||||
return;
|
|
||||||
const MCSectionELF *Group = Sections[RevGroupMap.lookup(Sym) - 1];
|
|
||||||
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
|
|
||||||
// FIXME: we could use the previous fragment
|
|
||||||
MCDataFragment *F = new MCDataFragment(&Data);
|
|
||||||
write(*F, Index);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ELFObjectWriter::computeIndexMap(
|
|
||||||
MCAssembler &Asm, std::vector<const MCSectionELF *> &Sections,
|
|
||||||
SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap) {
|
|
||||||
for (const MCSectionData &SD : Asm) {
|
|
||||||
const MCSectionELF &Section =
|
|
||||||
static_cast<const MCSectionELF &>(SD.getSection());
|
|
||||||
if (Section.getType() == ELF::SHT_GROUP)
|
|
||||||
continue;
|
|
||||||
Sections.push_back(&Section);
|
|
||||||
unsigned Index = Sections.size();
|
|
||||||
SectionIndexMap[&Section] = Index;
|
|
||||||
maybeAddToGroup(Asm, Sections, RevGroupMap, Section, Index);
|
|
||||||
createRelocationSection(Asm, Section);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ELFObjectWriter::computeSymbolTable(
|
void ELFObjectWriter::computeSymbolTable(
|
||||||
MCAssembler &Asm, const MCAsmLayout &Layout,
|
MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||||
const SectionIndexMapTy &SectionIndexMap,
|
const SectionIndexMapTy &SectionIndexMap,
|
||||||
@ -1124,10 +1075,11 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
|
UndefinedSymbolData[i].SymbolData->setIndex(Index++);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELFObjectWriter::createRelocationSection(MCAssembler &Asm,
|
const MCSectionELF *
|
||||||
|
ELFObjectWriter::createRelocationSection(MCAssembler &Asm,
|
||||||
const MCSectionELF &Sec) {
|
const MCSectionELF &Sec) {
|
||||||
if (Relocations[&Sec].empty())
|
if (Relocations[&Sec].empty())
|
||||||
return;
|
return nullptr;
|
||||||
|
|
||||||
MCContext &Ctx = Asm.getContext();
|
MCContext &Ctx = Asm.getContext();
|
||||||
const StringRef SectionName = Sec.getSectionName();
|
const StringRef SectionName = Sec.getSectionName();
|
||||||
@ -1149,6 +1101,7 @@ void ELFObjectWriter::createRelocationSection(MCAssembler &Asm,
|
|||||||
Flags, EntrySize, Sec.getGroup(), &Sec);
|
Flags, EntrySize, Sec.getGroup(), &Sec);
|
||||||
MCSectionData &RelSD = Asm.getOrCreateSectionData(*RelaSection);
|
MCSectionData &RelSD = Asm.getOrCreateSectionData(*RelaSection);
|
||||||
RelSD.setAlignment(is64Bit() ? 8 : 4);
|
RelSD.setAlignment(is64Bit() ? 8 : 4);
|
||||||
|
return RelaSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SmallVector<char, 128>
|
static SmallVector<char, 128>
|
||||||
@ -1356,7 +1309,7 @@ void ELFObjectWriter::writeRelocations(const MCAssembler &Asm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELFObjectWriter::createSectionHeaderStringTable(
|
const MCSectionELF *ELFObjectWriter::createSectionHeaderStringTable(
|
||||||
MCAssembler &Asm, std::vector<const MCSectionELF *> &Sections) {
|
MCAssembler &Asm, std::vector<const MCSectionELF *> &Sections) {
|
||||||
const MCSectionELF *ShstrtabSection = Sections[ShstrtabIndex - 1];
|
const MCSectionELF *ShstrtabSection = Sections[ShstrtabIndex - 1];
|
||||||
|
|
||||||
@ -1369,9 +1322,10 @@ void ELFObjectWriter::createSectionHeaderStringTable(
|
|||||||
}
|
}
|
||||||
ShStrTabBuilder.finalize(StringTableBuilder::ELF);
|
ShStrTabBuilder.finalize(StringTableBuilder::ELF);
|
||||||
OS << ShStrTabBuilder.data();
|
OS << ShStrTabBuilder.data();
|
||||||
|
return ShstrtabSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELFObjectWriter::createStringTable(
|
const MCSectionELF *ELFObjectWriter::createStringTable(
|
||||||
MCAssembler &Asm, std::vector<const MCSectionELF *> &Sections) {
|
MCAssembler &Asm, std::vector<const MCSectionELF *> &Sections) {
|
||||||
MCContext &Ctx = Asm.getContext();
|
MCContext &Ctx = Asm.getContext();
|
||||||
const MCSectionELF *StrtabSection =
|
const MCSectionELF *StrtabSection =
|
||||||
@ -1380,43 +1334,7 @@ void ELFObjectWriter::createStringTable(
|
|||||||
Sections.push_back(StrtabSection);
|
Sections.push_back(StrtabSection);
|
||||||
StringTableIndex = Sections.size();
|
StringTableIndex = Sections.size();
|
||||||
OS << StrTabBuilder.data();
|
OS << StrTabBuilder.data();
|
||||||
}
|
return StrtabSection;
|
||||||
|
|
||||||
void ELFObjectWriter::createIndexedSections(
|
|
||||||
MCAssembler &Asm, const MCAsmLayout &Layout, RevGroupMapTy &RevGroupMap,
|
|
||||||
std::vector<const MCSectionELF *> &Sections,
|
|
||||||
SectionIndexMapTy &SectionIndexMap) {
|
|
||||||
MCContext &Ctx = Asm.getContext();
|
|
||||||
|
|
||||||
const MCSectionELF *ShstrtabSection =
|
|
||||||
Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0);
|
|
||||||
Sections.push_back(ShstrtabSection);
|
|
||||||
ShstrtabIndex = Sections.size();
|
|
||||||
assert(ShstrtabIndex == 1);
|
|
||||||
|
|
||||||
// Build the groups
|
|
||||||
for (const MCSectionData &SD : Asm) {
|
|
||||||
const MCSectionELF &Section =
|
|
||||||
static_cast<const MCSectionELF &>(SD.getSection());
|
|
||||||
if (!(Section.getFlags() & ELF::SHF_GROUP))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const MCSymbol *SignatureSymbol = Section.getGroup();
|
|
||||||
Asm.getOrCreateSymbolData(*SignatureSymbol);
|
|
||||||
unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
|
|
||||||
if (!GroupIdx) {
|
|
||||||
const MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
|
|
||||||
Sections.push_back(Group);
|
|
||||||
GroupIdx = Sections.size();
|
|
||||||
|
|
||||||
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
|
|
||||||
Data.setAlignment(4);
|
|
||||||
MCDataFragment *F = new MCDataFragment(&Data);
|
|
||||||
write(*F, uint32_t(ELF::GRP_COMDAT));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
computeIndexMap(Asm, Sections, SectionIndexMap, RevGroupMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELFObjectWriter::writeSection(MCAssembler &Asm,
|
void ELFObjectWriter::writeSection(MCAssembler &Asm,
|
||||||
@ -1472,26 +1390,6 @@ void ELFObjectWriter::writeSection(MCAssembler &Asm,
|
|||||||
Alignment, Section.getEntrySize());
|
Alignment, Section.getEntrySize());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) {
|
|
||||||
return SD.getOrdinal() == ~UINT32_C(0) &&
|
|
||||||
!SD.getSection().isVirtualSection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ELFObjectWriter::writeDataSectionData(MCAssembler &Asm,
|
|
||||||
const MCAsmLayout &Layout,
|
|
||||||
const MCSectionData &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());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Asm.writeSectionData(&SD, Layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ELFObjectWriter::writeSectionHeader(
|
void ELFObjectWriter::writeSectionHeader(
|
||||||
ArrayRef<const MCSectionELF *> Sections, MCAssembler &Asm,
|
ArrayRef<const MCSectionELF *> Sections, MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
|
const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
|
||||||
@ -1512,7 +1410,8 @@ void ELFObjectWriter::writeSectionHeader(
|
|||||||
else
|
else
|
||||||
GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, Section.getGroup());
|
GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, Section.getGroup());
|
||||||
|
|
||||||
const std::pair<uint64_t, uint64_t> &Offsets = SectionOffsets[i];
|
const std::pair<uint64_t, uint64_t> &Offsets =
|
||||||
|
SectionOffsets.find(&Section)->second;
|
||||||
uint64_t Size = Section.getType() == ELF::SHT_NOBITS
|
uint64_t Size = Section.getType() == ELF::SHT_NOBITS
|
||||||
? Layout.getSectionAddressSize(&SD)
|
? Layout.getSectionAddressSize(&SD)
|
||||||
: Offsets.second - Offsets.first;
|
: Offsets.second - Offsets.first;
|
||||||
@ -1524,56 +1423,107 @@ void ELFObjectWriter::writeSectionHeader(
|
|||||||
|
|
||||||
void ELFObjectWriter::WriteObject(MCAssembler &Asm,
|
void ELFObjectWriter::WriteObject(MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout) {
|
const MCAsmLayout &Layout) {
|
||||||
|
CompressDebugSections(Asm, const_cast<MCAsmLayout &>(Layout));
|
||||||
|
|
||||||
|
std::vector<const MCSectionELF *> Sections;
|
||||||
|
MCContext &Ctx = Asm.getContext();
|
||||||
|
const MCSectionELF *ShstrtabSection =
|
||||||
|
Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0);
|
||||||
|
Sections.push_back(ShstrtabSection);
|
||||||
|
ShstrtabIndex = Sections.size();
|
||||||
|
|
||||||
RevGroupMapTy RevGroupMap;
|
RevGroupMapTy RevGroupMap;
|
||||||
SectionIndexMapTy SectionIndexMap;
|
SectionIndexMapTy SectionIndexMap;
|
||||||
|
|
||||||
CompressDebugSections(Asm, const_cast<MCAsmLayout &>(Layout));
|
std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
|
||||||
std::vector<const MCSectionELF *> Sections;
|
|
||||||
createIndexedSections(Asm, Layout, RevGroupMap, Sections, SectionIndexMap);
|
|
||||||
|
|
||||||
// Compute symbol table information.
|
|
||||||
computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap);
|
|
||||||
|
|
||||||
SectionOffsetsTy SectionOffsets;
|
|
||||||
|
|
||||||
// Write out the ELF header ...
|
// Write out the ELF header ...
|
||||||
writeHeader(Asm);
|
writeHeader(Asm);
|
||||||
|
|
||||||
// ... then the sections ...
|
// ... then the sections ...
|
||||||
SectionOffsets.push_back(std::make_pair(0, 0));
|
SectionOffsetsTy SectionOffsets;
|
||||||
for (auto I = ++Sections.begin(), E = Sections.end(); I != E; ++I) {
|
bool ComputedSymtab = false;
|
||||||
const MCSectionELF &Sec = **I;
|
for (const MCSectionData &SD : Asm) {
|
||||||
const MCSectionData &SD = Asm.getOrCreateSectionData(Sec);
|
const MCSectionELF &Section =
|
||||||
|
static_cast<const MCSectionELF &>(SD.getSection());
|
||||||
|
|
||||||
uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment());
|
uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment());
|
||||||
WriteZeros(Padding);
|
WriteZeros(Padding);
|
||||||
|
|
||||||
// Remember the offset into the file for this section.
|
// Remember the offset into the file for this section.
|
||||||
uint64_t SecStart = OS.tell();
|
uint64_t SecStart = OS.tell();
|
||||||
|
|
||||||
unsigned Type = Sec.getType();
|
const MCSymbol *SignatureSymbol = Section.getGroup();
|
||||||
if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA)
|
unsigned Type = Section.getType();
|
||||||
writeDataSectionData(Asm, Layout, SD);
|
if (Type == ELF::SHT_GROUP) {
|
||||||
else
|
assert(SignatureSymbol);
|
||||||
writeRelocations(Asm, *Sec.getAssociatedSection());
|
write(uint32_t(ELF::GRP_COMDAT));
|
||||||
|
for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
|
||||||
|
uint32_t SecIndex = SectionIndexMap.lookup(Member);
|
||||||
|
write(SecIndex);
|
||||||
|
}
|
||||||
|
} else if (Type == ELF::SHT_REL || Type == ELF::SHT_RELA) {
|
||||||
|
if (!ComputedSymtab) {
|
||||||
|
// Compute symbol table information.
|
||||||
|
computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap);
|
||||||
|
ComputedSymtab = true;
|
||||||
|
}
|
||||||
|
writeRelocations(Asm, *Section.getAssociatedSection());
|
||||||
|
} else {
|
||||||
|
Asm.writeSectionData(&SD, Layout);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t SecEnd = OS.tell();
|
uint64_t SecEnd = OS.tell();
|
||||||
SectionOffsets.push_back(std::make_pair(SecStart, SecEnd));
|
SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
|
||||||
|
|
||||||
|
if (Type == ELF::SHT_GROUP || Type == ELF::SHT_REL || Type == ELF::SHT_RELA)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const MCSectionELF *RelSection = createRelocationSection(Asm, Section);
|
||||||
|
|
||||||
|
if (SignatureSymbol) {
|
||||||
|
Asm.getOrCreateSymbolData(*SignatureSymbol);
|
||||||
|
unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
|
||||||
|
if (!GroupIdx) {
|
||||||
|
const MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
|
||||||
|
Sections.push_back(Group);
|
||||||
|
GroupIdx = Sections.size();
|
||||||
|
MCSectionData *GroupD = &Asm.getOrCreateSectionData(*Group);
|
||||||
|
GroupD->setAlignment(4);
|
||||||
|
}
|
||||||
|
GroupMembers[SignatureSymbol].push_back(&Section);
|
||||||
|
if (RelSection)
|
||||||
|
GroupMembers[SignatureSymbol].push_back(RelSection);
|
||||||
|
}
|
||||||
|
|
||||||
|
Sections.push_back(&Section);
|
||||||
|
SectionIndexMap[&Section] = Sections.size();
|
||||||
|
if (RelSection) {
|
||||||
|
Sections.push_back(RelSection);
|
||||||
|
SectionIndexMap[RelSection] = Sections.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ComputedSymtab) {
|
||||||
|
// Compute symbol table information.
|
||||||
|
computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap);
|
||||||
|
ComputedSymtab = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteSymbolTable(Asm, Layout, Sections, SectionOffsets);
|
WriteSymbolTable(Asm, Layout, Sections, SectionOffsets);
|
||||||
|
|
||||||
{
|
{
|
||||||
uint64_t SecStart = OS.tell();
|
uint64_t SecStart = OS.tell();
|
||||||
createStringTable(Asm, Sections);
|
const MCSectionELF *Sec = createStringTable(Asm, Sections);
|
||||||
uint64_t SecEnd = OS.tell();
|
uint64_t SecEnd = OS.tell();
|
||||||
SectionOffsets.push_back(std::make_pair(SecStart, SecEnd));
|
SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
uint64_t SecStart = OS.tell();
|
uint64_t SecStart = OS.tell();
|
||||||
createSectionHeaderStringTable(Asm, Sections);
|
const MCSectionELF *Sec = createSectionHeaderStringTable(Asm, Sections);
|
||||||
uint64_t SecEnd = OS.tell();
|
uint64_t SecEnd = OS.tell();
|
||||||
SectionOffsets[0] = std::make_pair(SecStart, SecEnd);
|
SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
|
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
|
||||||
|
@ -93,12 +93,16 @@ func1:
|
|||||||
@ CHECK: ]
|
@ CHECK: ]
|
||||||
@ CHECK: }
|
@ CHECK: }
|
||||||
|
|
||||||
|
@ CHECK: Section {
|
||||||
|
@ CHECK: Index: 8
|
||||||
|
@ CHECK-NEXT: Name: .rel.ARM.extab.TEST1
|
||||||
|
@ CHECK: }
|
||||||
|
|
||||||
@-------------------------------------------------------------------------------
|
@-------------------------------------------------------------------------------
|
||||||
@ Check the .ARM.exidx.TEST1 section
|
@ Check the .ARM.exidx.TEST1 section
|
||||||
@-------------------------------------------------------------------------------
|
@-------------------------------------------------------------------------------
|
||||||
@ CHECK: Section {
|
@ CHECK: Section {
|
||||||
@ CHECK: Index: 8
|
@ CHECK: Index: 9
|
||||||
@ CHECK-NEXT: Name: .ARM.exidx.TEST1
|
@ CHECK-NEXT: Name: .ARM.exidx.TEST1
|
||||||
@ CHECK: Type: SHT_ARM_EXIDX (0x70000001)
|
@ CHECK: Type: SHT_ARM_EXIDX (0x70000001)
|
||||||
@-------------------------------------------------------------------------------
|
@-------------------------------------------------------------------------------
|
||||||
@ -113,11 +117,6 @@ func1:
|
|||||||
@ CHECK: }
|
@ CHECK: }
|
||||||
|
|
||||||
|
|
||||||
@ CHECK: Section {
|
|
||||||
@ CHECK: Index: 9
|
|
||||||
@ CHECK-NEXT: Name: .rel.ARM.extab.TEST1
|
|
||||||
@ CHECK: }
|
|
||||||
|
|
||||||
@ CHECK: Section {
|
@ CHECK: Section {
|
||||||
@ CHECK: Index: 10
|
@ CHECK: Index: 10
|
||||||
@ CHECK-NEXT: Name: .rel.ARM.exidx.TEST1
|
@ CHECK-NEXT: Name: .rel.ARM.exidx.TEST1
|
||||||
|
@ -109,7 +109,7 @@ func2:
|
|||||||
@ Check the TEST2 section (without the dot in the beginning)
|
@ Check the TEST2 section (without the dot in the beginning)
|
||||||
@-------------------------------------------------------------------------------
|
@-------------------------------------------------------------------------------
|
||||||
@ CHECK: Section {
|
@ CHECK: Section {
|
||||||
@ CHECK: Index: 8
|
@ CHECK: Index: 10
|
||||||
@ CHECK-NEXT: Name: TEST2
|
@ CHECK-NEXT: Name: TEST2
|
||||||
@ CHECK: SectionData (
|
@ CHECK: SectionData (
|
||||||
@ CHECK: 0000: 1EFF2FE1 |../.|
|
@ CHECK: 0000: 1EFF2FE1 |../.|
|
||||||
@ -143,7 +143,7 @@ func2:
|
|||||||
@-------------------------------------------------------------------------------
|
@-------------------------------------------------------------------------------
|
||||||
@ This section should linked with TEST2 section.
|
@ This section should linked with TEST2 section.
|
||||||
@-------------------------------------------------------------------------------
|
@-------------------------------------------------------------------------------
|
||||||
@ CHECK: Link: 8
|
@ CHECK: Link: 10
|
||||||
|
|
||||||
@-------------------------------------------------------------------------------
|
@-------------------------------------------------------------------------------
|
||||||
@ The first word should be relocated to the code address in TEST2 section.
|
@ The first word should be relocated to the code address in TEST2 section.
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
@ name first we could use a FileCheck variable.
|
@ name first we could use a FileCheck variable.
|
||||||
|
|
||||||
@ CHECK: Section {
|
@ CHECK: Section {
|
||||||
@ CHECK: Index: 7
|
@ CHECK: Index: 6
|
||||||
@ CHECK-NEXT: Name: .text
|
@ CHECK-NEXT: Name: .text
|
||||||
@ CHECK-NEXT: Type: SHT_PROGBITS
|
@ CHECK-NEXT: Type: SHT_PROGBITS
|
||||||
@ CHECK-NEXT: Flags [
|
@ CHECK-NEXT: Flags [
|
||||||
@ -25,7 +25,7 @@
|
|||||||
@ CHECK-NEXT: EntrySize: 0
|
@ CHECK-NEXT: EntrySize: 0
|
||||||
@ CHECK-NEXT: }
|
@ CHECK-NEXT: }
|
||||||
@ CHECK-NEXT: Section {
|
@ CHECK-NEXT: Section {
|
||||||
@ CHECK-NEXT: Index: 8
|
@ CHECK-NEXT: Index: 7
|
||||||
@ CHECK-NEXT: Name: .ARM.exidx
|
@ CHECK-NEXT: Name: .ARM.exidx
|
||||||
@ CHECK-NEXT: Type: SHT_ARM_EXIDX
|
@ CHECK-NEXT: Type: SHT_ARM_EXIDX
|
||||||
@ CHECK-NEXT: Flags [
|
@ CHECK-NEXT: Flags [
|
||||||
@ -36,14 +36,14 @@
|
|||||||
@ CHECK-NEXT: Address: 0x0
|
@ CHECK-NEXT: Address: 0x0
|
||||||
@ CHECK-NEXT: Offset:
|
@ CHECK-NEXT: Offset:
|
||||||
@ CHECK-NEXT: Size: 8
|
@ CHECK-NEXT: Size: 8
|
||||||
@ CHECK-NEXT: Link: 7
|
@ CHECK-NEXT: Link: 6
|
||||||
@ CHECK-NEXT: Info: 0
|
@ CHECK-NEXT: Info: 0
|
||||||
@ CHECK-NEXT: AddressAlignment: 4
|
@ CHECK-NEXT: AddressAlignment: 4
|
||||||
@ CHECK-NEXT: EntrySize: 0
|
@ CHECK-NEXT: EntrySize: 0
|
||||||
@ CHECK-NEXT: }
|
@ CHECK-NEXT: }
|
||||||
|
|
||||||
@ CHECK: Section {
|
@ CHECK: Section {
|
||||||
@ CHECK: Index: 9
|
@ CHECK: Index: 10
|
||||||
@ CHECK-NEXT: Name: .text
|
@ CHECK-NEXT: Name: .text
|
||||||
@ CHECK-NEXT: Type: SHT_PROGBITS
|
@ CHECK-NEXT: Type: SHT_PROGBITS
|
||||||
@ CHECK-NEXT: Flags [
|
@ CHECK-NEXT: Flags [
|
||||||
@ -60,7 +60,7 @@
|
|||||||
@ CHECK-NEXT: EntrySize: 0
|
@ CHECK-NEXT: EntrySize: 0
|
||||||
@ CHECK-NEXT: }
|
@ CHECK-NEXT: }
|
||||||
@ CHECK-NEXT: Section {
|
@ CHECK-NEXT: Section {
|
||||||
@ CHECK-NEXT: Index: 10
|
@ CHECK-NEXT: Index: 11
|
||||||
@ CHECK-NEXT: Name: .ARM.exidx
|
@ CHECK-NEXT: Name: .ARM.exidx
|
||||||
@ CHECK-NEXT: Type: SHT_ARM_EXIDX
|
@ CHECK-NEXT: Type: SHT_ARM_EXIDX
|
||||||
@ CHECK-NEXT: Flags [
|
@ CHECK-NEXT: Flags [
|
||||||
@ -71,7 +71,7 @@
|
|||||||
@ CHECK-NEXT: Address: 0x0
|
@ CHECK-NEXT: Address: 0x0
|
||||||
@ CHECK-NEXT: Offset:
|
@ CHECK-NEXT: Offset:
|
||||||
@ CHECK-NEXT: Size: 8
|
@ CHECK-NEXT: Size: 8
|
||||||
@ CHECK-NEXT: Link: 9
|
@ CHECK-NEXT: Link: 10
|
||||||
@ CHECK-NEXT: Info: 0
|
@ CHECK-NEXT: Info: 0
|
||||||
@ CHECK-NEXT: AddressAlignment: 4
|
@ CHECK-NEXT: AddressAlignment: 4
|
||||||
@ CHECK-NEXT: EntrySize: 0
|
@ CHECK-NEXT: EntrySize: 0
|
||||||
|
@ -2,14 +2,14 @@
|
|||||||
|
|
||||||
// Test that we produce two foo sections, each in separate groups
|
// Test that we produce two foo sections, each in separate groups
|
||||||
|
|
||||||
// CHECK: Index: 2
|
// CHECK: Index: 5
|
||||||
// CHECK-NEXT: Name: .group
|
// CHECK-NEXT: Name: .group
|
||||||
|
|
||||||
// CHECK: Index: 3
|
// CHECK: Index: 6
|
||||||
// CHECK-NEXT: Name: .group
|
// CHECK-NEXT: Name: .foo
|
||||||
|
|
||||||
// CHECK: Index: 7
|
// CHECK: Index: 7
|
||||||
// CHECK-NEXT: Name: .foo
|
// CHECK-NEXT: Name: .group
|
||||||
|
|
||||||
// CHECK: Index: 8
|
// CHECK: Index: 8
|
||||||
// CHECK-NEXT: Name: .foo
|
// CHECK-NEXT: Name: .foo
|
||||||
@ -18,15 +18,15 @@
|
|||||||
|
|
||||||
// CHECK: Name: f1
|
// CHECK: Name: f1
|
||||||
// CHECK-NOT: }
|
// CHECK-NOT: }
|
||||||
// CHECK: Section: .group (0x2)
|
// CHECK: Section: .group (0x5)
|
||||||
|
|
||||||
// CHECK: Name: f2
|
// CHECK: Name: f2
|
||||||
// CHECK-NOT: }
|
// CHECK-NOT: }
|
||||||
// CHECK: Section: .group (0x3)
|
// CHECK: Section: .group (0x7)
|
||||||
|
|
||||||
// CHECK: Name: .foo
|
// CHECK: Name: .foo
|
||||||
// CHECK-NOT: }
|
// CHECK-NOT: }
|
||||||
// CHECK: Section: .foo (0x7)
|
// CHECK: Section: .foo (0x6)
|
||||||
|
|
||||||
// CHECK: Name: .foo
|
// CHECK: Name: .foo
|
||||||
// CHECK-NOT: }
|
// CHECK-NOT: }
|
||||||
|
@ -16,9 +16,9 @@ world:
|
|||||||
// CHECK: Name: .group
|
// CHECK: Name: .group
|
||||||
// CHECK-NOT: SectionData
|
// CHECK-NOT: SectionData
|
||||||
// CHECK: SectionData
|
// CHECK: SectionData
|
||||||
// CHECK-NEXT: 0000: 01000000 06000000 08000000
|
// CHECK-NEXT: 0000: 01000000 07000000 08000000
|
||||||
|
|
||||||
// CHECK: Index: 6
|
// CHECK: Index: 7
|
||||||
// CHECK-NEXT: Name: .text.world
|
// CHECK-NEXT: Name: .text.world
|
||||||
// CHECK-NOT: Section {
|
// CHECK-NOT: Section {
|
||||||
// CHECK: SHF_GROUP
|
// CHECK: SHF_GROUP
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s -t | FileCheck %s
|
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -s -t -sd | FileCheck %s
|
||||||
|
|
||||||
// Test that we produce the group sections and that they are at the beginning
|
// Test that we produce the group sections and that they are before the members
|
||||||
// of the file.
|
|
||||||
|
|
||||||
// CHECK: Section {
|
// CHECK: Section {
|
||||||
// CHECK: Index: 2
|
// CHECK: Index: 5
|
||||||
// CHECK-NEXT: Name: .group
|
// CHECK-NEXT: Name: .group
|
||||||
// CHECK-NEXT: Type: SHT_GROUP
|
// CHECK-NEXT: Type: SHT_GROUP
|
||||||
// CHECK-NEXT: Flags [
|
// CHECK-NEXT: Flags [
|
||||||
@ -16,9 +15,12 @@
|
|||||||
// CHECK-NEXT: Info: 1
|
// CHECK-NEXT: Info: 1
|
||||||
// CHECK-NEXT: AddressAlignment: 4
|
// CHECK-NEXT: AddressAlignment: 4
|
||||||
// CHECK-NEXT: EntrySize: 4
|
// CHECK-NEXT: EntrySize: 4
|
||||||
|
// CHECK-NEXT: SectionData (
|
||||||
|
// CHECK-NEXT: 0000: 01000000 06000000 07000000
|
||||||
|
// CHECK-NEXT: )
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK-NEXT: Section {
|
// CHECK: Section {
|
||||||
// CHECK-NEXT: Index: 3
|
// CHECK: Index: 8
|
||||||
// CHECK-NEXT: Name: .group
|
// CHECK-NEXT: Name: .group
|
||||||
// CHECK-NEXT: Type: SHT_GROUP
|
// CHECK-NEXT: Type: SHT_GROUP
|
||||||
// CHECK-NEXT: Flags [
|
// CHECK-NEXT: Flags [
|
||||||
@ -30,9 +32,12 @@
|
|||||||
// CHECK-NEXT: Info: 2
|
// CHECK-NEXT: Info: 2
|
||||||
// CHECK-NEXT: AddressAlignment: 4
|
// CHECK-NEXT: AddressAlignment: 4
|
||||||
// CHECK-NEXT: EntrySize: 4
|
// CHECK-NEXT: EntrySize: 4
|
||||||
|
// CHECK-NEXT: SectionData (
|
||||||
|
// CHECK-NEXT: 0000: 01000000 09000000
|
||||||
|
// CHECK-NEXT: )
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK-NEXT: Section {
|
// CHECK: Section {
|
||||||
// CHECK-NEXT: Index: 4
|
// CHECK: Index: 10
|
||||||
// CHECK-NEXT: Name: .group
|
// CHECK-NEXT: Name: .group
|
||||||
// CHECK-NEXT: Type: SHT_GROUP
|
// CHECK-NEXT: Type: SHT_GROUP
|
||||||
// CHECK-NEXT: Flags [
|
// CHECK-NEXT: Flags [
|
||||||
@ -44,6 +49,9 @@
|
|||||||
// CHECK-NEXT: Info: 10
|
// CHECK-NEXT: Info: 10
|
||||||
// CHECK-NEXT: AddressAlignment: 4
|
// CHECK-NEXT: AddressAlignment: 4
|
||||||
// CHECK-NEXT: EntrySize: 4
|
// CHECK-NEXT: EntrySize: 4
|
||||||
|
// CHECK-NEXT: SectionData (
|
||||||
|
// CHECK-NEXT: 0000: 01000000 0B000000 0C000000
|
||||||
|
// CHECK-NEXT: )
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
// Test that g1 and g2 are local, but g3 is an undefined global.
|
// Test that g1 and g2 are local, but g3 is an undefined global.
|
||||||
@ -64,7 +72,7 @@
|
|||||||
// CHECK-NEXT: Binding: Local
|
// CHECK-NEXT: Binding: Local
|
||||||
// CHECK-NEXT: Type: None
|
// CHECK-NEXT: Type: None
|
||||||
// CHECK-NEXT: Other: 0
|
// CHECK-NEXT: Other: 0
|
||||||
// CHECK-NEXT: Section: .group (0x3)
|
// CHECK-NEXT: Section: .group (0x8)
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
|
|
||||||
// CHECK: Symbol {
|
// CHECK: Symbol {
|
||||||
|
@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
// Test that the relocation points to the first section foo.
|
// Test that the relocation points to the first section foo.
|
||||||
|
|
||||||
// The first seciton foo has index 7
|
// The first seciton foo has index 6
|
||||||
// CHECK: Section {
|
// CHECK: Section {
|
||||||
// CHECK: Index: 7
|
// CHECK: Index: 6
|
||||||
// CHECK-NEXT: Name: foo (28)
|
// CHECK-NEXT: Name: foo (28)
|
||||||
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
|
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
|
||||||
// CHECK-NEXT: Flags [ (0x202)
|
// CHECK-NEXT: Flags [ (0x202)
|
||||||
@ -24,8 +24,8 @@
|
|||||||
// CHECK-NEXT: AddressAlignment: 1
|
// CHECK-NEXT: AddressAlignment: 1
|
||||||
// CHECK-NEXT: EntrySize: 0
|
// CHECK-NEXT: EntrySize: 0
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK-NEXT: Section {
|
// CHECK: Section {
|
||||||
// CHECK-NEXT: Index: 8
|
// CHECK: Index: 8
|
||||||
// CHECK-NEXT: Name: foo (28)
|
// CHECK-NEXT: Name: foo (28)
|
||||||
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
|
// CHECK-NEXT: Type: SHT_PROGBITS (0x1)
|
||||||
// CHECK-NEXT: Flags [ (0x200)
|
// CHECK-NEXT: Flags [ (0x200)
|
||||||
@ -83,7 +83,7 @@
|
|||||||
// symbol 6
|
// symbol 6
|
||||||
// CHECK-NOT: Name
|
// CHECK-NOT: Name
|
||||||
// CHECK: Name: foo
|
// CHECK: Name: foo
|
||||||
// CHECK: Section: foo (0x7)
|
// CHECK: Section: foo (0x6)
|
||||||
|
|
||||||
// symbol 7
|
// symbol 7
|
||||||
// CHECK-NOT: Name
|
// CHECK-NOT: Name
|
||||||
|
Loading…
x
Reference in New Issue
Block a user