use of soot.toolkits.scalar.Pair in project soot by Sable.
the class GeomPointsTo method preprocess.
/**
* Read in the program facts generated by SPARK.
* We also construct our own call graph and pointer variables.
*/
private void preprocess() {
int id;
int s, t;
// Build the call graph
n_func = Scene.v().getReachableMethods().size() + 1;
call_graph = new CgEdge[n_func];
n_calls = 0;
n_reach_spark_user_methods = 0;
id = 1;
QueueReader<MethodOrMethodContext> smList = Scene.v().getReachableMethods().listener();
CallGraph soot_callgraph = Scene.v().getCallGraph();
while (smList.hasNext()) {
final SootMethod func = smList.next().method();
func2int.put(func, id);
int2func.put(id, func);
/*
* We cannot identify all entry methods since some entry methods call themselves.
* In that case, the Soot CallGraph.isEntryMethod() function returns false.
*/
if (soot_callgraph.isEntryMethod(func) || func.isEntryMethod()) {
CgEdge p = new CgEdge(Constants.SUPER_MAIN, id, null, call_graph[Constants.SUPER_MAIN]);
call_graph[Constants.SUPER_MAIN] = p;
n_calls++;
}
if (!func.isJavaLibraryMethod())
++n_reach_spark_user_methods;
id++;
}
// Next, we scan all the call edges and rebuild the call graph in our own vocabulary
QueueReader<Edge> edgeList = Scene.v().getCallGraph().listener();
while (edgeList.hasNext()) {
Edge edge = edgeList.next();
if (edge.isClinit()) {
continue;
}
SootMethod src_func = edge.src();
SootMethod tgt_func = edge.tgt();
s = func2int.get(src_func);
t = func2int.get(tgt_func);
// Create a new call edge in our own format
CgEdge p = new CgEdge(s, t, edge, call_graph[s]);
call_graph[s] = p;
edgeMapping.put(edge, p);
// We collect callsite information
Stmt callsite = edge.srcStmt();
if (edge.isThreadRunCall() || edge.kind().isExecutor() || edge.kind().isAsyncTask()) {
// We don't modify the treatment to the thread run() calls
thread_run_callsites.add(callsite);
} else if (edge.isInstance() && !edge.isSpecial()) {
// We try to refine the virtual callsites (virtual + interface) with multiple call targets
InstanceInvokeExpr expr = (InstanceInvokeExpr) callsite.getInvokeExpr();
if (expr.getMethodRef().getSignature().contains("<java.lang.Thread: void start()>")) {
// It is a thread start function
thread_run_callsites.add(callsite);
} else {
p.base_var = findLocalVarNode(expr.getBase());
if (SootInfo.countCallEdgesForCallsite(callsite, true) > 1 && p.base_var != null) {
multiCallsites.add(callsite);
}
}
}
++n_calls;
}
// We build the wrappers for all the pointers built by SPARK
for (Iterator<VarNode> it = getVarNodeNumberer().iterator(); it.hasNext(); ) {
VarNode vn = it.next();
IVarAbstraction pn = makeInternalNode(vn);
pointers.add(pn);
}
for (Iterator<AllocDotField> it = getAllocDotFieldNodeNumberer().iterator(); it.hasNext(); ) {
AllocDotField adf = it.next();
// Some allocdotfield is invalid, we check and remove them
SparkField field = adf.getField();
if (field instanceof SootField) {
// This is an instance field of a class
Type decType = ((SootField) field).getDeclaringClass().getType();
Type baseType = adf.getBase().getType();
// baseType must be a sub type of decType
if (!castNeverFails(baseType, decType))
continue;
}
IVarAbstraction pn = makeInternalNode(adf);
pointers.add(pn);
}
for (Iterator<AllocNode> it = getAllocNodeNumberer().iterator(); it.hasNext(); ) {
AllocNode obj = it.next();
IVarAbstraction pn = makeInternalNode(obj);
allocations.add(pn);
}
// The address constraints, new obj -> p
for (Object object : allocSources()) {
IVarAbstraction obj = makeInternalNode((AllocNode) object);
Node[] succs = allocLookup((AllocNode) object);
for (Node element0 : succs) {
PlainConstraint cons = new PlainConstraint();
IVarAbstraction p = makeInternalNode(element0);
cons.expr.setPair(obj, p);
cons.type = Constants.NEW_CONS;
constraints.add(cons);
}
}
// The assign constraints, p -> q
Pair<Node, Node> intercall = new Pair<Node, Node>();
for (Object object : simpleSources()) {
IVarAbstraction p = makeInternalNode((VarNode) object);
Node[] succs = simpleLookup((VarNode) object);
for (Node element0 : succs) {
PlainConstraint cons = new PlainConstraint();
IVarAbstraction q = makeInternalNode(element0);
cons.expr.setPair(p, q);
cons.type = Constants.ASSIGN_CONS;
intercall.setPair((VarNode) object, element0);
cons.interCallEdges = lookupEdgesForAssignment(intercall);
constraints.add(cons);
}
}
intercall = null;
assign2edges.clear();
// The load constraints, p.f -> q
for (Object object : loadSources()) {
FieldRefNode frn = (FieldRefNode) object;
IVarAbstraction p = makeInternalNode(frn.getBase());
Node[] succs = loadLookup(frn);
for (Node element0 : succs) {
PlainConstraint cons = new PlainConstraint();
IVarAbstraction q = makeInternalNode(element0);
cons.f = frn.getField();
cons.expr.setPair(p, q);
cons.type = Constants.LOAD_CONS;
constraints.add(cons);
}
}
// The store constraints, p -> q.f
for (Object object : storeSources()) {
IVarAbstraction p = makeInternalNode((VarNode) object);
Node[] succs = storeLookup((VarNode) object);
for (Node element0 : succs) {
PlainConstraint cons = new PlainConstraint();
FieldRefNode frn = (FieldRefNode) element0;
IVarAbstraction q = makeInternalNode(frn.getBase());
cons.f = frn.getField();
cons.expr.setPair(p, q);
cons.type = Constants.STORE_CONS;
constraints.add(cons);
}
}
n_init_constraints = constraints.size();
// Initialize other stuff
low_cg = new int[n_func];
vis_cg = new int[n_func];
rep_cg = new int[n_func];
indeg_cg = new int[n_func];
scc_size = new int[n_func];
block_num = new int[n_func];
context_size = new long[n_func];
max_context_size_block = new long[n_func];
}
use of soot.toolkits.scalar.Pair in project soot by Sable.
the class MethodNodeFactory method caseCastExpr.
@Override
public final void caseCastExpr(CastExpr ce) {
Pair<Expr, String> castPair = new Pair<Expr, String>(ce, PointsToAnalysis.CAST_NODE);
ce.getOp().apply(this);
Node opNode = getNode();
Node castNode = pag.makeLocalVarNode(castPair, ce.getCastType(), method);
mpag.addInternalEdge(opNode, castNode);
setResult(castNode);
}
use of soot.toolkits.scalar.Pair in project soot by Sable.
the class MethodNodeFactory method casePhiExpr.
@Override
public final void casePhiExpr(PhiExpr e) {
Pair<Expr, String> phiPair = new Pair<Expr, String>(e, PointsToAnalysis.PHI_NODE);
Node phiNode = pag.makeLocalVarNode(phiPair, e.getType(), method);
for (Value op : e.getValues()) {
op.apply(MethodNodeFactory.this);
Node opNode = getNode();
mpag.addInternalEdge(opNode, phiNode);
}
setResult(phiNode);
}
use of soot.toolkits.scalar.Pair in project soot by Sable.
the class PAG method addCallTarget.
public final void addCallTarget(Edge e) {
if (!e.passesParameters())
return;
MethodPAG srcmpag = MethodPAG.v(this, e.src());
MethodPAG tgtmpag = MethodPAG.v(this, e.tgt());
Pair<Node, Node> pval;
if (e.isExplicit() || e.kind() == Kind.THREAD || e.kind() == Kind.ASYNCTASK) {
addCallTarget(srcmpag, tgtmpag, (Stmt) e.srcUnit(), e.srcCtxt(), e.tgtCtxt(), e);
} else if (e.kind() == Kind.EXECUTOR) {
InvokeExpr ie = e.srcStmt().getInvokeExpr();
boolean virtualCall = callAssigns.containsKey(ie);
Node parm = srcmpag.nodeFactory().getNode(ie.getArg(0));
parm = srcmpag.parameterize(parm, e.srcCtxt());
parm = parm.getReplacement();
Node thiz = tgtmpag.nodeFactory().caseThis();
thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
thiz = thiz.getReplacement();
addEdge(parm, thiz);
pval = addInterproceduralAssignment(parm, thiz, e);
callAssigns.put(ie, pval);
callToMethod.put(ie, srcmpag.getMethod());
if (virtualCall && !virtualCallsToReceivers.containsKey(ie)) {
virtualCallsToReceivers.put(ie, parm);
}
} else if (e.kind() == Kind.HANDLER) {
InvokeExpr ie = e.srcStmt().getInvokeExpr();
boolean virtualCall = callAssigns.containsKey(ie);
assert virtualCall == true;
Node base = srcmpag.nodeFactory().getNode(((VirtualInvokeExpr) ie).getBase());
base = srcmpag.parameterize(base, e.srcCtxt());
base = base.getReplacement();
Node thiz = tgtmpag.nodeFactory().caseThis();
thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
thiz = thiz.getReplacement();
addEdge(base, thiz);
pval = addInterproceduralAssignment(base, thiz, e);
callAssigns.put(ie, pval);
callToMethod.put(ie, srcmpag.getMethod());
virtualCallsToReceivers.put(ie, base);
} else if (e.kind() == Kind.PRIVILEGED) {
// Flow from first parameter of doPrivileged() invocation
// to this of target, and from return of target to the
// return of doPrivileged()
InvokeExpr ie = e.srcStmt().getInvokeExpr();
Node parm = srcmpag.nodeFactory().getNode(ie.getArg(0));
parm = srcmpag.parameterize(parm, e.srcCtxt());
parm = parm.getReplacement();
Node thiz = tgtmpag.nodeFactory().caseThis();
thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
thiz = thiz.getReplacement();
addEdge(parm, thiz);
pval = addInterproceduralAssignment(parm, thiz, e);
callAssigns.put(ie, pval);
callToMethod.put(ie, srcmpag.getMethod());
if (e.srcUnit() instanceof AssignStmt) {
AssignStmt as = (AssignStmt) e.srcUnit();
Node ret = tgtmpag.nodeFactory().caseRet();
ret = tgtmpag.parameterize(ret, e.tgtCtxt());
ret = ret.getReplacement();
Node lhs = srcmpag.nodeFactory().getNode(as.getLeftOp());
lhs = srcmpag.parameterize(lhs, e.srcCtxt());
lhs = lhs.getReplacement();
addEdge(ret, lhs);
pval = addInterproceduralAssignment(ret, lhs, e);
callAssigns.put(ie, pval);
callToMethod.put(ie, srcmpag.getMethod());
}
} else if (e.kind() == Kind.FINALIZE) {
Node srcThis = srcmpag.nodeFactory().caseThis();
srcThis = srcmpag.parameterize(srcThis, e.srcCtxt());
srcThis = srcThis.getReplacement();
Node tgtThis = tgtmpag.nodeFactory().caseThis();
tgtThis = tgtmpag.parameterize(tgtThis, e.tgtCtxt());
tgtThis = tgtThis.getReplacement();
addEdge(srcThis, tgtThis);
pval = addInterproceduralAssignment(srcThis, tgtThis, e);
} else if (e.kind() == Kind.NEWINSTANCE) {
Stmt s = (Stmt) e.srcUnit();
InstanceInvokeExpr iie = (InstanceInvokeExpr) s.getInvokeExpr();
Node cls = srcmpag.nodeFactory().getNode(iie.getBase());
cls = srcmpag.parameterize(cls, e.srcCtxt());
cls = cls.getReplacement();
Node newObject = nodeFactory.caseNewInstance((VarNode) cls);
Node initThis = tgtmpag.nodeFactory().caseThis();
initThis = tgtmpag.parameterize(initThis, e.tgtCtxt());
initThis = initThis.getReplacement();
addEdge(newObject, initThis);
if (s instanceof AssignStmt) {
AssignStmt as = (AssignStmt) s;
Node asLHS = srcmpag.nodeFactory().getNode(as.getLeftOp());
asLHS = srcmpag.parameterize(asLHS, e.srcCtxt());
asLHS = asLHS.getReplacement();
addEdge(newObject, asLHS);
}
pval = addInterproceduralAssignment(newObject, initThis, e);
callAssigns.put(s.getInvokeExpr(), pval);
callToMethod.put(s.getInvokeExpr(), srcmpag.getMethod());
} else if (e.kind() == Kind.REFL_INVOKE) {
// Flow (1) from first parameter of invoke(..) invocation
// to this of target, (2) from the contents of the second (array)
// parameter
// to all parameters of the target, and (3) from return of target to
// the
// return of invoke(..)
// (1)
InvokeExpr ie = e.srcStmt().getInvokeExpr();
Value arg0 = ie.getArg(0);
// if "null" is passed in, omit the edge
if (arg0 != NullConstant.v()) {
Node parm0 = srcmpag.nodeFactory().getNode(arg0);
parm0 = srcmpag.parameterize(parm0, e.srcCtxt());
parm0 = parm0.getReplacement();
Node thiz = tgtmpag.nodeFactory().caseThis();
thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
thiz = thiz.getReplacement();
addEdge(parm0, thiz);
pval = addInterproceduralAssignment(parm0, thiz, e);
callAssigns.put(ie, pval);
callToMethod.put(ie, srcmpag.getMethod());
}
// (2)
Value arg1 = ie.getArg(1);
SootMethod tgt = e.getTgt().method();
// edge
if (arg1 != NullConstant.v() && tgt.getParameterCount() > 0) {
Node parm1 = srcmpag.nodeFactory().getNode(arg1);
parm1 = srcmpag.parameterize(parm1, e.srcCtxt());
parm1 = parm1.getReplacement();
FieldRefNode parm1contents = makeFieldRefNode((VarNode) parm1, ArrayElement.v());
for (int i = 0; i < tgt.getParameterCount(); i++) {
// if no reference type, create no edge
if (!(tgt.getParameterType(i) instanceof RefLikeType))
continue;
Node tgtParmI = tgtmpag.nodeFactory().caseParm(i);
tgtParmI = tgtmpag.parameterize(tgtParmI, e.tgtCtxt());
tgtParmI = tgtParmI.getReplacement();
addEdge(parm1contents, tgtParmI);
pval = addInterproceduralAssignment(parm1contents, tgtParmI, e);
callAssigns.put(ie, pval);
}
}
// the return type of the callee is actually a reference type
if (e.srcUnit() instanceof AssignStmt && (tgt.getReturnType() instanceof RefLikeType)) {
AssignStmt as = (AssignStmt) e.srcUnit();
Node ret = tgtmpag.nodeFactory().caseRet();
ret = tgtmpag.parameterize(ret, e.tgtCtxt());
ret = ret.getReplacement();
Node lhs = srcmpag.nodeFactory().getNode(as.getLeftOp());
lhs = srcmpag.parameterize(lhs, e.srcCtxt());
lhs = lhs.getReplacement();
addEdge(ret, lhs);
pval = addInterproceduralAssignment(ret, lhs, e);
callAssigns.put(ie, pval);
}
} else if (e.kind() == Kind.REFL_CLASS_NEWINSTANCE || e.kind() == Kind.REFL_CONSTR_NEWINSTANCE) {
// (1) create a fresh node for the new object
// (2) create edge from this object to "this" of the constructor
// (3) if this is a call to Constructor.newInstance and not
// Class.newInstance,
// create edges passing the contents of the arguments array of the
// call
// to all possible parameters of the target
// (4) if we are inside an assign statement,
// assign the fresh object from (1) to the LHS of the assign
// statement
Stmt s = (Stmt) e.srcUnit();
InstanceInvokeExpr iie = (InstanceInvokeExpr) s.getInvokeExpr();
// (1)
Node cls = srcmpag.nodeFactory().getNode(iie.getBase());
cls = srcmpag.parameterize(cls, e.srcCtxt());
cls = cls.getReplacement();
if (cls instanceof ContextVarNode)
cls = findLocalVarNode(((VarNode) cls).getVariable());
VarNode newObject = makeGlobalVarNode(cls, RefType.v("java.lang.Object"));
SootClass tgtClass = e.getTgt().method().getDeclaringClass();
RefType tgtType = tgtClass.getType();
AllocNode site = makeAllocNode(new Pair<Node, SootClass>(cls, tgtClass), tgtType, null);
addEdge(site, newObject);
// (2)
Node initThis = tgtmpag.nodeFactory().caseThis();
initThis = tgtmpag.parameterize(initThis, e.tgtCtxt());
initThis = initThis.getReplacement();
addEdge(newObject, initThis);
addInterproceduralAssignment(newObject, initThis, e);
// (3)
if (e.kind() == Kind.REFL_CONSTR_NEWINSTANCE) {
Value arg = iie.getArg(0);
SootMethod tgt = e.getTgt().method();
// edge
if (arg != NullConstant.v() && tgt.getParameterCount() > 0) {
Node parm0 = srcmpag.nodeFactory().getNode(arg);
parm0 = srcmpag.parameterize(parm0, e.srcCtxt());
parm0 = parm0.getReplacement();
FieldRefNode parm1contents = makeFieldRefNode((VarNode) parm0, ArrayElement.v());
for (int i = 0; i < tgt.getParameterCount(); i++) {
// if no reference type, create no edge
if (!(tgt.getParameterType(i) instanceof RefLikeType))
continue;
Node tgtParmI = tgtmpag.nodeFactory().caseParm(i);
tgtParmI = tgtmpag.parameterize(tgtParmI, e.tgtCtxt());
tgtParmI = tgtParmI.getReplacement();
addEdge(parm1contents, tgtParmI);
pval = addInterproceduralAssignment(parm1contents, tgtParmI, e);
callAssigns.put(iie, pval);
}
}
}
// (4)
if (s instanceof AssignStmt) {
AssignStmt as = (AssignStmt) s;
Node asLHS = srcmpag.nodeFactory().getNode(as.getLeftOp());
asLHS = srcmpag.parameterize(asLHS, e.srcCtxt());
asLHS = asLHS.getReplacement();
addEdge(newObject, asLHS);
}
pval = addInterproceduralAssignment(newObject, initThis, e);
callAssigns.put(s.getInvokeExpr(), pval);
callToMethod.put(s.getInvokeExpr(), srcmpag.getMethod());
} else {
throw new RuntimeException("Unhandled edge " + e);
}
}
use of soot.toolkits.scalar.Pair in project soot by Sable.
the class SparkNativeHelper method assignObjectToImpl.
protected void assignObjectToImpl(ReferenceVariable lhs, AbstractObject obj) {
AllocNode objNode = pag.makeAllocNode(new Pair("AbstractObject", obj.getType()), obj.getType(), null);
VarNode var;
if (lhs instanceof FieldRefNode) {
var = pag.makeGlobalVarNode(objNode, objNode.getType());
pag.addEdge((Node) lhs, var);
} else {
var = (VarNode) lhs;
}
pag.addEdge(objNode, var);
}
Aggregations