summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/Object.h
diff options
context:
space:
mode:
authorJake Ehrlich <jakehehrlich@google.com>2018-03-07 19:59:15 +0000
committerJake Ehrlich <jakehehrlich@google.com>2018-03-07 19:59:15 +0000
commit0a151bd6efbf528026cba0786897cb0a60f63e8c (patch)
treecf4a8b060978c201722b965cde156f5ecc1da5f0 /llvm/tools/llvm-objcopy/Object.h
parent80ec0c3106fc3e35588b6a32a3f026f49634477c (diff)
downloadbcm5719-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.h45
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;
OpenPOWER on IntegriCloud