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;

现在,让我告诉你我到目前为止所做的事情。

  1. 我调试了我的检测工具,发现这个 .0 是在加载模块而不是打印时添加的。我发现这一点是因为我的工具输出了一些用于调试的指令,并且它们在加载后就已经有了 .0s。
  2. 我尝试多次加载和打印同一个模块,这就是结果。
%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

如果这不会阻止我开发我的工具,那会很有趣。

  1. 已验证 opt 工具不会发生这种情况。
[user@host]opt hoge.ll -o foo.ll
[user@host]diff hoge.ll foo.ll
[user@host]

这意味着 opt 一定有我遗漏的东西。

  1. 阅读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 时,它们会被编入索引以避免冲突。


感谢您在评论中提供的所有帮助。 :)