From: Rafael Espindola Date: Fri, 22 May 2015 23:58:30 +0000 (+0000) Subject: Produce a single string table in a ELF .o X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7c4f3dcc5ef8dc639ace97a976d7854c49d6dd0c;p=oota-llvm.git 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 --- diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 87aacaabd79..60a9bd2dc56 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -107,7 +107,6 @@ class ELFObjectWriter : public MCObjectWriter { llvm::DenseMap> Relocations; - StringTableBuilder ShStrTabBuilder; /// @} /// @name Symbol Table Data @@ -129,8 +128,8 @@ class ELFObjectWriter : public MCObjectWriter { unsigned StringTableIndex; // This holds the .symtab section index. unsigned SymbolTableIndex; - - unsigned ShstrtabIndex; + // This holds the .symtab_shndx section index. + unsigned SymtabShndxSectionIndex = 0; // Sections in the order they are to be output in the section table. std::vector SectionTable; @@ -157,7 +156,6 @@ class ELFObjectWriter : public MCObjectWriter { WeakrefUsedInReloc.clear(); Renames.clear(); Relocations.clear(); - ShStrTabBuilder.clear(); StrTabBuilder.clear(); FileSymbolData.clear(); LocalSymbolData.clear(); @@ -224,7 +222,6 @@ class ELFObjectWriter : public MCObjectWriter { MCSectionELF *createRelocationSection(MCContext &Ctx, const MCSectionELF &Sec); - const MCSectionELF *createSectionHeaderStringTable(); const MCSectionELF *createStringTable(MCContext &Ctx); void ExecutePostLayoutBinding(MCAssembler &Asm, @@ -261,7 +258,7 @@ class ELFObjectWriter : public MCObjectWriter { unsigned ELFObjectWriter::addToSectionTable(MCSectionELF *Sec) { SectionTable.push_back(Sec); - ShStrTabBuilder.add(Sec->getSectionName()); + StrTabBuilder.add(Sec->getSectionName()); return SectionTable.size(); } @@ -395,8 +392,8 @@ void ELFObjectWriter::writeHeader(const MCAssembler &Asm) { Write16(0); // e_shstrndx = Section # of '.shstrtab' - assert(ShstrtabIndex < ELF::SHN_LORESERVE); - Write16(ShstrtabIndex); + assert(StringTableIndex < ELF::SHN_LORESERVE); + Write16(StringTableIndex); } uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym, @@ -541,13 +538,7 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, void ELFObjectWriter::writeSymbolTable(MCContext &Ctx, const MCAsmLayout &Layout, SectionOffsetsTy &SectionOffsets) { - unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; - - // Symbol table - MCSectionELF *SymtabSection = - Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, ""); - SymtabSection->setAlignment(is64Bit() ? 8 : 4); - SymbolTableIndex = addToSectionTable(SymtabSection); + MCSectionELF *SymtabSection = SectionTable[SymbolTableIndex - 1]; // The string table must be emitted first because we need the index // 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); ArrayRef ShndxIndexes = Writer.getShndxIndexes(); - if (ShndxIndexes.empty()) + if (ShndxIndexes.empty()) { + assert(SymtabShndxSectionIndex == 0); return; + } + assert(SymtabShndxSectionIndex != 0); SecStart = OS.tell(); - MCSectionELF *SymtabShndxSection = - Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); - addToSectionTable(SymtabShndxSection); - SymtabShndxSection->setAlignment(4); + MCSectionELF *SymtabShndxSection = SectionTable[SymtabShndxSectionIndex - 1]; for (uint32_t Index : ShndxIndexes) write(Index); SecEnd = OS.tell(); @@ -917,6 +908,14 @@ void ELFObjectWriter::computeSymbolTable( MCAssembler &Asm, const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap, 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: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? if (NeedsGOT) { @@ -928,6 +927,7 @@ void ELFObjectWriter::computeSymbolTable( } // Add the data for the symbols. + bool HasLargeSectionIndex = false; for (const MCSymbol &Symbol : Asm.symbols()) { MCSymbolData &SD = Symbol.getData(); @@ -959,10 +959,13 @@ void ELFObjectWriter::computeSymbolTable( assert(!Local); MSD.SectionIndex = ELF::SHN_COMMON; } else if (BaseSymbol->isUndefined()) { - if (isSignature && !Used) + if (isSignature && !Used) { MSD.SectionIndex = RevGroupMap.lookup(&Symbol); - else + if (MSD.SectionIndex >= ELF::SHN_LORESERVE) + HasLargeSectionIndex = true; + } else { MSD.SectionIndex = ELF::SHN_UNDEF; + } if (!Used && WeakrefUsed) MCELF::SetBinding(SD, ELF::STB_WEAK); } else { @@ -970,6 +973,8 @@ void ELFObjectWriter::computeSymbolTable( static_cast(BaseSymbol->getSection()); MSD.SectionIndex = SectionIndexMap.lookup(&Section); 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 @@ @@ -1023,6 +1028,13 @@ void ELFObjectWriter::computeSymbolTable( 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) 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) { - MCSectionELF *StrtabSection = - Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); - StringTableIndex = addToSectionTable(StrtabSection); + MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1]; OS << StrTabBuilder.data(); return StrtabSection; } @@ -1285,7 +1288,7 @@ void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap, Section.getType() == ELF::SHT_ARM_EXIDX) sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); - WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()), + WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()), Section.getType(), Section.getFlags(), 0, Offset, Size, sh_link, sh_info, Section.getAlignment(), Section.getEntrySize()); @@ -1328,9 +1331,9 @@ void ELFObjectWriter::writeSectionHeader( void ELFObjectWriter::WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) { MCContext &Ctx = Asm.getContext(); - MCSectionELF *ShstrtabSection = - Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0); - ShstrtabIndex = addToSectionTable(ShstrtabSection); + MCSectionELF *StrtabSection = + Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); + StringTableIndex = addToSectionTable(StrtabSection); RevGroupMapTy RevGroupMap; SectionIndexMapTy SectionIndexMap; @@ -1426,13 +1429,6 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, 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 Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); WriteZeros(Padding); diff --git a/test/MC/ELF/empty.s b/test/MC/ELF/empty.s index a371af443da..6ddbd8c942a 100644 --- a/test/MC/ELF/empty.s +++ b/test/MC/ELF/empty.s @@ -11,16 +11,16 @@ // WINDOWS-NEXT: Arch: x86_64 // 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: Name: .shstrtab +// CHECK: Name: .strtab // CHECK-NEXT: Type: SHT_STRTAB // CHECK-NEXT: Flags [ // CHECK-NEXT: ] // CHECK-NEXT: Address: 0x0 // CHECK-NEXT: Offset: -// CHECK-NEXT: Size: 44 +// CHECK-NEXT: Size: 34 // CHECK-NEXT: Link: 0 // CHECK-NEXT: Info: 0 // CHECK-NEXT: AddressAlignment: 1 @@ -84,16 +84,3 @@ // CHECK-NEXT: AddressAlignment: 8 // CHECK-NEXT: EntrySize: 24 // 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: } diff --git a/test/MC/ELF/strtab-suffix-opt.s b/test/MC/ELF/strtab-suffix-opt.s index eb5da8a0155..05246564460 100644 --- a/test/MC/ELF/strtab-suffix-opt.s +++ b/test/MC/ELF/strtab-suffix-opt.s @@ -16,6 +16,6 @@ foobar: .Ltmp3: .size foobar, .Ltmp3-foobar -// CHECK: Name: foobar (1) -// CHECK: Name: bar (4) -// CHECK: Name: foo (8) +// CHECK: Name: foobar (16) +// CHECK: Name: bar (19) +// CHECK: Name: foo (23)