xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-modextract/llvm-modextract.cpp (revision 13ec1e3155c7e9bf037b12af186351b7fa9b9450)
1 //===-- llvm-modextract.cpp - LLVM module extractor utility ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This program is for testing features that rely on multi-module bitcode files.
10 // It takes a multi-module bitcode file, extracts one of the modules and writes
11 // it to the output file.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/Bitcode/BitcodeReader.h"
16 #include "llvm/Bitcode/BitcodeWriter.h"
17 #include "llvm/Support/CommandLine.h"
18 #include "llvm/Support/Error.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/ToolOutputFile.h"
21 
22 using namespace llvm;
23 
24 static cl::OptionCategory ModextractCategory("Modextract Options");
25 
26 static cl::opt<bool>
27     BinaryExtract("b", cl::desc("Whether to perform binary extraction"),
28                   cl::cat(ModextractCategory));
29 
30 static cl::opt<std::string> OutputFilename("o", cl::Required,
31                                            cl::desc("Output filename"),
32                                            cl::value_desc("filename"),
33                                            cl::cat(ModextractCategory));
34 
35 static cl::opt<std::string> InputFilename(cl::Positional,
36                                           cl::desc("<input bitcode>"),
37                                           cl::init("-"),
38                                           cl::cat(ModextractCategory));
39 
40 static cl::opt<unsigned> ModuleIndex("n", cl::Required,
41                                      cl::desc("Index of module to extract"),
42                                      cl::value_desc("index"),
43                                      cl::cat(ModextractCategory));
44 
45 int main(int argc, char **argv) {
46   cl::HideUnrelatedOptions({&ModextractCategory, &getColorCategory()});
47   cl::ParseCommandLineOptions(argc, argv, "Module extractor");
48 
49   ExitOnError ExitOnErr("llvm-modextract: error: ");
50 
51   std::unique_ptr<MemoryBuffer> MB =
52       ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename)));
53   std::vector<BitcodeModule> Ms = ExitOnErr(getBitcodeModuleList(*MB));
54 
55   LLVMContext Context;
56   if (ModuleIndex >= Ms.size()) {
57     errs() << "llvm-modextract: error: module index out of range; bitcode file "
58               "contains "
59            << Ms.size() << " module(s)\n";
60     return 1;
61   }
62 
63   std::error_code EC;
64   std::unique_ptr<ToolOutputFile> Out(
65       new ToolOutputFile(OutputFilename, EC, sys::fs::OF_None));
66   ExitOnErr(errorCodeToError(EC));
67 
68   if (BinaryExtract) {
69     SmallVector<char, 0> Result;
70     BitcodeWriter Writer(Result);
71     Result.append(Ms[ModuleIndex].getBuffer().begin(),
72                   Ms[ModuleIndex].getBuffer().end());
73     Writer.copyStrtab(Ms[ModuleIndex].getStrtab());
74     Out->os() << Result;
75     Out->keep();
76     return 0;
77   }
78 
79   std::unique_ptr<Module> M = ExitOnErr(Ms[ModuleIndex].parseModule(Context));
80   WriteBitcodeToFile(*M, Out->os());
81 
82   Out->keep();
83   return 0;
84 }
85