From b9ffeb0979956b871a1a783615aa8d6ebe060c31 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 28 May 2015 17:54:01 +0000 Subject: [PATCH] Merge computeSymbolTable and writeSymbolTable. For now this just saves a few loops, but it will allow more simplifications in the future. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238444 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/MC/ELFObjectWriter.cpp | 174 +++++++++++++++++-------------------- 1 file changed, 80 insertions(+), 94 deletions(-) diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp index 37762a40874..6c5df9c22a1 100644 --- a/lib/MC/ELFObjectWriter.cpp +++ b/lib/MC/ELFObjectWriter.cpp @@ -186,9 +186,6 @@ class ELFObjectWriter : public MCObjectWriter { typedef std::map> SectionOffsetsTy; - void writeSymbolTable(MCContext &Ctx, const MCAsmLayout &Layout, - SectionOffsetsTy &SectionOffsets); - bool shouldRelocateWithSymbol(const MCAssembler &Asm, const MCSymbolRefExpr *RefA, const MCSymbol *Sym, uint64_t C, @@ -212,7 +209,8 @@ class ELFObjectWriter : public MCObjectWriter { /// \param RevGroupMap - Maps a signature symbol to the group section. void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap, - const RevGroupMapTy &RevGroupMap); + const RevGroupMapTy &RevGroupMap, + SectionOffsetsTy &SectionOffsets); MCSectionELF *createRelocationSection(MCContext &Ctx, const MCSectionELF &Sec); @@ -508,76 +506,6 @@ void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, MSD.SectionIndex, IsReserved); } -void ELFObjectWriter::writeSymbolTable(MCContext &Ctx, - const MCAsmLayout &Layout, - SectionOffsetsTy &SectionOffsets) { - const 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. - - SymbolTableWriter Writer(*this, is64Bit()); - - uint64_t Padding = - OffsetToAlignment(OS.tell(), SymtabSection->getAlignment()); - WriteZeros(Padding); - - uint64_t SecStart = OS.tell(); - - // The first entry is the undefined symbol entry. - Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); - - for (unsigned i = 0, e = FileSymbolData.size(); i != e; ++i) { - Writer.writeSymbol(FileSymbolData[i], ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, - ELF::STV_DEFAULT, ELF::SHN_ABS, true); - } - - // Write the symbol table entries. - LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1; - - for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { - ELFSymbolData &MSD = LocalSymbolData[i]; - WriteSymbol(Writer, MSD, Layout); - } - - for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { - ELFSymbolData &MSD = ExternalSymbolData[i]; - MCSymbolData &Data = MSD.Symbol->getData(); - assert(((Data.getFlags() & ELF_STB_Global) || - (Data.getFlags() & ELF_STB_Weak)) && - "External symbol requires STB_GLOBAL or STB_WEAK flag"); - WriteSymbol(Writer, MSD, Layout); - if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) - LastLocalSymbolIndex++; - } - - for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { - ELFSymbolData &MSD = UndefinedSymbolData[i]; - MCSymbolData &Data = MSD.Symbol->getData(); - WriteSymbol(Writer, MSD, Layout); - if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) - LastLocalSymbolIndex++; - } - - uint64_t SecEnd = OS.tell(); - SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd); - - ArrayRef ShndxIndexes = Writer.getShndxIndexes(); - if (ShndxIndexes.empty()) { - assert(SymtabShndxSectionIndex == 0); - return; - } - assert(SymtabShndxSectionIndex != 0); - - SecStart = OS.tell(); - const MCSectionELF *SymtabShndxSection = - SectionTable[SymtabShndxSectionIndex - 1]; - for (uint32_t Index : ShndxIndexes) - write(Index); - SecEnd = OS.tell(); - SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); -} - // It is always valid to create a relocation with a symbol. It is preferable // to use a relocation with a section if that is possible. Using the section // allows us to omit some local symbols from the symbol table. @@ -873,9 +801,11 @@ bool ELFObjectWriter::isLocal(const MCSymbol &Symbol, bool isUsedInReloc) { void ELFObjectWriter::computeSymbolTable( MCAssembler &Asm, const MCAsmLayout &Layout, - const SectionIndexMapTy &SectionIndexMap, - const RevGroupMapTy &RevGroupMap) { + const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap, + SectionOffsetsTy &SectionOffsets) { MCContext &Ctx = Asm.getContext(); + SymbolTableWriter Writer(*this, is64Bit()); + // Symbol table unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; MCSectionELF *SymtabSection = @@ -883,6 +813,15 @@ void ELFObjectWriter::computeSymbolTable( SymtabSection->setAlignment(is64Bit() ? 8 : 4); SymbolTableIndex = addToSectionTable(SymtabSection); + uint64_t Padding = + OffsetToAlignment(OS.tell(), SymtabSection->getAlignment()); + WriteZeros(Padding); + + uint64_t SecStart = OS.tell(); + + // The first entry is the undefined symbol entry. + Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); + // Add the data for the symbols. bool HasLargeSectionIndex = false; for (const MCSymbol &Symbol : Asm.symbols()) { @@ -1000,15 +939,6 @@ void ELFObjectWriter::computeSymbolTable( for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) FileSymbolData.push_back(StrTabBuilder.getOffset(*i)); - for (ELFSymbolData &MSD : LocalSymbolData) - MSD.StringIndex = MCELF::GetType(MSD.Symbol->getData()) == ELF::STT_SECTION - ? 0 - : StrTabBuilder.getOffset(MSD.Name); - for (ELFSymbolData &MSD : ExternalSymbolData) - MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); - for (ELFSymbolData& MSD : UndefinedSymbolData) - MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); - // Symbols are required to be in lexicographic order. array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); @@ -1017,13 +947,71 @@ void ELFObjectWriter::computeSymbolTable( // Set the symbol indices. Local symbols must come before all other // symbols with non-local bindings. unsigned Index = FileSymbolData.size() + 1; - for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) - LocalSymbolData[i].Symbol->setIndex(Index++); - for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) - ExternalSymbolData[i].Symbol->setIndex(Index++); - for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) - UndefinedSymbolData[i].Symbol->setIndex(Index++); + for (ELFSymbolData &MSD : LocalSymbolData) { + MSD.StringIndex = MCELF::GetType(MSD.Symbol->getData()) == ELF::STT_SECTION + ? 0 + : StrTabBuilder.getOffset(MSD.Name); + MSD.Symbol->setIndex(Index++); + } + for (ELFSymbolData &MSD : ExternalSymbolData) { + MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); + MSD.Symbol->setIndex(Index++); + } + for (ELFSymbolData &MSD : UndefinedSymbolData) { + MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); + MSD.Symbol->setIndex(Index++); + } + + for (unsigned i = 0, e = FileSymbolData.size(); i != e; ++i) { + Writer.writeSymbol(FileSymbolData[i], ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, + ELF::STV_DEFAULT, ELF::SHN_ABS, true); + } + + // Write the symbol table entries. + LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1; + + for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { + ELFSymbolData &MSD = LocalSymbolData[i]; + WriteSymbol(Writer, MSD, Layout); + } + + for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { + ELFSymbolData &MSD = ExternalSymbolData[i]; + MCSymbolData &Data = MSD.Symbol->getData(); + assert(((Data.getFlags() & ELF_STB_Global) || + (Data.getFlags() & ELF_STB_Weak)) && + "External symbol requires STB_GLOBAL or STB_WEAK flag"); + WriteSymbol(Writer, MSD, Layout); + if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) + LastLocalSymbolIndex++; + } + + for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { + ELFSymbolData &MSD = UndefinedSymbolData[i]; + MCSymbolData &Data = MSD.Symbol->getData(); + WriteSymbol(Writer, MSD, Layout); + if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) + LastLocalSymbolIndex++; + } + + uint64_t SecEnd = OS.tell(); + SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd); + + ArrayRef ShndxIndexes = Writer.getShndxIndexes(); + if (ShndxIndexes.empty()) { + assert(SymtabShndxSectionIndex == 0); + return; + } + assert(SymtabShndxSectionIndex != 0); + + SecStart = OS.tell(); + const MCSectionELF *SymtabShndxSection = + SectionTable[SymtabShndxSectionIndex - 1]; + for (uint32_t Index : ShndxIndexes) + write(Index); + SecEnd = OS.tell(); + SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); } MCSectionELF * @@ -1359,7 +1347,7 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, } // Compute symbol table information. - computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap); + computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, SectionOffsets); for (MCSectionELF *RelSection : Relocations) { uint64_t Padding = OffsetToAlignment(OS.tell(), RelSection->getAlignment()); @@ -1374,8 +1362,6 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm, SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd); } - writeSymbolTable(Ctx, Layout, SectionOffsets); - { uint64_t SecStart = OS.tell(); const MCSectionELF *Sec = createStringTable(Ctx); -- 2.34.1