gpt4 book ai didi

c++ - 识别 llvm 中的虚拟调用站点

转载 作者:行者123 更新时间:2023-11-30 05:14:04 25 4
gpt4 key购买 nike

我需要在我的 LLVM pass 中识别虚函数调用站点,以及识别可能在运行时调用的候选函数。

class B
{
virtual void F() { // do something }
};

class D : public B
{
void F() { // do something else }
};

B* d = new D();
d->F();

例如,对于给定的层次结构和 F 的调用,将 B::F 和 D::F 都确定为可能的候选对象。

在寻找解决方案时,我遇到了 Clang CFI(控制流集成),他们说他们通过检查虚拟表指针是否在一组候选虚拟表指针中来识别它是否有效。因此,我假设有一种方法可以获取有关继承层次结构的信息。但是我找不到任何如何在 llvm 中完成这项工作的方法。

那么有人知道如何做到这一点吗?

最佳答案

在 llvm 开发人员的帮助下,我找到了解决问题的方法,并想在这里分享它,以备不时之需。

在 llvm 中有一个转换 pass -wholeprogramdevirt,这几乎是我想要实现的。它识别模块中的虚拟调用站点和候选被调用者,然后在可能的情况下尝试去虚拟化这些调用。例如,如果一个虚函数仅在一个类层次结构中实现,则对该函数的间接调用将替换为对已实现函数的直接调用。

class B
{
virtual void F() { // do something }
};

class D : public B {};

B* d = new D();
d->F();

因此对于这种情况,F 的间接调用将被 B::F 的直接调用所取代。WholeProgramDevirt pass 使用类型元数据和 llvm 类型检查内在函数来识别虚拟调用站点和候选被调用者。

首先,您需要获取启用了 clang 的 -fwhole-program-vtables 标志的位码。这将为虚拟调用站点生成相应的内部函数。这些内部函数是 llvm.type.test、llvm.checked.load 和 llvm.assume。然后使用这些内在函数,整个程序 devirtualizer 找到虚拟调用站点,并为他们每个人找到候选被调用者。

对于我的案例,我不需要进行转换,所以我将其实现为分析过程并收集结果以供进一步使用。

关于c++ - 识别 llvm 中的虚拟调用站点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43596742/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com