如何使用LLVM Pass插入inline assembly指令及插入失效问题解决
解决方案
核心问题排查方向
首先分两种场景确认问题根因:
- 运行Pass后输出的IR中已经不存在int3的asm调用:说明指令被优化Pass删除
- IR中存在调用,但生成二进制时无对应指令:说明类型不匹配或后端配置问题
修改后的代码
你代码中最可能的问题是函数类型Ty定义错误,以及缺少部分防止优化的属性,以下是修正后的完整代码:
LLVMContext *Ctx = &M.getContext(); // 正确定义int3对应的汇编函数类型:无返回值、无入参 FunctionType *AsmFnTy = FunctionType::get(Type::getVoidTy(*Ctx), false); BasicBlock::iterator IP = BB.getFirstInsertionPt(); IRBuilder<> IRB(&(*IP)); StringRef asmString = "int3"; StringRef constraints = "~{dirflag},~{fpsr},~{flags}"; // 第4个参数hasSideEffects设为true是核心,避免被判定为无用代码删除 llvm::InlineAsm *IA = llvm::InlineAsm::get(AsmFnTy, asmString, constraints, true, false, InlineAsm::AD_ATT); llvm::CallInst *AsmCall = IRB.CreateCall(IA, {}); // 加防止优化的属性 AsmCall->addAttribute(AttributeList::FunctionIndex, Attribute::NoUnwind); AsmCall->addAttribute(AttributeList::FunctionIndex, Attribute::NoDuplicate); AsmCall->addAttribute(AttributeList::FunctionIndex, Attribute::NoMerge); // 如果需要和你对比的生效IR对齐,可手动添加srcloc元数据,非必须 // MDNode *SrcLoc = MDNode::get(*Ctx, ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(*Ctx), 0))); // AsmCall->setMetadata("srcloc", SrcLoc);
验证步骤
- 先运行opt加载你的Pass时添加
-disable-llvm-passes参数,输出IR检查是否已经成功插入asm调用,排除其他优化Pass干扰 - 确认目标编译架构为x86/x86_64,int3为x86平台专属指令,其他架构会被忽略
- 生成二进制时不要添加
-ffreestanding等会裁剪标准汇编语义的编译参数
内容的提问来源于stack exchange,提问作者gazile
相关产品推荐
相关产品推荐

