[llvm] b5913e6 - Introduce llvm-install-name-tool

Alexander Shaposhnikov via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 6 11:51:06 PST 2019


Author: Alexander Shaposhnikov
Date: 2019-11-06T11:50:58-08:00
New Revision: b5913e6d2f6d13fb753df701619731ca11936316

URL: https://github.com/llvm/llvm-project/commit/b5913e6d2f6d13fb753df701619731ca11936316
DIFF: https://github.com/llvm/llvm-project/commit/b5913e6d2f6d13fb753df701619731ca11936316.diff

LOG: Introduce llvm-install-name-tool

This diff adds a new "driver" for llvm-objcopy
which is supposed to emulate the behavior of install-name-tool.

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

Test plan: make check-all

Added: 
    llvm/test/tools/llvm-objcopy/MachO/Inputs/i386.yaml
    llvm/test/tools/llvm-objcopy/MachO/Inputs/x86_64.yaml
    llvm/test/tools/llvm-objcopy/MachO/install-name-tool-add-rpath.test
    llvm/test/tools/llvm-objcopy/MachO/install-name-tool-help-message.test
    llvm/test/tools/llvm-objcopy/MachO/install-name-tool-version.test
    llvm/tools/llvm-objcopy/InstallNameToolOpts.td

Modified: 
    llvm/tools/llvm-objcopy/CMakeLists.txt
    llvm/tools/llvm-objcopy/CopyConfig.cpp
    llvm/tools/llvm-objcopy/CopyConfig.h
    llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
    llvm/tools/llvm-objcopy/MachO/Object.cpp
    llvm/tools/llvm-objcopy/MachO/Object.h
    llvm/tools/llvm-objcopy/llvm-objcopy.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/test/tools/llvm-objcopy/MachO/Inputs/i386.yaml b/llvm/test/tools/llvm-objcopy/MachO/Inputs/i386.yaml
new file mode 100644
index 000000000000..15e62206e95e
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/Inputs/i386.yaml
@@ -0,0 +1,88 @@
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACE
+  cputype:         0x00000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           4
+  sizeofcmds:      312
+  flags:           0x00002000
+LoadCommands:
+  - cmd:             LC_SEGMENT
+    cmdsize:         192
+    segname:         ''
+    vmaddr:          0
+    vmsize:          72
+    fileoff:         340
+    filesize:        72
+    maxprot:         7
+    initprot:        7
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000000000000
+        size:            18
+        offset:          0x00000154
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __eh_frame
+        segname:         __TEXT
+        addr:            0x0000000000000014
+        size:            52
+        offset:          0x00000168
+        align:           2
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x6800000B
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_VERSION_MIN_MACOSX
+    cmdsize:         16
+    version:         656384
+    sdk:             0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          412
+    nsyms:           1
+    stroff:          424
+    strsize:         8
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       0
+    iextdefsym:      0
+    nextdefsym:      1
+    iundefsym:       1
+    nundefsym:       0
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  0
+    nindirectsyms:   0
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+LinkEditData:
+  NameList:
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+  StringTable:
+    - ''
+    - _main
+    - ''
+...

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/Inputs/x86_64.yaml b/llvm/test/tools/llvm-objcopy/MachO/Inputs/x86_64.yaml
new file mode 100644
index 000000000000..5b059bb5a1bb
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/Inputs/x86_64.yaml
@@ -0,0 +1,89 @@
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x01000007
+  cpusubtype:      0x00000003
+  filetype:        0x00000001
+  ncmds:           4
+  sizeofcmds:      352
+  flags:           0x00002000
+  reserved:        0x00000000
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         ''
+    vmaddr:          0
+    vmsize:          80
+    fileoff:         384
+    filesize:        80
+    maxprot:         7
+    initprot:        7
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x0000000000000000
+        size:            15
+        offset:          0x00000180
+        align:           4
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+      - sectname:        __eh_frame
+        segname:         __TEXT
+        addr:            0x0000000000000010
+        size:            64
+        offset:          0x00000190
+        align:           3
+        reloff:          0x00000000
+        nreloc:          0
+        flags:           0x6800000B
+        reserved1:       0x00000000
+        reserved2:       0x00000000
+        reserved3:       0x00000000
+  - cmd:             LC_VERSION_MIN_MACOSX
+    cmdsize:         16
+    version:         656384
+    sdk:             0
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          464
+    nsyms:           1
+    stroff:          480
+    strsize:         8
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       0
+    iextdefsym:      0
+    nextdefsym:      1
+    iundefsym:       1
+    nundefsym:       0
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  0
+    nindirectsyms:   0
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+LinkEditData:
+  NameList:
+    - n_strx:          1
+      n_type:          0x0F
+      n_sect:          1
+      n_desc:          0
+      n_value:         0
+  StringTable:
+    - ''
+    - _main
+    - ''
+...

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-add-rpath.test b/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-add-rpath.test
new file mode 100644
index 000000000000..6d262019429a
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-add-rpath.test
@@ -0,0 +1,23 @@
+## This test checks adding a new LC_RPATH load command to a MachO binary.
+
+# RUN: yaml2obj %p/Inputs/i386.yaml > %t.i386
+# RUN: llvm-install-name-tool -add_rpath @executable_path/. %t.i386
+# RUN: llvm-objdump -p %t.i386 | FileCheck --check-prefix=NEW-RPATH %s
+
+# RUN: yaml2obj %p/Inputs/x86_64.yaml > %t.x86_64
+# RUN: llvm-install-name-tool -add_rpath @executable_path/. %t.x86_64
+# RUN: llvm-objdump -p %t.x86_64 | FileCheck --check-prefix=NEW-RPATH %s
+
+# NEW-RPATH: cmd LC_RPATH
+# NEW-RPATH-NEXT: cmdsize
+# NEW-RPATH-NEXT: @executable_path/.
+
+# RUN: not llvm-install-name-tool -add_rpath @executable_path/. %t.i386 2>&1 \
+# RUN: | FileCheck --check-prefix=DUPLICATE-RPATH %s
+
+# DUPLICATE-RPATH: duplicate load command
+
+# RUN: not llvm-install-name-tool -add_rpath @executable_path/. 2>&1 \
+# RUN: | FileCheck --check-prefix=NO-INPUT %s
+
+# NO-INPUT: no input file specified

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-help-message.test b/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-help-message.test
new file mode 100644
index 000000000000..43e5290c3793
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-help-message.test
@@ -0,0 +1,10 @@
+# RUN: llvm-install-name-tool -h | FileCheck --check-prefix=INSTALL-NAME-TOOL-USAGE %s
+# RUN: llvm-install-name-tool --help | FileCheck --check-prefix=INSTALL-NAME-TOOL-USAGE %s
+# RUN: not llvm-install-name-tool 2>&1 | FileCheck --check-prefix=INSTALL-NAME-TOOL-USAGE %s
+# RUN: not llvm-install-name-tool -abcabc 2>&1 | FileCheck --check-prefix=UNKNOWN-ARG %s
+# RUN: not llvm-install-name-tool --abcabc 2>&1 | FileCheck --check-prefix=UNKNOWN-ARG %s
+
+# INSTALL-NAME-TOOL-USAGE: USAGE: llvm-install-name-tool
+# INSTALL-NAME-TOOL-USAGE: @FILE
+
+# UNKNOWN-ARG: unknown argument '{{-+}}abcabc'

diff  --git a/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-version.test b/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-version.test
new file mode 100644
index 000000000000..295e57356101
--- /dev/null
+++ b/llvm/test/tools/llvm-objcopy/MachO/install-name-tool-version.test
@@ -0,0 +1,2 @@
+# RUN: llvm-install-name-tool --version | FileCheck %s
+# CHECK: {{ version }}

diff  --git a/llvm/tools/llvm-objcopy/CMakeLists.txt b/llvm/tools/llvm-objcopy/CMakeLists.txt
index 50c890b59769..6d4048f040ba 100644
--- a/llvm/tools/llvm-objcopy/CMakeLists.txt
+++ b/llvm/tools/llvm-objcopy/CMakeLists.txt
@@ -9,6 +9,10 @@ set(LLVM_TARGET_DEFINITIONS ObjcopyOpts.td)
 tablegen(LLVM ObjcopyOpts.inc -gen-opt-parser-defs)
 add_public_tablegen_target(ObjcopyOptsTableGen)
 
+set(LLVM_TARGET_DEFINITIONS InstallNameToolOpts.td)
+tablegen(LLVM InstallNameToolOpts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(InstallNameToolOptsTableGen)
+
 set(LLVM_TARGET_DEFINITIONS StripOpts.td)
 tablegen(LLVM StripOpts.inc -gen-opt-parser-defs)
 add_public_tablegen_target(StripOptsTableGen)
@@ -31,9 +35,11 @@ add_llvm_tool(llvm-objcopy
   MachO/Object.cpp
   DEPENDS
   ObjcopyOptsTableGen
+  InstallNameToolOptsTableGen
   StripOptsTableGen
   )
 
+add_llvm_tool_symlink(llvm-install-name-tool llvm-objcopy)
 add_llvm_tool_symlink(llvm-strip llvm-objcopy)
 
 if(LLVM_INSTALL_BINUTILS_SYMLINKS)

diff  --git a/llvm/tools/llvm-objcopy/CopyConfig.cpp b/llvm/tools/llvm-objcopy/CopyConfig.cpp
index d707bec20c49..73ed00b5cb2a 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.cpp
+++ b/llvm/tools/llvm-objcopy/CopyConfig.cpp
@@ -63,6 +63,44 @@ class ObjcopyOptTable : public opt::OptTable {
   ObjcopyOptTable() : OptTable(ObjcopyInfoTable) {}
 };
 
+enum InstallNameToolID {
+  INSTALL_NAME_TOOL_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
+               HELPTEXT, METAVAR, VALUES)                                      \
+  INSTALL_NAME_TOOL_##ID,
+#include "InstallNameToolOpts.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE)                                                    \
+  const char *const INSTALL_NAME_TOOL_##NAME[] = VALUE;
+#include "InstallNameToolOpts.inc"
+#undef PREFIX
+
+static const opt::OptTable::Info InstallNameToolInfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
+               HELPTEXT, METAVAR, VALUES)                                      \
+  {INSTALL_NAME_TOOL_##PREFIX,                                                 \
+   NAME,                                                                       \
+   HELPTEXT,                                                                   \
+   METAVAR,                                                                    \
+   INSTALL_NAME_TOOL_##ID,                                                     \
+   opt::Option::KIND##Class,                                                   \
+   PARAM,                                                                      \
+   FLAGS,                                                                      \
+   INSTALL_NAME_TOOL_##GROUP,                                                  \
+   INSTALL_NAME_TOOL_##ALIAS,                                                  \
+   ALIASARGS,                                                                  \
+   VALUES},
+#include "InstallNameToolOpts.inc"
+#undef OPTION
+};
+
+class InstallNameToolOptTable : public opt::OptTable {
+public:
+  InstallNameToolOptTable() : OptTable(InstallNameToolInfoTable) {}
+};
+
 enum StripID {
   STRIP_INVALID = 0, // This is not an option ID.
 #define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM,  \
@@ -752,6 +790,57 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
   return std::move(DC);
 }
 
+// ParseInstallNameToolOptions returns the config and sets the input arguments.
+// If a help flag is set then ParseInstallNameToolOptions will print the help
+// messege and exit.
+Expected<DriverConfig>
+parseInstallNameToolOptions(ArrayRef<const char *> ArgsArr) {
+  DriverConfig DC;
+  CopyConfig Config;
+  InstallNameToolOptTable T;
+  unsigned MissingArgumentIndex, MissingArgumentCount;
+  llvm::opt::InputArgList InputArgs =
+      T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
+
+  if (InputArgs.size() == 0) {
+    printHelp(T, errs(), "llvm-install-name-tool");
+    exit(1);
+  }
+
+  if (InputArgs.hasArg(INSTALL_NAME_TOOL_help)) {
+    printHelp(T, outs(), "llvm-install-name-tool");
+    exit(0);
+  }
+
+  if (InputArgs.hasArg(INSTALL_NAME_TOOL_version)) {
+    outs() << "llvm-install-name-tool, compatible with cctools "
+              "install_name_tool\n";
+    cl::PrintVersionMessage();
+    exit(0);
+  }
+
+  for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_add_rpath))
+    Config.RPathToAdd.push_back(Arg->getValue());
+
+  SmallVector<StringRef, 2> Positional;
+  for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_UNKNOWN))
+    return createStringError(errc::invalid_argument, "unknown argument '%s'",
+                             Arg->getAsString(InputArgs).c_str());
+  for (auto Arg : InputArgs.filtered(INSTALL_NAME_TOOL_INPUT))
+    Positional.push_back(Arg->getValue());
+  if (Positional.empty())
+    return createStringError(errc::invalid_argument, "no input file specified");
+  if (Positional.size() > 1)
+    return createStringError(
+        errc::invalid_argument,
+        "llvm-install-name-tool expects a single input file");
+  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.

diff  --git a/llvm/tools/llvm-objcopy/CopyConfig.h b/llvm/tools/llvm-objcopy/CopyConfig.h
index 55a55d3a2bc2..c83f688e76c2 100644
--- a/llvm/tools/llvm-objcopy/CopyConfig.h
+++ b/llvm/tools/llvm-objcopy/CopyConfig.h
@@ -175,6 +175,7 @@ struct CopyConfig {
   std::vector<StringRef> AddSection;
   std::vector<StringRef> DumpSection;
   std::vector<StringRef> SymbolsToAdd;
+  std::vector<StringRef> RPathToAdd;
 
   // Section matchers
   NameMatcher KeepSection;
@@ -251,6 +252,12 @@ Expected<DriverConfig>
 parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
                     llvm::function_ref<Error(Error)> ErrorCallback);
 
+// ParseInstallNameToolOptions returns the config and sets the input arguments.
+// If a help flag is set then ParseInstallNameToolOptions will print the help
+// messege and exit.
+Expected<DriverConfig>
+parseInstallNameToolOptions(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
@@ -258,7 +265,6 @@ parseObjcopyOptions(ArrayRef<const char *> ArgsArr,
 Expected<DriverConfig>
 parseStripOptions(ArrayRef<const char *> ArgsArr,
                   llvm::function_ref<Error(Error)> ErrorCallback);
-
 } // namespace objcopy
 } // namespace llvm
 

diff  --git a/llvm/tools/llvm-objcopy/InstallNameToolOpts.td b/llvm/tools/llvm-objcopy/InstallNameToolOpts.td
new file mode 100644
index 000000000000..35047a57994c
--- /dev/null
+++ b/llvm/tools/llvm-objcopy/InstallNameToolOpts.td
@@ -0,0 +1,22 @@
+//===-- InstallNameToolOpts.td - llvm-install-name-tool 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-install-name.
+//
+//===----------------------------------------------------------------------===//
+
+include "llvm/Option/OptParser.td"
+
+def help : Flag<["--"], "help">;
+def h : Flag<["-"], "h">, Alias<help>;
+
+def add_rpath : Option<["-", "--"], "add_rpath", KIND_SEPARATE>,
+                HelpText<"Add new rpath">;
+
+def version : Flag<["--"], "version">,
+              HelpText<"Print the version and exit.">;

diff  --git a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
index d14354e8d067..652c0ac09577 100644
--- a/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/MachOObjcopy.cpp
@@ -59,6 +59,18 @@ static void removeSymbols(const CopyConfig &Config, Object &Obj) {
   Obj.SymTable.removeSymbols(RemovePred);
 }
 
+static LoadCommand buildRPathLoadCommand(StringRef Path) {
+  LoadCommand LC;
+  MachO::rpath_command RPathLC;
+  RPathLC.cmd = MachO::LC_RPATH;
+  RPathLC.path = sizeof(MachO::rpath_command);
+  RPathLC.cmdsize = alignTo(sizeof(MachO::rpath_command) + Path.size(), 8);
+  LC.MachOLoadCommand.rpath_command_data = RPathLC;
+  LC.Payload.assign(RPathLC.cmdsize - sizeof(MachO::rpath_command), 0);
+  std::copy(Path.begin(), Path.end(), LC.Payload.begin());
+  return LC;
+}
+
 static Error handleArgs(const CopyConfig &Config, Object &Obj) {
   if (Config.AllowBrokenLinks || !Config.BuildIdLinkDir.empty() ||
       Config.BuildIdLinkInput || Config.BuildIdLinkOutput ||
@@ -81,7 +93,6 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
     return createStringError(llvm::errc::invalid_argument,
                              "option not supported by llvm-objcopy for MachO");
   }
-
   removeSections(Config, Obj);
 
   // Mark symbols to determine which symbols are still needed.
@@ -95,6 +106,19 @@ static Error handleArgs(const CopyConfig &Config, Object &Obj) {
       for (Section &Sec : LC.Sections)
         Sec.Relocations.clear();
 
+  for (StringRef RPath : Config.RPathToAdd) {
+    for (LoadCommand &LC : Obj.LoadCommands) {
+      if (LC.MachOLoadCommand.load_command_data.cmd == MachO::LC_RPATH &&
+          RPath == StringRef(reinterpret_cast<char *>(LC.Payload.data()),
+                             LC.Payload.size())
+                       .trim(0)) {
+        return createStringError(errc::invalid_argument,
+                                 "rpath " + RPath +
+                                     " would create a duplicate load command");
+      }
+    }
+    Obj.addLoadCommand(buildRPathLoadCommand(RPath));
+  }
   return Error::success();
 }
 

diff  --git a/llvm/tools/llvm-objcopy/MachO/Object.cpp b/llvm/tools/llvm-objcopy/MachO/Object.cpp
index 5626782d7d6e..812853ec4639 100644
--- a/llvm/tools/llvm-objcopy/MachO/Object.cpp
+++ b/llvm/tools/llvm-objcopy/MachO/Object.cpp
@@ -29,6 +29,10 @@ void Object::removeSections(function_ref<bool(const Section &)> ToRemove) {
                       std::end(LC.Sections));
 }
 
+void Object::addLoadCommand(LoadCommand LC) {
+  LoadCommands.push_back(std::move(LC));
+}
+
 } // end namespace macho
 } // end namespace objcopy
 } // end namespace llvm

diff  --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h
index 8642ce3c0d94..098556d7402c 100644
--- a/llvm/tools/llvm-objcopy/MachO/Object.h
+++ b/llvm/tools/llvm-objcopy/MachO/Object.h
@@ -74,7 +74,7 @@ struct LoadCommand {
   // The raw content of the payload of the load command (located right after the
   // corresponding struct). In some cases it is either empty or can be
   // copied-over without digging into its structure.
-  ArrayRef<uint8_t> Payload;
+  std::vector<uint8_t> Payload; 
 
   // Some load commands can contain (inside the payload) an array of sections,
   // though the contents of the sections are stored separately. The struct
@@ -270,6 +270,7 @@ struct Object {
   Optional<size_t> FunctionStartsCommandIndex;
 
   void removeSections(function_ref<bool(const Section &)> ToRemove);
+  void addLoadCommand(LoadCommand LC);
 };
 
 } // end namespace macho

diff  --git a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
index a68210f3fdd3..e662f35f4b08 100644
--- a/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
+++ b/llvm/tools/llvm-objcopy/llvm-objcopy.cpp
@@ -313,11 +313,20 @@ static Error executeObjcopy(CopyConfig &Config) {
   return Error::success();
 }
 
+namespace {
+
+enum class ToolType { Objcopy, Strip, InstallNameTool };
+
+} // anonymous namespace
+
 int main(int argc, char **argv) {
   InitLLVM X(argc, argv);
   ToolName = argv[0];
-  bool IsStrip = sys::path::stem(ToolName).contains("strip");
-
+  ToolType Tool = StringSwitch<ToolType>(sys::path::stem(ToolName))
+                      .EndsWith("strip", ToolType::Strip)
+                      .EndsWith("install-name-tool", ToolType::InstallNameTool)
+                      .EndsWith("install_name_tool", ToolType::InstallNameTool)
+                      .Default(ToolType::Objcopy);
   // Expand response files.
   // TODO: Move these lines, which are copied from lib/Support/CommandLine.cpp,
   // into a separate function in the CommandLine library and call that function
@@ -332,10 +341,11 @@ int main(int argc, char **argv) {
                           NewArgv);
 
   auto Args = makeArrayRef(NewArgv).drop_front();
-
   Expected<DriverConfig> DriverConfig =
-      IsStrip ? parseStripOptions(Args, reportWarning)
-              : parseObjcopyOptions(Args, reportWarning);
+      (Tool == ToolType::Strip) ? parseStripOptions(Args, reportWarning)
+                                : ((Tool == ToolType::InstallNameTool)
+                                       ? parseInstallNameToolOptions(Args)
+                                       : parseObjcopyOptions(Args, reportWarning));
   if (!DriverConfig) {
     logAllUnhandledErrors(DriverConfig.takeError(),
                           WithColor::error(errs(), ToolName));


        


More information about the llvm-commits mailing list