[llvm] r238073 - Produce a single string table in a ELF .o

Sean Silva chisophugis at gmail.com
Fri May 22 17:28:02 PDT 2015


On Fri, May 22, 2015 at 4:58 PM, Rafael Espindola <
rafael.espindola at gmail.com> wrote:

> Author: rafael
> Date: Fri May 22 18:58:30 2015
> New Revision: 238073
>
> URL: http://llvm.org/viewvc/llvm-project?rev=238073&view=rev
> Log:
> 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.
>

When you show a measurement, it is vital to explain what is being measured.

-- Sean Silva


>
> Modified:
>     llvm/trunk/lib/MC/ELFObjectWriter.cpp
>     llvm/trunk/test/MC/ELF/empty.s
>     llvm/trunk/test/MC/ELF/strtab-suffix-opt.s
>
> Modified: llvm/trunk/lib/MC/ELFObjectWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/ELFObjectWriter.cpp?rev=238073&r1=238072&r2=238073&view=diff
>
> ==============================================================================
> --- llvm/trunk/lib/MC/ELFObjectWriter.cpp (original)
> +++ llvm/trunk/lib/MC/ELFObjectWriter.cpp Fri May 22 18:58:30 2015
> @@ -107,7 +107,6 @@ class ELFObjectWriter : public MCObjectW
>
>      llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
>          Relocations;
> -    StringTableBuilder ShStrTabBuilder;
>
>      /// @}
>      /// @name Symbol Table Data
> @@ -129,8 +128,8 @@ class ELFObjectWriter : public MCObjectW
>      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<MCSectionELF *> SectionTable;
> @@ -157,7 +156,6 @@ class ELFObjectWriter : public MCObjectW
>        WeakrefUsedInReloc.clear();
>        Renames.clear();
>        Relocations.clear();
> -      ShStrTabBuilder.clear();
>        StrTabBuilder.clear();
>        FileSymbolData.clear();
>        LocalSymbolData.clear();
> @@ -224,7 +222,6 @@ class ELFObjectWriter : public MCObjectW
>      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 MCObjectW
>
>  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
>    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(Symbol
>  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(M
>    SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
>
>    ArrayRef<uint32_t> 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<const MCSectionELF&>(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(c
>    }
>  }
>
> -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
>        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;
> @@ -1425,13 +1428,6 @@ void ELFObjectWriter::WriteObject(MCAsse
>      uint64_t SecEnd = OS.tell();
>      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);
>
> Modified: llvm/trunk/test/MC/ELF/empty.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/empty.s?rev=238073&r1=238072&r2=238073&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/MC/ELF/empty.s (original)
> +++ llvm/trunk/test/MC/ELF/empty.s Fri May 22 18:58:30 2015
> @@ -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:   }
>
> Modified: llvm/trunk/test/MC/ELF/strtab-suffix-opt.s
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ELF/strtab-suffix-opt.s?rev=238073&r1=238072&r2=238073&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/MC/ELF/strtab-suffix-opt.s (original)
> +++ llvm/trunk/test/MC/ELF/strtab-suffix-opt.s Fri May 22 18:58:30 2015
> @@ -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)
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150522/650222e7/attachment.html>


More information about the llvm-commits mailing list