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