From 51e4fb6e38bdb07ccbe7c6a33ff92319772c5449 Mon Sep 17 00:00:00 2001 From: Jake Ehrlich Date: Mon, 16 Jul 2018 19:48:52 +0000 Subject: [PATCH] [llvm-objcopy] Add support for large indexes This patch is an update of an older patch that never landed (see here: https://reviews.llvm.org/D42516) Recently various users have run into this issue and it just 100% has to be solved at this point. The main difference in this patch is that I use gunzip instead of unzip which should hopefully allow tests to pass. Please review this as if it is a new patch however. I found some issues along the way and made some minor modifications. The binary used in this patch for testing (a zip file to make it small) can be found here: https://drive.google.com/file/d/1UjsnTO9edLttZibbr-2T1bJl92KEQFAO/view?usp=sharing Differential Revision: https://reviews.llvm.org/D49206 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@337204 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm-objcopy/Inputs/many-sections.o.gz | Bin 0 -> 155402 bytes test/tools/llvm-objcopy/Inputs/ungzip.py | 5 + .../tools/llvm-objcopy/auto-remove-shndx.test | 5 + test/tools/llvm-objcopy/many-sections.test | 53 +++++ test/tools/llvm-objcopy/remove-shndx.test | 7 + test/tools/llvm-objcopy/strict-no-add.test | 10 + tools/llvm-objcopy/Object.cpp | 188 ++++++++++++++++-- tools/llvm-objcopy/Object.h | 48 ++++- 8 files changed, 295 insertions(+), 21 deletions(-) create mode 100644 test/tools/llvm-objcopy/Inputs/many-sections.o.gz create mode 100644 test/tools/llvm-objcopy/Inputs/ungzip.py create mode 100644 test/tools/llvm-objcopy/auto-remove-shndx.test create mode 100644 test/tools/llvm-objcopy/many-sections.test create mode 100644 test/tools/llvm-objcopy/remove-shndx.test create mode 100644 test/tools/llvm-objcopy/strict-no-add.test diff --git a/test/tools/llvm-objcopy/Inputs/many-sections.o.gz b/test/tools/llvm-objcopy/Inputs/many-sections.o.gz new file mode 100644 index 0000000000000000000000000000000000000000..e71add0ff134e2b00801fe85638a22f8040e0d76 GIT binary patch literal 155402 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
;9 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 literal 0 HcmV?d00001 diff --git a/test/tools/llvm-objcopy/Inputs/ungzip.py b/test/tools/llvm-objcopy/Inputs/ungzip.py new file mode 100644 index 00000000000..41f858edae2 --- /dev/null +++ b/test/tools/llvm-objcopy/Inputs/ungzip.py @@ -0,0 +1,5 @@ +import gzip +import sys + +with gzip.open(sys.argv[1], 'rb') as f: + sys.stdout.write(f.read()) diff --git a/test/tools/llvm-objcopy/auto-remove-shndx.test b/test/tools/llvm-objcopy/auto-remove-shndx.test new file mode 100644 index 00000000000..54525fd208e --- /dev/null +++ b/test/tools/llvm-objcopy/auto-remove-shndx.test @@ -0,0 +1,5 @@ +# RUN: python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t +# RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t %t2 +# RUN: llvm-readobj -sections %t2 | FileCheck --check-prefix=SECS %s + +# SECS-NOT: Name: .symtab_shndx diff --git a/test/tools/llvm-objcopy/many-sections.test b/test/tools/llvm-objcopy/many-sections.test new file mode 100644 index 00000000000..29148ca01f3 --- /dev/null +++ b/test/tools/llvm-objcopy/many-sections.test @@ -0,0 +1,53 @@ +RUN: python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t +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 + +EHDR: Format: ELF64-x86-64 +EHDR-NEXT: Arch: x86_64 +EHDR-NEXT: AddressSize: 64bit +EHDR-NEXT: LoadName: +EHDR-NEXT: ElfHeader { +EHDR-NEXT: Ident { +EHDR-NEXT: Magic: (7F 45 4C 46) +EHDR-NEXT: Class: 64-bit (0x2) +EHDR-NEXT: DataEncoding: LittleEndian (0x1) +EHDR-NEXT: FileVersion: 1 +EHDR-NEXT: OS/ABI: SystemV (0x0) +EHDR-NEXT: ABIVersion: 0 +EHDR-NEXT: Unused: (00 00 00 00 00 00 00) +EHDR-NEXT: } +EHDR-NEXT: Type: Relocatable (0x1) +EHDR-NEXT: Machine: EM_X86_64 (0x3E) +EHDR-NEXT: Version: 1 +EHDR-NEXT: Entry: 0x0 +EHDR-NEXT: ProgramHeaderOffset: 0x40 +EHDR-NEXT: SectionHeaderOffset: +EHDR-NEXT: Flags [ (0x0) +EHDR-NEXT: ] +EHDR-NEXT: HeaderSize: 64 +EHDR-NEXT: ProgramHeaderEntrySize: 56 +EHDR-NEXT: ProgramHeaderCount: 0 +EHDR-NEXT: SectionHeaderEntrySize: 64 +EHDR-NEXT: SectionHeaderCount: 0 +EHDR-NEXT: StringTableSectionIndex: 65535 +EHDR-NEXT: } + +SECS: Index: 65285 +SECS-NEXT: Name: .symtab +SECS-NEXT: Type: SHT_SYMTAB +SECS: Name: .symtab_shndx +SECS-NEXT: Type: SHT_SYMTAB_SHNDX +SECS-NEXT: Flags [ (0x0) +SECS-NEXT: ] +SECS-NEXT: Address: 0x0 +SECS-NEXT: Offset: +# There should be #syms * EntrySize bytes. +SECS-NEXT: Size: 261136 +SECS-NEXT: Link: 65285 +SECS-NEXT: Info: +SECS-NEXT: AddressAlignment: 4 +SECS-NEXT: EntrySize: 4 +SECS: Index: 65287 +SYMS: 65284 diff --git a/test/tools/llvm-objcopy/remove-shndx.test b/test/tools/llvm-objcopy/remove-shndx.test new file mode 100644 index 00000000000..c20e29a7e4c --- /dev/null +++ b/test/tools/llvm-objcopy/remove-shndx.test @@ -0,0 +1,7 @@ +# This test checks to see that a .symtab_shndx section is added to any binary +# that needs it, even if the original was removed. +RUN: python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t +RUN: llvm-objcopy -R .symtab_shndx %t %t2 +RUN: llvm-readobj -sections %t2 | FileCheck %s + +CHECK: Name: .symtab_shndx ( diff --git a/test/tools/llvm-objcopy/strict-no-add.test b/test/tools/llvm-objcopy/strict-no-add.test new file mode 100644 index 00000000000..54656262d60 --- /dev/null +++ b/test/tools/llvm-objcopy/strict-no-add.test @@ -0,0 +1,10 @@ +# This test makes sure that sections added at the end that don't have symbols +# defined in them don't trigger the creation of a large index table. + +RUN: python %p/Inputs/ungzip.py %p/Inputs/many-sections.o.gz > %t.0 +RUN: cat %p/Inputs/alloc-symtab.o > %t +RUN: llvm-objcopy -R .text -R s0 -R s1 -R s2 -R s3 -R s4 -R s5 -R s6 %t.0 %t2 +RUN: llvm-objcopy -add-section=.s0=%t -add-section=.s1=%t -add-section=.s2=%t %t2 %t2 +RUN: llvm-readobj -sections %t2 | FileCheck --check-prefix=SECS %s + +SECS-NOT: Name: .symtab_shndx diff --git a/tools/llvm-objcopy/Object.cpp b/tools/llvm-objcopy/Object.cpp index f803ffe1d81..a214f0d42f6 100644 --- a/tools/llvm-objcopy/Object.cpp +++ b/tools/llvm-objcopy/Object.cpp @@ -101,6 +101,10 @@ template void ELFWriter::writeShdr(const SectionBase &Sec) { SectionVisitor::~SectionVisitor() {} +void BinarySectionWriter::visit(const SectionIndexSection &Sec) { + error("Cannot write symbol section index table '" + Sec.Name + "' "); +} + void BinarySectionWriter::visit(const SymbolTableSection &Sec) { error("Cannot write symbol table '" + Sec.Name + "' out to binary"); } @@ -154,6 +158,29 @@ void StringTableSection::accept(SectionVisitor &Visitor) const { Visitor.visit(*this); } +template +void ELFSectionWriter::visit(const SectionIndexSection &Sec) { + uint8_t *Buf = Out.getBufferStart() + Sec.Offset; + auto *IndexesBuffer = reinterpret_cast(Buf); + std::copy(std::begin(Sec.Indexes), std::end(Sec.Indexes), IndexesBuffer); +} + +void SectionIndexSection::initialize(SectionTableRef SecTable) { + Size = 0; + setSymTab(SecTable.getSectionOfType( + Link, + "Link field value " + Twine(Link) + " in section " + Name + " is invalid", + "Link field value " + Twine(Link) + " in section " + Name + + " is not a symbol table")); + Symbols->setShndxTable(this); +} + +void SectionIndexSection::finalize() { Link = Symbols->Index; } + +void SectionIndexSection::accept(SectionVisitor &Visitor) const { + Visitor.visit(*this); +} + static bool isValidReservedSectionIndex(uint16_t Index, uint16_t Machine) { switch (Index) { case SHN_ABS: @@ -172,8 +199,13 @@ static bool isValidReservedSectionIndex(uint16_t Index, uint16_t Machine) { return false; } +// Large indexes force us to clarify exactly what this function should do. This +// function should return the value that will appear in st_shndx when written +// out. uint16_t Symbol::getShndx() const { if (DefinedIn != nullptr) { + if (DefinedIn->Index >= SHN_LORESERVE) + return SHN_XINDEX; return DefinedIn->Index; } switch (ShndxType) { @@ -187,6 +219,7 @@ uint16_t Symbol::getShndx() const { case SYMBOL_HEXAGON_SCOMMON_2: case SYMBOL_HEXAGON_SCOMMON_4: case SYMBOL_HEXAGON_SCOMMON_8: + case SYMBOL_XINDEX: return static_cast(ShndxType); } llvm_unreachable("Symbol with invalid ShndxType encountered"); @@ -207,6 +240,8 @@ void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type, Sym.Binding = Bind; Sym.Type = Type; Sym.DefinedIn = DefinedIn; + if (DefinedIn != nullptr) + DefinedIn->HasSymbol = true; if (DefinedIn == nullptr) { if (Shndx >= SHN_LORESERVE) Sym.ShndxType = static_cast(Shndx); @@ -222,6 +257,8 @@ void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type, } void SymbolTableSection::removeSectionReferences(const SectionBase *Sec) { + if (SectionIndexTable == Sec) + SectionIndexTable = nullptr; if (SymbolNames == Sec) { error("String table " + SymbolNames->Name + " cannot be removed because it is referenced by the symbol table " + @@ -274,7 +311,17 @@ void SymbolTableSection::finalize() { Info = MaxLocalIndex + 1; } -void SymbolTableSection::addSymbolNames() { +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); + } + } // Add all of our strings to SymbolNames so that SymbolNames has the right // size before layout is decided. for (auto &Sym : Symbols) @@ -654,12 +701,32 @@ template void ELFBuilder::initSymbolTable(SymbolTableSection *SymTab) { const Elf_Shdr &Shdr = *unwrapOrError(ElfFile.getSection(SymTab->Index)); StringRef StrTabData = unwrapOrError(ElfFile.getStringTableForSymtab(Shdr)); + ArrayRef ShndxData; - for (const auto &Sym : unwrapOrError(ElfFile.symbols(&Shdr))) { + auto Symbols = unwrapOrError(ElfFile.symbols(&Shdr)); + for (const auto &Sym : Symbols) { SectionBase *DefSection = nullptr; StringRef Name = unwrapOrError(Sym.getName(StrTabData)); - if (Sym.st_shndx >= SHN_LORESERVE) { + if (Sym.st_shndx == SHN_XINDEX) { + if (SymTab->getShndxTable() == nullptr) + error("Symbol '" + Name + + "' has index SHN_XINDEX but no SHT_SYMTAB_SHNDX section exists."); + if (ShndxData.data() == nullptr) { + const Elf_Shdr &ShndxSec = + *unwrapOrError(ElfFile.getSection(SymTab->getShndxTable()->Index)); + ShndxData = unwrapOrError( + ElfFile.template getSectionContentsAsArray(&ShndxSec)); + if (ShndxData.size() != Symbols.size()) + error("Symbol section index table does not have the same number of " + "entries as the symbol table."); + } + Elf_Word Index = ShndxData[&Sym - Symbols.begin()]; + DefSection = Obj.sections().getSection( + Index, + "Symbol '" + Name + "' has invalid section index " + + Twine(Index)); + } else if (Sym.st_shndx >= SHN_LORESERVE) { if (!isValidReservedSectionIndex(Sym.st_shndx, Obj.Machine)) { error( "Symbol '" + Name + @@ -669,7 +736,7 @@ void ELFBuilder::initSymbolTable(SymbolTableSection *SymTab) { } else if (Sym.st_shndx != SHN_UNDEF) { DefSection = Obj.sections().getSection( Sym.st_shndx, "Symbol '" + Name + - "' is defined in invalid section with index " + + "' is defined has invalid section index " + Twine(Sym.st_shndx)); } @@ -699,14 +766,14 @@ void initRelocations(RelocationSection *Relocs, SymbolTableSection *SymbolTable, } } -SectionBase *SectionTableRef::getSection(uint16_t Index, Twine ErrMsg) { +SectionBase *SectionTableRef::getSection(uint32_t Index, Twine ErrMsg) { if (Index == SHN_UNDEF || Index > Sections.size()) error(ErrMsg); return Sections[Index - 1].get(); } template -T *SectionTableRef::getSectionOfType(uint16_t Index, Twine IndexErrMsg, +T *SectionTableRef::getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg) { if (T *Sec = dyn_cast(getSection(Index, IndexErrMsg))) return Sec; @@ -753,6 +820,11 @@ SectionBase &ELFBuilder::makeSection(const Elf_Shdr &Shdr) { Obj.SymbolTable = &SymTab; return SymTab; } + case SHT_SYMTAB_SHNDX: { + auto &ShndxSection = Obj.addSection(); + Obj.SectionIndexTable = &ShndxSection; + return ShndxSection; + } case SHT_NOBITS: return Obj.addSection
(Data); default: @@ -783,6 +855,12 @@ template void ELFBuilder::readSectionHeaders() { Sec.Index = Index++; } + // If a section index table exists we'll need to initialize it before we + // initialize the symbol table because the symbol table might need to + // reference it. + if (Obj.SectionIndexTable) + Obj.SectionIndexTable->initialize(Obj.sections()); + // Now that all of the sections have been added we can fill out some extra // details about symbol tables. We need the symbol table filled out before // any relocations. @@ -825,9 +903,13 @@ template void ELFBuilder::build() { readSectionHeaders(); readProgramHeaders(); + uint32_t ShstrIndex = Ehdr.e_shstrndx; + if (ShstrIndex == SHN_XINDEX) + ShstrIndex = unwrapOrError(ElfFile.getSection(0))->sh_link; + Obj.SectionNames = Obj.sections().template getSectionOfType( - Ehdr.e_shstrndx, + ShstrIndex, "e_shstrndx field value " + Twine(Ehdr.e_shstrndx) + " in elf header " + " is invalid", "e_shstrndx field value " + Twine(Ehdr.e_shstrndx) + @@ -893,8 +975,27 @@ template void ELFWriter::writeEhdr() { Ehdr.e_shentsize = sizeof(Elf_Shdr); if (WriteSectionHeaders) { Ehdr.e_shoff = Obj.SHOffset; - Ehdr.e_shnum = size(Obj.sections()) + 1; - Ehdr.e_shstrndx = Obj.SectionNames->Index; + // """ + // If the number of sections is greater than or equal to + // SHN_LORESERVE (0xff00), this member has the value zero and the actual + // number of section header table entries is contained in the sh_size field + // of the section header at index 0. + // """ + auto Shnum = size(Obj.sections()) + 1; + if (Shnum >= SHN_LORESERVE) + Ehdr.e_shnum = 0; + else + Ehdr.e_shnum = Shnum; + // """ + // If the section name string table section index is greater than or equal + // to SHN_LORESERVE (0xff00), this member has the value SHN_XINDEX (0xffff) + // and the actual index of the section name string table section is + // contained in the sh_link field of the section header at index 0. + // """ + if (Obj.SectionNames->Index >= SHN_LORESERVE) + Ehdr.e_shstrndx = SHN_XINDEX; + else + Ehdr.e_shstrndx = Obj.SectionNames->Index; } else { Ehdr.e_shoff = 0; Ehdr.e_shnum = 0; @@ -917,8 +1018,17 @@ template void ELFWriter::writeShdrs() { Shdr.sh_flags = 0; Shdr.sh_addr = 0; Shdr.sh_offset = 0; - Shdr.sh_size = 0; - Shdr.sh_link = 0; + // See writeEhdr for why we do this. + uint64_t Shnum = size(Obj.sections()) + 1; + if (Shnum >= SHN_LORESERVE) + Shdr.sh_size = Shnum; + else + Shdr.sh_size = 0; + // See writeEhdr for why we do this. + if (Obj.SectionNames != nullptr && Obj.SectionNames->Index >= SHN_LORESERVE) + Shdr.sh_link = Obj.SectionNames->Index; + else + Shdr.sh_link = 0; Shdr.sh_info = 0; Shdr.sh_addralign = 0; Shdr.sh_entsize = 0; @@ -946,9 +1056,10 @@ void Object::removeSections(std::function ToRemove) { }); if (SymbolTable != nullptr && ToRemove(*SymbolTable)) SymbolTable = nullptr; - if (SectionNames != nullptr && ToRemove(*SectionNames)) { + if (SectionNames != nullptr && ToRemove(*SectionNames)) SectionNames = nullptr; - } + if (SectionIndexTable != nullptr && ToRemove(*SectionIndexTable)) + SectionIndexTable = nullptr; // Now make sure there are no remaining references to the sections that will // be removed. Sometimes it is impossible to remove a reference so we emit // an error here instead. @@ -1109,16 +1220,59 @@ template void ELFWriter::finalize() { error("Cannot write section header table because section header string " "table was removed."); - // Make sure we add the names of all the sections. + Obj.sortSections(); + + // We need to assign indexes before we perform layout because we need to know + // if we need large indexes or not. We can assign indexes first and check as + // we go to see if we will actully need large indexes. + bool NeedsLargeIndexes = false; + if (size(Obj.sections()) >= SHN_LORESERVE) { + auto Sections = Obj.sections(); + NeedsLargeIndexes = + std::any_of(Sections.begin() + SHN_LORESERVE, Sections.end(), + [](const SectionBase &Sec) { return Sec.HasSymbol; }); + // TODO: handle case where only one section needs the large index table but + // only needs it because the large index table hasn't been removed yet. + } + + if (NeedsLargeIndexes) { + // This means we definitely need to have a section index table but if we + // already have one then we should use it instead of making a new one. + if (Obj.SymbolTable != nullptr && Obj.SectionIndexTable == nullptr) { + // Addition of a section to the end does not invalidate the indexes of + // other sections and assigns the correct index to the new section. + auto &Shndx = Obj.addSection(); + Obj.SymbolTable->setShndxTable(&Shndx); + Shndx.setSymTab(Obj.SymbolTable); + } + } else { + // Since we don't need SectionIndexTable we should remove it and all + // references to it. + if (Obj.SectionIndexTable != nullptr) { + Obj.removeSections([this](const SectionBase &Sec) { + return &Sec == Obj.SectionIndexTable; + }); + } + } + + // Make sure we add the names of all the sections. Importantly this must be + // done after we decide to add or remove SectionIndexes. if (Obj.SectionNames != nullptr) for (const auto &Section : Obj.sections()) { Obj.SectionNames->addString(Section.Name); } - // Make sure we add the names of all the symbols. + + // Before we can prepare for layout the indexes need to be finalized. + uint64_t Index = 0; + for (auto &Sec : Obj.sections()) + Sec.Index = Index++; + + // The symbol table does not update all other sections on update. For + // instance, symbol names are not added as new symbols are added. This means + // that some sections, like .strtab, don't yet have their final size. if (Obj.SymbolTable != nullptr) - Obj.SymbolTable->addSymbolNames(); + Obj.SymbolTable->prepareForLayout(); - Obj.sortSections(); assignOffsets(); // Finalize SectionNames first so that we can assign name indexes. diff --git a/tools/llvm-objcopy/Object.h b/tools/llvm-objcopy/Object.h index 2e20b5b299f..b8f45a431e1 100644 --- a/tools/llvm-objcopy/Object.h +++ b/tools/llvm-objcopy/Object.h @@ -37,6 +37,7 @@ class RelocationSection; class DynamicRelocationSection; class GnuDebugLinkSection; class GroupSection; +class SectionIndexSection; class Segment; class Object; struct Symbol; @@ -54,10 +55,10 @@ public: iterator begin() { return iterator(Sections.data()); } iterator end() { return iterator(Sections.data() + Sections.size()); } - SectionBase *getSection(uint16_t Index, Twine ErrMsg); + SectionBase *getSection(uint32_t Index, Twine ErrMsg); template - T *getSectionOfType(uint16_t Index, Twine IndexErrMsg, Twine TypeErrMsg); + T *getSectionOfType(uint32_t Index, Twine IndexErrMsg, Twine TypeErrMsg); }; enum ElfType { ELFT_ELF32LE, ELFT_ELF64LE, ELFT_ELF32BE, ELFT_ELF64BE }; @@ -74,6 +75,7 @@ public: virtual void visit(const DynamicRelocationSection &Sec) = 0; virtual void visit(const GnuDebugLinkSection &Sec) = 0; virtual void visit(const GroupSection &Sec) = 0; + virtual void visit(const SectionIndexSection &Sec) = 0; }; class SectionWriter : public SectionVisitor { @@ -91,6 +93,7 @@ public: virtual void visit(const RelocationSection &Sec) override = 0; virtual void visit(const GnuDebugLinkSection &Sec) override = 0; virtual void visit(const GroupSection &Sec) override = 0; + virtual void visit(const SectionIndexSection &Sec) override = 0; explicit SectionWriter(Buffer &Buf) : Out(Buf) {} }; @@ -107,6 +110,7 @@ public: void visit(const RelocationSection &Sec) override; void visit(const GnuDebugLinkSection &Sec) override; void visit(const GroupSection &Sec) override; + void visit(const SectionIndexSection &Sec) override; explicit ELFSectionWriter(Buffer &Buf) : SectionWriter(Buf) {} }; @@ -123,6 +127,7 @@ public: void visit(const RelocationSection &Sec) override; void visit(const GnuDebugLinkSection &Sec) override; void visit(const GroupSection &Sec) override; + void visit(const SectionIndexSection &Sec) override; explicit BinarySectionWriter(Buffer &Buf) : SectionWriter(Buf) {} }; @@ -230,8 +235,9 @@ public: StringRef Name; Segment *ParentSegment = nullptr; uint64_t HeaderOffset; - uint64_t OriginalOffset; + uint64_t OriginalOffset = std::numeric_limits::max(); uint32_t Index; + bool HasSymbol = false; uint64_t Addr = 0; uint64_t Align = 1; @@ -371,6 +377,7 @@ enum SymbolShndxType { SYMBOL_HEXAGON_SCOMMON_2 = ELF::SHN_HEXAGON_SCOMMON_2, SYMBOL_HEXAGON_SCOMMON_4 = ELF::SHN_HEXAGON_SCOMMON_4, SYMBOL_HEXAGON_SCOMMON_8 = ELF::SHN_HEXAGON_SCOMMON_8, + SYMBOL_XINDEX = ELF::SHN_XINDEX, }; struct Symbol { @@ -389,6 +396,32 @@ struct Symbol { uint16_t getShndx() const; }; +class SectionIndexSection : public SectionBase { + MAKE_SEC_WRITER_FRIEND + +private: + std::vector Indexes; + SymbolTableSection *Symbols = nullptr; + +public: + virtual ~SectionIndexSection() {} + void addIndex(uint32_t Index) { + Indexes.push_back(Index); + Size += 4; + } + void setSymTab(SymbolTableSection *SymTab) { Symbols = SymTab; } + void initialize(SectionTableRef SecTable) override; + void finalize() override; + void accept(SectionVisitor &Visitor) const override; + + SectionIndexSection() { + Name = ".symtab_shndx"; + Align = 4; + EntrySize = 4; + Type = ELF::SHT_SYMTAB_SHNDX; + } +}; + class SymbolTableSection : public SectionBase { MAKE_SEC_WRITER_FRIEND @@ -398,6 +431,7 @@ class SymbolTableSection : public SectionBase { protected: std::vector> Symbols; StringTableSection *SymbolNames = nullptr; + SectionIndexSection *SectionIndexTable = nullptr; using SymPtr = std::unique_ptr; @@ -405,9 +439,13 @@ public: void addSymbol(StringRef Name, uint8_t Bind, uint8_t Type, SectionBase *DefinedIn, uint64_t Value, uint8_t Visibility, uint16_t Shndx, uint64_t Sz); - void addSymbolNames(); + void prepareForLayout(); // An 'empty' symbol table still contains a null symbol. bool empty() const { return Symbols.size() == 1; } + void setShndxTable(SectionIndexSection *ShndxTable) { + SectionIndexTable = ShndxTable; + } + const SectionIndexSection *getShndxTable() const { return SectionIndexTable; } const SectionBase *getStrTab() const { return SymbolNames; } const Symbol *getSymbolByIndex(uint32_t Index) const; Symbol *getSymbolByIndex(uint32_t Index); @@ -589,6 +627,7 @@ private: using Elf_Addr = typename ELFT::Addr; using Elf_Shdr = typename ELFT::Shdr; using Elf_Ehdr = typename ELFT::Ehdr; + using Elf_Word = typename ELFT::Word; const ELFFile &ElfFile; Object &Obj; @@ -652,6 +691,7 @@ public: StringTableSection *SectionNames = nullptr; SymbolTableSection *SymbolTable = nullptr; + SectionIndexSection *SectionIndexTable = nullptr; void sortSections(); SectionTableRef sections() { return SectionTableRef(Sections); } -- 2.50.1