1311116Sdim//===-- llvm-modextract.cpp - LLVM module extractor utility ---------------===// 2311116Sdim// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6311116Sdim// 7311116Sdim//===----------------------------------------------------------------------===// 8311116Sdim// 9311116Sdim// This program is for testing features that rely on multi-module bitcode files. 10311116Sdim// It takes a multi-module bitcode file, extracts one of the modules and writes 11311116Sdim// it to the output file. 12311116Sdim// 13311116Sdim//===----------------------------------------------------------------------===// 14311116Sdim 15311116Sdim#include "llvm/Bitcode/BitcodeReader.h" 16311116Sdim#include "llvm/Bitcode/BitcodeWriter.h" 17311116Sdim#include "llvm/Support/CommandLine.h" 18311116Sdim#include "llvm/Support/Error.h" 19311116Sdim#include "llvm/Support/FileSystem.h" 20311116Sdim#include "llvm/Support/ToolOutputFile.h" 21311116Sdim 22311116Sdimusing namespace llvm; 23311116Sdim 24311116Sdimstatic cl::opt<bool> 25311116Sdim BinaryExtract("b", cl::desc("Whether to perform binary extraction")); 26311116Sdim 27311116Sdimstatic cl::opt<std::string> OutputFilename("o", cl::Required, 28311116Sdim cl::desc("Output filename"), 29311116Sdim cl::value_desc("filename")); 30311116Sdim 31311116Sdimstatic cl::opt<std::string> 32311116Sdim InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-")); 33311116Sdim 34311116Sdimstatic cl::opt<unsigned> ModuleIndex("n", cl::Required, 35311116Sdim cl::desc("Index of module to extract"), 36311116Sdim cl::value_desc("index")); 37311116Sdim 38311116Sdimint main(int argc, char **argv) { 39311116Sdim cl::ParseCommandLineOptions(argc, argv, "Module extractor"); 40311116Sdim 41311116Sdim ExitOnError ExitOnErr("llvm-modextract: error: "); 42311116Sdim 43311116Sdim std::unique_ptr<MemoryBuffer> MB = 44311116Sdim ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename))); 45311116Sdim std::vector<BitcodeModule> Ms = ExitOnErr(getBitcodeModuleList(*MB)); 46311116Sdim 47311116Sdim LLVMContext Context; 48311116Sdim if (ModuleIndex >= Ms.size()) { 49311116Sdim errs() << "llvm-modextract: error: module index out of range; bitcode file " 50311116Sdim "contains " 51311116Sdim << Ms.size() << " module(s)\n"; 52311116Sdim return 1; 53311116Sdim } 54311116Sdim 55311116Sdim std::error_code EC; 56327952Sdim std::unique_ptr<ToolOutputFile> Out( 57360784Sdim new ToolOutputFile(OutputFilename, EC, sys::fs::OF_None)); 58311116Sdim ExitOnErr(errorCodeToError(EC)); 59311116Sdim 60311116Sdim if (BinaryExtract) { 61321369Sdim SmallVector<char, 0> Result; 62321369Sdim BitcodeWriter Writer(Result); 63321369Sdim Result.append(Ms[ModuleIndex].getBuffer().begin(), 64321369Sdim Ms[ModuleIndex].getBuffer().end()); 65321369Sdim Writer.copyStrtab(Ms[ModuleIndex].getStrtab()); 66321369Sdim Out->os() << Result; 67311116Sdim Out->keep(); 68311116Sdim return 0; 69311116Sdim } 70311116Sdim 71311116Sdim std::unique_ptr<Module> M = ExitOnErr(Ms[ModuleIndex].parseModule(Context)); 72341825Sdim WriteBitcodeToFile(*M, Out->os()); 73311116Sdim 74311116Sdim Out->keep(); 75311116Sdim return 0; 76311116Sdim} 77