summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-objcopy/Object.h
diff options
context:
space:
mode:
authorJake Ehrlich <jakehehrlich@google.com>2017-10-10 18:47:09 +0000
committerJake Ehrlich <jakehehrlich@google.com>2017-10-10 18:47:09 +0000
commit36a2eb34ed394b7277df6ef9b935bfe2be3402b8 (patch)
tree876ae8d0fd21d2494acbb401953c66431e5e7a64 /llvm/tools/llvm-objcopy/Object.h
parentc5ff72708d232079e1c2099165584cf8d03e1c7e (diff)
downloadbcm5719-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.h48
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;
OpenPOWER on IntegriCloud