mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-19 02:25:01 +00:00
Produce a single string table in a ELF .o
Normally an ELF .o has two string tables, one for symbols, one for section names. With the scheme of naming sections like ".text.foo" where foo is a symbol, there is a big potential saving in using a single one. Building llvm+clang+lld with master and with this patch the results were: master: 193,267,008 bytes patch: 186,107,952 bytes master non unique section names: 183,260,192 bytes patch non unique section names: 183,118,632 bytes So using non usique saves 10,006,816 bytes, and the patch saves 7,159,056 while still using distinct names for the sections. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238073 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -107,7 +107,6 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
|
|
||||||
llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
|
llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
|
||||||
Relocations;
|
Relocations;
|
||||||
StringTableBuilder ShStrTabBuilder;
|
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// @name Symbol Table Data
|
/// @name Symbol Table Data
|
||||||
@@ -129,8 +128,8 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
unsigned StringTableIndex;
|
unsigned StringTableIndex;
|
||||||
// This holds the .symtab section index.
|
// This holds the .symtab section index.
|
||||||
unsigned SymbolTableIndex;
|
unsigned SymbolTableIndex;
|
||||||
|
// This holds the .symtab_shndx section index.
|
||||||
unsigned ShstrtabIndex;
|
unsigned SymtabShndxSectionIndex = 0;
|
||||||
|
|
||||||
// Sections in the order they are to be output in the section table.
|
// Sections in the order they are to be output in the section table.
|
||||||
std::vector<MCSectionELF *> SectionTable;
|
std::vector<MCSectionELF *> SectionTable;
|
||||||
@@ -157,7 +156,6 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
WeakrefUsedInReloc.clear();
|
WeakrefUsedInReloc.clear();
|
||||||
Renames.clear();
|
Renames.clear();
|
||||||
Relocations.clear();
|
Relocations.clear();
|
||||||
ShStrTabBuilder.clear();
|
|
||||||
StrTabBuilder.clear();
|
StrTabBuilder.clear();
|
||||||
FileSymbolData.clear();
|
FileSymbolData.clear();
|
||||||
LocalSymbolData.clear();
|
LocalSymbolData.clear();
|
||||||
@@ -224,7 +222,6 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
MCSectionELF *createRelocationSection(MCContext &Ctx,
|
MCSectionELF *createRelocationSection(MCContext &Ctx,
|
||||||
const MCSectionELF &Sec);
|
const MCSectionELF &Sec);
|
||||||
|
|
||||||
const MCSectionELF *createSectionHeaderStringTable();
|
|
||||||
const MCSectionELF *createStringTable(MCContext &Ctx);
|
const MCSectionELF *createStringTable(MCContext &Ctx);
|
||||||
|
|
||||||
void ExecutePostLayoutBinding(MCAssembler &Asm,
|
void ExecutePostLayoutBinding(MCAssembler &Asm,
|
||||||
@@ -261,7 +258,7 @@ class ELFObjectWriter : public MCObjectWriter {
|
|||||||
|
|
||||||
unsigned ELFObjectWriter::addToSectionTable(MCSectionELF *Sec) {
|
unsigned ELFObjectWriter::addToSectionTable(MCSectionELF *Sec) {
|
||||||
SectionTable.push_back(Sec);
|
SectionTable.push_back(Sec);
|
||||||
ShStrTabBuilder.add(Sec->getSectionName());
|
StrTabBuilder.add(Sec->getSectionName());
|
||||||
return SectionTable.size();
|
return SectionTable.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -395,8 +392,8 @@ void ELFObjectWriter::writeHeader(const MCAssembler &Asm) {
|
|||||||
Write16(0);
|
Write16(0);
|
||||||
|
|
||||||
// e_shstrndx = Section # of '.shstrtab'
|
// e_shstrndx = Section # of '.shstrtab'
|
||||||
assert(ShstrtabIndex < ELF::SHN_LORESERVE);
|
assert(StringTableIndex < ELF::SHN_LORESERVE);
|
||||||
Write16(ShstrtabIndex);
|
Write16(StringTableIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
|
uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
|
||||||
@@ -541,13 +538,7 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD,
|
|||||||
void ELFObjectWriter::writeSymbolTable(MCContext &Ctx,
|
void ELFObjectWriter::writeSymbolTable(MCContext &Ctx,
|
||||||
const MCAsmLayout &Layout,
|
const MCAsmLayout &Layout,
|
||||||
SectionOffsetsTy &SectionOffsets) {
|
SectionOffsetsTy &SectionOffsets) {
|
||||||
unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
|
MCSectionELF *SymtabSection = SectionTable[SymbolTableIndex - 1];
|
||||||
|
|
||||||
// Symbol table
|
|
||||||
MCSectionELF *SymtabSection =
|
|
||||||
Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
|
|
||||||
SymtabSection->setAlignment(is64Bit() ? 8 : 4);
|
|
||||||
SymbolTableIndex = addToSectionTable(SymtabSection);
|
|
||||||
|
|
||||||
// The string table must be emitted first because we need the index
|
// The string table must be emitted first because we need the index
|
||||||
// into the string table for all the symbol names.
|
// into the string table for all the symbol names.
|
||||||
@@ -599,14 +590,14 @@ void ELFObjectWriter::writeSymbolTable(MCContext &Ctx,
|
|||||||
SectionOffsets[SymtabSection] = 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()) {
|
||||||
|
assert(SymtabShndxSectionIndex == 0);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
assert(SymtabShndxSectionIndex != 0);
|
||||||
|
|
||||||
SecStart = OS.tell();
|
SecStart = OS.tell();
|
||||||
MCSectionELF *SymtabShndxSection =
|
MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1];
|
||||||
Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
|
|
||||||
addToSectionTable(SymtabShndxSection);
|
|
||||||
SymtabShndxSection->setAlignment(4);
|
|
||||||
for (uint32_t Index : ShndxIndexes)
|
for (uint32_t Index : ShndxIndexes)
|
||||||
write(Index);
|
write(Index);
|
||||||
SecEnd = OS.tell();
|
SecEnd = OS.tell();
|
||||||
@@ -917,6 +908,14 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
MCAssembler &Asm, const MCAsmLayout &Layout,
|
MCAssembler &Asm, const MCAsmLayout &Layout,
|
||||||
const SectionIndexMapTy &SectionIndexMap,
|
const SectionIndexMapTy &SectionIndexMap,
|
||||||
const RevGroupMapTy &RevGroupMap) {
|
const RevGroupMapTy &RevGroupMap) {
|
||||||
|
MCContext &Ctx = Asm.getContext();
|
||||||
|
// Symbol table
|
||||||
|
unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
|
||||||
|
MCSectionELF *SymtabSection =
|
||||||
|
Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
|
||||||
|
SymtabSection->setAlignment(is64Bit() ? 8 : 4);
|
||||||
|
SymbolTableIndex = addToSectionTable(SymtabSection);
|
||||||
|
|
||||||
// FIXME: Is this the correct place to do this?
|
// FIXME: Is this the correct place to do this?
|
||||||
// FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
|
// FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed?
|
||||||
if (NeedsGOT) {
|
if (NeedsGOT) {
|
||||||
@@ -928,6 +927,7 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the data for the symbols.
|
// Add the data for the symbols.
|
||||||
|
bool HasLargeSectionIndex = false;
|
||||||
for (const MCSymbol &Symbol : Asm.symbols()) {
|
for (const MCSymbol &Symbol : Asm.symbols()) {
|
||||||
MCSymbolData &SD = Symbol.getData();
|
MCSymbolData &SD = Symbol.getData();
|
||||||
|
|
||||||
@@ -959,10 +959,13 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
assert(!Local);
|
assert(!Local);
|
||||||
MSD.SectionIndex = ELF::SHN_COMMON;
|
MSD.SectionIndex = ELF::SHN_COMMON;
|
||||||
} else if (BaseSymbol->isUndefined()) {
|
} else if (BaseSymbol->isUndefined()) {
|
||||||
if (isSignature && !Used)
|
if (isSignature && !Used) {
|
||||||
MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
|
MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
|
||||||
else
|
if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
|
||||||
|
HasLargeSectionIndex = true;
|
||||||
|
} else {
|
||||||
MSD.SectionIndex = ELF::SHN_UNDEF;
|
MSD.SectionIndex = ELF::SHN_UNDEF;
|
||||||
|
}
|
||||||
if (!Used && WeakrefUsed)
|
if (!Used && WeakrefUsed)
|
||||||
MCELF::SetBinding(SD, ELF::STB_WEAK);
|
MCELF::SetBinding(SD, ELF::STB_WEAK);
|
||||||
} else {
|
} else {
|
||||||
@@ -970,6 +973,8 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
static_cast<const MCSectionELF&>(BaseSymbol->getSection());
|
static_cast<const MCSectionELF&>(BaseSymbol->getSection());
|
||||||
MSD.SectionIndex = SectionIndexMap.lookup(&Section);
|
MSD.SectionIndex = SectionIndexMap.lookup(&Section);
|
||||||
assert(MSD.SectionIndex && "Invalid section index!");
|
assert(MSD.SectionIndex && "Invalid section index!");
|
||||||
|
if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
|
||||||
|
HasLargeSectionIndex = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The @@@ in symbol version is replaced with @ in undefined symbols and @@
|
// The @@@ in symbol version is replaced with @ in undefined symbols and @@
|
||||||
@@ -1023,6 +1028,13 @@ void ELFObjectWriter::computeSymbolTable(
|
|||||||
ExternalSymbolData.push_back(MSD);
|
ExternalSymbolData.push_back(MSD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (HasLargeSectionIndex) {
|
||||||
|
MCSectionELF *SymtabShndxSection =
|
||||||
|
Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
|
||||||
|
SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
|
||||||
|
SymtabShndxSection->setAlignment(4);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
|
for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i)
|
||||||
StrTabBuilder.add(*i);
|
StrTabBuilder.add(*i);
|
||||||
|
|
||||||
@@ -1227,17 +1239,8 @@ void ELFObjectWriter::writeRelocations(const MCAssembler &Asm,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCSectionELF *ELFObjectWriter::createSectionHeaderStringTable() {
|
|
||||||
const MCSectionELF *ShstrtabSection = SectionTable[ShstrtabIndex - 1];
|
|
||||||
ShStrTabBuilder.finalize(StringTableBuilder::ELF);
|
|
||||||
OS << ShStrTabBuilder.data();
|
|
||||||
return ShstrtabSection;
|
|
||||||
}
|
|
||||||
|
|
||||||
const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) {
|
const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) {
|
||||||
MCSectionELF *StrtabSection =
|
MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
|
||||||
Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
|
|
||||||
StringTableIndex = addToSectionTable(StrtabSection);
|
|
||||||
OS << StrTabBuilder.data();
|
OS << StrTabBuilder.data();
|
||||||
return StrtabSection;
|
return StrtabSection;
|
||||||
}
|
}
|
||||||
@@ -1285,7 +1288,7 @@ void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
|
|||||||
Section.getType() == ELF::SHT_ARM_EXIDX)
|
Section.getType() == ELF::SHT_ARM_EXIDX)
|
||||||
sh_link = SectionIndexMap.lookup(Section.getAssociatedSection());
|
sh_link = SectionIndexMap.lookup(Section.getAssociatedSection());
|
||||||
|
|
||||||
WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()),
|
WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()),
|
||||||
Section.getType(), Section.getFlags(), 0, Offset, Size,
|
Section.getType(), Section.getFlags(), 0, Offset, Size,
|
||||||
sh_link, sh_info, Section.getAlignment(),
|
sh_link, sh_info, Section.getAlignment(),
|
||||||
Section.getEntrySize());
|
Section.getEntrySize());
|
||||||
@@ -1328,9 +1331,9 @@ void ELFObjectWriter::writeSectionHeader(
|
|||||||
void ELFObjectWriter::WriteObject(MCAssembler &Asm,
|
void ELFObjectWriter::WriteObject(MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout) {
|
const MCAsmLayout &Layout) {
|
||||||
MCContext &Ctx = Asm.getContext();
|
MCContext &Ctx = Asm.getContext();
|
||||||
MCSectionELF *ShstrtabSection =
|
MCSectionELF *StrtabSection =
|
||||||
Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0);
|
Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
|
||||||
ShstrtabIndex = addToSectionTable(ShstrtabSection);
|
StringTableIndex = addToSectionTable(StrtabSection);
|
||||||
|
|
||||||
RevGroupMapTy RevGroupMap;
|
RevGroupMapTy RevGroupMap;
|
||||||
SectionIndexMapTy SectionIndexMap;
|
SectionIndexMapTy SectionIndexMap;
|
||||||
@@ -1426,13 +1429,6 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
|
|||||||
SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
|
SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
uint64_t SecStart = OS.tell();
|
|
||||||
const MCSectionELF *Sec = createSectionHeaderStringTable();
|
|
||||||
uint64_t SecEnd = OS.tell();
|
|
||||||
SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
|
uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
|
||||||
uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment);
|
uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment);
|
||||||
WriteZeros(Padding);
|
WriteZeros(Padding);
|
||||||
|
@@ -11,16 +11,16 @@
|
|||||||
// WINDOWS-NEXT: Arch: x86_64
|
// WINDOWS-NEXT: Arch: x86_64
|
||||||
|
|
||||||
// Test that like gnu as we create text, data and bss by default. Also test
|
// Test that like gnu as we create text, data and bss by default. Also test
|
||||||
// that shstrtab, symtab and strtab are listed.
|
// that symtab and strtab are listed.
|
||||||
|
|
||||||
// CHECK: Section {
|
// CHECK: Section {
|
||||||
// CHECK: Name: .shstrtab
|
// CHECK: Name: .strtab
|
||||||
// CHECK-NEXT: Type: SHT_STRTAB
|
// CHECK-NEXT: Type: SHT_STRTAB
|
||||||
// CHECK-NEXT: Flags [
|
// CHECK-NEXT: Flags [
|
||||||
// CHECK-NEXT: ]
|
// CHECK-NEXT: ]
|
||||||
// CHECK-NEXT: Address: 0x0
|
// CHECK-NEXT: Address: 0x0
|
||||||
// CHECK-NEXT: Offset:
|
// CHECK-NEXT: Offset:
|
||||||
// CHECK-NEXT: Size: 44
|
// CHECK-NEXT: Size: 34
|
||||||
// CHECK-NEXT: Link: 0
|
// CHECK-NEXT: Link: 0
|
||||||
// CHECK-NEXT: Info: 0
|
// CHECK-NEXT: Info: 0
|
||||||
// CHECK-NEXT: AddressAlignment: 1
|
// CHECK-NEXT: AddressAlignment: 1
|
||||||
@@ -84,16 +84,3 @@
|
|||||||
// CHECK-NEXT: AddressAlignment: 8
|
// CHECK-NEXT: AddressAlignment: 8
|
||||||
// CHECK-NEXT: EntrySize: 24
|
// CHECK-NEXT: EntrySize: 24
|
||||||
// CHECK-NEXT: }
|
// CHECK-NEXT: }
|
||||||
// CHECK: Section {
|
|
||||||
// CHECK: Name: .strtab
|
|
||||||
// CHECK-NEXT: Type: SHT_STRTAB
|
|
||||||
// CHECK-NEXT: Flags [
|
|
||||||
// CHECK-NEXT: ]
|
|
||||||
// CHECK-NEXT: Address: 0x0
|
|
||||||
// CHECK-NEXT: Offset:
|
|
||||||
// CHECK-NEXT: Size: 1
|
|
||||||
// CHECK-NEXT: Link: 0
|
|
||||||
// CHECK-NEXT: Info: 0
|
|
||||||
// CHECK-NEXT: AddressAlignment: 1
|
|
||||||
// CHECK-NEXT: EntrySize: 0
|
|
||||||
// CHECK-NEXT: }
|
|
||||||
|
@@ -16,6 +16,6 @@ foobar:
|
|||||||
.Ltmp3:
|
.Ltmp3:
|
||||||
.size foobar, .Ltmp3-foobar
|
.size foobar, .Ltmp3-foobar
|
||||||
|
|
||||||
// CHECK: Name: foobar (1)
|
// CHECK: Name: foobar (16)
|
||||||
// CHECK: Name: bar (4)
|
// CHECK: Name: bar (19)
|
||||||
// CHECK: Name: foo (8)
|
// CHECK: Name: foo (23)
|
||||||
|
Reference in New Issue
Block a user