如何在新版LLVM中查找特定函数CallSite及替代use_back()
嘿,刚好在LLVM开发中经常跟CallSite打交道,我来帮你解决这两个问题~
如何在LLVM中查找特定函数的CallSite
要定位特定函数的所有调用点,有两种常用的思路:
直接遍历目标函数的用户列表
每个调用指令(CallInst或InvokeInst)都是目标函数的直接用户,所以我们可以遍历目标函数的users()集合,筛选出调用指令并转换为CallSite:// 首先获取目标函数的指针(假设M是当前Module的引用) Function* TargetFunc = M.getFunction("your_target_function_name"); if (!TargetFunc) { errs() << "Target function not found!\n"; return; } // 遍历目标函数的所有用户 for (User* U : TargetFunc->users()) { // 判断该用户是否是调用指令(CallBase是CallInst和InvokeInst的父类) if (auto* CB = dyn_cast<CallBase>(U)) { CallSite CS(CB); // 在这里处理CallSite,比如打印调用位置、获取参数等 errs() << "Found call site: " << *CB << "\n"; } }遍历整个模块的所有指令(适合间接调用场景)
如果目标函数存在间接调用(比如通过函数指针调用),上面的方法可能无法覆盖,这时候可以遍历模块内所有函数的基本块和指令,检查每个调用指令的目标是否是我们要找的函数:Function* TargetFunc = M.getFunction("your_target_function_name"); if (!TargetFunc) { errs() << "Target function not found!\n"; return; } for (Function& F : M) { for (BasicBlock& BB : F) { for (Instruction& I : BB) { if (auto* CB = dyn_cast<CallBase>(&I)) { // 检查调用的目标函数是否匹配 if (CB->getCalledFunction() == TargetFunc) { CallSite CS(CB); // 处理CallSite逻辑 } } } } }
新版LLVM中替代
use_back()创建CallSite的方法 你说得没错,use_back()方法在新版LLVM中已经被移除了——原因很简单:LLVM内部的use列表是无顺序保证的,依赖use_back()获取"最后一个调用点"的逻辑本身就不可靠,而且这个方法的性能表现也不佳。
现在要实现类似的功能,正确的做法是遍历目标函数的users集合,找到符合要求的调用指令,具体分两种场景:
只想获取任意一个调用点
如果原来的代码只是随便取一个调用点(比如旧版用use_back()只是为了拿到一个示例),可以遍历users找到第一个匹配的调用指令:Function* SomeFunc = ...; // 你的目标函数指针 CallSite CS; for (User* U : SomeFunc->users()) { if (auto* CB = dyn_cast<CallBase>(U)) { CS = CallSite(CB); break; // 取第一个找到的调用点 } } // 记得检查CallSite是否有效 if (CS) { // 执行你的业务逻辑 }确定目标函数只有一个调用点
如果能保证目标函数只有一个调用点,可以直接取users集合的第一个元素:Function* SomeFunc = ...; if (!SomeFunc->users().empty()) { User* U = *SomeFunc->users().begin(); if (auto* CB = dyn_cast<CallBase>(U)) { CallSite CS(CB); // 处理逻辑 } }
总的来说,新版LLVM更鼓励开发者显式遍历use列表,而不是依赖不确定的顺序方法,这样代码会更健壮。
内容的提问来源于stack exchange,提问作者Luba A
相关产品推荐
相关产品推荐

