LLVM IR 加载类型名称修改
LLVM IR Loading type name mangling
我很难解决这个加载 LLVM-IR 模块的问题。
首先是这里的问题。
我有这个 LLVM-IR 文件和这个指令:
%7 = getelementptr inbounds %struct.hoge, %struct.hoge* %6, i32 0, i32 0, !dbg !34
现在,当我使用我的工具加载它时,它变成了这样:
%7 = getelementptr inbounds %struct.hoge.0, %struct.hoge.0* %6, i32 0, i32 0, !dbg !34
我的目标是在所有结构类型的末尾去掉这个 .0
。
这是一些代码,
模块加载:
Module *FPR_::load(const path &input) const {
// Construct module
SMDiagnostic err;
unique_ptr<Module> module{parseIRFile(input.string(), err, ctx, true, "")};
...
模块打印:
ofstream ofs("hoge.ll");
string str;
raw_string_ostream rso(str);
module->print(rso, NULL, true, true);
ofs << str;
现在,让我告诉你我到目前为止所做的事情。
- 我调试了我的检测工具,发现这个
.0
是在加载模块而不是打印时添加的。我发现这一点是因为我的工具输出了一些用于调试的指令,并且它们在加载后就已经有了 .0
s。
- 我尝试多次加载和打印同一个模块,这就是结果。
%7 = getelementptr inbounds %struct.hoge.0.0.0.0.0.0, %struct.hoge.0.0.0.0.0.0* %6, i32 0, i32 0, !dbg !34
如果这不会阻止我开发我的工具,那会很有趣。
- 已验证
opt
工具不会发生这种情况。
[user@host]opt hoge.ll -o foo.ll
[user@host]diff hoge.ll foo.ll
[user@host]
这意味着 opt
一定有我遗漏的东西。
- 阅读
opt
的源代码。
有些代码感觉很重要。这就是我最终得到的结果。
LLVMContext ctx;
ctx.setDiscardValueNames(false);
ctx.enableDebugTypeODRUniquing();
FPR_::FPR_ FPR_(path(src_ll.getValue()), path(dep_ll.getValue()), ctx, options); // Module gets loaded in this constructor.
Context
里的选项都是我发现的,opt
好像做的不一样。但目前还没有结果。
坦率地说,我不知道如何解决这个问题。因此,我们将不胜感激任何帮助。
另外,我知道建议使用 opt
工具本身进行静态分析或检测。
但问题是,我正在尝试制作的工具也将静态分析用于动态分析。所以我不希望我的程序在输出经过检测的 LLVM-IR 时结束。
我可以做一些肮脏的 hack 而不是 return 从 runOnModule
方法,然后从那里打印模块。但我确实想尽可能避免这种情况。
提前致谢!
简答:
不要使用相同的 LLVMContext
来读取模块,如果它们不 应该在同一个程序中。
长答案:
通过读取具有相同 LLVMContext
的多个 Module
,您暗示那些 Module
应该在同一个程序中。
那么发生的事情是,当有多个具有相同类型名称的 Module
时,它们会被编入索引以避免冲突。
感谢您在评论中提供的所有帮助。 :)
我很难解决这个加载 LLVM-IR 模块的问题。
首先是这里的问题。 我有这个 LLVM-IR 文件和这个指令:
%7 = getelementptr inbounds %struct.hoge, %struct.hoge* %6, i32 0, i32 0, !dbg !34
现在,当我使用我的工具加载它时,它变成了这样:
%7 = getelementptr inbounds %struct.hoge.0, %struct.hoge.0* %6, i32 0, i32 0, !dbg !34
我的目标是在所有结构类型的末尾去掉这个 .0
。
这是一些代码,
模块加载:
Module *FPR_::load(const path &input) const {
// Construct module
SMDiagnostic err;
unique_ptr<Module> module{parseIRFile(input.string(), err, ctx, true, "")};
...
模块打印:
ofstream ofs("hoge.ll");
string str;
raw_string_ostream rso(str);
module->print(rso, NULL, true, true);
ofs << str;
现在,让我告诉你我到目前为止所做的事情。
- 我调试了我的检测工具,发现这个
.0
是在加载模块而不是打印时添加的。我发现这一点是因为我的工具输出了一些用于调试的指令,并且它们在加载后就已经有了.0
s。 - 我尝试多次加载和打印同一个模块,这就是结果。
%7 = getelementptr inbounds %struct.hoge.0.0.0.0.0.0, %struct.hoge.0.0.0.0.0.0* %6, i32 0, i32 0, !dbg !34
如果这不会阻止我开发我的工具,那会很有趣。
- 已验证
opt
工具不会发生这种情况。
[user@host]opt hoge.ll -o foo.ll
[user@host]diff hoge.ll foo.ll
[user@host]
这意味着 opt
一定有我遗漏的东西。
- 阅读
opt
的源代码。 有些代码感觉很重要。这就是我最终得到的结果。
LLVMContext ctx;
ctx.setDiscardValueNames(false);
ctx.enableDebugTypeODRUniquing();
FPR_::FPR_ FPR_(path(src_ll.getValue()), path(dep_ll.getValue()), ctx, options); // Module gets loaded in this constructor.
Context
里的选项都是我发现的,opt
好像做的不一样。但目前还没有结果。
坦率地说,我不知道如何解决这个问题。因此,我们将不胜感激任何帮助。
另外,我知道建议使用 opt
工具本身进行静态分析或检测。
但问题是,我正在尝试制作的工具也将静态分析用于动态分析。所以我不希望我的程序在输出经过检测的 LLVM-IR 时结束。
我可以做一些肮脏的 hack 而不是 return 从 runOnModule
方法,然后从那里打印模块。但我确实想尽可能避免这种情况。
提前致谢!
简答:
不要使用相同的 LLVMContext
来读取模块,如果它们不 应该在同一个程序中。
长答案:
通过读取具有相同 LLVMContext
的多个 Module
,您暗示那些 Module
应该在同一个程序中。
那么发生的事情是,当有多个具有相同类型名称的 Module
时,它们会被编入索引以避免冲突。
感谢您在评论中提供的所有帮助。 :)