[llvm] r331663 - [tools] Introduce llvm-strip

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Mon May 7 12:32:09 PDT 2018


Author: alexshap
Date: Mon May  7 12:32:09 2018
New Revision: 331663

URL: http://llvm.org/viewvc/llvm-project?rev=331663&view=rev
Log:
[tools] Introduce llvm-strip

llvm-strip is supposed to be a drop-in replacement for binutils strip.
To start the ball rolling this diff adds the initial bits for llvm-strip,
more features will be added incrementally over time.

Test plan: make check-all

Differential revision: https://reviews.llvm.org/D46407


Added:
    llvm/trunk/tools/llvm-objcopy/ObjcopyOpts.td
      - copied unchanged from r331662, llvm/trunk/tools/llvm-objcopy/Opts.td
    llvm/trunk/tools/llvm-objcopy/StripOpts.td
Removed:
    llvm/trunk/tools/llvm-objcopy/Opts.td
Modified:
    llvm/trunk/test/tools/llvm-objcopy/strip-all.test
    llvm/trunk/test/tools/llvm-objcopy/strip-debug.test
    llvm/trunk/tools/llvm-objcopy/CMakeLists.txt
    llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp

Modified: llvm/trunk/test/tools/llvm-objcopy/strip-all.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/strip-all.test?rev=331663&r1=331662&r2=331663&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/strip-all.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/strip-all.test Mon May  7 12:32:09 2018
@@ -2,6 +2,14 @@
 # RUN: llvm-objcopy --strip-all %t %t2
 # RUN: llvm-readobj -file-headers -sections %t2 | FileCheck %s
 
+# We run yaml2obj again rather than copy %t to avoid interfering
+# with llvm-objcopy's test (which potentially could have corrupted/updated the binary).
+
+# RUN: yaml2obj %s > %t3
+# RUN: llvm-strip %t3 
+# RUN: llvm-readobj -file-headers -sections %t3 | FileCheck %s
+# RUN: cmp %t2 %t3
+
 !ELF
 FileHeader:
   Class:           ELFCLASS64

Modified: llvm/trunk/test/tools/llvm-objcopy/strip-debug.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-objcopy/strip-debug.test?rev=331663&r1=331662&r2=331663&view=diff
==============================================================================
--- llvm/trunk/test/tools/llvm-objcopy/strip-debug.test (original)
+++ llvm/trunk/test/tools/llvm-objcopy/strip-debug.test Mon May  7 12:32:09 2018
@@ -2,6 +2,16 @@
 # RUN: llvm-objcopy -strip-debug %t %t2
 # RUN: llvm-readobj -file-headers -sections -symbols %t2 | FileCheck %s
 
+# We run yaml2obj again rather than copy %t to avoid interfering 
+# with llvm-objcopy's test (which potentially could have corrupted/updated the binary).
+
+# RUN: yaml2obj %s > %t3
+# RUN: llvm-strip -strip-debug %t3
+# RUN: llvm-readobj -file-headers -sections -symbols %t3 | FileCheck %s
+# RUN: cmp %t2 %t3
+
+# RUN: not llvm-strip -strip-debug 2>&1 | FileCheck %s --check-prefix=NO-INPUT-FILES
+
 !ELF
 FileHeader:
   Class:           ELFCLASS64
@@ -52,3 +62,5 @@ Symbols:
 # CHECK-NEXT:     Section: .text
 # CHECK-NEXT:   }
 # CHECK-NEXT: ]
+
+# NO-INPUT-FILES: No input file specified

Modified: llvm/trunk/tools/llvm-objcopy/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/CMakeLists.txt?rev=331663&r1=331662&r2=331663&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-objcopy/CMakeLists.txt Mon May  7 12:32:09 2018
@@ -5,18 +5,25 @@ set(LLVM_LINK_COMPONENTS
   MC
   )
 
-set(LLVM_TARGET_DEFINITIONS Opts.td)
+set(LLVM_TARGET_DEFINITIONS ObjcopyOpts.td)
+tablegen(LLVM ObjcopyOpts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(ObjcopyOptsTableGen)
 
-tablegen(LLVM Opts.inc -gen-opt-parser-defs)
-add_public_tablegen_target(ObjcopyTableGen)
+set(LLVM_TARGET_DEFINITIONS StripOpts.td)
+tablegen(LLVM StripOpts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(StripOptsTableGen)
 
 add_llvm_tool(llvm-objcopy
   llvm-objcopy.cpp
   Object.cpp
   DEPENDS
-  ObjcopyTableGen
+  ObjcopyOptsTableGen
+  StripOptsTableGen
   )
 
+add_llvm_tool_symlink(llvm-strip llvm-objcopy)
+
 if(LLVM_INSTALL_BINUTILS_SYMLINKS)
   add_llvm_tool_symlink(objcopy llvm-objcopy)
+  add_llvm_tool_symlink(strip llvm-objcopy)
 endif()

Removed: llvm/trunk/tools/llvm-objcopy/Opts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/Opts.td?rev=331662&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/Opts.td (original)
+++ llvm/trunk/tools/llvm-objcopy/Opts.td (removed)
@@ -1,80 +0,0 @@
-include "llvm/Option/OptParser.td"
-
-multiclass Eq<string name> {
-  def NAME: Separate<["--", "-"], name>;
-  def NAME # _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>;
-}
-
-def help : Flag<["-", "--"], "help">;
-defm binary_architecture : Eq<"binary-architecture">,
-                           HelpText<"Used when transforming an architecture-less format (such as binary) to another format">;
-def B : JoinedOrSeparate<["-"], "B">,
-        Alias<binary_architecture>;
-defm input_target : Eq<"input-target">,
-                    HelpText<"Format of the input file">,
-                    Values<"binary">;
-defm output_target : Eq<"output-target">,
-                     HelpText<"Format of the output file">,
-                     Values<"binary">;
-def O : JoinedOrSeparate<["-"], "O">,
-        Alias<output_target>;
-defm split_dwo : Eq<"split-dwo">,
-                 MetaVarName<"dwo-file">,
-                 HelpText<"Equivalent to extract-dwo on the input file to <dwo-file>, then strip-dwo on the input file">;
-defm add_gnu_debuglink : Eq<"add-gnu-debuglink">,
-                         MetaVarName<"debug-file">,
-                         HelpText<"Add a .gnu_debuglink for <debug-file>">;
-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">,
-            MetaVarName<"section">,
-            HelpText<"Keep <section>">;
-defm only_keep : Eq<"only-keep">,
-                 MetaVarName<"section">,
-                 HelpText<"Remove all but <section>">;
-def j : JoinedOrSeparate<["-"], "j">,
-                      Alias<only_keep>;
-defm add_section : Eq<"add-section">,
-                   MetaVarName<"section=file">,
-                   HelpText<"Make a section named <section> with the contents of <file>.">;
-def strip_all : Flag<["-", "--"], "strip-all">,
-                HelpText<"Remove non-allocated sections other than .gnu.warning* sections">;
-def strip_all_gnu : Flag<["-", "--"], "strip-all-gnu">,
-                    HelpText<"Compaitable with GNU objcopy's --strip-all">;
-def strip_debug : Flag<["-", "--"], "strip-debug">,
-                  HelpText<"Remove all debug information">;
-def strip_dwo : Flag<["-", "--"], "strip-dwo">,
-                HelpText<"Remove all DWARF .dwo sections from file">;
-def strip_sections : Flag<["-", "--"], "strip-sections">,
-                     HelpText<"Remove all section headers">;
-def strip_non_alloc : Flag<["-", "--"], "strip-non-alloc">,
-                      HelpText<"Remove all non-allocated sections">;
-def extract_dwo : Flag<["-", "--"], "extract-dwo">,
-                  HelpText<"Remove all sections that are not DWARF .dwo sections from file">;
-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">;
-def L : JoinedOrSeparate<["-"], "L">,
-        Alias<localize_symbol>;
-defm globalize_symbol : Eq<"globalize-symbol">,
-                       MetaVarName<"symbol">,
-                       HelpText<"Mark <symbol> as global">;
-defm weaken_symbol : Eq<"weaken-symbol">,
-                       MetaVarName<"symbol">,
-                       HelpText<"Mark <symbol> as weak">;
-def W : JoinedOrSeparate<["-"], "W">,
-        Alias<weaken_symbol>;
-def weaken : Flag<["-", "--"], "weaken">,
-                  HelpText<"Mark all global symbols as weak">;
-def discard_all : Flag<["-", "--"], "discard-all">,
-                      HelpText<"Remove all local symbols except file and section symbols">;
-def x : Flag<["-"], "x">,
-        Alias<discard_all>;

Added: llvm/trunk/tools/llvm-objcopy/StripOpts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-objcopy/StripOpts.td?rev=331663&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/StripOpts.td (added)
+++ llvm/trunk/tools/llvm-objcopy/StripOpts.td Mon May  7 12:32:09 2018
@@ -0,0 +1,12 @@
+include "llvm/Option/OptParser.td"
+
+multiclass Eq<string name> {
+  def NAME: Separate<["--", "-"], name>;
+  def NAME # _eq: Joined<["--", "-"], name # "=">, Alias<!cast<Separate>(NAME)>;
+}
+
+def help : Flag<["-", "--"], "help">;
+
+def strip_debug : Flag<["-", "--"], "strip-debug">,
+                  HelpText<"Remove debugging symbols only">;
+

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=331663&r1=331662&r2=331663&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp (original)
+++ llvm/trunk/tools/llvm-objcopy/llvm-objcopy.cpp Mon May  7 12:32:09 2018
@@ -28,6 +28,7 @@
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/FileOutputBuffer.h"
 #include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
 #include <algorithm>
 #include <cassert>
@@ -45,17 +46,17 @@ using namespace ELF;
 
 namespace {
 
-enum ID {
+enum ObjcopyID {
   OBJCOPY_INVALID = 0, // This is not an option ID.
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
                HELPTEXT, METAVAR, VALUES)                                      \
   OBJCOPY_##ID,
-#include "Opts.inc"
+#include "ObjcopyOpts.inc"
 #undef OPTION
 };
 
 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
-#include "Opts.inc"
+#include "ObjcopyOpts.inc"
 #undef PREFIX
 
 static const opt::OptTable::Info ObjcopyInfoTable[] = {
@@ -65,7 +66,7 @@ static const opt::OptTable::Info Objcopy
    METAVAR,         OBJCOPY_##ID, opt::Option::KIND##Class,                    \
    PARAM,           FLAGS,        OBJCOPY_##GROUP,                             \
    OBJCOPY_##ALIAS, ALIASARGS,    VALUES},
-#include "Opts.inc"
+#include "ObjcopyOpts.inc"
 #undef OPTION
 };
 
@@ -74,6 +75,31 @@ public:
   ObjcopyOptTable() : OptTable(ObjcopyInfoTable, true) {}
 };
 
+enum StripID {
+  STRIP_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
+               HELPTEXT, METAVAR, VALUES)                                      \
+  STRIP_##ID,
+#include "StripOpts.inc"
+#undef OPTION
+};
+
+static const opt::OptTable::Info StripInfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
+               HELPTEXT, METAVAR, VALUES)                                      \
+  {PREFIX,          NAME,         HELPTEXT,                                    \
+   METAVAR,         STRIP_##ID, opt::Option::KIND##Class,                      \
+   PARAM,           FLAGS,        STRIP_##GROUP,                               \
+   STRIP_##ALIAS, ALIASARGS,    VALUES},
+#include "StripOpts.inc"
+#undef OPTION
+};
+
+class StripOptTable : public opt::OptTable {
+public:
+  StripOptTable() : OptTable(StripInfoTable, true) {}
+};
+
 } // namespace
 
 // The name this program was invoked as.
@@ -122,16 +148,16 @@ struct CopyConfig {
   std::vector<StringRef> SymbolsToGlobalize;
   std::vector<StringRef> SymbolsToWeaken;
   StringMap<StringRef> SymbolsToRename;
-  bool StripAll;
-  bool StripAllGNU;
-  bool StripDebug;
-  bool StripSections;
-  bool StripNonAlloc;
-  bool StripDWO;
-  bool ExtractDWO;
-  bool LocalizeHidden;
-  bool Weaken;
-  bool DiscardAll;
+  bool StripAll = false;
+  bool StripAllGNU = false;
+  bool StripDebug = false;
+  bool StripSections = false;
+  bool StripNonAlloc = false;
+  bool StripDWO = false;
+  bool ExtractDWO = false;
+  bool LocalizeHidden = false;
+  bool Weaken = false;
+  bool DiscardAll = false;
 };
 
 using SectionPred = std::function<bool(const SectionBase &Sec)>;
@@ -449,10 +475,50 @@ CopyConfig ParseObjcopyOptions(ArrayRef<
   return Config;
 }
 
+// ParseStripOptions returns the config and sets the input arguments. If a
+// help flag is set then ParseStripOptions will print the help messege and
+// exit.
+CopyConfig ParseStripOptions(ArrayRef<const char *> ArgsArr) {
+  StripOptTable T;
+  unsigned MissingArgumentIndex, MissingArgumentCount;
+  llvm::opt::InputArgList InputArgs =
+      T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
+
+  if (InputArgs.size() == 0 || InputArgs.hasArg(STRIP_help)) {
+    T.PrintHelp(outs(), "llvm-strip <input> [ <output> ]", "strip tool");
+    exit(0);
+  }
+
+  SmallVector<const char *, 2> Positional;
+  for (auto Arg : InputArgs.filtered(STRIP_UNKNOWN))
+    error("unknown argument '" + Arg->getAsString(InputArgs) + "'");
+  for (auto Arg : InputArgs.filtered(STRIP_INPUT))
+    Positional.push_back(Arg->getValue());
+
+  if (Positional.empty())
+    error("No input file specified");
+
+  if (Positional.size() > 2)
+    error("Support for multiple input files is not implemented yet");
+
+  CopyConfig Config;
+  Config.InputFilename = Positional[0];
+  Config.OutputFilename = Positional[0];
+
+  // Strip debug info only.
+  Config.StripDebug = InputArgs.hasArg(STRIP_strip_debug);
+  if (!Config.StripDebug)
+    Config.StripAll = true;
+  return Config;
+}
+
 int main(int argc, char **argv) {
   InitLLVM X(argc, argv);
   ToolName = argv[0];
-
-  CopyConfig Config = ParseObjcopyOptions(makeArrayRef(argv + 1, argc));
+  CopyConfig Config;
+  if (sys::path::stem(ToolName).endswith_lower("strip"))
+    Config = ParseStripOptions(makeArrayRef(argv + 1, argc));
+  else
+    Config = ParseObjcopyOptions(makeArrayRef(argv + 1, argc));
   ExecuteElfObjcopy(Config);
 }




More information about the llvm-commits mailing list