use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class TypeBasedReflectionModelTest method genericLocalVsStringConstantTest.
private void genericLocalVsStringConstantTest(boolean useConstantBase) {
resetSoot();
Options.v().set_allow_phantom_refs(true);
Options.v().set_whole_program(true);
Options.v().set_no_bodies_for_excluded(true);
Scene.v().loadBasicClasses();
SootClass tc = setUpTestClass(useConstantBase);
Scene.v().addClass(tc);
tc.setApplicationClass();
Scene.v().setMainClass(tc);
Scene.v().forceResolve(tc.getName(), BODIES);
Scene.v().loadNecessaryClasses();
Options.v().setPhaseOption("cg.spark", "on");
Options.v().setPhaseOption("cg", "types-for-invoke:true");
// this option is necessary to get constant bases working
Options.v().setPhaseOption("wjpp.cimbt", "enabled:true");
Options.v().setPhaseOption("wjpp.cimbt", "verbose:true");
PackManager.v().getPack("wjpp").apply();
PackManager.v().getPack("cg").apply();
CallGraph callGraph = Scene.v().getCallGraph();
boolean found = false;
for (Edge edge : callGraph) {
if (edge.getSrc().method().getSignature().contains("main") && edge.getTgt().method().getSignature().contains("concat")) {
found = true;
break;
}
}
Assert.assertTrue("There should be an edge from main to String.concat after resolution of the target of Method.invoke, but none found", found);
}
use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class HeapInsNodeGenerator method initFlowGraph.
@Override
public void initFlowGraph(GeomPointsTo ptAnalyzer) {
int k;
int n_legal_cons;
int nf1, nf2;
int code;
IVarAbstraction my_lhs, my_rhs;
// Visit all the simple constraints
n_legal_cons = 0;
for (PlainConstraint cons : ptAnalyzer.constraints) {
if (!cons.isActive)
continue;
my_lhs = cons.getLHS().getRepresentative();
my_rhs = cons.getRHS().getRepresentative();
nf1 = ptAnalyzer.getMethodIDFromPtr(my_lhs);
nf2 = ptAnalyzer.getMethodIDFromPtr(my_rhs);
// Test how many globals are in this constraint
code = ((nf1 == Constants.SUPER_MAIN ? 1 : 0) << 1) | (nf2 == Constants.SUPER_MAIN ? 1 : 0);
switch(cons.type) {
case Constants.NEW_CONS:
// We directly add the objects to the points-to set
my_rhs.add_points_to_3((AllocNode) my_lhs.getWrappedNode(), // to decide if the receiver is a global or not
(code & 1) == 1 ? 0 : 1, // if the object is a global or not
(code >> 1) == 1 ? 0 : 1, (code & 1) == 1 ? ptAnalyzer.context_size[nf1] : ptAnalyzer.context_size[nf2]);
// Enqueue to the worklist
ptAnalyzer.getWorklist().push(my_rhs);
break;
case Constants.ASSIGN_CONS:
// The core part of any context sensitive algorithms
if (cons.interCallEdges != null) {
// Inter-procedural assignment
for (Iterator<Edge> it = cons.interCallEdges.iterator(); it.hasNext(); ) {
Edge sEdge = it.next();
CgEdge q = ptAnalyzer.getInternalEdgeFromSootEdge(sEdge);
if (q.is_obsoleted == true) {
continue;
}
// Parameter passing
if (nf2 == q.t) {
if (nf1 == Constants.SUPER_MAIN) {
my_lhs.add_simple_constraint_3(my_rhs, 0, q.map_offset, ptAnalyzer.max_context_size_block[q.s]);
} else {
// We should treat the self recursive calls specially
if (q.s == q.t) {
my_lhs.add_simple_constraint_3(my_rhs, 1, 1, ptAnalyzer.context_size[nf1]);
} else {
for (k = 0; k < ptAnalyzer.block_num[nf1]; ++k) {
my_lhs.add_simple_constraint_3(my_rhs, k * ptAnalyzer.max_context_size_block[nf1] + 1, q.map_offset, ptAnalyzer.max_context_size_block[nf1]);
}
}
}
} else {
if (q.s == q.t) {
my_lhs.add_simple_constraint_3(my_rhs, 1, 1, ptAnalyzer.context_size[nf2]);
} else {
for (k = 0; k < ptAnalyzer.block_num[nf2]; ++k) {
my_lhs.add_simple_constraint_3(my_rhs, q.map_offset, k * ptAnalyzer.max_context_size_block[nf2] + 1, ptAnalyzer.max_context_size_block[nf2]);
}
}
}
}
} else {
// Intraprocedural
// And, assignment involves global variable goes here. By
// definition, global variables belong to SUPER_MAIN.
// By the Jimple IR, not both sides are global variables
my_lhs.add_simple_constraint_3(my_rhs, nf1 == Constants.SUPER_MAIN ? 0 : 1, nf2 == Constants.SUPER_MAIN ? 0 : 1, nf1 == Constants.SUPER_MAIN ? ptAnalyzer.context_size[nf2] : ptAnalyzer.context_size[nf1]);
}
break;
case Constants.LOAD_CONS:
// lhs is always a local
// rhs = lhs.f
cons.code = full_convertor[code];
cons.otherSide = my_rhs;
my_lhs.put_complex_constraint(cons);
break;
case Constants.STORE_CONS:
// rhs is always a local
// rhs.f = lhs
cons.code = full_convertor[code];
cons.otherSide = my_lhs;
my_rhs.put_complex_constraint(cons);
break;
default:
throw new RuntimeException("Invalid node type");
}
++n_legal_cons;
}
ptAnalyzer.ps.printf("Only %d (%.1f%%) constraints are needed for this run.\n", n_legal_cons, ((double) n_legal_cons / ptAnalyzer.n_init_constraints) * 100);
}
use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class FullSensitiveNodeGenerator method initFlowGraph.
@Override
public void initFlowGraph(GeomPointsTo ptAnalyzer) {
int k;
int n_legal_cons;
int nf1, nf2;
int code;
IVarAbstraction my_lhs, my_rhs;
// Visit all the simple constraints
n_legal_cons = 0;
for (PlainConstraint cons : ptAnalyzer.constraints) {
if (!cons.isActive)
continue;
my_lhs = cons.getLHS().getRepresentative();
my_rhs = cons.getRHS().getRepresentative();
nf1 = ptAnalyzer.getMethodIDFromPtr(my_lhs);
nf2 = ptAnalyzer.getMethodIDFromPtr(my_rhs);
// Test how many globals are in this constraint
code = ((nf1 == Constants.SUPER_MAIN ? 1 : 0) << 1) | (nf2 == Constants.SUPER_MAIN ? 1 : 0);
switch(cons.type) {
case Constants.NEW_CONS:
if (code == 0) {
// the allocation result is assigned to a local variable
my_rhs.add_points_to_3((AllocNode) my_lhs.getWrappedNode(), 1, 1, ptAnalyzer.context_size[nf1]);
} else {
// Assigned to a global or the object itself is a global
my_rhs.add_points_to_4((AllocNode) my_lhs.getWrappedNode(), 1, 1, ptAnalyzer.context_size[nf2], ptAnalyzer.context_size[nf1]);
}
// Enqueue to the worklist
ptAnalyzer.getWorklist().push(my_rhs);
break;
case Constants.ASSIGN_CONS:
if (cons.interCallEdges != null) {
// Inter-procedural assignment (parameter passing, function return)
for (Iterator<Edge> it = cons.interCallEdges.iterator(); it.hasNext(); ) {
Edge sEdge = it.next();
CgEdge q = ptAnalyzer.getInternalEdgeFromSootEdge(sEdge);
if (q.is_obsoleted == true) {
continue;
}
// Parameter passing or not
if (nf2 == q.t) {
// In that case, nf1 is SUPER_MAIN.
if (nf1 == Constants.SUPER_MAIN) {
my_lhs.add_simple_constraint_4(my_rhs, 1, q.map_offset, 1, ptAnalyzer.max_context_size_block[q.s]);
} else {
// We should treat the self recursive calls specially
if (q.s == q.t) {
my_lhs.add_simple_constraint_3(my_rhs, 1, 1, ptAnalyzer.context_size[nf1]);
} else {
for (k = 0; k < ptAnalyzer.block_num[nf1]; ++k) {
my_lhs.add_simple_constraint_3(my_rhs, k * ptAnalyzer.max_context_size_block[nf1] + 1, q.map_offset, ptAnalyzer.max_context_size_block[nf1]);
}
}
}
} else {
if (q.s == q.t) {
// Self-recursive calls may fall here, we handle them properly
my_lhs.add_simple_constraint_3(my_rhs, 1, 1, ptAnalyzer.context_size[nf2]);
} else {
for (k = 0; k < ptAnalyzer.block_num[nf2]; ++k) {
my_lhs.add_simple_constraint_3(my_rhs, q.map_offset, k * ptAnalyzer.max_context_size_block[nf2] + 1, ptAnalyzer.max_context_size_block[nf2]);
}
}
}
}
} else {
if (code == 0) {
// local to local assignment
my_lhs.add_simple_constraint_3(my_rhs, 1, 1, ptAnalyzer.context_size[nf1]);
} else {
my_lhs.add_simple_constraint_4(my_rhs, 1, 1, ptAnalyzer.context_size[nf1], ptAnalyzer.context_size[nf2]);
}
}
break;
case Constants.LOAD_CONS:
// lhs is always a local
// rhs = lhs.f
cons.code = full_convertor[code];
cons.otherSide = my_rhs;
my_lhs.put_complex_constraint(cons);
break;
case Constants.STORE_CONS:
// rhs is always a local
// rhs.f = lhs
cons.code = full_convertor[code];
cons.otherSide = my_lhs;
my_rhs.put_complex_constraint(cons);
break;
default:
throw new RuntimeException("Invalid type");
}
++n_legal_cons;
}
ptAnalyzer.ps.printf("Only %d (%.1f%%) constraints are needed for this run.\n", n_legal_cons, ((double) n_legal_cons / ptAnalyzer.n_init_constraints) * 100);
}
use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class AbstractInterproceduralAnalysis method analyseCall.
/**
* Analyse the call {@code callStmt} in the context {@code src}, and put the
* result into {@code dst}. For each possible target of the call, this will
* get the summary for the target method (possibly
* {@link #summaryOfUnanalysedMethod(SootMethod)}) and
* {@link #applySummary(Object, Stmt, Object, Object)}, then merge the
* results into {@code dst} using {@link #merge(Object, Object, Object)}.
*
* @param src
* @param dst
* @param callStmt
*
* @see #summaryOfUnanalysedMethod(SootMethod)
* @see #applySummary(Object, Stmt, Object, Object)
*/
public void analyseCall(S src, Stmt callStmt, S dst) {
S accum = newInitialSummary();
copy(accum, dst);
System.out.println("Edges out of " + callStmt + "...");
for (Iterator<Edge> it = cg.edgesOutOf(callStmt); it.hasNext(); ) {
Edge edge = it.next();
SootMethod m = edge.tgt();
System.out.println("\t-> " + m.getSignature());
S elem;
if (data.containsKey(m)) {
// analysed method
elem = data.get(m);
} else {
// unanalysed method
if (!unanalysed.containsKey(m)) {
unanalysed.put(m, summaryOfUnanalysedMethod(m));
}
elem = unanalysed.get(m);
}
applySummary(src, callStmt, elem, accum);
merge(dst, accum, dst);
}
}
use of soot.jimple.toolkits.callgraph.Edge in project soot by Sable.
the class OnFlyCallGraph method processCallEdges.
private void processCallEdges() {
while (callEdges.hasNext()) {
Edge e = callEdges.next();
MethodPAG amp = MethodPAG.v(pag, e.tgt());
amp.build();
amp.addToPAG(e.tgtCtxt());
pag.addCallTarget(e);
}
}
Aggregations