diff options
author | Alexander Shaposhnikov <shal1t712@gmail.com> | 2018-04-26 18:28:17 +0000 |
---|---|---|
committer | Alexander Shaposhnikov <shal1t712@gmail.com> | 2018-04-26 18:28:17 +0000 |
commit | 5b92658eab7529e1393a483742057e7476dce79c (patch) | |
tree | 719ec9f422a20cf6a9ae97646434594bed96ef35 /tools/llvm-objcopy | |
parent | 16388e77fc9f18ae83ef1615852a45dbec25cdc6 (diff) |
[llvm-objcopy] Implement --redefine-sym option
This diff implements --redefine-sym option
for changing the name of a symbol.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D46029
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@330973 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-objcopy')
-rw-r--r-- | tools/llvm-objcopy/Object.cpp | 12 | ||||
-rw-r--r-- | tools/llvm-objcopy/Object.h | 3 | ||||
-rw-r--r-- | tools/llvm-objcopy/Opts.td | 7 | ||||
-rw-r--r-- | tools/llvm-objcopy/llvm-objcopy.cpp | 55 |
4 files changed, 38 insertions, 39 deletions
diff --git a/tools/llvm-objcopy/Object.cpp b/tools/llvm-objcopy/Object.cpp index c7ce2309ffb..07b60367b9e 100644 --- a/tools/llvm-objcopy/Object.cpp +++ b/tools/llvm-objcopy/Object.cpp @@ -202,15 +202,9 @@ void SymbolTableSection::removeSectionReferences(const SectionBase *Sec) { assignIndices(); } -void SymbolTableSection::localize( - std::function<bool(const Symbol &)> ToLocalize) { - for (const auto &Sym : Symbols) { - if (ToLocalize(*Sym)) - Sym->Binding = STB_LOCAL; - } - - // Now that the local symbols aren't grouped at the start we have to reorder - // the symbols to respect this property. +void SymbolTableSection::updateSymbols(function_ref<void(Symbol &)> Callable) { + for (auto &Sym : Symbols) + Callable(*Sym); std::stable_partition( std::begin(Symbols), std::end(Symbols), [](const SymPtr &Sym) { return Sym->Binding == STB_LOCAL; }); diff --git a/tools/llvm-objcopy/Object.h b/tools/llvm-objcopy/Object.h index ddc0da16aa4..2598b249a7c 100644 --- a/tools/llvm-objcopy/Object.h +++ b/tools/llvm-objcopy/Object.h @@ -365,8 +365,9 @@ public: void addSymbolNames(); const SectionBase *getStrTab() const { return SymbolNames; } const Symbol *getSymbolByIndex(uint32_t Index) const; + void updateSymbols(function_ref<void(Symbol &)> Callable); + void removeSectionReferences(const SectionBase *Sec) override; - void localize(std::function<bool(const Symbol &)> ToLocalize); void initialize(SectionTableRef SecTable) override; void finalize() override; void accept(SectionVisitor &Visitor) const override; diff --git a/tools/llvm-objcopy/Opts.td b/tools/llvm-objcopy/Opts.td index a4d864a7c5b..6e7159559fe 100644 --- a/tools/llvm-objcopy/Opts.td +++ b/tools/llvm-objcopy/Opts.td @@ -27,6 +27,9 @@ defm add_gnu_debuglink : Eq<"add-gnu-debuglink">, defm remove_section : Eq<"remove-section">, MetaVarName<"section">, HelpText<"Remove <section>">; +defm redefine_symbol : Eq<"redefine-sym">, + MetaVarName<"old=new">, + HelpText<"Change the name of a symbol old to new">; def R : JoinedOrSeparate<["-"], "R">, Alias<remove_section>; defm keep : Eq<"keep">, @@ -57,7 +60,7 @@ def extract_dwo : Flag<["-", "--"], "extract-dwo">, def localize_hidden : Flag<["-", "--"], "localize-hidden">, HelpText<"Mark all symbols that have hidden or internal visibility as local">; defm localize_symbol : Eq<"localize-symbol">, - MetaVarName<"symbol">, - HelpText<"Mark <symbol> as local">; + MetaVarName<"symbol">, + HelpText<"Mark <symbol> as local">; def L : JoinedOrSeparate<["-"], "L">, Alias<localize_symbol>; diff --git a/tools/llvm-objcopy/llvm-objcopy.cpp b/tools/llvm-objcopy/llvm-objcopy.cpp index 7158ceed53f..a4b38cfaf2e 100644 --- a/tools/llvm-objcopy/llvm-objcopy.cpp +++ b/tools/llvm-objcopy/llvm-objcopy.cpp @@ -118,7 +118,8 @@ struct CopyConfig { std::vector<StringRef> Keep; std::vector<StringRef> OnlyKeep; std::vector<StringRef> AddSection; - std::vector<StringRef> LocalizeSymbol; + std::vector<StringRef> SymbolsToLocalize; + StringMap<StringRef> SymbolsToRename; bool StripAll; bool StripAllGNU; bool StripDebug; @@ -130,7 +131,6 @@ struct CopyConfig { }; using SectionPred = std::function<bool(const SectionBase &Sec)>; -using SymbolPred = std::function<bool(const Symbol &Sym)>; bool IsDWOSection(const SectionBase &Sec) { return Sec.Name.endswith(".dwo"); } @@ -190,31 +190,9 @@ void HandleArgs(const CopyConfig &Config, Object &Obj, const Reader &Reader, SplitDWOToFile(Config, Reader, Config.SplitDWO, OutputElfType); } - SymbolPred LocalizePred = [](const Symbol &) { return false; }; - - // Localize: - - if (Config.LocalizeHidden) { - LocalizePred = [](const Symbol &Sym) { - return Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL; - }; - } - - if (!Config.LocalizeSymbol.empty()) { - LocalizePred = [LocalizePred, &Config](const Symbol &Sym) { - return LocalizePred(Sym) || - std::find(std::begin(Config.LocalizeSymbol), - std::end(Config.LocalizeSymbol), - Sym.Name) != std::end(Config.LocalizeSymbol); - }; - } - - Obj.SymbolTable->localize(LocalizePred); - SectionPred RemovePred = [](const SectionBase &) { return false; }; // Removes: - if (!Config.ToRemove.empty()) { RemovePred = [&Config](const SectionBase &Sec) { return std::find(std::begin(Config.ToRemove), std::end(Config.ToRemove), @@ -283,7 +261,6 @@ void HandleArgs(const CopyConfig &Config, Object &Obj, const Reader &Reader, }; // Explicit copies: - if (!Config.OnlyKeep.empty()) { RemovePred = [&Config, RemovePred, &Obj](const SectionBase &Sec) { // Explicitly keep these sections regardless of previous removes. @@ -335,8 +312,23 @@ void HandleArgs(const CopyConfig &Config, Object &Obj, const Reader &Reader, } } - if (!Config.AddGnuDebugLink.empty()) { + if (!Config.AddGnuDebugLink.empty()) Obj.addSection<GnuDebugLinkSection>(Config.AddGnuDebugLink); + + if (Obj.SymbolTable) { + Obj.SymbolTable->updateSymbols([&](Symbol &Sym) { + if ((Config.LocalizeHidden && + (Sym.Visibility == STV_HIDDEN || Sym.Visibility == STV_INTERNAL)) || + (!Config.SymbolsToLocalize.empty() && + std::find(std::begin(Config.SymbolsToLocalize), + std::end(Config.SymbolsToLocalize), + Sym.Name) != std::end(Config.SymbolsToLocalize))) + Sym.Binding = STB_LOCAL; + + const auto I = Config.SymbolsToRename.find(Sym.Name); + if (I != Config.SymbolsToRename.end()) + Sym.Name = I->getValue(); + }); } } @@ -397,6 +389,15 @@ CopyConfig ParseObjcopyOptions(ArrayRef<const char *> ArgsArr) { Config.SplitDWO = InputArgs.getLastArgValue(OBJCOPY_split_dwo); Config.AddGnuDebugLink = InputArgs.getLastArgValue(OBJCOPY_add_gnu_debuglink); + + for (auto Arg : InputArgs.filtered(OBJCOPY_redefine_symbol)) { + if (!StringRef(Arg->getValue()).contains('=')) + error("Bad format for --redefine-sym"); + auto Old2New = StringRef(Arg->getValue()).split('='); + if (!Config.SymbolsToRename.insert(Old2New).second) + error("Multiple redefinition of symbol " + Old2New.first); + } + for (auto Arg : InputArgs.filtered(OBJCOPY_remove_section)) Config.ToRemove.push_back(Arg->getValue()); for (auto Arg : InputArgs.filtered(OBJCOPY_keep)) @@ -414,7 +415,7 @@ CopyConfig ParseObjcopyOptions(ArrayRef<const char *> ArgsArr) { Config.ExtractDWO = InputArgs.hasArg(OBJCOPY_extract_dwo); Config.LocalizeHidden = InputArgs.hasArg(OBJCOPY_localize_hidden); for (auto Arg : InputArgs.filtered(OBJCOPY_localize_symbol)) - Config.LocalizeSymbol.push_back(Arg->getValue()); + Config.SymbolsToLocalize.push_back(Arg->getValue()); return Config; } |