diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 77 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 48 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 9 |
3 files changed, 10 insertions, 124 deletions
diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index bb79e4269d4..3e6606f7095 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -37,7 +37,6 @@ void Segment::writeSegment(FileOutputBuffer &Out) const { std::copy(std::begin(Contents), std::end(Contents), Buf); } -void SectionBase::removeSectionReferences(const SectionBase *Sec) {} void SectionBase::initialize(SectionTableRef SecTable) {} void SectionBase::finalize() {} @@ -139,19 +138,6 @@ void SymbolTableSection::addSymbol(StringRef Name, uint8_t Bind, uint8_t Type, Size += this->EntrySize; } -void SymbolTableSection::removeSectionReferences(const SectionBase *Sec) { - if (SymbolNames == Sec) { - error("String table " + SymbolNames->Name + - " cannot be removed because it is referenced by the symbol table " + - this->Name); - } - auto Iter = - std::remove_if(std::begin(Symbols), std::end(Symbols), - [=](const SymPtr &Sym) { return Sym->DefinedIn == Sec; }); - Size -= (std::end(Symbols) - Iter) * this->EntrySize; - Symbols.erase(Iter, std::end(Symbols)); -} - void SymbolTableSection::initialize(SectionTableRef SecTable) { Size = 0; setStrTab(SecTable.getSectionOfType<StringTableSection>( @@ -209,19 +195,7 @@ void SymbolTableSectionImpl<ELFT>::writeSection( } template <class SymTabType> -void RelocSectionWithSymtabBase<SymTabType>::removeSectionReferences( - const SectionBase *Sec) { - if (Symbols == Sec) { - error("Symbol table " + Symbols->Name + " cannot be removed because it is " - "referenced by the relocation " - "section " + - this->Name); - } -} - -template <class SymTabType> -void RelocSectionWithSymtabBase<SymTabType>::initialize( - SectionTableRef SecTable) { +void RelocationSectionBase<SymTabType>::initialize(SectionTableRef SecTable) { setSymTab(SecTable.getSectionOfType<SymTabType>( Link, "Link field value " + Twine(Link) + " in section " + Name + " is invalid", @@ -236,8 +210,7 @@ void RelocSectionWithSymtabBase<SymTabType>::initialize( setSection(nullptr); } -template <class SymTabType> -void RelocSectionWithSymtabBase<SymTabType>::finalize() { +template <class SymTabType> void RelocationSectionBase<SymTabType>::finalize() { this->Link = Symbols->Index; if (SecToApplyRel != nullptr) this->Info = SecToApplyRel->Index; @@ -276,14 +249,6 @@ void DynamicRelocationSection::writeSection(llvm::FileOutputBuffer &Out) const { Out.getBufferStart() + Offset); } -void SectionWithStrTab::removeSectionReferences(const SectionBase *Sec) { - if (StrTab == Sec) { - error("String table " + StrTab->Name + " cannot be removed because it is " - "referenced by the section " + - this->Name); - } -} - bool SectionWithStrTab::classof(const SectionBase *S) { return isa<DynamicSymbolTableSection>(S) || isa<DynamicSection>(S); } @@ -624,41 +589,6 @@ void Object<ELFT>::writeSectionData(FileOutputBuffer &Out) const { Section->writeSection(Out); } -template <class ELFT> -void Object<ELFT>::removeSections( - std::function<bool(const SectionBase &)> ToRemove) { - - auto Iter = std::stable_partition( - std::begin(Sections), std::end(Sections), [=](const SecPtr &Sec) { - if (ToRemove(*Sec)) - return false; - if (auto RelSec = dyn_cast<RelocationSectionBase>(Sec.get())) - return !ToRemove(*RelSec->getSection()); - return true; - }); - if (SymbolTable != nullptr && ToRemove(*SymbolTable)) - SymbolTable = nullptr; - if (ToRemove(*SectionNames)) { - // Right now llvm-objcopy always outputs section headers. This will not - // always be the case. Eventully the section header table will become - // optional and if no section header is output then there dosn't need to be - // a section header string table. - error("Cannot remove " + SectionNames->Name + - " because it is the section header string table."); - } - // 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. - for (auto &RemoveSec : make_range(Iter, std::end(Sections))) { - for (auto &Segment : Segments) - Segment->removeSection(RemoveSec.get()); - for (auto &KeepSec : make_range(std::begin(Sections), Iter)) - KeepSec->removeSectionReferences(RemoveSec.get()); - } - // Now finally get rid of them all togethor. - Sections.erase(Iter, std::end(Sections)); -} - template <class ELFT> void ELFObject<ELFT>::sortSections() { // Put all sections in offset order. Maintain the ordering as closely as // possible while meeting that demand however. @@ -762,8 +692,7 @@ template <class ELFT> void ELFObject<ELFT>::finalize() { this->SectionNames->addString(Section->Name); } // Make sure we add the names of all the symbols. - if (this->SymbolTable != nullptr) - this->SymbolTable->addSymbolNames(); + this->SymbolTable->addSymbolNames(); sortSections(); assignOffsets(); diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index 3def0930a94..398eed7e16c 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -58,7 +58,6 @@ 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; }; @@ -99,8 +98,7 @@ public: return *Sections.begin(); return nullptr; } - void removeSection(const SectionBase *Sec) { Sections.erase(Sec); } - void addSection(const SectionBase *Sec) { Sections.insert(Sec); } + void addSection(const SectionBase *sec) { Sections.insert(sec); } template <class ELFT> void writeHeader(llvm::FileOutputBuffer &Out) const; void writeSegment(llvm::FileOutputBuffer &Out) const; }; @@ -166,8 +164,6 @@ 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, @@ -175,7 +171,6 @@ 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) { @@ -195,49 +190,20 @@ struct Relocation { uint32_t Type; }; -// 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 { +template <class SymTabType> class RelocationSectionBase : public SectionBase { private: SymTabType *Symbols = nullptr; - -protected: - RelocSectionWithSymtabBase() {} + SectionBase *SecToApplyRel = nullptr; public: void setSymTab(SymTabType *StrTab) { Symbols = StrTab; } - - void removeSectionReferences(const SectionBase *Sec) override; + void setSection(SectionBase *Sec) { SecToApplyRel = Sec; } void initialize(SectionTableRef SecTable) override; void finalize() override; }; template <class ELFT> -class RelocationSection - : public RelocSectionWithSymtabBase<SymbolTableSection> { +class RelocationSection : public RelocationSectionBase<SymbolTableSection> { private: typedef typename ELFT::Rel Elf_Rel; typedef typename ELFT::Rela Elf_Rela; @@ -264,7 +230,6 @@ 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); @@ -288,7 +253,7 @@ public: }; class DynamicRelocationSection - : public RelocSectionWithSymtabBase<DynamicSymbolTableSection> { + : public RelocationSectionBase<DynamicSymbolTableSection> { private: llvm::ArrayRef<uint8_t> Contents; @@ -339,7 +304,6 @@ 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; diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index 775c5ae42b6..9b233951b8d 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -56,24 +56,17 @@ cl::opt<std::string> OutputFilename(cl::Positional, cl::desc("<output>"), cl::opt<std::string> OutputFormat("O", cl::desc("set output format to one of the following:" "\n\tbinary")); -// TODO: make this a cl::list to support removing multiple sections -cl::opt<std::string> ToRemove("remove-section", - cl::desc("Remove a specific section")); -cl::alias ToRemoveA("R", cl::desc("Alias for remove-section"), cl::aliasopt(ToRemove)); void CopyBinary(const ELFObjectFile<ELF64LE> &ObjFile) { std::unique_ptr<FileOutputBuffer> Buffer; std::unique_ptr<Object<ELF64LE>> Obj; if (!OutputFormat.empty() && OutputFormat != "binary") error("invalid output format '" + OutputFormat + "'"); + if (!OutputFormat.empty() && OutputFormat == "binary") Obj = llvm::make_unique<BinaryObject<ELF64LE>>(ObjFile); else Obj = llvm::make_unique<ELFObject<ELF64LE>>(ObjFile); - if (!ToRemove.empty()) { - Obj->removeSections( - [&](const SectionBase &Sec) { return ToRemove == Sec.Name; }); - } Obj->finalize(); ErrorOr<std::unique_ptr<FileOutputBuffer>> BufferOrErr = FileOutputBuffer::create(OutputFilename, Obj->totalSize(), |