From: Peter Collingbourne Date: Tue, 29 Nov 2016 21:54:33 +0000 (+0000) Subject: Add llvm-modextract tool. X-Git-Tag: llvmorg-4.0.0-rc1~3414 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cb6b920ba077fd2fb9cb1f4e4dc576ef9e9e3322;p=platform%2Fupstream%2Fllvm.git Add llvm-modextract tool. This program is for testing features that rely on multi-module bitcode files. It takes a multi-module bitcode file, extracts one of the modules and writes it to the output file. Differential Revision: https://reviews.llvm.org/D26778 llvm-svn: 288201 --- diff --git a/llvm/include/llvm/Bitcode/BitcodeReader.h b/llvm/include/llvm/Bitcode/BitcodeReader.h index 30ae4ab..cd4cd90 100644 --- a/llvm/include/llvm/Bitcode/BitcodeReader.h +++ b/llvm/include/llvm/Bitcode/BitcodeReader.h @@ -66,7 +66,9 @@ namespace llvm { bool ShouldLazyLoadMetadata); public: - ArrayRef getBuffer() const { return Buffer; } + StringRef getBuffer() const { + return StringRef((const char *)Buffer.begin(), Buffer.size()); + } /// Read the bitcode module and prepare for lazy deserialization of function /// bodies. If ShouldLazyLoadMetadata is true, lazily load metadata as well. diff --git a/llvm/test/CMakeLists.txt b/llvm/test/CMakeLists.txt index 43e5b82..635197b 100644 --- a/llvm/test/CMakeLists.txt +++ b/llvm/test/CMakeLists.txt @@ -48,6 +48,7 @@ set(LLVM_TEST_DEPENDS llvm-lto2 llvm-mc llvm-mcmarkup + llvm-modextract llvm-nm llvm-objdump llvm-opt-report diff --git a/llvm/test/lit.cfg b/llvm/test/lit.cfg index b9ca54b..523d69c 100644 --- a/llvm/test/lit.cfg +++ b/llvm/test/lit.cfg @@ -298,6 +298,7 @@ for pattern in [r"\bbugpoint\b(?!-)", r"\bllvm-lto2\b", r"\bllvm-mc\b", r"\bllvm-mcmarkup\b", + r"\bllvm-modextract\b", r"\bllvm-nm\b", r"\bllvm-objdump\b", r"\bllvm-pdbdump\b", diff --git a/llvm/test/tools/llvm-modextract/single.ll b/llvm/test/tools/llvm-modextract/single.ll new file mode 100644 index 0000000..32915ff --- /dev/null +++ b/llvm/test/tools/llvm-modextract/single.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as -o %t %s +; RUN: llvm-modextract -n 0 -o - %t | llvm-dis | FileCheck %s +; RUN: not llvm-modextract -n 1 -o - %t 2>&1 | FileCheck --check-prefix=ERROR %s +; RUN: llvm-modextract -b -n 0 -o - %t | llvm-dis | FileCheck %s +; RUN: not llvm-modextract -b -n 1 -o - %t 2>&1 | FileCheck --check-prefix=ERROR %s + +; CHECK: define void @f() +; ERROR: llvm-modextract: error: module index out of range; bitcode file contains 1 module(s) + +define void @f() { + ret void +} diff --git a/llvm/tools/LLVMBuild.txt b/llvm/tools/LLVMBuild.txt index d8cf22e..65d3d6f 100644 --- a/llvm/tools/LLVMBuild.txt +++ b/llvm/tools/LLVMBuild.txt @@ -36,6 +36,7 @@ subdirectories = llvm-lto llvm-mc llvm-mcmarkup + llvm-modextract llvm-nm llvm-objdump llvm-pdbdump diff --git a/llvm/tools/llvm-modextract/CMakeLists.txt b/llvm/tools/llvm-modextract/CMakeLists.txt new file mode 100644 index 0000000..a7fa47a --- /dev/null +++ b/llvm/tools/llvm-modextract/CMakeLists.txt @@ -0,0 +1,10 @@ +set(LLVM_LINK_COMPONENTS + IRReader + BitWriter + Core + Support + ) + +add_llvm_tool(llvm-modextract + llvm-modextract.cpp + ) diff --git a/llvm/tools/llvm-modextract/LLVMBuild.txt b/llvm/tools/llvm-modextract/LLVMBuild.txt new file mode 100644 index 0000000..6ae5a67 --- /dev/null +++ b/llvm/tools/llvm-modextract/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/llvm-modextract/LLVMBuild.txt --------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; 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-modextract +parent = Tools +required_libraries = BitReader BitWriter diff --git a/llvm/tools/llvm-modextract/llvm-modextract.cpp b/llvm/tools/llvm-modextract/llvm-modextract.cpp new file mode 100644 index 0000000..b4279f2 --- /dev/null +++ b/llvm/tools/llvm-modextract/llvm-modextract.cpp @@ -0,0 +1,72 @@ +//===-- llvm-modextract.cpp - LLVM module extractor utility ---------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program is for testing features that rely on multi-module bitcode files. +// It takes a multi-module bitcode file, extracts one of the modules and writes +// it to the output file. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/Bitcode/BitcodeWriter.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/ToolOutputFile.h" + +using namespace llvm; + +static cl::opt + BinaryExtract("b", cl::desc("Whether to perform binary extraction")); + +static cl::opt OutputFilename("o", cl::Required, + cl::desc("Output filename"), + cl::value_desc("filename")); + +static cl::opt + InputFilename(cl::Positional, cl::desc(""), cl::init("-")); + +static cl::opt ModuleIndex("n", cl::Required, + cl::desc("Index of module to extract"), + cl::value_desc("index")); + +int main(int argc, char **argv) { + cl::ParseCommandLineOptions(argc, argv, "Module extractor"); + + ExitOnError ExitOnErr("llvm-modextract: error: "); + + std::unique_ptr MB = + ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename))); + std::vector Ms = ExitOnErr(getBitcodeModuleList(*MB)); + + LLVMContext Context; + if (ModuleIndex >= Ms.size()) { + errs() << "llvm-modextract: error: module index out of range; bitcode file " + "contains " + << Ms.size() << " module(s)\n"; + return 1; + } + + std::error_code EC; + std::unique_ptr Out( + new tool_output_file(OutputFilename, EC, sys::fs::F_None)); + ExitOnErr(errorCodeToError(EC)); + + if (BinaryExtract) { + SmallVector Header; + BitcodeWriter Writer(Header); + Out->os() << Header << Ms[ModuleIndex].getBuffer(); + return 0; + } + + std::unique_ptr M = ExitOnErr(Ms[ModuleIndex].parseModule(Context)); + WriteBitcodeToFile(M.get(), Out->os()); + + return 0; +}