[llvm] r361896 - [tools] Introduce llvm-lipo
Alexander Shaposhnikov via llvm-commits
llvm-commits at lists.llvm.org
Tue May 28 16:22:13 PDT 2019
Author: alexshap
Date: Tue May 28 16:22:12 2019
New Revision: 361896
URL: http://llvm.org/viewvc/llvm-project?rev=361896&view=rev
Log:
[tools] Introduce llvm-lipo
This diff starts the implementation of llvm-lipo
which is supposed to be a drop-in replacement for the well-known tool lipo.
Test plan: make check-all
Differential revision: https://reviews.llvm.org/D61927
Added:
llvm/trunk/test/tools/llvm-lipo/
llvm/trunk/test/tools/llvm-lipo/help-message.test
llvm/trunk/test/tools/llvm-lipo/verify-arch-macho-binary.test
llvm/trunk/test/tools/llvm-lipo/verify-arch-universal-binary.test
llvm/trunk/tools/llvm-lipo/
llvm/trunk/tools/llvm-lipo/CMakeLists.txt
llvm/trunk/tools/llvm-lipo/LLVMBuild.txt
llvm/trunk/tools/llvm-lipo/LipoOpts.td
llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp
Modified:
llvm/trunk/test/CMakeLists.txt
Modified: llvm/trunk/test/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CMakeLists.txt?rev=361896&r1=361895&r2=361896&view=diff
==============================================================================
--- llvm/trunk/test/CMakeLists.txt (original)
+++ llvm/trunk/test/CMakeLists.txt Tue May 28 16:22:12 2019
@@ -72,6 +72,7 @@ set(LLVM_TEST_DEPENDS
llvm-jitlink
llvm-lib
llvm-link
+ llvm-lipo
llvm-lto2
llvm-mc
llvm-mca
Added: llvm/trunk/test/tools/llvm-lipo/help-message.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-lipo/help-message.test?rev=361896&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-lipo/help-message.test (added)
+++ llvm/trunk/test/tools/llvm-lipo/help-message.test Tue May 28 16:22:12 2019
@@ -0,0 +1,13 @@
+# RUN: llvm-lipo -h | FileCheck --check-prefix=LIPO-USAGE %s
+# RUN: llvm-lipo --help | FileCheck --check-prefix=LIPO-USAGE %s
+
+# RUN: llvm-lipo -version | FileCheck --check-prefix=LIPO-VERSION %s
+# RUN: llvm-lipo --version | FileCheck --check-prefix=LIPO-VERSION %s
+
+# RUN: not llvm-lipo 2>&1 | FileCheck --check-prefix=LIPO-USAGE %s
+# RUN: not llvm-lipo -abcabc 2>&1 | FileCheck --check-prefix=LIPO-UNKNOWN-ARG %s
+# RUN: not llvm-lipo --abcabc 2>&1 | FileCheck --check-prefix=LIPO-UNKNOWN-ARG %s
+
+# LIPO-USAGE: USAGE: llvm-lipo
+# LIPO-UNKNOWN-ARG: unknown argument '{{-+}}abcabc'
+# LIPO-VERSION: {{ version }}
Added: llvm/trunk/test/tools/llvm-lipo/verify-arch-macho-binary.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-lipo/verify-arch-macho-binary.test?rev=361896&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-lipo/verify-arch-macho-binary.test (added)
+++ llvm/trunk/test/tools/llvm-lipo/verify-arch-macho-binary.test Tue May 28 16:22:12 2019
@@ -0,0 +1,31 @@
+# RUN: yaml2obj %s > %t
+
+# RUN: llvm-lipo %t -verify_arch i386
+# RUN: llvm-lipo %t --verify_arch i386
+
+# RUN: not llvm-lipo %t -verify_arch aarch64
+# RUN: not llvm-lipo %t -verify_arch aarch64 i386
+
+# INVALID_ARCH: Invalid architecture: aarch101
+# RUN: not llvm-lipo %t -verify_arch aarch101 2>&1 | FileCheck --check-prefix=INVALID_ARCH %s
+
+# INVALID_OBJ: The file was not recognized as a valid object file
+# RUN: touch %t.empty
+# RUN: not llvm-lipo %t.empty -verify_arch aarch101 2>&1 | FileCheck --check-prefix=INVALID_OBJ %s
+
+# NO_INPUT_OBJ: at least one input file should be specified
+# RUN: not llvm-lipo -verify_arch i386 2>&1 | FileCheck --check-prefix=NO_INPUT_OBJ %s
+
+# MULTIPLE_INPUT_OBJ: verify_arch expects a single input file
+# RUN: not llvm-lipo %t %t -verify_arch i386 2>&1 | FileCheck --check-prefix=MULTIPLE_INPUT_OBJ %s
+
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACE
+ cputype: 0x00000007
+ cpusubtype: 0x00000003
+ filetype: 0x00000001
+ ncmds: 0
+ sizeofcmds: 0
+ flags: 0x00002000
+...
Added: llvm/trunk/test/tools/llvm-lipo/verify-arch-universal-binary.test
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-lipo/verify-arch-universal-binary.test?rev=361896&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-lipo/verify-arch-universal-binary.test (added)
+++ llvm/trunk/test/tools/llvm-lipo/verify-arch-universal-binary.test Tue May 28 16:22:12 2019
@@ -0,0 +1,44 @@
+# RUN: yaml2obj %s > %t
+
+# RUN: llvm-lipo %t -verify_arch i386
+# RUN: llvm-lipo %t -verify_arch i386 x86_64
+
+# RUN: not llvm-lipo %t -verify_arch aarch64
+# RUN: not llvm-lipo %t -verify_arch aarch64 i386
+
+--- !fat-mach-o
+FatHeader:
+ magic: 0xCAFEBABE
+ nfat_arch: 2
+FatArchs:
+ - cputype: 0x00000007
+ cpusubtype: 0x00000003
+ offset: 0x0000000000001000
+ size: 28
+ align: 12
+ - cputype: 0x01000007
+ cpusubtype: 0x00000003
+ offset: 0x0000000000002000
+ size: 32
+ align: 12
+Slices:
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACE
+ cputype: 0x00000007
+ cpusubtype: 0x00000003
+ filetype: 0x00000001
+ ncmds: 0
+ sizeofcmds: 0
+ flags: 0x00002000
+ - !mach-o
+ FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x01000007
+ cpusubtype: 0x00000003
+ filetype: 0x00000001
+ ncmds: 0
+ sizeofcmds: 0
+ flags: 0x00002000
+ reserved: 0x00000000
+...
Added: llvm/trunk/tools/llvm-lipo/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lipo/CMakeLists.txt?rev=361896&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-lipo/CMakeLists.txt (added)
+++ llvm/trunk/tools/llvm-lipo/CMakeLists.txt Tue May 28 16:22:12 2019
@@ -0,0 +1,16 @@
+set(LLVM_LINK_COMPONENTS
+ ${LLVM_TARGETS_TO_BUILD}
+ Object
+ Option
+ Support
+)
+
+set(LLVM_TARGET_DEFINITIONS LipoOpts.td)
+tablegen(LLVM LipoOpts.inc -gen-opt-parser-defs)
+add_public_tablegen_target(LipoOptsTableGen)
+
+add_llvm_tool(llvm-lipo
+ llvm-lipo.cpp
+ DEPENDS
+ LipoOptsTableGen
+)
Added: llvm/trunk/tools/llvm-lipo/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lipo/LLVMBuild.txt?rev=361896&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-lipo/LLVMBuild.txt (added)
+++ llvm/trunk/tools/llvm-lipo/LLVMBuild.txt Tue May 28 16:22:12 2019
@@ -0,0 +1,20 @@
+;===- ./tools/llvm-lipo/LLVMBuild.txt --------------------------*- Conf -*--===;
+;
+; 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 is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+[component_0]
+type = Tool
+name = llvm-lipo
+parent = Tools
+required_libraries = Object Option Support
Added: llvm/trunk/tools/llvm-lipo/LipoOpts.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lipo/LipoOpts.td?rev=361896&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-lipo/LipoOpts.td (added)
+++ llvm/trunk/tools/llvm-lipo/LipoOpts.td Tue May 28 16:22:12 2019
@@ -0,0 +1,10 @@
+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 verify_arch : Option<["-", "--"], "verify_arch", KIND_REMAINING_ARGS>,
+ HelpText<"Verify that the specified arch_types are present in the input file">;
Added: llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp?rev=361896&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp (added)
+++ llvm/trunk/tools/llvm-lipo/llvm-lipo.cpp Tue May 28 16:22:12 2019
@@ -0,0 +1,185 @@
+//===-- llvm-lipo.cpp - a tool for manipulating universal binaries --------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// A utility for creating / splitting / inspecting universal binaries.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/MachO.h"
+#include "llvm/Object/MachOUniversal.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Option/Arg.h"
+#include "llvm/Option/ArgList.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/InitLLVM.h"
+#include "llvm/Support/WithColor.h"
+
+using namespace llvm;
+using namespace llvm::object;
+
+static const StringRef ToolName = "llvm-lipo";
+
+LLVM_ATTRIBUTE_NORETURN static void reportError(Twine Message) {
+ WithColor::error(errs(), ToolName) << Message << "\n";
+ errs().flush();
+ exit(EXIT_FAILURE);
+}
+
+LLVM_ATTRIBUTE_NORETURN static void reportError(StringRef File, Error E) {
+ assert(E);
+ std::string Buf;
+ raw_string_ostream OS(Buf);
+ logAllUnhandledErrors(std::move(E), OS);
+ OS.flush();
+ WithColor::error(errs(), ToolName) << "'" << File << "': " << Buf;
+ exit(EXIT_FAILURE);
+}
+
+namespace {
+enum LipoID {
+ LIPO_INVALID = 0, // This is not an option ID.
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ LIPO_##ID,
+#include "LipoOpts.inc"
+#undef OPTION
+};
+
+#define PREFIX(NAME, VALUE) const char *const LIPO_##NAME[] = VALUE;
+#include "LipoOpts.inc"
+#undef PREFIX
+
+static const opt::OptTable::Info LipoInfoTable[] = {
+#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
+ HELPTEXT, METAVAR, VALUES) \
+ {LIPO_##PREFIX, NAME, HELPTEXT, \
+ METAVAR, LIPO_##ID, opt::Option::KIND##Class, \
+ PARAM, FLAGS, LIPO_##GROUP, \
+ LIPO_##ALIAS, ALIASARGS, VALUES},
+#include "LipoOpts.inc"
+#undef OPTION
+};
+
+class LipoOptTable : public opt::OptTable {
+public:
+ LipoOptTable() : OptTable(LipoInfoTable) {}
+};
+
+struct Config {
+ SmallVector<std::string, 1> InputFiles;
+ SmallVector<std::string, 1> VerifyArchList;
+};
+
+} // end namespace
+
+static Config parseLipoOptions(ArrayRef<const char *> ArgsArr) {
+ Config C;
+ LipoOptTable T;
+ unsigned MissingArgumentIndex, MissingArgumentCount;
+ llvm::opt::InputArgList InputArgs =
+ T.ParseArgs(ArgsArr, MissingArgumentIndex, MissingArgumentCount);
+
+ if (InputArgs.size() == 0) {
+ // PrintHelp does not accept Twine.
+ T.PrintHelp(errs(), "llvm-lipo input[s] option[s]", "llvm-lipo");
+ exit(EXIT_FAILURE);
+ }
+
+ if (InputArgs.hasArg(LIPO_help)) {
+ // PrintHelp does not accept Twine.
+ T.PrintHelp(outs(), "llvm-lipo input[s] option[s]", "llvm-lipo");
+ exit(EXIT_SUCCESS);
+ }
+
+ if (InputArgs.hasArg(LIPO_version)) {
+ outs() << ToolName + "\n";
+ cl::PrintVersionMessage();
+ exit(EXIT_SUCCESS);
+ }
+
+ for (auto Arg : InputArgs.filtered(LIPO_UNKNOWN))
+ reportError("unknown argument '" + Arg->getAsString(InputArgs) + "'");
+
+ for (auto Arg : InputArgs.filtered(LIPO_INPUT))
+ C.InputFiles.push_back(Arg->getValue());
+ if (C.InputFiles.empty())
+ reportError("at least one input file should be specified");
+
+ if (InputArgs.hasArg(LIPO_verify_arch)) {
+ for (auto A : InputArgs.getAllArgValues(LIPO_verify_arch))
+ C.VerifyArchList.push_back(A);
+ if (C.VerifyArchList.empty())
+ reportError(
+ "verify_arch requires at least one architecture to be specified");
+ if (C.InputFiles.size() > 1)
+ reportError("verify_arch expects a single input file");
+ }
+ return C;
+}
+
+static SmallVector<OwningBinary<Binary>, 1>
+readInputBinaries(ArrayRef<std::string> InputFiles) {
+ SmallVector<OwningBinary<Binary>, 1> InputBinaries;
+ for (StringRef InputFile : InputFiles) {
+ Expected<OwningBinary<llvm::object::Binary>> BinaryOrErr =
+ createBinary(InputFile);
+ if (!BinaryOrErr)
+ reportError(InputFile, BinaryOrErr.takeError());
+ if (!isa<MachOObjectFile>(BinaryOrErr->getBinary()) &&
+ !isa<MachOUniversalBinary>(BinaryOrErr->getBinary()))
+ reportError("File " + InputFile + " has unsupported binary format");
+ InputBinaries.push_back(std::move(*BinaryOrErr));
+ }
+ return InputBinaries;
+}
+
+LLVM_ATTRIBUTE_NORETURN
+static void verifyArch(ArrayRef<OwningBinary<Binary>> InputBinaries,
+ ArrayRef<std::string> VerifyArchList) {
+ assert(!InputBinaries.empty() &&
+ "The list of input binaries should be non-empty");
+ assert(!VerifyArchList.empty() &&
+ "The list of architectures should be non-empty");
+ assert(InputBinaries.size() == 1 && "Incorrect number of input binaries");
+
+ for (StringRef Arch : VerifyArchList)
+ if (Triple(Arch).getArch() == Triple::ArchType::UnknownArch)
+ reportError("Invalid architecture: " + Arch);
+
+ if (auto UO =
+ dyn_cast<MachOUniversalBinary>(InputBinaries.front().getBinary())) {
+ for (StringRef Arch : VerifyArchList) {
+ Expected<std::unique_ptr<MachOObjectFile>> Obj =
+ UO->getObjectForArch(Arch);
+ if (!Obj)
+ exit(EXIT_FAILURE);
+ }
+ } else if (auto O =
+ dyn_cast<MachOObjectFile>(InputBinaries.front().getBinary())) {
+ const Triple::ArchType ObjectArch = O->getArch();
+ for (StringRef Arch : VerifyArchList)
+ if (ObjectArch != Triple(Arch).getArch())
+ exit(EXIT_FAILURE);
+ } else {
+ llvm_unreachable("Unexpected binary format");
+ }
+ exit(EXIT_SUCCESS);
+}
+
+int main(int argc, char **argv) {
+ InitLLVM X(argc, argv);
+ Config C = parseLipoOptions(makeArrayRef(argv + 1, argc));
+ SmallVector<OwningBinary<Binary>, 1> InputBinaries =
+ readInputBinaries(C.InputFiles);
+ if (!C.VerifyArchList.empty())
+ verifyArch(InputBinaries, C.VerifyArchList);
+ return EXIT_SUCCESS;
+}
More information about the llvm-commits
mailing list