Skip to content

Commit cb6b920

Browse files
committedNov 29, 2016
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
1 parent 96e2915 commit cb6b920

File tree

8 files changed

+122
-1
lines changed

8 files changed

+122
-1
lines changed
 

‎llvm/include/llvm/Bitcode/BitcodeReader.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,9 @@ namespace llvm {
6666
bool ShouldLazyLoadMetadata);
6767

6868
public:
69-
ArrayRef<uint8_t> getBuffer() const { return Buffer; }
69+
StringRef getBuffer() const {
70+
return StringRef((const char *)Buffer.begin(), Buffer.size());
71+
}
7072

7173
/// Read the bitcode module and prepare for lazy deserialization of function
7274
/// bodies. If ShouldLazyLoadMetadata is true, lazily load metadata as well.

‎llvm/test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ set(LLVM_TEST_DEPENDS
4848
llvm-lto2
4949
llvm-mc
5050
llvm-mcmarkup
51+
llvm-modextract
5152
llvm-nm
5253
llvm-objdump
5354
llvm-opt-report

‎llvm/test/lit.cfg

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ for pattern in [r"\bbugpoint\b(?!-)",
298298
r"\bllvm-lto2\b",
299299
r"\bllvm-mc\b",
300300
r"\bllvm-mcmarkup\b",
301+
r"\bllvm-modextract\b",
301302
r"\bllvm-nm\b",
302303
r"\bllvm-objdump\b",
303304
r"\bllvm-pdbdump\b",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
; RUN: llvm-as -o %t %s
2+
; RUN: llvm-modextract -n 0 -o - %t | llvm-dis | FileCheck %s
3+
; RUN: not llvm-modextract -n 1 -o - %t 2>&1 | FileCheck --check-prefix=ERROR %s
4+
; RUN: llvm-modextract -b -n 0 -o - %t | llvm-dis | FileCheck %s
5+
; RUN: not llvm-modextract -b -n 1 -o - %t 2>&1 | FileCheck --check-prefix=ERROR %s
6+
7+
; CHECK: define void @f()
8+
; ERROR: llvm-modextract: error: module index out of range; bitcode file contains 1 module(s)
9+
10+
define void @f() {
11+
ret void
12+
}

‎llvm/tools/LLVMBuild.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ subdirectories =
3636
llvm-lto
3737
llvm-mc
3838
llvm-mcmarkup
39+
llvm-modextract
3940
llvm-nm
4041
llvm-objdump
4142
llvm-pdbdump
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
set(LLVM_LINK_COMPONENTS
2+
IRReader
3+
BitWriter
4+
Core
5+
Support
6+
)
7+
8+
add_llvm_tool(llvm-modextract
9+
llvm-modextract.cpp
10+
)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
;===- ./tools/llvm-modextract/LLVMBuild.txt --------------------*- Conf -*--===;
2+
;
3+
; The LLVM Compiler Infrastructure
4+
;
5+
; This file is distributed under the University of Illinois Open Source
6+
; License. See LICENSE.TXT for details.
7+
;
8+
;===------------------------------------------------------------------------===;
9+
;
10+
; This is an LLVMBuild description file for the components in this subdirectory.
11+
;
12+
; For more information on the LLVMBuild system, please see:
13+
;
14+
; http://llvm.org/docs/LLVMBuild.html
15+
;
16+
;===------------------------------------------------------------------------===;
17+
18+
[component_0]
19+
type = Tool
20+
name = llvm-modextract
21+
parent = Tools
22+
required_libraries = BitReader BitWriter
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
//===-- llvm-modextract.cpp - LLVM module extractor utility ---------------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
//
10+
// This program is for testing features that rely on multi-module bitcode files.
11+
// It takes a multi-module bitcode file, extracts one of the modules and writes
12+
// it to the output file.
13+
//
14+
//===----------------------------------------------------------------------===//
15+
16+
#include "llvm/Bitcode/BitcodeReader.h"
17+
#include "llvm/Bitcode/BitcodeWriter.h"
18+
#include "llvm/Support/CommandLine.h"
19+
#include "llvm/Support/Error.h"
20+
#include "llvm/Support/FileSystem.h"
21+
#include "llvm/Support/ToolOutputFile.h"
22+
23+
using namespace llvm;
24+
25+
static cl::opt<bool>
26+
BinaryExtract("b", cl::desc("Whether to perform binary extraction"));
27+
28+
static cl::opt<std::string> OutputFilename("o", cl::Required,
29+
cl::desc("Output filename"),
30+
cl::value_desc("filename"));
31+
32+
static cl::opt<std::string>
33+
InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
34+
35+
static cl::opt<unsigned> ModuleIndex("n", cl::Required,
36+
cl::desc("Index of module to extract"),
37+
cl::value_desc("index"));
38+
39+
int main(int argc, char **argv) {
40+
cl::ParseCommandLineOptions(argc, argv, "Module extractor");
41+
42+
ExitOnError ExitOnErr("llvm-modextract: error: ");
43+
44+
std::unique_ptr<MemoryBuffer> MB =
45+
ExitOnErr(errorOrToExpected(MemoryBuffer::getFileOrSTDIN(InputFilename)));
46+
std::vector<BitcodeModule> Ms = ExitOnErr(getBitcodeModuleList(*MB));
47+
48+
LLVMContext Context;
49+
if (ModuleIndex >= Ms.size()) {
50+
errs() << "llvm-modextract: error: module index out of range; bitcode file "
51+
"contains "
52+
<< Ms.size() << " module(s)\n";
53+
return 1;
54+
}
55+
56+
std::error_code EC;
57+
std::unique_ptr<tool_output_file> Out(
58+
new tool_output_file(OutputFilename, EC, sys::fs::F_None));
59+
ExitOnErr(errorCodeToError(EC));
60+
61+
if (BinaryExtract) {
62+
SmallVector<char, 0> Header;
63+
BitcodeWriter Writer(Header);
64+
Out->os() << Header << Ms[ModuleIndex].getBuffer();
65+
return 0;
66+
}
67+
68+
std::unique_ptr<Module> M = ExitOnErr(Ms[ModuleIndex].parseModule(Context));
69+
WriteBitcodeToFile(M.get(), Out->os());
70+
71+
return 0;
72+
}

0 commit comments

Comments
 (0)
Please sign in to comment.