如何获取LLVM模块中的所有值?含InlineAsm查找需求
如何在LLVM模块中找到所有InlineAsm值
你之前尝试用符号表的方法行不通,是因为InlineAsm实例通常不会出现在全局或函数的符号表中——它们一般是作为CallInst或InvokeInst的操作数直接存在的,不属于命名符号范畴。
要找到模块里所有的InlineAsm,正确的做法是遍历模块内的每一条指令,检查指令的操作数中是否包含InlineAsm类型的值。下面是可行的实现代码:
llvm::Module &M = ...; // 注意这里用引用,避免不必要的模块拷贝 // 遍历模块中所有函数 for (auto &F : M) { // 遍历函数中所有基本块 for (auto &BB : F) { // 遍历基本块中所有指令 for (auto &I : BB) { // 优先检查调用类指令(InlineAsm最常见的使用场景) if (auto *Call = dyn_cast<CallBase>(&I)) { Value *Callee = Call->getCalledOperand(); if (auto *IA = dyn_cast<InlineAsm>(Callee)) { // 找到目标InlineAsm,执行你的逻辑 // do something with IA } } // 额外检查所有指令操作数,覆盖其他罕见场景 for (auto &Op : I.operands()) { if (auto *IA = dyn_cast<InlineAsm>(Op.get())) { // 处理找到的InlineAsm } } } } }
关键说明:
- 符号表的局限性:符号表仅存储有名字的全局值、函数、全局变量等命名实体,而InlineAsm大多是匿名的,直接作为指令操作数使用,不会被加入符号表。
- CallBase的作用:
CallBase是CallInst和InvokeInst的基类,覆盖了所有调用类指令,这是InlineAsm最常出现的场景。 - 全操作数检查:如果InlineAsm出现在其他指令的操作数中(比如作为常量表达式的一部分),遍历所有指令的操作数可以确保不会遗漏。
你也可以用LLVM的inst_iterator来更简洁地遍历模块内所有指令:
for (llvm::inst_iterator I = llvm::inst_begin(M), E = llvm::inst_end(M); I != E; ++I) { // 检查调用指令 if (auto *Call = dyn_cast<CallBase>(&*I)) { if (auto *IA = dyn_cast<InlineAsm>(Call->getCalledOperand())) { // 处理找到的InlineAsm } } // 检查所有操作数 for (auto &Op : I->operands()) { if (auto *IA = dyn_cast<InlineAsm>(Op.get())) { // 处理找到的InlineAsm } } }
这样就能覆盖模块中所有可能存在的InlineAsm实例了。
内容的提问来源于stack exchange,提问作者user9614249
相关产品推荐
相关产品推荐

