LLVM提供的工具已经十分丰富,基本上可以满足我们的使用需求,但是使用现成的工具往往会具有一定的局限在性,遇到问题是,我们总是喜欢自己撸代码来完成自己的目标,那么如何编译LLVM字节码文件中的Instruction呢? 且看下面的源代码:
#include <fstream> #include <iostream> #include <memory> #include <iosfwd> #include <llvm-c/IRReader.h> #include <llvm/IR/LLVMContext.h> #include <llvm/Support/SourceMgr.h> #include <llvm/Support/MemoryBuffer.h> #include <llvm/IR/Module.h> #include <llvm/IRReader/IRReader.h> #include <llvm/IR/IRBuilder.h> #include <llvm/IR/Function.h> #include <llvm/IR/BasicBlock.h> #include <llvm/IR/Instruction.h> #include "llvm/Support/raw_ostream.h" #include "llvm/Support/FormattedStream.h"
using namespace llvm; using namespace std;
int main(int argc, char** argv){ if (argc < 2) { errs() << "Expected an argument - IR file name\n"; exit(1); }
LLVMContext &Context = getGlobalContext(); SMDiagnostic Err;
std::unique_ptr<llvm::Module> module = parseIRFile(argv[1], Err, Context); Module* Mod = module.get();
if (!Mod) { Err.print(argv[0], errs()); return 1; }
for (Module::iterator FunIt = Mod->begin() ; FunIt != Mod->end() ; ++FunIt) { for (Function::iterator i = FunIt->begin(), e = FunIt->end(); i != e; ++i) { std::cout<< "Basic block name=" << i->getName().str() << std::endl; for(auto j=i->begin(),f=i->end(); j!=f;j++) { j->dump(); } } }
formatted_raw_ostream* Out; }
|
这段代码就可以实现遍历LLVM字节码文件,但是现在他还无法通过通过编译,为了编译它,我们还需要创建一个cmakelist.txt文件,将下面的内容添加到这个文件当中
project(llvmtest) cmake_minimum_required(VERSION 2.8)
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -std=c++14")
include_directories(${LLVM_INCLUDE_DIRS}) add_definitions(${LLVM_DEFINITIONS})
add_executable(llvmtest DynamicValue.cpp main.cpp)
llvm_map_components_to_libnames(llvm_libs support core irreader engine nativecodegen)
target_link_libraries(llvmtest pthread dl )
target_link_libraries(llvmtest ${llvm_libs})
target_link_libraries(llvmtest LLVMX86AsmParser LLVMX86Desc LLVMX86AsmPrinter LLVMX86Info LLVMX86Utils LLVMipo LLVMScalarOpts LLVMInstCombine LLVMTransformUtils LLVMipa LLVMAnalysis LLVMTarget LLVMOption LLVMMCParser LLVMMC LLVMObject LLVMBitReader LLVMCore LLVMSupport LLVMExecutionEngine LLVMMCJIT )
|
接下来就可以编译我们的代码了,编译成功后将生成一个llvmtest的可执行文件,使用它就可以遍历llvm字节码文件了,
例如:
./llvmtest test1.bc