summaryrefslogtreecommitdiff
path: root/tools/llvm-objcopy
diff options
context:
space:
mode:
authorAlexander Shaposhnikov <shal1t712@gmail.com>2018-04-26 18:28:17 +0000
committerAlexander Shaposhnikov <shal1t712@gmail.com>2018-04-26 18:28:17 +0000
commit5b92658eab7529e1393a483742057e7476dce79c (patch)
tree719ec9f422a20cf6a9ae97646434594bed96ef35 /tools/llvm-objcopy
parent16388e77fc9f18ae83ef1615852a45dbec25cdc6 (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.cpp12
-rw-r--r--tools/llvm-objcopy/Object.h3
-rw-r--r--tools/llvm-objcopy/Opts.td7
-rw-r--r--tools/llvm-objcopy/llvm-objcopy.cpp55
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;
}