diff options
Diffstat (limited to 'llvm/tools/llvm-objcopy')
-rw-r--r-- | llvm/tools/llvm-objcopy/ObjcopyOpts.td | 5 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.cpp | 29 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/Object.h | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-objcopy/llvm-objcopy.cpp | 11 |
4 files changed, 49 insertions, 3 deletions
diff --git a/llvm/tools/llvm-objcopy/ObjcopyOpts.td b/llvm/tools/llvm-objcopy/ObjcopyOpts.td index 487a3125f00..0ab658b00bc 100644 --- a/llvm/tools/llvm-objcopy/ObjcopyOpts.td +++ b/llvm/tools/llvm-objcopy/ObjcopyOpts.td @@ -78,3 +78,8 @@ def discard_all : Flag<["-", "--"], "discard-all">, HelpText<"Remove all local symbols except file and section symbols">; def x : Flag<["-"], "x">, Alias<discard_all>; +defm strip_symbol : Eq<"strip-symbol">, + MetaVarName<"symbol">, + HelpText<"Remove symbol <symbol>">; +def N : JoinedOrSeparate<["-"], "N">, + Alias<strip_symbol>; diff --git a/llvm/tools/llvm-objcopy/Object.cpp b/llvm/tools/llvm-objcopy/Object.cpp index 93487dc5bf6..efb3207aa8d 100644 --- a/llvm/tools/llvm-objcopy/Object.cpp +++ b/llvm/tools/llvm-objcopy/Object.cpp @@ -47,6 +47,7 @@ template <class ELFT> void ELFWriter<ELFT>::writePhdr(const Segment &Seg) { } void SectionBase::removeSectionReferences(const SectionBase *Sec) {} +void SectionBase::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) {} void SectionBase::initialize(SectionTableRef SecTable) {} void SectionBase::finalize() {} @@ -206,7 +207,8 @@ void SymbolTableSection::updateSymbols(function_ref<void(Symbol &)> Callable) { assignIndices(); } -void SymbolTableSection::removeSymbols(function_ref<bool(Symbol &)> ToRemove) { +void SymbolTableSection::removeSymbols( + function_ref<bool(const Symbol &)> ToRemove) { Symbols.erase( std::remove_if(std::begin(Symbols), std::end(Symbols), [ToRemove](const SymPtr &Sym) { return ToRemove(*Sym); }), @@ -342,6 +344,14 @@ void RelocationSection::accept(SectionVisitor &Visitor) const { Visitor.visit(*this); } +void RelocationSection::removeSymbols( + function_ref<bool(const Symbol &)> ToRemove) { + for (const Relocation &Reloc : Relocations) + if (ToRemove(*Reloc.RelocSymbol)) + error("not stripping symbol `" + Reloc.RelocSymbol->Name + + "' because it is named in a relocation"); +} + void SectionWriter::visit(const DynamicRelocationSection &Sec) { std::copy(std::begin(Sec.Contents), std::end(Sec.Contents), Out.getBufferStart() + Sec.Offset); @@ -365,6 +375,15 @@ void GroupSection::finalize() { this->Link = SymTab->Index; } +void GroupSection::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) { + if (ToRemove(*Sym)) { + error("Symbol " + Sym->Name + + " cannot be removed because it is " + "referenced by the section " + + this->Name + "[" + Twine(this->Index) + "]"); + } +} + void Section::initialize(SectionTableRef SecTable) { if (Link != ELF::SHN_UNDEF) LinkSection = @@ -904,6 +923,14 @@ void Object::removeSections(std::function<bool(const SectionBase &)> ToRemove) { Sections.erase(Iter, std::end(Sections)); } +void Object::removeSymbols(function_ref<bool(const Symbol &)> ToRemove) { + if (!SymbolTable) + return; + + for (const SecPtr &Sec : Sections) + Sec->removeSymbols(ToRemove); +} + void Object::sortSections() { // Put all sections in offset order. Maintain the ordering as closely as // possible while meeting that demand however. diff --git a/llvm/tools/llvm-objcopy/Object.h b/llvm/tools/llvm-objcopy/Object.h index 845d6819052..ac384c1fdfe 100644 --- a/llvm/tools/llvm-objcopy/Object.h +++ b/llvm/tools/llvm-objcopy/Object.h @@ -38,6 +38,7 @@ class GnuDebugLinkSection; class GroupSection; class Segment; class Object; +struct Symbol; class SectionTableRef { MutableArrayRef<std::unique_ptr<SectionBase>> Sections; @@ -209,6 +210,7 @@ public: virtual void initialize(SectionTableRef SecTable); virtual void finalize(); virtual void removeSectionReferences(const SectionBase *Sec); + virtual void removeSymbols(function_ref<bool(const Symbol &)> ToRemove); virtual void accept(SectionVisitor &Visitor) const = 0; }; @@ -366,12 +368,12 @@ public: const SectionBase *getStrTab() const { return SymbolNames; } const Symbol *getSymbolByIndex(uint32_t Index) const; void updateSymbols(function_ref<void(Symbol &)> Callable); - void removeSymbols(function_ref<bool(Symbol &)> ToRemove); void removeSectionReferences(const SectionBase *Sec) override; void initialize(SectionTableRef SecTable) override; void finalize() override; void accept(SectionVisitor &Visitor) const override; + void removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; static bool classof(const SectionBase *S) { return S->Type == ELF::SHT_SYMTAB; @@ -432,6 +434,7 @@ class RelocationSection public: void addRelocation(Relocation Rel) { Relocations.push_back(Rel); } void accept(SectionVisitor &Visitor) const override; + void removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; static bool classof(const SectionBase *S) { if (S->Flags & ELF::SHF_ALLOC) @@ -465,6 +468,7 @@ public: void initialize(SectionTableRef SecTable) override{}; void accept(SectionVisitor &) const override; void finalize() override; + void removeSymbols(function_ref<bool(const Symbol &)> ToRemove) override; static bool classof(const SectionBase *S) { return S->Type == ELF::SHT_GROUP; @@ -619,6 +623,7 @@ public: ConstRange<Segment> segments() const { return make_pointee_range(Segments); } void removeSections(std::function<bool(const SectionBase &)> ToRemove); + void removeSymbols(function_ref<bool(const Symbol &)> ToRemove); template <class T, class... Ts> T &addSection(Ts &&... Args) { auto Sec = llvm::make_unique<T>(std::forward<Ts>(Args)...); auto Ptr = Sec.get(); diff --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp index 1cfcb06e8e4..e08648ea0af 100644 --- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp @@ -147,6 +147,7 @@ struct CopyConfig { std::vector<StringRef> SymbolsToLocalize; std::vector<StringRef> SymbolsToGlobalize; std::vector<StringRef> SymbolsToWeaken; + std::vector<StringRef> SymbolsToRemove; StringMap<StringRef> SymbolsToRename; bool StripAll = false; bool StripAllGNU = false; @@ -371,11 +372,17 @@ void HandleArgs(const CopyConfig &Config, Object &Obj, const Reader &Reader, Sym.Name = I->getValue(); }); - Obj.SymbolTable->removeSymbols([&](const Symbol &Sym) { + Obj.removeSymbols([&](const Symbol &Sym) { if (Config.DiscardAll && Sym.Binding == STB_LOCAL && Sym.getShndx() != SHN_UNDEF && Sym.Type != STT_FILE && Sym.Type != STT_SECTION) return true; + + if (!Config.SymbolsToRemove.empty() && + is_contained(Config.SymbolsToRemove, Sym.Name)) { + return true; + } + return false; }); } @@ -476,6 +483,8 @@ CopyConfig ParseObjcopyOptions(ArrayRef<const char *> ArgsArr) { Config.SymbolsToGlobalize.push_back(Arg->getValue()); for (auto Arg : InputArgs.filtered(OBJCOPY_weaken_symbol)) Config.SymbolsToWeaken.push_back(Arg->getValue()); + for (auto Arg : InputArgs.filtered(OBJCOPY_strip_symbol)) + Config.SymbolsToRemove.push_back(Arg->getValue()); return Config; } |