diff options
author | Jake Ehrlich <jakehehrlich@google.com> | 2018-03-07 19:59:15 +0000 |
---|---|---|
committer | Jake Ehrlich <jakehehrlich@google.com> | 2018-03-07 19:59:15 +0000 |
commit | 0a151bd6efbf528026cba0786897cb0a60f63e8c (patch) | |
tree | cf4a8b060978c201722b965cde156f5ecc1da5f0 /llvm/tools/llvm-objcopy/Object.h | |
parent | 80ec0c3106fc3e35588b6a32a3f026f49634477c (diff) | |
download | bcm5719-llvm-0a151bd6efbf528026cba0786897cb0a60f63e8c.tar.gz bcm5719-llvm-0a151bd6efbf528026cba0786897cb0a60f63e8c.zip |
[llvm-objcopy] Add support for large indexes
Because of -ffunction-sections (and maybe other use cases I'm not aware of?) it
can occur that we need more than 0xfeff sections but ELF dosn't support that
many sections. To solve this problem SHN_XINDEX exists and with it come a whole
host of changes for section indexes everywhere. This change adds support for
those cases which should allow llvm-objcopy to copy binaries that have an
arbitrary number of sections.
Differential Revision: https://reviews.llvm.org/D42516
llvm-svn: 326940
Diffstat (limited to 'llvm/tools/llvm-objcopy/Object.h')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index 27beafc0ce6..5b99b8b2be2 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -35,6 +35,7 @@ class SymbolTableSection; class RelocationSection; class DynamicRelocationSection; class GnuDebugLinkSection; +class SectionIndexSection; class Segment; class Object; @@ -52,10 +53,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 <class T> - 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 }; @@ -71,6 +72,7 @@ public: virtual void visit(const RelocationSection &Sec) = 0; virtual void visit(const DynamicRelocationSection &Sec) = 0; virtual void visit(const GnuDebugLinkSection &Sec) = 0; + virtual void visit(const SectionIndexSection &Sec) = 0; }; class SectionWriter : public SectionVisitor { @@ -87,6 +89,7 @@ public: virtual void visit(const SymbolTableSection &Sec) override = 0; virtual void visit(const RelocationSection &Sec) override = 0; virtual void visit(const GnuDebugLinkSection &Sec) override = 0; + virtual void visit(const SectionIndexSection &Sec) override = 0; SectionWriter(FileOutputBuffer &Buf) : Out(Buf) {} }; @@ -102,6 +105,7 @@ public: void visit(const SymbolTableSection &Sec) override; void visit(const RelocationSection &Sec) override; void visit(const GnuDebugLinkSection &Sec) override; + void visit(const SectionIndexSection &Sec) override; ELFSectionWriter(FileOutputBuffer &Buf) : SectionWriter(Buf) {} }; @@ -117,6 +121,7 @@ public: void visit(const SymbolTableSection &Sec) override; void visit(const RelocationSection &Sec) override; void visit(const GnuDebugLinkSection &Sec) override; + void visit(const SectionIndexSection &Sec) override; BinarySectionWriter(FileOutputBuffer &Buf) : SectionWriter(Buf) {} }; @@ -187,6 +192,7 @@ public: uint64_t HeaderOffset; uint64_t OriginalOffset; uint32_t Index; + bool HasSymbol = false; uint64_t Addr = 0; uint64_t Align = 1; @@ -323,6 +329,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 { @@ -340,6 +347,33 @@ struct Symbol { uint16_t getShndx() const; }; +class SectionIndexSection : public SectionBase { + MAKE_SEC_WRITER_FRIEND + +private: + std::vector<uint32_t> Indexes; + SymbolTableSection *Symbols; + +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"; + OriginalOffset = std::numeric_limits<uint64_t>::max(); + Align = 4; + EntrySize = 4; + Type = ELF::SHT_SYMTAB_SHNDX; + } +}; + class SymbolTableSection : public SectionBase { MAKE_SEC_WRITER_FRIEND @@ -348,6 +382,7 @@ class SymbolTableSection : public SectionBase { protected: std::vector<std::unique_ptr<Symbol>> Symbols; StringTableSection *SymbolNames = nullptr; + SectionIndexSection *SectionIndexTable = nullptr; using SymPtr = std::unique_ptr<Symbol>; @@ -355,7 +390,9 @@ 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(); + void setShndxTable(SectionIndexSection *ShndxTable) { SectionIndexTable = ShndxTable; } + const SectionBase *getShndxTable() const { return SectionIndexTable; } const SectionBase *getStrTab() const { return SymbolNames; } const Symbol *getSymbolByIndex(uint32_t Index) const; void removeSectionReferences(const SectionBase *Sec) override; @@ -516,6 +553,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<ELFT> &ElfFile; Object &Obj; @@ -581,6 +619,7 @@ public: StringTableSection *SectionNames = nullptr; SymbolTableSection *SymbolTable = nullptr; + SectionIndexSection *SectionIndexTable = nullptr; Object(std::shared_ptr<MemoryBuffer> Data) : OwnedData(Data) {} virtual ~Object() = default; |