Index: test/tools/llvm-objcopy/ELF/many-sections.test =================================================================== --- test/tools/llvm-objcopy/ELF/many-sections.test +++ test/tools/llvm-objcopy/ELF/many-sections.test @@ -3,6 +3,7 @@ RUN: llvm-readobj --file-headers %t2 | FileCheck --check-prefix=EHDR %s RUN: llvm-readobj --sections %t2 | FileCheck --check-prefix=SECS %s RUN: llvm-readobj --symbols %t2 | grep "Symbol {" | wc -l | FileCheck --check-prefix=SYMS %s +RUN: llvm-readelf -s %t2 | FileCheck %s --check-prefix=SYM_SEC_IDS EHDR: Format: ELF64-x86-64 EHDR-NEXT: Arch: x86_64 @@ -51,3 +52,11 @@ SECS-NEXT: EntrySize: 4 SECS: Index: 65287 SYMS: 65284 + +# SYM_SEC_IDS: 61423: 0000000000000000 0 NOTYPE LOCAL DEFAULT PRC[0xff01] s9 +# SYM_SEC_IDS-NEXT: 61424: 0000000000000000 0 NOTYPE LOCAL DEFAULT PRC[0xff00] s9 +# SYM_SEC_IDS-NEXT: 61425: 0000000000000000 0 NOTYPE LOCAL DEFAULT 6530 s9 +# SYM_SEC_IDS-NEXT: 61426: 0000000000000000 0 NOTYPE LOCAL DEFAULT PRC[0xff03] s9 +# SYM_SEC_IDS-NEXT: 61427: 0000000000000000 0 NOTYPE LOCAL DEFAULT PRC[0xff04] s9 +# SYM_SEC_IDS-NEXT: 61428: 0000000000000000 0 NOTYPE LOCAL DEFAULT PRC[0xff05] s9 + 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 > 0); + 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 @@ -486,22 +486,30 @@ } 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); - } - } + // Reserve proper amount of space in section index table, so we can + // layout sections correctly. We will fill the table with correct + // indexes later in fillShdnxTable. + 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; + // Fill section index table with real section indexes. This function must + // be called after assignOffsets. + 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 +1669,11 @@ assignOffsets(); + // layoutSections could have modified section indexes, so we need + // to fill the 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);