我正在将一个为 LLVM 2.9 编写的 LLVM 插件 (LLFI) 移植到最新版本的 LLVM/Clang。
使用启用断言的 LLVM3.2 构建测试我的插件时,我收到以下错误:
opt: /home/kzvr/ubc/llfi/llvm3/llvmsrc/lib/IR/Instructions.cpp:281:
void llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>,
const llvm::Twine&): Assertion `(i >= FTy->getNumParams() ||
FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad
signature!"' failed.
0 opt 0x00000000017931a6 llvm::sys::PrintStackTrace(_IO_FILE*) + 38
1 opt 0x0000000001793423
2 opt 0x0000000001792e7b
3 libpthread.so.0 0x00007f0c0279fff0
4 libc.so.6 0x00007f0c018a91b5 gsignal + 53
5 libc.so.6 0x00007f0c018abfc0 abort + 384
6 libc.so.6 0x00007f0c018a2301 __assert_fail + 241
7 opt 0x00000000016e78c4 llvm::CallInst::init(llvm::Value*, llvm::ArrayRef<llvm::Value*>, llvm::Twine const&) + 402
8 LLFI.so 0x00007f0c0165adcb
9 LLFI.so 0x00007f0c0165aa83
10 LLFI.so 0x00007f0c016581c5
11 opt 0x000000000171c02c llvm::FPPassManager::doFinalization(llvm::Module&) + 88
12 opt 0x000000000171c449 llvm::MPPassManager::runOnModule(llvm::Module&) + 1013
13 opt 0x000000000171c8a6 llvm::PassManagerImpl::run(llvm::Module&) + 254
14 opt 0x000000000171cc01 llvm::PassManager::run(llvm::Module&) + 39
15 opt 0x000000000087a089 main + 5591
16 libc.so.6 0x00007f0c01895c8d __libc_start_main + 253
17 opt 0x000000000086bf59
在插件代码中,我对 llvm::CallInst::Create 进行了多次调用,基于上述情况,我相信其中至少有一个执行不正确。它们几乎都是这样的:
ArrayRef<Value*> arrayArgs(args);
Instruction* callInst = CallInst::Create( injectFunc, arrayArgs, fiName, insertInst);
其中 args 是 std::vector,injectFunc 是 llvm::Constant*,fiName 是 std::string,insertInst 是 llvm::Instruction*
问题是,作为 LLVM 新手,我不知道如何从这一点上缩小我的 bughunt 范围。所以我有几个问题:
- 如何找到对 CallInst::Create 的调用是导致 CallInst::init 断言失败的调用?
- 说明正确使用 CallInst 类的文档在哪里?谷歌搜索会产生自动生成的源代码文档,我已经仔细研究过但无济于事。
- 这个插件的 2.9 和 3.2 版本之间的唯一区别(就 CallInst 而言)是传递 std::vector 迭代器到 CallInst::create 替换为传递从 std::vector 构造的 ArrayRef。我是否不正确地从 Vector 构造了 ArrayRef?
在此先感谢您的帮助,我希望这个问题不会太模糊。