The follwing is a snippet of code to find some indirect calls in a module, which I learned from TopDownClosure.cpp: void FPS::repairCallGraph(Module &M) { CompleteBUDataStructures &DS = getAnalysis<CompleteBUDataStructures>(); for (Module::iterator f = M.begin(); f != M.end(); ++f ) { if( f->isExternal() ) continue; for (Function::iterator I = f->begin(); I != f->end(); ++I) { for(BasicBlock::iterator J = I->begin(); J != I->end(); ++J) { if(CallInst *cs = dyn_cast<CallInst>(J)) { Function *callee = cs->getCalledFunction(); if(callee) continue;//not a function pointer. for(CompleteBUDataStructures::callee_iterator K = DS.callee_begin(J); K !DS.callee_end(J); ++K) { if(K->first != J) continue; CallGraphNode *cgn = getAnalysis<CallGraph>()[f]; // Find a indirect call! CallGraphNode *calleecgn = getAnalysis<CallGraph>()[K->second]; cgn->addCalledFunction(calleecgn); std::cerr<<"\n indirect call in "<<f->getName()<<*J<<", callee: "<<K->second->getName(); } } } } } } But my code does not always works: if the arguments are not pointer, CompleteBUDataStructures not records it. So, if you want to find all indirect calls, you maybe have to repair CompleteBUDataStructures. :) If you do not use BUDataStructures, you can do it yourself: find all load/store instructions with its destination is function type.
On Mon, 2006-05-22 at 15:33 +0800, 夏一民 wrote:> But my code does not always works: if the arguments are not pointer, > CompleteBUDataStructures not records it. So, if you want to find all indirect > calls, you maybe have to repair CompleteBUDataStructures. :)Not surprising, CBU is trying to do something entirely different that what you are.> If you do not use BUDataStructures, you can do it yourself: find all load/store > instructions with its destination is function type.You may want to look at how the call graph builder works. It finds all indirect call sites, and also finds all functions whose address escapes (this is, may be called indirectly). Finding indirect calls is actually easy, just check if the Op(0) of the call (or invoke) instruction !isa<Function>. Andrew
On Monday 22 May 2006 22:22, Andrew Lenharth wrote:> On Mon, 2006-05-22 at 15:33 +0800, 澶忎竴姘� wrote: > > But my code does not always works: if the arguments are not pointer, > > CompleteBUDataStructures not records it. So, if you want to find all indirect > > calls, you maybe have to repair CompleteBUDataStructures. :) > > Not surprising, CBU is trying to do something entirely different that > what you are. > > > If you do not use BUDataStructures, you can do it yourself: find all load/store > > instructions with its destination is function type. > > You may want to look at how the call graph builder works. It finds all > indirect call sites, and also finds all functions whose address escapes > (this is, may be called indirectly).The BasicCallGraph class only lines out the indirect calls(makes the caller point to external node), but do not resolves them using alias analysis such as DSA. I think DSA solve this problem for interested call sites by finding the corresponding globals(i.e. the functions) for the callsite DSnode. Maybe 夏一民 just wanted to point out that DSA does not take all callsite into count. But just as suggested in callgraph.h, "As an extension in the future, there may be multiple nodes with a null function. These will be used when we can prove (through pointer analysis) that an indirect call site can call only a specific set of functions." Maybe Chris can us give more helpful comments.> > Finding indirect calls is actually easy, just check if the Op(0) of the > call (or invoke) instruction !isa<Function>. > > Andrew > > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >-- Regards, Nai