如何从ifstream加载LLVM位码文件? [英] How to load LLVM bitcode file from an ifstream?

查看:139
本文介绍了如何从ifstream加载LLVM位码文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在运行时加载在 .bc 文件中定义的LLVM模块,但遇到了陷阱。

I'm trying to load an LLVM module defined in a .bc file at runtime but have run into a snag.

感兴趣的位码由 hello.cpp 产生:

// hello.cpp
// build with:
// clang-3.4 -c -emit-llvm hello.cpp -o hello.bc
#include <iostream>

void hello()
{
  std::cout << "Hello, world!" << std::endl;
}

当程序尝试在运行时加载它时, c $ c> llvm :: BitstreamCursor :: Read():

When the program below attempts to load it at runtime, it crashes inside llvm::BitstreamCursor::Read():

// main.cpp
// build with:
// g++ main.cpp `llvm-config-3.4 --cppflags --ldflags --libs` -ldl -lpthread -lcurses
#include <llvm/IR/Module.h>
#include <llvm/IRReader/IRReader.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/Support/SourceMgr.h>
#include <llvm/Support/MemoryBuffer.h>
#include <llvm/Support/raw_ostream.h>
#include <fstream>
#include <iostream>

llvm::Module *load_module(std::ifstream &stream)
{
  if(!stream)
  {
    std::cerr << "error after open stream" << std::endl;
    return 0;
  }

  // load bitcode
  std::string ir((std::istreambuf_iterator<char>(stream)), (std::istreambuf_iterator<char>()));

  // parse it
  using namespace llvm;
  LLVMContext context;
  SMDiagnostic error;
  Module *module = ParseIR(MemoryBuffer::getMemBuffer(StringRef(ir.c_str())), error, context);

  if(!module)
  {
    std::string what;
    llvm::raw_string_ostream os(what);
    error.print("error after ParseIR()", os);
    std::cerr << what;
  } // end if

  return module;
}

int main()
{
  std::ifstream stream("hello.bc", std::ios_base::binary);
  llvm::Module *m = load_module(stream);
  if(m)
  {
    m->dump();
  }

  return 0;
}

我正在使用LLVM v3.4

I'm building against LLVM v3.4 using the command lines mentioned in the comments.

任何想法我做错了什么?

Any idea what I'm doing wrong?

推荐答案

有两个问题:


  1. LLVMContext 的生命周期需要超过模块的生命周期。否则模块将引用不再存在的 LLVMContext

  2. 引用IR的 StringRef 应该从包含IR的 std :: string 构造,而不是零终止串。否则 ParseIR 将无法正确找到IR的结尾。

  1. The lifetime of the LLVMContext needs to outlast the lifetime of the Module. Otherwise the Module will refer to a LLVMContext which no longer exists.
  2. The StringRef referring to the IR should be constructed from the std::string containing the IR, not a zero-terminated string. Otherwise ParseIR won't find the end of the IR correctly.

修正版本的 load_module

llvm::Module *load_module(std::ifstream &stream, llvm::LLVMContext &context)
{
  if(!stream)
  {
    std::cerr << "error after open stream" << std::endl;
    return 0;
  }

  // load bitcode
  std::string ir((std::istreambuf_iterator<char>(stream)), (std::istreambuf_iterator<char>()));

  // parse it
  using namespace llvm;
  SMDiagnostic error;
  Module *module = ParseIR(MemoryBuffer::getMemBuffer(StringRef(ir)), error, context);

  if(!module)
  {
    std::string what;
    llvm::raw_string_ostream os(what);
    error.print("error after ParseIR()", os);
    std::cerr << what;
  } // end if

  return module;
}

这篇关于如何从ifstream加载LLVM位码文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆