[llvm] r330973 - [llvm-objcopy] Implement --redefine-sym option

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 26 11:28:17 PDT 2018


Author: alexshap
Date: Thu Apr 26 11:28:17 2018
New Revision: 330973

URL: http://llvm.org/viewvc/llvm-project?rev=330973&view=rev
Log:
[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


Added:
    llvm/trunk/test/tools/llvm-objcopy/redefine-symbol.test
Modified:
    llvm/trunk/tools/llvm-objcopy/Object.cpp
    llvm/trunk/tools/llvm-objcopy/Object.h
    llvm/trunk/tools/llvm-objcopy/Opts.td
    llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp

Added: llvm/trunk/test/tools/llvm-objcopy/redefine-symbol.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/redefine-symbol.test?rev=330973&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/redefine-symbol.test (added)
+++ llvm/trunk/test/tools/llvm-objcopy/redefine-symbol.test Thu Apr 26 11:28:17 2018
@@ -0,0 +1,81 @@
+# RUN: yaml2obj %s > %t
+# RUN: llvm-objcopy --redefine-sym foo=oof --redefine-sym empty= %t %t2
+# RUN: llvm-readobj -symbols %t2 | FileCheck %s
+# RUN: not llvm-objcopy --redefine-sym barbar %t %t2 2>&1 | FileCheck %s --check-prefix=BAD-FORMAT
+# RUN: not llvm-objcopy --redefine-sym foo=f1 --redefine-sym foo=f2 %t %t2 2>&1 | FileCheck %s --check-prefix=MULTIPLE-REDEFINITION
+
+!ELF
+FileHeader:
+  Class:           ELFCLASS64
+  Data:            ELFDATA2LSB
+  Type:            ET_EXEC
+  Machine:         EM_X86_64
+Sections:
+  - Name:            .text
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC, SHF_EXECINSTR ]
+    Address:         0x1000
+    AddressAlign:    0x0000000000000010
+    Content:         "0000000000000000"
+  - Name:            .data
+    Type:            SHT_PROGBITS
+    Flags:           [ SHF_ALLOC ]
+    Address:         0x2000
+    AddressAlign:    0x0000000000000010
+    Content:         "0000000000000000"
+Symbols:
+  Global:
+    - Name:     foo
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    0x1004
+    - Name:     bar
+      Type:     STT_OBJECT
+      Section:  .data
+      Value:    0x2000
+      Size:     4
+    - Name:     empty
+      Type:     STT_FUNC
+      Section:  .text
+      Value:    0x1008
+
+#CHECK: Symbols [
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name:
+#CHECK-NEXT:    Value: 0x0
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Local
+#CHECK-NEXT:    Type: None
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: Undefined
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: oof
+#CHECK-NEXT:    Value: 0x1004
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Global
+#CHECK-NEXT:    Type: Function
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: .text
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: bar
+#CHECK-NEXT:    Value: 0x2000
+#CHECK-NEXT:    Size: 4
+#CHECK-NEXT:    Binding: Global
+#CHECK-NEXT:    Type: Object
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: .data
+#CHECK-NEXT:  }
+#CHECK-NEXT:  Symbol {
+#CHECK-NEXT:    Name: 
+#CHECK-NEXT:    Value: 0x1008
+#CHECK-NEXT:    Size: 0
+#CHECK-NEXT:    Binding: Global
+#CHECK-NEXT:    Type: Function
+#CHECK-NEXT:    Other: 0
+#CHECK-NEXT:    Section: .text
+#CHECK-NEXT:  }
+
+#BAD-FORMAT: Bad format for --redefine-sym
+#MULTIPLE-REDEFINITION: Multiple redefinition of symbol foo

Modified: llvm/trunk/tools/llvm-objcopy/Object.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.cpp?rev=330973&r1=330972&r2=330973&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.cpp Thu Apr 26 11:28:17 2018
@@ -202,15 +202,9 @@ void SymbolTableSection::removeSectionRe
   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; });

Modified: llvm/trunk/tools/llvm-objcopy/Object.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Object.h?rev=330973&r1=330972&r2=330973&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Object.h (original)
+++ llvm/trunk/tools/llvm-objcopy/Object.h Thu Apr 26 11:28:17 2018
@@ -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;

Modified: llvm/trunk/tools/llvm-objcopy/Opts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Opts.td?rev=330973&r1=330972&r2=330973&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Opts.td (original)
+++ llvm/trunk/tools/llvm-objcopy/Opts.td Thu Apr 26 11:28:17 2018
@@ -27,6 +27,9 @@ defm add_gnu_debuglink : Eq<"add-gnu-deb
 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<["-", "--"], "ext
 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>;

Modified: llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp?rev=330973&r1=330972&r2=330973&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Thu Apr 26 11:28:17 2018
@@ -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
     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
     };
 
   // 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
     }
   }
 
-  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<
 
   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<
   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;
 }




More information about the llvm-commits mailing list