我正在编写一些LLVM代码来查找间接调用。现在我已经创建了触发llvm :: loadinstructions,llvm :: bitcast指令等的C代码
但是,我无法编写任何触发此操作的间接C代码:
if(CallInst *CI = dyn_cast<CallInst>(&*S)) {
if(!CI->getCalledFunction()) {
if(StoreInst *SI = dyn_cast<StoreInst>(CI->getCalledValue()))
/* do something */
}}}
答案 0 :(得分:1)
您确定您的情况包括阅读StoreInst
吗?
如果您创建以下功能,则会使用LoadInst
来达到您的条件。
extern int printf(const char *fmt, ...);
static void foo() {
printf("Hello!\n");
}
int main() {
void (*pointer)(void) = foo;
pointer();
return 0;
}
对应的LLVM IR:
; Function Attrs: nounwind ssp uwtable
define i32 @main() #0 !dbg !7 {
%1 = alloca i32, align 4
%2 = alloca void ()*, align 8
store i32 0, i32* %1, align 4
call void @llvm.dbg.declare(metadata void ()** %2, metadata !11, metadata !15), !dbg !16
store void ()* @foo, void ()** %2, align 8, !dbg !16
%3 = load void ()*, void ()** %2, align 8, !dbg !17
call void %3(), !dbg !17
ret i32 0, !dbg !18
}
使用clang -g -c -emit-llvm main.c
编译。
以下代码:
int main(int argc, const char * argv[]) {
LLVMContext context;
const char *path = "main.bc";
auto BufferOrError = MemoryBuffer::getFile(path);
if (!BufferOrError) {
std::cout << "Can't open bitcode file '" << path << "'\n";
return 1;
}
auto moduleOrError = parseBitcodeFile(BufferOrError->get()->getMemBufferRef(), context);
if (!moduleOrError) {
std::cout << "Can't parse bitcode file '" << path << "'\n";
return 1;
}
Module *module = moduleOrError->get();
for (auto &F: *module) {
for (auto &BB: F) {
for (auto &I: BB) {
if (CallInst *CI = dyn_cast<CallInst>(&I)) {
if (!CI->getCalledFunction()) {
CI->dump();
if (StoreInst *SI = dyn_cast<StoreInst>(CI->getCalledValue())) {
errs() << "StoreInst\n";
CI->dump();
}
if (LoadInst *LI = dyn_cast<LoadInst>(CI->getCalledValue())) {
errs() << "LoadInst\n";
LI->dump();
}
}
}
}
}
}
return 0;
}
产生
call void %3(), !dbg !17
LoadInst
%3 = load void ()*, void ()** %2, align 8, !dbg !17