Index: tools/llvm-objcopy/ELF/Object.h =================================================================== --- tools/llvm-objcopy/ELF/Object.h +++ tools/llvm-objcopy/ELF/Object.h @@ -481,9 +481,14 @@ public: virtual ~SectionIndexSection() {} void addIndex(uint32_t Index) { - Indexes.push_back(Index); - Size += 4; + assert(Size); + Indexes.push_back(Index); } + + void reserve(size_t NumSymbols) { + Indexes.reserve(NumSymbols); + Size = NumSymbols * 4; + } void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; } void initialize(SectionTableRef SecTable) override; void finalize() override; @@ -524,6 +529,7 @@ SectionIndexTable = ShndxTable; } const SectionIndexSection *getShndxTable() const { return SectionIndexTable; } + void fillShndxTable(); const SectionBase *getStrTab() const { return SymbolNames; } const Symbol *getSymbolByIndex(uint32_t Index) const; Symbol *getSymbolByIndex(uint32_t Index); Index: tools/llvm-objcopy/ELF/Object.cpp =================================================================== --- tools/llvm-objcopy/ELF/Object.cpp +++ tools/llvm-objcopy/ELF/Object.cpp @@ -488,20 +488,25 @@ void SymbolTableSection::prepareForLayout() { // Add all potential section indexes before file layout so that the section // index section has the approprite size. - if (SectionIndexTable != nullptr) { - for (const auto &Sym : Symbols) { - if (Sym->DefinedIn != nullptr && Sym->DefinedIn->Index >= SHN_LORESERVE) - SectionIndexTable->addIndex(Sym->DefinedIn->Index); - else - SectionIndexTable->addIndex(SHN_UNDEF); - } - } + if (SectionIndexTable) + SectionIndexTable->reserve(Symbols.size()); // Add all of our strings to SymbolNames so that SymbolNames has the right // size before layout is decided. for (auto &Sym : Symbols) SymbolNames->addString(Sym->Name); } +void SymbolTableSection::fillShndxTable() { + if (SectionIndexTable == nullptr) + return; + for (const auto &Sym : Symbols) { + if (Sym->DefinedIn != nullptr && Sym->DefinedIn->Index >= SHN_LORESERVE) + SectionIndexTable->addIndex(Sym->DefinedIn->Index); + else + SectionIndexTable->addIndex(SHN_UNDEF); + } +} + const Symbol *SymbolTableSection::getSymbolByIndex(uint32_t Index) const { if (Symbols.size() <= Index) error("Invalid symbol index: " + Twine(Index)); @@ -1661,6 +1666,11 @@ assignOffsets(); + // layoutSections could have modified section indexes, that why we need + // to fill index table after assignOffsets. + if (Obj.SymbolTable != nullptr) + Obj.SymbolTable->fillShndxTable(); + // Finally now that all offsets and indexes have been set we can finalize any // remaining issues. uint64_t Offset = Obj.SHOffset + sizeof(Elf_Shdr);