[llvm-objcopy][MachO] Add llvm-bitcode-strip driver
authorAlexander Shaposhnikov <alexshap@fb.com>
Sat, 19 Sep 2020 01:11:22 +0000 (18:11 -0700)
committerAlexander Shaposhnikov <alexshap@fb.com>
Sat, 19 Sep 2020 01:13:05 +0000 (18:13 -0700)
This diff adds llvm-bitcode-strip driver to llvm-objcopy.
In the future this will enable us to build a replacement for the tool bitcode_strip.

Test plan: make check-all

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

llvm/test/CMakeLists.txt
llvm/test/lit.cfg.py
llvm/test/tools/llvm-objcopy/tool-help-message.test
llvm/test/tools/llvm-objcopy/tool-name.test
llvm/test/tools/llvm-objcopy/tool-version.test
llvm/tools/llvm-objcopy/BitcodeStripOpts.td [new file with mode: 0644]
llvm/tools/llvm-objcopy/CMakeLists.txt
llvm/tools/llvm-objcopy/CopyConfig.cpp
llvm/tools/llvm-objcopy/CopyConfig.h
llvm/tools/llvm-objcopy/llvm-objcopy.cpp

index 12f5641..4263937 100644 (file)
@@ -60,6 +60,7 @@ set(LLVM_TEST_DEPENDS
           llvm-ar
           llvm-as
           llvm-bcanalyzer
+          llvm-bitcode-strip
           llvm-c-test
           llvm-cat
           llvm-cfi-verify
index 9a1dd4e..223bd0e 100644 (file)
@@ -141,15 +141,16 @@ tools = [
     ToolSubst('%llvm-objcopy', FindTool('llvm-objcopy')),
     ToolSubst('%llvm-strip', FindTool('llvm-strip')),
     ToolSubst('%llvm-install-name-tool', FindTool('llvm-install-name-tool')),
+    ToolSubst('%llvm-bitcode-strip', FindTool('llvm-bitcode-strip')),
     ToolSubst('%split-file', FindTool('split-file')),
 ]
 
 # FIXME: Why do we have both `lli` and `%lli` that do slightly different things?
 tools.extend([
     'dsymutil', 'lli', 'lli-child-target', 'llvm-ar', 'llvm-as',
-    'llvm-addr2line', 'llvm-bcanalyzer', 'llvm-config', 'llvm-cov',
-    'llvm-cxxdump', 'llvm-cvtres', 'llvm-diff', 'llvm-dis', 'llvm-dwarfdump',
-    'llvm-exegesis', 'llvm-extract', 'llvm-isel-fuzzer', 'llvm-ifs',
+    'llvm-addr2line', 'llvm-bcanalyzer', 'llvm-bitcode-strip', 'llvm-config', 
+    'llvm-cov', 'llvm-cxxdump', 'llvm-cvtres', 'llvm-diff', 'llvm-dis', 
+    'llvm-dwarfdump', 'llvm-exegesis', 'llvm-extract', 'llvm-isel-fuzzer', 'llvm-ifs',
     'llvm-install-name-tool', 'llvm-jitlink', 'llvm-opt-fuzzer', 'llvm-lib',
     'llvm-link', 'llvm-lto', 'llvm-lto2', 'llvm-mc', 'llvm-mca',
     'llvm-modextract', 'llvm-nm', 'llvm-objcopy', 'llvm-objdump',
index 3f99d91..b8ad3b7 100644 (file)
 # RUN: not llvm-install-name-tool -add_rpath @executable 2>&1 | FileCheck %s --check-prefix=NO-INPUT-FILES
 # RUN: not llvm-install-name-tool -add_rpath @executable f1 f2 2>&1 | FileCheck %s --check-prefix=MULTIPLE-INPUT-FILES
 
+# RUN: llvm-bitcode-strip -h | FileCheck --check-prefix=BITCODE-STRIP-USAGE %s --match-full-lines
+# RUN: llvm-bitcode-strip --help | FileCheck --check-prefix=BITCODE-STRIP-USAGE %s --match-full-lines
+# RUN: not llvm-bitcode-strip 2>&1 | FileCheck --check-prefix=BITCODE-STRIP-USAGE %s --match-full-lines
+# RUN: not llvm-bitcode-strip -abcabc 2>&1 | FileCheck --check-prefix=UNKNOWN-ARG %s
+# RUN: not llvm-bitcode-strip --abcabc 2>&1 | FileCheck --check-prefix=UNKNOWN-ARG %s
+# RUN: not llvm-bitcode-strip f1 f2 2>&1 | FileCheck %s --check-prefix=MULTIPLE-INPUT-FILES
+
 # OBJCOPY-USAGE:  USAGE: llvm-objcopy [options] input [output]
 # OBJCOPY-USAGE:  Pass @FILE as argument to read options from FILE.
 
@@ -29,6 +36,9 @@
 # INSTALL-NAME-TOOL-USAGE: USAGE: llvm-install-name-tool [options] input
 # INSTALL-NAME-TOOL-USAGE: Pass @FILE as argument to read options from FILE.
 
+# BITCODE-STRIP-USAGE: USAGE: llvm-bitcode-strip [options] input
+# BITCODE-STRIP-USAGE: Pass @FILE as argument to read options from FILE.
+
 # UNKNOWN-ARG:    unknown argument '{{-+}}abcabc'
 # NO-INPUT-FILES: no input file specified
 # MULTIPLE-INPUT-FILES: expects a single input file
index a273375..4364d08 100644 (file)
 # RUN: %t/install_name_tool.exe --help | FileCheck --check-prefix=INSTALL %s
 
 # INSTALL: OVERVIEW: llvm-install-name-tool tool
+
+## This driver emulates bitcode_strip on macOS.
+# RUN: ln -s llvm-bitcode-strip %t/llvm-bitcode-strip-10
+# RUN: ln -s llvm-bitcode-strip %t/bitcode_strip.exe
+
+# RUN: llvm-bitcode-strip --help | FileCheck --check-prefix=BITCODE-STRIP %s
+# RUN: %t/llvm-bitcode-strip-10 --help | FileCheck --check-prefix=BITCODE-STRIP %s
+# RUN: %t/bitcode_strip.exe --help | FileCheck --check-prefix=BITCODE-STRIP %s
+
+# BITCODE-STRIP: OVERVIEW: llvm-bitcode-strip tool
index a6cc8f9..e2fb551 100644 (file)
@@ -7,6 +7,9 @@
 # RUN: llvm-install-name-tool --version | FileCheck %s
 # RUN: llvm-install-name-tool -V | FileCheck %s
 
+# RUN: llvm-bitcode-strip --version | FileCheck %s
+# RUN: llvm-bitcode-strip -V | FileCheck %s
+
 # OBJCOPY-DAG: {{ version }}
 # OBJCOPY-DAG: GNU objcopy
 
diff --git a/llvm/tools/llvm-objcopy/BitcodeStripOpts.td b/llvm/tools/llvm-objcopy/BitcodeStripOpts.td
new file mode 100644 (file)
index 0000000..cc17816
--- /dev/null
@@ -0,0 +1,24 @@
+//===-- BitcodeStripOpts.td - llvm-bitcode-strip options  ---------------*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file describes the command line options of llvm-bitcode-strip.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Option/OptParser.td"
+
+def help : Flag<["--"], "help">;
+
+def h : Flag<["-"], "h">, Alias<help>;
+
+def version : Flag<["--"], "version">,
+              HelpText<"Print the version and exit.">;
+
+def V : Flag<["-"], "V">,
+        Alias<version>,
+        HelpText<"Alias for --version">;
index 49eab05..1f733c3 100644 (file)
@@ -13,6 +13,10 @@ set(LLVM_TARGET_DEFINITIONS InstallNameToolOpts.td)
 tablegen(LLVM InstallNameToolOpts.inc -gen-opt-parser-defs)
 add_public_tablegen_target(InstallNameToolOptsTableGen)
 
+set(LLVM_TARGET_DEFINITIONS BitcodeStripOpts.td)
+tablegen(LLVM BitcodeStripOpts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(BitcodeStripOptsTableGen)
+
 set(LLVM_TARGET_DEFINITIONS StripOpts.td)
 tablegen(LLVM StripOpts.inc -gen-opt-parser-defs)
 add_public_tablegen_target(StripOptsTableGen)
@@ -44,6 +48,7 @@ add_llvm_tool(llvm-objcopy
   )
 
 add_llvm_tool_symlink(llvm-install-name-tool llvm-objcopy)
+add_llvm_tool_symlink(llvm-bitcode-strip llvm-objcopy)
 add_llvm_tool_symlink(llvm-strip llvm-objcopy)
 
 if(LLVM_INSTALL_BINUTILS_SYMLINKS)
@@ -53,4 +58,5 @@ endif()
 
 if(LLVM_INSTALL_CCTOOLS_SYMLINKS)
   add_llvm_tool_symlink(install_name_tool llvm-install-name-tool)
+  add_llvm_tool_symlink(bitcode_strip llvm-bitcode-strip)
 endif()
index 63e672e..a98c16e 100644 (file)
@@ -101,6 +101,43 @@ public:
   InstallNameToolOptTable() : OptTable(InstallNameToolInfoTable) {}
 };
 
+enum BitcodeStripID {
+  BITCODE_STRIP_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
+               HELPTEXT, METAVAR, VALUES)                                      \
+  BITCODE_STRIP_##ID,
+#include "BitcodeStripOpts.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE) const char *const BITCODE_STRIP_##NAME[] = VALUE;
+#include "BitcodeStripOpts.inc"
+#undef PREFIX
+
+static const opt::OptTable::Info BitcodeStripInfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
+               HELPTEXT, METAVAR, VALUES)                                      \
+  {BITCODE_STRIP_##PREFIX,                                                     \
+   NAME,                                                                       \
+   HELPTEXT,                                                                   \
+   METAVAR,                                                                    \
+   BITCODE_STRIP_##ID,                                                         \
+   opt::Option::KIND##Class,                                                   \
+   PARAM,                                                                      \
+   FLAGS,                                                                      \
+   BITCODE_STRIP_##GROUP,                                                      \
+   BITCODE_STRIP_##ALIAS,                                                      \
+   ALIASARGS,                                                                  \
+   VALUES},
+#include "BitcodeStripOpts.inc"
+#undef OPTION
+};
+
+class BitcodeStripOptTable : public opt::OptTable {
+public:
+  BitcodeStripOptTable() : OptTable(BitcodeStripInfoTable) {}
+};
+
 enum StripID {
   STRIP_INVALID = 0, // This is not an option ID.
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
@@ -395,7 +432,7 @@ template <class T> static ErrorOr<T> getAsInteger(StringRef Val) {
 
 namespace {
 
-enum class ToolType { Objcopy, Strip, InstallNameTool };
+enum class ToolType { Objcopy, Strip, InstallNameTool, BitcodeStrip };
 
 } // anonymous namespace
 
@@ -415,6 +452,10 @@ static void printHelp(const opt::OptTable &OptTable, raw_ostream &OS,
     ToolName = "llvm-install-name-tool";
     HelpText = " [options] input";
     break;
+  case ToolType::BitcodeStrip:
+    ToolName = "llvm-bitcode-strip";
+    HelpText = " [options] input";
+    break;
   }
   OptTable.PrintHelp(OS, (ToolName + HelpText).str().c_str(),
                      (ToolName + " tool").str().c_str());
@@ -931,6 +972,50 @@ parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
   return std::move(DC);
 }
 
+Expected<DriverConfig>
+parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr) {
+  DriverConfig DC;
+  CopyConfig Config;
+  BitcodeStripOptTable T;
+  unsigned MissingArgumentIndex, MissingArgumentCount;
+  opt::InputArgList InputArgs =
+      T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
+
+  if (InputArgs.size() == 0) {
+    printHelp(T, errs(), ToolType::BitcodeStrip);
+    exit(1);
+  }
+
+  if (InputArgs.hasArg(BITCODE_STRIP_help)) {
+    printHelp(T, outs(), ToolType::BitcodeStrip);
+    exit(0);
+  }
+
+  if (InputArgs.hasArg(BITCODE_STRIP_version)) {
+    outs() << "llvm-bitcode-strip, compatible with cctools "
+              "bitcode_strip\n";
+    cl::PrintVersionMessage();
+    exit(0);
+  }
+
+  for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_UNKNOWN))
+    return createStringError(errc::invalid_argument, "unknown argument '%s'",
+                             Arg->getAsString(InputArgs).c_str());
+
+  SmallVector<StringRef, 2> Positional;
+  for (auto *Arg : InputArgs.filtered(BITCODE_STRIP_INPUT))
+    Positional.push_back(Arg->getValue());
+  if (Positional.size() > 1)
+    return createStringError(errc::invalid_argument,
+                             "llvm-bitcode-strip expects a single input file");
+  assert(!Positional.empty());
+  Config.InputFilename = Positional[0];
+  Config.OutputFilename = Positional[0];
+
+  DC.CopyConfigs.push_back(std::move(Config));
+  return std::move(DC);
+}
+
 // ParseStripOptions returns the config and sets the input arguments. If a
 // help flag is set then ParseStripOptions will print the help messege and
 // exit.
index 1341dd6..666d0d4 100644 (file)
@@ -267,6 +267,11 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
 Expected<DriverConfig>
 parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr);
 
+// ParseBitcodeStripOptions returns the config and sets the input arguments.
+// If a help flag is set then ParseBitcodeStripOptions will print the help
+// messege and exit.
+Expected<DriverConfig> parseBitcodeStripOptions(ArrayRef<const char *> ArgsArr);
+
 // ParseStripOptions returns the config and sets the input arguments. If a
 // help flag is set then ParseStripOptions will print the help messege and
 // exit. ErrorCallback is used to handle recoverable errors. An Error returned
index 69b23b6..ee882ff 100644 (file)
@@ -320,7 +320,7 @@ static Error executeObjcopy(CopyConfig &Config) {
 
 namespace {
 
-enum class ToolType { Objcopy, Strip, InstallNameTool };
+enum class ToolType { Objcopy, Strip, InstallNameTool, BitcodeStrip };
 
 } // anonymous namespace
 
@@ -341,7 +341,9 @@ int main(int argc, char **argv) {
            (I + Tool.size() == Stem.size() || !isAlnum(Stem[I + Tool.size()]));
   };
   ToolType Tool = ToolType::Objcopy;
-  if (Is("strip"))
+  if (Is("bitcode-strip") || Is("bitcode_strip"))
+    Tool = ToolType::BitcodeStrip;
+  else if (Is("strip"))
     Tool = ToolType::Strip;
   else if (Is("install-name-tool") || Is("install_name_tool"))
     Tool = ToolType::InstallNameTool;
@@ -361,10 +363,13 @@ int main(int argc, char **argv) {
 
   auto Args = makeArrayRef(NewArgv).drop_front();
   Expected<DriverConfig> DriverConfig =
-      (Tool == ToolType::Strip) ? parseStripOptions(Args, reportWarning)
-                                : ((Tool == ToolType::InstallNameTool)
-                                       ? parseInstallNameToolOptions(Args)
-                                       : parseObjcopyOptions(Args, reportWarning));
+      (Tool == ToolType::Strip)
+          ? parseStripOptions(Args, reportWarning)
+          : ((Tool == ToolType::InstallNameTool)
+                 ? parseInstallNameToolOptions(Args)
+                 : ((Tool == ToolType::BitcodeStrip)
+                        ? parseBitcodeStripOptions(Args)
+                        : parseObjcopyOptions(Args, reportWarning)));
   if (!DriverConfig) {
     logAllUnhandledErrors(DriverConfig.takeError(),
                           WithColor::error(errs(), ToolName));