我最近开始使用LLVM。我试图在LLVM中编写一个传递给出以下代码
string = (char *)malloc(100);
string = NULL;
和相应的LLVM IR
%call = call noalias i8* @malloc(i64 100) #3
store i8* %call, i8** %string, align 8
store i8* null, i8** %string, align 8
检测调用malloc
的指令,提取已分配的number of bytes
(在本例中为100),返回的address
以及分配地址的变量名称。
std::map<std::string, std::tuple<size_t, int> > mem_addrs; // stores pointer name, address and no. of bytes allocated
Count() : ModulePass(ID) {}
virtual bool runOnModule(Module &M) {
for (Function &F: M) {
for (BasicBlock &B: F) {
for (Instruction &I: B) {
if(CallInst* call_inst = dyn_cast<CallInst>(&I)) {
Function* fn = call_inst->getCalledFunction();
StringRef fn_name = fn->getName();
errs() << fn_name << " : " << "\n";
for(auto args = fn->arg_begin(); args != fn->arg_end(); ++args) {
ConstantInt* arg = dyn_cast<ConstantInt>(&(*args));
if (arg != NULL)
errs() << arg->getValue() << "\n";
}
}
}
}
}
输出
-VirtualBox:~/program_analysis$ opt -load $LLVMLIB/CSE231.so -analyze -count < $BENCHMARKS/leaktest/leaktest.bc > $OUTPUTLOGS/welcome.static.log
ok
allocaimw
allocaleak
allocamalloc : 0x2f5d9e0
0 opt 0x0000000001315cf2 llvm::sys::PrintStackTrace(_IO_FILE*) + 34
1 opt 0x0000000001315914
2 libpthread.so.0 0x00007f0b53f12330
3 opt 0x00000000012ec78f llvm::APInt::toString(llvm::SmallVectorImpl<char>&, unsigned int, bool, bool) const + 79
4 opt 0x00000000012ed309 llvm::APInt::print(llvm::raw_ostream&, bool) const + 57
5 CSE231.so 0x00007f0b52f16661
6 opt 0x00000000012ad6cd llvm::legacy::PassManagerImpl::run(llvm::Module&) + 797
7 opt 0x000000000058e190 main + 2752
8 libc.so.6 0x00007f0b5313af45 __libc_start_main + 245
9 opt 0x00000000005ab2ca
Stack dump:
0. Program arguments: opt -load /home/hifza/program_analysis/llvm/build/Release+Asserts/lib/CSE231.so -analyze -count
1. Running pass 'Instruction Counts Pass' on module '<stdin>'.
Segmentation fault (core dumped)
我能够检测到malloc
指令,但是我无法找到相应的内存地址和指定的字节数。任何人都可以指导我如何做到这一点?谢谢。
答案 0 :(得分:1)
您不会检查dyn_cast<ConstantInt>(&(*args))
的结果。如果转换类型不是ConstantInt
,则返回nullptr
。在下一行(arg->getValue()
)中,您取消引用它。
答案 1 :(得分:0)
我更喜欢检测malloc调用,
一旦检测到malloc,就可以简单地获取ip-> getOperand(0)访问的字节 指向内存的变量名称不过是您刚从代码中以 lhs 开头的Store inst返回的值
Am共享代码段,这也将适用于跨过程的情况,并支持新的运算符。
void findOperand(Value *itVal) {
std::stack<Value *> st;
st.push(itVal);
while(!st.empty()) {
auto ele = st.top();
st.pop();
if(isa<Instruction>(ele)) {
Instruction *tip = (Instruction *)ele;
if(isa<AllocaInst>(tip)) {
errs()<<"others\n";
//opdSet.insert(ele);
}else if(isa<LoadInst>(tip)) {
Value *ti = tip->getOperand(0);
if(!isa<ConstantData>(ti))
st.push(ti);
} else if(isa<CallInst>(tip)) {
Function *calledFp = cast<CallInst>(tip)->getCalledFunction();
errs()<<calledFp->getName()<<"\n";
if(calledFp->getName() == "malloc" || calledFp->getName() == "_Znwm") {
errs()<<"Dynamic memory allocation!\n";
errs()<<tip->getNumOperands()<<"\n";
errs()<<tip->getOperand(0)<<"\n";
} else {
//fetch the last bb of the function
auto bb = calledFp->end();
if(bb != calledFp->begin()) {
bb --;
BasicBlock *bp = &(*bb);
//fetch the terminator
Instruction *term = bp->getTerminator();
if(isa<ReturnInst>(term)) {
//find Operand
findOperand(term->getOperand(0));
errs()<<"done\n";
}
}
}
} else {
for(int i=0, numOp = tip->getNumOperands(); i < numOp; i++) {
Value *ti = tip->getOperand(i);
if(!isa<ConstantData>(ti)) {
st.push(ti);
}
}
}
} else if (isa<GlobalVariable>(ele)) {
errs()<<"others\n";
}
}
}//findOperand
void visitStoreInst(StoreInst &ip) {
Value *lhs = ip.getOperand(1);
Value *rhs = ip.getOperand(0);
if(lhs->getType()->getContainedType(0)->isPointerTy()) {
//figure out rhs
errs()<<"pointer assignment!"<<lhs->getName()<<"\n";
findOperand(rhs);
}
}