use of soot.jimple.spark.pag.GlobalVarNode in project soot by Sable.
the class OfflineProcessor method setAllUserCodeVariablesUseful.
/**
* All the pointers that we need their points-to information are marked.
* @param virtualBaseSet
*/
protected void setAllUserCodeVariablesUseful() {
for (int i = 0; i < n_var; ++i) {
IVarAbstraction pn = int2var.get(i);
if (pn != pn.getRepresentative())
continue;
Node node = pn.getWrappedNode();
int sm_id = geomPTA.getMethodIDFromPtr(pn);
if (!geomPTA.isReachableMethod(sm_id))
continue;
if (node instanceof VarNode) {
// flag == true if node is defined in the Java library
boolean defined_in_lib = false;
if (node instanceof LocalVarNode) {
defined_in_lib = ((LocalVarNode) node).getMethod().isJavaLibraryMethod();
} else if (node instanceof GlobalVarNode) {
SootClass sc = ((GlobalVarNode) node).getDeclaringClass();
if (sc != null)
defined_in_lib = sc.isJavaLibraryClass();
}
if (!defined_in_lib && !geomPTA.isExceptionPointer(node)) {
// Defined in the user code
pn.willUpdate = true;
}
}
}
}
use of soot.jimple.spark.pag.GlobalVarNode in project soot by Sable.
the class DemandCSPointsTo method findUpContextsForVar.
protected CallingContextSet findUpContextsForVar(AllocAndContext allocAndContext, VarContextAndUp varContextAndUp) {
final AllocNode alloc = allocAndContext.alloc;
final ImmutableStack<Integer> allocContext = allocAndContext.context;
CallingContextSet tmpSet = checkUpContextCache(varContextAndUp, allocAndContext);
if (tmpSet != null) {
return tmpSet;
}
final CallingContextSet ret = new CallingContextSet();
upContextCache.get(varContextAndUp).put(allocAndContext, ret);
nesting++;
if (DEBUG) {
debugPrint("finding up context for " + varContextAndUp + " to " + alloc + " " + allocContext);
}
try {
final Set<VarAndContext> marked = new HashSet<VarAndContext>();
final Stack<VarAndContext> worklist = new Stack<VarAndContext>();
final Propagator<VarAndContext> p = new Propagator<VarAndContext>(marked, worklist);
p.prop(varContextAndUp);
class UpContextEdgeHandler extends IncomingEdgeHandler {
@Override
public void handleAlloc(AllocNode allocNode, VarAndContext origVarAndContext) {
VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
if (allocNode == alloc) {
if (allocContext.topMatches(contextAndUp.context)) {
ImmutableStack<Integer> reverse = contextAndUp.upContext.reverse();
ImmutableStack<Integer> toAdd = allocContext.popAll(contextAndUp.context).pushAll(reverse);
if (DEBUG) {
debugPrint("found up context " + toAdd);
}
ret.add(toAdd);
} else if (contextAndUp.context.topMatches(allocContext)) {
ImmutableStack<Integer> toAdd = contextAndUp.upContext.reverse();
if (DEBUG) {
debugPrint("found up context " + toAdd);
}
ret.add(toAdd);
}
}
}
@Override
public void handleMatchSrc(VarNode matchSrc, PointsToSetInternal intersection, VarNode loadBase, VarNode storeBase, VarAndContext origVarAndContext, SparkField field, boolean refine) {
VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
if (DEBUG) {
debugPrint("CHECKING " + alloc);
}
PointsToSetInternal tmp = new HybridPointsToSet(alloc.getType(), pag);
tmp.add(alloc);
AllocAndContextSet allocContexts = findContextsForAllocs(new VarAndContext(matchSrc, EMPTY_CALLSTACK), tmp);
// Set allocContexts = Collections.singleton(new Object());
if (!refine) {
if (!allocContexts.isEmpty()) {
ret.add(contextAndUp.upContext.reverse());
}
} else {
if (!allocContexts.isEmpty()) {
for (AllocAndContext t : allocContexts) {
ImmutableStack<Integer> discoveredAllocContext = t.context;
if (!allocContext.topMatches(discoveredAllocContext)) {
continue;
}
ImmutableStack<Integer> trueAllocContext = allocContext.popAll(discoveredAllocContext);
AllocAndContextSet allocAndContexts = findContextsForAllocs(new VarAndContext(storeBase, trueAllocContext), intersection);
for (AllocAndContext allocAndContext : allocAndContexts) {
// CallingContextSet upContexts;
if (fieldCheckHeuristic.validFromBothEnds(field)) {
ret.addAll(findUpContextsForVar(allocAndContext, new VarContextAndUp(loadBase, contextAndUp.context, contextAndUp.upContext)));
} else {
CallingContextSet tmpContexts = findVarContextsFromAlloc(allocAndContext, loadBase);
// upContexts = new CallingContextSet();
for (ImmutableStack<Integer> tmpContext : tmpContexts) {
if (tmpContext.topMatches(contextAndUp.context)) {
ImmutableStack<Integer> reverse = contextAndUp.upContext.reverse();
ImmutableStack<Integer> toAdd = tmpContext.popAll(contextAndUp.context).pushAll(reverse);
ret.add(toAdd);
}
}
}
}
}
}
}
}
@Override
Object getResult() {
return ret;
}
@Override
void handleAssignSrc(VarAndContext newVarAndContext, VarAndContext origVarAndContext, AssignEdge assignEdge) {
VarContextAndUp contextAndUp = (VarContextAndUp) origVarAndContext;
ImmutableStack<Integer> upContext = contextAndUp.upContext;
ImmutableStack<Integer> newUpContext = upContext;
if (assignEdge.isParamEdge() && contextAndUp.context.isEmpty()) {
if (upContext.size() < ImmutableStack.getMaxSize()) {
newUpContext = pushWithRecursionCheck(upContext, assignEdge);
}
;
}
p.prop(new VarContextAndUp(newVarAndContext.var, newVarAndContext.context, newUpContext));
}
@Override
boolean shouldHandleSrc(VarNode src) {
if (src instanceof GlobalVarNode) {
// // for now, just give up
throw new TerminateEarlyException();
}
return src.getP2Set().contains(alloc);
}
}
;
UpContextEdgeHandler edgeHandler = new UpContextEdgeHandler();
processIncomingEdges(edgeHandler, worklist);
nesting--;
// }
return ret;
} catch (CallSiteException e) {
upContextCache.remove(varContextAndUp);
throw e;
}
}
use of soot.jimple.spark.pag.GlobalVarNode in project soot by Sable.
the class DemandCSPointsTo method getFlowsToHelper.
protected Set<VarNode> getFlowsToHelper(AllocAndContext allocAndContext) {
Set<VarNode> ret = new ArraySet<VarNode>();
try {
HashSet<VarAndContext> marked = new HashSet<VarAndContext>();
Stack<VarAndContext> worklist = new Stack<VarAndContext>();
Propagator<VarAndContext> p = new Propagator<VarAndContext>(marked, worklist);
AllocNode alloc = allocAndContext.alloc;
ImmutableStack<Integer> allocContext = allocAndContext.context;
Node[] newBarNodes = pag.allocLookup(alloc);
for (int i = 0; i < newBarNodes.length; i++) {
VarNode v = (VarNode) newBarNodes[i];
ret.add(v);
p.prop(new VarAndContext(v, allocContext));
}
while (!worklist.isEmpty()) {
incrementNodesTraversed();
VarAndContext curVarAndContext = worklist.pop();
if (DEBUG) {
debugPrint("looking at " + curVarAndContext);
}
VarNode curVar = curVarAndContext.var;
ImmutableStack<Integer> curContext = curVarAndContext.context;
ret.add(curVar);
// assign
Collection<AssignEdge> assignEdges = filterAssigns(curVar, curContext, false, true);
for (AssignEdge assignEdge : assignEdges) {
VarNode dst = assignEdge.getDst();
ImmutableStack<Integer> newContext = curContext;
if (assignEdge.isReturnEdge()) {
if (!curContext.isEmpty()) {
if (!callEdgeInSCC(assignEdge)) {
assert assignEdge.getCallSite().equals(curContext.peek()) : assignEdge + " " + curContext;
newContext = curContext.pop();
} else {
newContext = popRecursiveCallSites(curContext);
}
}
} else if (assignEdge.isParamEdge()) {
if (DEBUG)
debugPrint("entering call site " + assignEdge.getCallSite());
// if (!isRecursive(curContext, assignEdge)) {
// newContext = curContext.push(assignEdge
// .getCallSite());
// }
newContext = pushWithRecursionCheck(curContext, assignEdge);
}
if (assignEdge.isReturnEdge() && curContext.isEmpty() && csInfo.isVirtCall(assignEdge.getCallSite())) {
Set<SootMethod> targets = refineCallSite(assignEdge.getCallSite(), newContext);
if (!targets.contains(((LocalVarNode) assignEdge.getDst()).getMethod())) {
continue;
}
}
if (dst instanceof GlobalVarNode) {
newContext = EMPTY_CALLSTACK;
}
p.prop(new VarAndContext(dst, newContext));
}
// putfield_bars
Set<VarNode> matchTargets = vMatches.vMatchLookup(curVar);
Node[] pfTargets = pag.storeLookup(curVar);
for (int i = 0; i < pfTargets.length; i++) {
FieldRefNode frNode = (FieldRefNode) pfTargets[i];
final VarNode storeBase = frNode.getBase();
SparkField field = frNode.getField();
// FieldRefNode>(curVar, frNode);
for (Pair<VarNode, VarNode> load : fieldToLoads.get(field)) {
final VarNode loadBase = load.getO2();
final PointsToSetInternal loadBaseP2Set = loadBase.getP2Set();
final PointsToSetInternal storeBaseP2Set = storeBase.getP2Set();
final VarNode matchTgt = load.getO1();
if (matchTargets.contains(matchTgt)) {
if (DEBUG) {
debugPrint("match source " + matchTgt);
}
PointsToSetInternal intersection = SootUtil.constructIntersection(storeBaseP2Set, loadBaseP2Set, pag);
boolean checkField = fieldCheckHeuristic.validateMatchesForField(field);
if (checkField) {
AllocAndContextSet sharedAllocContexts = findContextsForAllocs(new VarAndContext(storeBase, curContext), intersection);
for (AllocAndContext curAllocAndContext : sharedAllocContexts) {
CallingContextSet upContexts;
if (fieldCheckHeuristic.validFromBothEnds(field)) {
upContexts = findUpContextsForVar(curAllocAndContext, new VarContextAndUp(loadBase, EMPTY_CALLSTACK, EMPTY_CALLSTACK));
} else {
upContexts = findVarContextsFromAlloc(curAllocAndContext, loadBase);
}
for (ImmutableStack<Integer> upContext : upContexts) {
p.prop(new VarAndContext(matchTgt, upContext));
}
}
} else {
p.prop(new VarAndContext(matchTgt, EMPTY_CALLSTACK));
}
// h.handleMatchSrc(matchSrc, intersection,
// storeBase,
// loadBase, varAndContext, checkGetfield);
// if (h.terminate())
// return;
}
}
}
}
return ret;
} catch (CallSiteException e) {
allocAndContextCache.remove(allocAndContext);
throw e;
}
}
use of soot.jimple.spark.pag.GlobalVarNode in project soot by Sable.
the class SootUtil method buildStoreMap.
public static FieldAccessMap buildStoreMap(PAG pag) {
FieldAccessMap ret = new FieldAccessMap();
Iterator frNodeIter = pag.storeInvSourcesIterator();
while (frNodeIter.hasNext()) {
FieldRefNode frNode = (FieldRefNode) frNodeIter.next();
SparkField field = frNode.getField();
Node[] targets = pag.storeInvLookup(frNode);
for (int i = 0; i < targets.length; i++) {
VarNode target = (VarNode) targets[i];
if (target instanceof GlobalVarNode)
continue;
ret.put(field, new Pair<FieldRefNode, LocalVarNode>(frNode, (LocalVarNode) target));
}
}
return ret;
}
use of soot.jimple.spark.pag.GlobalVarNode in project soot by Sable.
the class DemandCSPointsTo method processIncomingEdges.
protected void processIncomingEdges(IncomingEdgeHandler h, Stack<VarAndContext> worklist) {
while (!worklist.isEmpty()) {
incrementNodesTraversed();
VarAndContext varAndContext = worklist.pop();
if (DEBUG) {
debugPrint("looking at " + varAndContext);
}
VarNode v = varAndContext.var;
ImmutableStack<Integer> callingContext = varAndContext.context;
Node[] newEdges = pag.allocInvLookup(v);
for (int i = 0; i < newEdges.length; i++) {
AllocNode allocNode = (AllocNode) newEdges[i];
h.handleAlloc(allocNode, varAndContext);
if (h.terminate()) {
return;
}
}
Collection<AssignEdge> assigns = filterAssigns(v, callingContext, true, true);
for (AssignEdge assignEdge : assigns) {
VarNode src = assignEdge.getSrc();
// }
if (h.shouldHandleSrc(src)) {
ImmutableStack<Integer> newContext = callingContext;
if (assignEdge.isParamEdge()) {
if (!callingContext.isEmpty()) {
if (!callEdgeInSCC(assignEdge)) {
assert assignEdge.getCallSite().equals(callingContext.peek()) : assignEdge + " " + callingContext;
newContext = callingContext.pop();
} else {
newContext = popRecursiveCallSites(callingContext);
}
}
// } else if (refiningCallSite) {
// if (!fieldCheckHeuristic.aggressiveVirtCallRefine())
// {
// // throw new CallSiteException();
// }
// }
} else if (assignEdge.isReturnEdge()) {
if (DEBUG)
debugPrint("entering call site " + assignEdge.getCallSite());
// if (!isRecursive(callingContext, assignEdge)) {
// newContext = callingContext.push(assignEdge
// .getCallSite());
// }
newContext = pushWithRecursionCheck(callingContext, assignEdge);
}
if (assignEdge.isParamEdge()) {
Integer callSite = assignEdge.getCallSite();
if (csInfo.isVirtCall(callSite) && !weirdCall(callSite)) {
Set<SootMethod> targets = refineCallSite(callSite, newContext);
if (DEBUG) {
debugPrint(targets.toString());
}
SootMethod targetMethod = ((LocalVarNode) assignEdge.getDst()).getMethod();
if (!targets.contains(targetMethod)) {
if (DEBUG) {
debugPrint("skipping call because of call graph");
}
continue;
}
}
}
if (src instanceof GlobalVarNode) {
newContext = EMPTY_CALLSTACK;
}
h.handleAssignSrc(new VarAndContext(src, newContext), varAndContext, assignEdge);
if (h.terminate()) {
return;
}
}
}
Set<VarNode> matchSources = vMatches.vMatchInvLookup(v);
Node[] loads = pag.loadInvLookup(v);
for (int i = 0; i < loads.length; i++) {
FieldRefNode frNode = (FieldRefNode) loads[i];
final VarNode loadBase = frNode.getBase();
SparkField field = frNode.getField();
// FieldRefNode>(v, frNode);
for (Pair<VarNode, VarNode> store : fieldToStores.get(field)) {
final VarNode storeBase = store.getO2();
final PointsToSetInternal storeBaseP2Set = storeBase.getP2Set();
final PointsToSetInternal loadBaseP2Set = loadBase.getP2Set();
final VarNode matchSrc = store.getO1();
if (matchSources.contains(matchSrc)) {
if (h.shouldHandleSrc(matchSrc)) {
if (DEBUG) {
debugPrint("match source " + matchSrc);
}
PointsToSetInternal intersection = SootUtil.constructIntersection(storeBaseP2Set, loadBaseP2Set, pag);
boolean checkGetfield = fieldCheckHeuristic.validateMatchesForField(field);
h.handleMatchSrc(matchSrc, intersection, loadBase, storeBase, varAndContext, field, checkGetfield);
if (h.terminate())
return;
}
}
}
}
}
}
Aggregations