确定LLVM中的虚拟呼叫站点



我需要在我的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中有一个转换通行证 - WhoLeprogragragramdevirt,它正在做我想实现的目标。它可以在模块中标识虚拟呼叫站点和候选级别,然后在可能的情况下试图使这些呼叫变得不合时宜。例如,如果仅在一个类别的层次结构中实现虚拟函数,则将对该函数的间接调用替换为已实现函数的直接调用。

class B
{
virtual void F() { // do something }
};
class D : public B {};
B* d = new D();
d->F();

因此,对于F :: f的直接呼叫,F. f。WhoLeprogramdevirt Pass使用类型的元数据和LLVM类型检查固有功能以识别虚拟呼叫站点和候选Callees。

首先,您需要使用Clang的-Fth-Fhole-Program-Vtables flag启用BitCode。这将为虚拟呼叫站点生成相应的固有函数。这些内在功能是llvm.type.test,llvm.checked.load和llvm.assume。然后使用这些内在的整个程序Devirtualizer查找虚拟呼叫站点,并为每个程序候选Callees找到。

就我的情况而言,我不需要进行转换,因此我将其作为分析实现并收集结果。

最新更新