如何拦截LLVM lli工具输入? [英] How to intercept LLVM lli tool input?

查看:164
本文介绍了如何拦截LLVM lli工具输入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用LLVM lli工具作为静态库(将main()重命名为lli()并将其导出到libLLi.a中)-为它创建丰富的UI.我该如何修改(或不经修改使用)以拦截标准输入?

I'd like to use LLVM lli tool as static library (rename main() to lli() and export it in libLLi.a) - to create rich UI for it. How can i modify it (or use without modifications) in order to intercept stdin?

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

Assume i know how to generate LLVM assembly file (using clang -S -emit-llvm .. -o output.ll) and how to execute it using lli tool (lli output.ll).

常见用例:

lli将解释的简单应用程序的源代码:

Source code of simple app to be interpreted by lli:

#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控件).

I need to interpret LLVM assembly for it and to show InputBox when cin.getline invoked and show TextBox when cout << invoked (InputBox and TextBox are rich UI controls).

PS.我无法分叉进程并转发整个子进程的stdin/stdout.

PS. I can't fork process and forward stdin/stdout of the whole child process.

推荐答案

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

lli is already a thin wrapper around llvm library functions, just use those instead. The main() function in tools/lli/lli.cpp is long only because it supports tons of flags to control every possible setting. After you strip it down it should be less than 10 lines to create an ExecutionEngine using an EngineBuilder and use it to run a llvm::Function.

您可能还会发现第4章万花筒"教程很有帮助,在其中添加了JIT对语言的支持.这也演示了如何使用EngineBuilder,尽管他们选择构建的ExecutionEngine是JIT而不是Interpreter,但您可以针对自己的用例对其进行自定义.

You might also find chapter 4 of the Kaleidoscope tutorial helpful, where they add JIT support to the language. This also demonstrates how to use an EngineBuilder, though the ExecutionEngine they choose to build is a JIT instead of an Interpreter, you can customize it for your use case.

现在,对于问题的另一部分,如何捕获stdinstdout? LLVM不是VM,代码正在您的进程中运行,并使用stdin和stdout.我的第一个建议是,由于您已经具有LLVM IR格式的功能,因此只需运行一个转换过程即可用您自己的I/O功能替换标准I/O功能.如果可以使ABI排队,一种更简单的方法是使用ExecutionEngine重新映射.调用EE->updateGlobalMapping(functionDeclInIR, &replacementFunctionInNativeCode)告诉ExecutionEngine,对于functionDeclInIR的Function*在本机代码中由replaceFunctionInNativeCode表示.您需要提供自己的使用GUI的_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc的实现(又称ostream :: operator<<).

Now for the other part of your question, how do you trap stdin and stdout? LLVM is not a VM, the code is running in your process and using your stdin and stdout. My first suggestion is that since you already have the function in LLVM IR format, just run a transformation pass that replaces standard I/O functions with your own I/O functions. A simpler way to do that if you can get the ABI to line up, is to do the remapping with the ExecutionEngine. Call EE->updateGlobalMapping(functionDeclInIR, &replacementFunctionInNativeCode) to tell the ExecutionEngine that the Function* for functionDeclInIR is represented in native code by replacementFunctionInNativeCode. You would need to provide your own implementation of _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc (aka. ostream::operator<<) which uses your GUI.

这篇关于如何拦截LLVM lli工具输入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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