From ae2e11429b9c23c1f35a6478f44e564d52534c8b Mon Sep 17 00:00:00 2001 From: Eugene Leviant Date: Fri, 12 Apr 2019 11:59:30 +0000 Subject: [PATCH] [llvm-objcopy] Fill .symtab_shndx section correctly Differential revision: https://reviews.llvm.org/D60555 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@358278 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../tools/llvm-objcopy/ELF/many-sections.test | 50 +++++++++++++++++++ tools/llvm-objcopy/ELF/Object.cpp | 33 ++++++++---- tools/llvm-objcopy/ELF/Object.h | 10 +++- 3 files changed, 81 insertions(+), 12 deletions(-) diff --git a/test/tools/llvm-objcopy/ELF/many-sections.test b/test/tools/llvm-objcopy/ELF/many-sections.test index 1dd41cfb10c..6fed22a9800 100644 --- a/test/tools/llvm-objcopy/ELF/many-sections.test +++ b/test/tools/llvm-objcopy/ELF/many-sections.test @@ -3,6 +3,7 @@ RUN: llvm-objcopy %t %t2 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-readobj -symbols %t2 | FileCheck %s --check-prefix=SYM_SEC_IDS EHDR: Format: ELF64-x86-64 EHDR-NEXT: Arch: x86_64 @@ -51,3 +52,52 @@ SECS-NEXT: AddressAlignment: 4 SECS-NEXT: EntrySize: 4 SECS: Index: 65287 SYMS: 65284 + +SYM_SEC_IDS: Section: s9 (0xFEFF) +SYM_SEC_IDS-NEXT: } +SYM_SEC_IDS-NEXT: Symbol { +SYM_SEC_IDS-NEXT: Name: s9 (37) +SYM_SEC_IDS-NEXT: Value: 0x0 +SYM_SEC_IDS-NEXT: Size: 0 +SYM_SEC_IDS-NEXT: Binding: Local (0x0) +SYM_SEC_IDS-NEXT: Type: None (0x0) +SYM_SEC_IDS-NEXT: Other: 0 +SYM_SEC_IDS-NEXT: Section: s9 (0xFF01) +SYM_SEC_IDS-NEXT: } +SYM_SEC_IDS-NEXT: Symbol { +SYM_SEC_IDS-NEXT: Name: s9 (37) +SYM_SEC_IDS-NEXT: Value: 0x0 +SYM_SEC_IDS-NEXT: Size: 0 +SYM_SEC_IDS-NEXT: Binding: Local (0x0) +SYM_SEC_IDS-NEXT: Type: None (0x0) +SYM_SEC_IDS-NEXT: Other: 0 +SYM_SEC_IDS-NEXT: Section: s9 (0xFF00) +SYM_SEC_IDS-NEXT: } +SYM_SEC_IDS-NEXT: Symbol { +SYM_SEC_IDS-NEXT: Name: s9 (37) +SYM_SEC_IDS-NEXT: Value: 0x0 +SYM_SEC_IDS-NEXT: Size: 0 +SYM_SEC_IDS-NEXT: Binding: Local (0x0) +SYM_SEC_IDS-NEXT: Type: None (0x0) +SYM_SEC_IDS-NEXT: Other: 0 +SYM_SEC_IDS-NEXT: Section: s9 (0x1982) +SYM_SEC_IDS-NEXT: } +SYM_SEC_IDS-NEXT: Symbol { +SYM_SEC_IDS-NEXT: Name: s9 (37) +SYM_SEC_IDS-NEXT: Value: 0x0 +SYM_SEC_IDS-NEXT: Size: 0 +SYM_SEC_IDS-NEXT: Binding: Local (0x0) +SYM_SEC_IDS-NEXT: Type: None (0x0) +SYM_SEC_IDS-NEXT: Other: 0 +SYM_SEC_IDS-NEXT: Section: s9 (0xFF03) +SYM_SEC_IDS-NEXT: } +SYM_SEC_IDS-NEXT: Symbol { +SYM_SEC_IDS-NEXT: Name: s9 (37) +SYM_SEC_IDS-NEXT: Value: 0x0 +SYM_SEC_IDS-NEXT: Size: 0 +SYM_SEC_IDS-NEXT: Binding: Local (0x0) +SYM_SEC_IDS-NEXT: Type: None (0x0) +SYM_SEC_IDS-NEXT: Other: 0 +SYM_SEC_IDS-NEXT: Section: s9 (0xFF04) +SYM_SEC_IDS-NEXT: } + diff --git a/tools/llvm-objcopy/ELF/Object.cpp b/tools/llvm-objcopy/ELF/Object.cpp index de51851ecfe..979ab0a2163 100644 --- a/tools/llvm-objcopy/ELF/Object.cpp +++ b/tools/llvm-objcopy/ELF/Object.cpp @@ -486,22 +486,30 @@ void SymbolTableSection::finalize() { } 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 @@ template Error ELFWriter::finalize() { 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); diff --git a/tools/llvm-objcopy/ELF/Object.h b/tools/llvm-objcopy/ELF/Object.h index 4e0e23e5f49..31e2c652a8d 100644 --- a/tools/llvm-objcopy/ELF/Object.h +++ b/tools/llvm-objcopy/ELF/Object.h @@ -481,9 +481,14 @@ private: 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 @@ public: 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); -- 2.50.1