1 //===-- llvm-tapi-diff.cpp - tbd comparator command-line driver ---*-
2 // C++
3 //-*-===//
4 //
5 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6 // See https://llvm.org/LICENSE.txt for license information.
7 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // This file defines the command-line driver for the llvm-tapi difference
12 // engine.
13 //
14 //===----------------------------------------------------------------------===//
15 #include "DiffEngine.h"
16 #include "llvm/Object/TapiUniversal.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/Error.h"
19 #include "llvm/Support/InitLLVM.h"
20 #include "llvm/Support/WithColor.h"
21 #include "llvm/Support/raw_ostream.h"
22 #include <cstdlib>
23
24 using namespace llvm;
25 using namespace MachO;
26 using namespace object;
27
28 namespace {
29 cl::OptionCategory NMCat("llvm-tapi-diff Options");
30 cl::opt<std::string> InputFileNameLHS(cl::Positional, cl::desc("<first file>"),
31 cl::cat(NMCat));
32 cl::opt<std::string> InputFileNameRHS(cl::Positional, cl::desc("<second file>"),
33 cl::cat(NMCat));
34
35 std::string ToolName;
36 } // anonymous namespace
37
38 ExitOnError ExitOnErr;
39
setErrorBanner(ExitOnError & ExitOnErr,std::string InputFile)40 void setErrorBanner(ExitOnError &ExitOnErr, std::string InputFile) {
41 ExitOnErr.setBanner(ToolName + ": error: " + InputFile + ": ");
42 }
43
convertFileToBinary(std::string & Filename)44 Expected<std::unique_ptr<Binary>> convertFileToBinary(std::string &Filename) {
45 ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
46 MemoryBuffer::getFileOrSTDIN(Filename);
47 if (BufferOrErr.getError())
48 return errorCodeToError(BufferOrErr.getError());
49 return createBinary(BufferOrErr.get()->getMemBufferRef());
50 }
51
main(int Argc,char ** Argv)52 int main(int Argc, char **Argv) {
53 InitLLVM X(Argc, Argv);
54 cl::HideUnrelatedOptions(NMCat);
55 cl::ParseCommandLineOptions(
56 Argc, Argv,
57 "This tool will compare two tbd files and return the "
58 "differences in those files.");
59 if (InputFileNameLHS.empty() || InputFileNameRHS.empty()) {
60 cl::PrintHelpMessage();
61 return EXIT_FAILURE;
62 }
63
64 ToolName = Argv[0];
65
66 setErrorBanner(ExitOnErr, InputFileNameLHS);
67 auto BinLHS = ExitOnErr(convertFileToBinary(InputFileNameLHS));
68
69 TapiUniversal *FileLHS = dyn_cast<TapiUniversal>(BinLHS.get());
70 if (!FileLHS) {
71 ExitOnErr(
72 createStringError(std::errc::executable_format_error,
73 "Error when parsing file, unsupported file format"));
74 }
75
76 setErrorBanner(ExitOnErr, InputFileNameRHS);
77 auto BinRHS = ExitOnErr(convertFileToBinary(InputFileNameRHS));
78
79 TapiUniversal *FileRHS = dyn_cast<TapiUniversal>(BinRHS.get());
80 if (!FileRHS) {
81 ExitOnErr(
82 createStringError(std::errc::executable_format_error,
83 "Error when parsing file, unsupported file format"));
84 }
85
86 raw_ostream &OS = outs();
87
88 return DiffEngine(FileLHS, FileRHS).compareFiles(OS);
89 }
90