diff options
author | Jake Ehrlich <jakehehrlich@google.com> | 2017-10-10 18:47:09 +0000 |
---|---|---|
committer | Jake Ehrlich <jakehehrlich@google.com> | 2017-10-10 18:47:09 +0000 |
commit | 36a2eb34ed394b7277df6ef9b935bfe2be3402b8 (patch) | |
tree | 876ae8d0fd21d2494acbb401953c66431e5e7a64 /llvm/tools/llvm-objcopy/Object.h | |
parent | c5ff72708d232079e1c2099165584cf8d03e1c7e (diff) | |
download | bcm5719-llvm-36a2eb34ed394b7277df6ef9b935bfe2be3402b8.tar.gz bcm5719-llvm-36a2eb34ed394b7277df6ef9b935bfe2be3402b8.zip |
[llvm-objcopy] Add support for removing sections
This change adds support for removing sections using the -R field (as
GNU objcopy does as well). This change should let us add many helpful
tests and is a proper stepping stone for adding more general kinds of
stripping.
Differential Revision: https://reviews.llvm.org/D38260
llvm-svn: 315346
Diffstat (limited to 'llvm/tools/llvm-objcopy/Object.h')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 48 |
1 files changed, 42 insertions, 6 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index 398eed7e16c..3def0930a94 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -58,6 +58,7 @@ public: virtual ~SectionBase() {} virtual void initialize(SectionTableRef SecTable); virtual void finalize(); + virtual void removeSectionReferences(const SectionBase *Sec); template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const; virtual void writeSection(llvm::FileOutputBuffer &Out) const = 0; }; @@ -98,7 +99,8 @@ public: return *Sections.begin(); return nullptr; } - void addSection(const SectionBase *sec) { Sections.insert(sec); } + void removeSection(const SectionBase *Sec) { Sections.erase(Sec); } + void addSection(const SectionBase *Sec) { Sections.insert(Sec); } template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const; void writeSegment(llvm::FileOutputBuffer &Out) const; }; @@ -164,6 +166,8 @@ protected: std::vector<std::unique_ptr<Symbol>> Symbols; StringTableSection *SymbolNames = nullptr; + typedef std::unique_ptr<Symbol> SymPtr; + public: void setStrTab(StringTableSection *StrTab) { SymbolNames = StrTab; } void addSymbol(llvm::StringRef Name, uint8_t Bind, uint8_t Type, @@ -171,6 +175,7 @@ public: uint64_t Sz); void addSymbolNames(); const Symbol *getSymbolByIndex(uint32_t Index) const; + void removeSectionReferences(const SectionBase *Sec) override; void initialize(SectionTableRef SecTable) override; void finalize() override; static bool classof(const SectionBase *S) { @@ -190,20 +195,49 @@ struct Relocation { uint32_t Type; }; -template <class SymTabType> class RelocationSectionBase : public SectionBase { +// All relocation sections denote relocations to apply to another section. +// However, some relocation sections use a dynamic symbol table and others use +// a regular symbol table. Because the types of the two symbol tables differ in +// our system (because they should behave differently) we can't uniformly +// represent all relocations with the same base class if we expose an interface +// that mentions the symbol table type. So we split the two base types into two +// different classes, one which handles the section the relocation is applied to +// and another which handles the symbol table type. The symbol table type is +// taken as a type parameter to the class (see RelocSectionWithSymtabBase). +class RelocationSectionBase : public SectionBase { +protected: + SectionBase *SecToApplyRel = nullptr; + +public: + const SectionBase *getSection() const { return SecToApplyRel; } + void setSection(SectionBase *Sec) { SecToApplyRel = Sec; } + + static bool classof(const SectionBase *S) { + return S->Type == llvm::ELF::SHT_REL || S->Type == llvm::ELF::SHT_RELA; + } +}; + +// Takes the symbol table type to use as a parameter so that we can deduplicate +// that code between the two symbol table types. +template <class SymTabType> +class RelocSectionWithSymtabBase : public RelocationSectionBase { private: SymTabType *Symbols = nullptr; - SectionBase *SecToApplyRel = nullptr; + +protected: + RelocSectionWithSymtabBase() {} public: void setSymTab(SymTabType *StrTab) { Symbols = StrTab; } - void setSection(SectionBase *Sec) { SecToApplyRel = Sec; } + + void removeSectionReferences(const SectionBase *Sec) override; void initialize(SectionTableRef SecTable) override; void finalize() override; }; template <class ELFT> -class RelocationSection : public RelocationSectionBase<SymbolTableSection> { +class RelocationSection + : public RelocSectionWithSymtabBase<SymbolTableSection> { private: typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; @@ -230,6 +264,7 @@ private: public: SectionWithStrTab(llvm::ArrayRef<uint8_t> Data) : Section(Data) {} void setStrTab(StringTableSection *StringTable) { StrTab = StringTable; } + void removeSectionReferences(const SectionBase *Sec) override; void initialize(SectionTableRef SecTable) override; void finalize() override; static bool classof(const SectionBase *S); @@ -253,7 +288,7 @@ public: }; class DynamicRelocationSection - : public RelocationSectionBase<DynamicSymbolTableSection> { + : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> { private: llvm::ArrayRef<uint8_t> Contents; @@ -304,6 +339,7 @@ public: uint32_t Flags; Object(const llvm::object::ELFObjectFile<ELFT> &Obj); + void removeSections(std::function<bool(const SectionBase &)> ToRemove); virtual size_t totalSize() const = 0; virtual void finalize() = 0; virtual void write(llvm::FileOutputBuffer &Out) const = 0; |