Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/* Qilin - a Java Pointer Analysis Framework
* Copyright (C) 2021-2030 Qilin developers
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3.0 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
*/
package qilin.core.builder;
import java.util.*;
import qilin.CoreConfig;
import qilin.core.PTA;
import qilin.core.PTAScene;
import qilin.core.VirtualCalls;
import qilin.core.builder.callgraph.Edge;
import qilin.core.builder.callgraph.Kind;
import qilin.core.builder.callgraph.OnFlyCallGraph;
import qilin.core.context.Context;
import qilin.core.pag.*;
import qilin.core.sets.P2SetVisitor;
import qilin.core.sets.PointsToSetInternal;
import qilin.util.DataFactory;
import qilin.util.PTAUtils;
import qilin.util.queue.ChunkedQueue;
import qilin.util.queue.QueueReader;
import sootup.core.jimple.basic.Local;
import sootup.core.jimple.basic.StmtPositionInfo;
import sootup.core.jimple.basic.Value;
import sootup.core.jimple.common.constant.NullConstant;
import sootup.core.jimple.common.expr.AbstractInvokeExpr;
import sootup.core.jimple.common.expr.JSpecialInvokeExpr;
import sootup.core.jimple.common.expr.JStaticInvokeExpr;
import sootup.core.jimple.common.stmt.JAssignStmt;
import sootup.core.jimple.common.stmt.JInvokeStmt;
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.model.SootMethod;
import sootup.core.signatures.MethodSubSignature;
import sootup.core.types.ClassType;
import sootup.core.types.ReferenceType;
import sootup.core.types.Type;
import sootup.core.types.UnknownType;
public class CallGraphBuilder {
private static final ClassType clRunnable = PTAUtils.getClassType("java.lang.Runnable");
protected final Map> receiverToSites;
protected final Map> methodToInvokeStmt;
protected final Set reachMethods;
private ChunkedQueue rmQueue;
protected final Set calledges;
protected final PTA pta;
protected final PAG pag;
protected final PTAScene ptaScene;
protected final VirtualCalls virtualCalls;
protected OnFlyCallGraph cicg;
public CallGraphBuilder(PTA pta) {
this.pta = pta;
this.pag = pta.getPag();
this.ptaScene = pta.getScene();
ptaScene.setCallGraph(new OnFlyCallGraph());
this.virtualCalls = new VirtualCalls(ptaScene.getView());
receiverToSites = DataFactory.createMap(ptaScene.getView().getClasses().size());
methodToInvokeStmt = DataFactory.createMap();
reachMethods = DataFactory.createSet();
calledges = DataFactory.createSet();
}
public void setRMQueue(ChunkedQueue rmQueue) {
this.rmQueue = rmQueue;
}
public Collection getReachableMethods() {
return reachMethods;
}
// initialize the receiver to sites map with the number of locals * an
// estimate for the number of contexts per methods
public Map> getReceiverToSitesMap() {
return receiverToSites;
}
public Collection callSitesLookUp(VarNode receiver) {
return receiverToSites.getOrDefault(receiver, Collections.emptySet());
}
public SootMethod resolveNonSpecial(ClassType t, MethodSubSignature subSig) {
return virtualCalls.resolveNonSpecial(t, subSig);
}
public OnFlyCallGraph getCallGraph() {
if (cicg == null) {
constructCallGraph();
}
return ptaScene.getCallGraph();
}
public OnFlyCallGraph getCICallGraph() {
if (cicg == null) {
constructCallGraph();
}
return cicg;
}
private void constructCallGraph() {
cicg = new OnFlyCallGraph();
Map>> map = DataFactory.createMap();
calledges.forEach(
e -> {
ptaScene.getCallGraph().addEdge(e);
SootMethod src = e.src();
SootMethod tgt = e.tgt();
Stmt unit = e.srcUnit();
Map> submap =
map.computeIfAbsent(unit, k -> DataFactory.createMap());
Set set = submap.computeIfAbsent(src, k -> DataFactory.createSet());
if (set.add(tgt)) {
cicg.addEdge(
new Edge(
new ContextMethod(src, pta.emptyContext()),
e.srcUnit(),
new ContextMethod(tgt, pta.emptyContext()),
e.kind()));
}
});
}
public List getEntryPoints() {
Node thisRef = pag.getMethodPAG(ptaScene.getFakeMainMethod()).nodeFactory().caseThis();
thisRef = pta.parameterize(thisRef, pta.emptyContext());
pag.addEdge(pta.getRootNode(), thisRef);
return Collections.singletonList(
pta.parameterize(ptaScene.getFakeMainMethod(), pta.emptyContext()));
}
public void initReachableMethods() {
for (ContextMethod momc : getEntryPoints()) {
if (reachMethods.add(momc)) {
rmQueue.add(momc);
}
}
}
public VarNode getReceiverVarNode(Local receiver, ContextMethod m) {
if (receiver.getType() == UnknownType.getInstance()) {
System.out.println("why unknown??" + m.method() + ";;" + receiver);
throw new RuntimeException();
}
LocalVarNode base = pag.makeLocalVarNode(receiver, receiver.getType(), m.method());
return (VarNode) pta.parameterize(base, m.context());
}
protected void dispatch(AllocNode receiverNode, VirtualCallSite site) {
Type type = receiverNode.getType();
final QueueReader targets = dispatch(type, site);
while (targets.hasNext()) {
SootMethod target = targets.next();
if (site.iie() instanceof JSpecialInvokeExpr) {
Type calleeDeclType = target.getDeclaringClassType();
if (!PTAUtils.canStoreType(pta.getView(), type, calleeDeclType)) {
continue;
}
}
addVirtualEdge(site.container(), site.getUnit(), target, site.kind(), receiverNode);
}
}
private void addVirtualEdge(
ContextMethod caller, Stmt callStmt, SootMethod callee, Kind kind, AllocNode receiverNode) {
Context tgtContext = pta.createCalleeCtx(caller, receiverNode, new CallSite(callStmt), callee);
ContextMethod cstarget = pta.parameterize(callee, tgtContext);
handleCallEdge(new Edge(caller, callStmt, cstarget, kind));
Node thisRef = pag.getMethodPAG(callee).nodeFactory().caseThis();
thisRef = pta.parameterize(thisRef, cstarget.context());
pag.addEdge(receiverNode, thisRef);
}
public void injectCallEdge(Object heapOrType, ContextMethod callee, Kind kind) {
Map