如何拦截LLVM lli工具输入?

时间:2014-10-21 06:33:38

标签: llvm interpreter

我想将LLVM lli工具用作静态库(将main()重命名为lli()并将其导出到libLLi.a中) - 为其创建丰富的UI。我如何修改它(或使用而无需修改)以拦截stdin?

假设我知道如何生成LLVM程序集文件(使用clang -S -emit-llvm .. -o output.ll)以及如何使用lli工具(lli output.ll)执行它。

常见用例:

由lli解释的简单app的源代码:

#include <iostream>

using namespace std;

int main() {
    char name[128]; 
    cout << "type your name: ";
    cin.getline(name, sizeof(name));
    cout << "hi, " << name << endl;

    return 0;
}

我需要为它解释LLVM程序集并在调用cin.getline时显示InputBox,并在调用cout <<时显示TextBox(InputBox和TextBox是丰富的UI控件)。

PS。我不能分叉进程并转发整个子进程的stdin / stdout。

1 个答案:

答案 0 :(得分:4)

lli已经是llvm库函数的一个瘦包装器,只需使用它们。 tools/lli/lli.cpp中的main()函数很长,只是因为它支持大量的标志来控制每个可能的设置。将其剥离后,使用EngineBuilder创建ExecutionEngine并使用它来运行llvm::Function时,应该少于10行。

您可能还会发现chapter 4 of the Kaleidoscope tutorial很有帮助,他们会在该语言中添加JIT支持。这也演示了如何使用EngineBuilder,尽管他们选择构建的ExecutionEngine是JIT而不是Interpreter,您可以根据用例自定义它。

现在针对问题的其他部分,您如何陷阱stdinstdout? LLVM不是VM,代码在您的进程中运行并使用您的stdin和stdout。我的第一个建议是,既然你已经拥有LLVM IR格式的功能,只需运行一个转换过程,用你自己的I / O函数替换标准的I / O函数。如果可以让ABI排队,更简单的方法是使用ExecutionEngine进行重映射。调用EE->updateGlobalMapping(functionDeclInIR, &replacementFunctionInNativeCode)告诉ExecutionEngine,functionDeclInIR的Function*由nativeFunctionInNativeCode在本机代码中表示。您需要提供自己的_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(aka。ostream :: operator&lt;&lt;)的实现,它使用您的GUI。