Skip to content

Commit

Permalink
reverting last commit because I implemented a cleaner solution (added…
Browse files Browse the repository at this point in the history
… a new edge kind)
  • Loading branch information
Eric Bodden committed Feb 17, 2010
1 parent 316c846 commit 16efdd0
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 151 deletions.
6 changes: 0 additions & 6 deletions generated/singletons/soot/Singletons.java
Original file line number Diff line number Diff line change
Expand Up @@ -886,10 +886,4 @@ public soot.jimple.toolkits.annotation.j5anno.AnnotationGenerator soot_jimple_to
return instance_soot_jimple_toolkits_annotation_j5anno_AnnotationGenerator;
}

private soot.jimple.toolkits.reflection.ReflectionTraceInfo instance_soot_jimple_toolkits_reflection_ReflectionTraceInfo;
public soot.jimple.toolkits.reflection.ReflectionTraceInfo soot_jimple_toolkits_reflection_ReflectionTraceInfo() {
if( instance_soot_jimple_toolkits_reflection_ReflectionTraceInfo == null ) instance_soot_jimple_toolkits_reflection_ReflectionTraceInfo = new soot.jimple.toolkits.reflection.ReflectionTraceInfo( g );
return instance_soot_jimple_toolkits_reflection_ReflectionTraceInfo;
}

}
1 change: 0 additions & 1 deletion src/singletons.list
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,3 @@ soot.jimple.toolkits.thread.synchronization.LockAllocator
soot.jimple.toolkits.thread.mhp.MhpTransformer
soot.JastAddInitialResolver
soot.jimple.toolkits.annotation.j5anno.AnnotationGenerator
soot.jimple.toolkits.reflection.ReflectionTraceInfo
6 changes: 4 additions & 2 deletions src/soot/Kind.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ public final class Kind implements Numberable
/** Due to call to Method.invoke(..). */
public static final Kind REFL_INVOKE = new Kind( "REFL_METHOD_INVOKE" );
/** Due to call to Constructor.newInstance(..). */
public static final Kind REFL_NEWINSTANCE = new Kind( "REFL_CONSTRUCTOR_NEWINSTANCE" );
public static final Kind REFL_CONSTR_NEWINSTANCE = new Kind( "REFL_CONSTRUCTOR_NEWINSTANCE" );
/** Due to call to Class.newInstance(..) when reflection log is enabled. */
public static final Kind REFL_CLASS_NEWINSTANCE = new Kind( "REFL_CLASS_NEWINSTANCE" );

private Kind( String name ) {
this.name = name;
Expand All @@ -66,7 +68,7 @@ private Kind( String name ) {
public boolean passesParameters() {
return isExplicit() || this == THREAD || this == FINALIZE ||
this == PRIVILEGED || this == NEWINSTANCE || this == INVOKE_FINALIZE ||
this == REFL_INVOKE || this == REFL_NEWINSTANCE;
this == REFL_INVOKE || this == REFL_CONSTR_NEWINSTANCE || this == REFL_CLASS_NEWINSTANCE;
}

/** Returns true if the call is due to an explicit invoke statement. */
Expand Down
33 changes: 4 additions & 29 deletions src/soot/jimple/spark/builder/GlobalNodeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,8 @@
*/

package soot.jimple.spark.builder;
import java.util.Set;

import soot.AnySubType;
import soot.ArrayType;
import soot.PointsToAnalysis;
import soot.RefType;
import soot.Scene;
import soot.SootClass;
import soot.SootMethod;
import soot.jimple.spark.pag.AllocNode;
import soot.jimple.spark.pag.ArrayElement;
import soot.jimple.spark.pag.ContextVarNode;
import soot.jimple.spark.pag.Node;
import soot.jimple.spark.pag.PAG;
import soot.jimple.spark.pag.VarNode;
import soot.jimple.toolkits.reflection.ReflectionTraceInfo;
import soot.jimple.spark.pag.*;
import soot.*;
import soot.toolkits.scalar.Pair;

/** Factory for nodes not specific to a given method.
Expand Down Expand Up @@ -131,24 +117,13 @@ final public Node caseNewInstance( VarNode cls ) {
if( cls instanceof ContextVarNode ) cls = pag.findLocalVarNode( cls.getVariable() );
VarNode local = pag.makeGlobalVarNode( cls, RefType.v( "java.lang.Object" ) );
for (SootClass cl : Scene.v().dynamicClasses()) {
AllocNode site = pag.makeAllocNode( new Pair<VarNode,SootClass>(cls, cl), cl.getType(), null );
AllocNode site = pag.makeAllocNode( new Pair(cls, cl), cl.getType(), null );
pag.addEdge( site, local );
}
return local;
}

public Node caseNewInstanceWithReflLog(VarNode cls, SootMethod container) {
Set<SootClass> classNewInstanceClasses = ReflectionTraceInfo.v().classNewInstanceClasses(container);
if( cls instanceof ContextVarNode ) cls = pag.findLocalVarNode( cls.getVariable() );
VarNode local = pag.makeGlobalVarNode( cls, RefType.v( "java.lang.Object" ) );
for (SootClass cl : classNewInstanceClasses) {
AllocNode site = pag.makeAllocNode( new Pair<VarNode,SootClass>(cls, cl), cl.getType(), null );
pag.addEdge( site, local );
}
return local;
}

public Node caseThrow() {
public Node caseThrow() {
VarNode ret = pag.makeGlobalVarNode( PointsToAnalysis.EXCEPTION_NODE,
RefType.v("java.lang.Throwable") );
ret.setInterProcTarget();
Expand Down
121 changes: 35 additions & 86 deletions src/soot/jimple/spark/pag/PAG.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,75 +18,27 @@
*/

package soot.jimple.spark.pag;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import soot.Context;
import soot.FastHierarchy;
import soot.G;
import soot.Kind;
import soot.Local;
import soot.PhaseOptions;
import soot.PointsToAnalysis;
import soot.PointsToSet;
import soot.RefLikeType;
import soot.RefType;
import soot.Scene;
import soot.SootClass;
import soot.SootField;
import soot.SootMethod;
import soot.Type;
import soot.Value;
import soot.jimple.AssignStmt;
import soot.jimple.ClassConstant;
import soot.jimple.InstanceInvokeExpr;
import soot.jimple.InvokeExpr;
import soot.jimple.NullConstant;
import soot.jimple.Stmt;
import soot.jimple.spark.builder.GlobalNodeFactory;
import soot.jimple.spark.builder.MethodNodeFactory;
import soot.jimple.spark.internal.TypeManager;
import soot.jimple.spark.sets.BitPointsToSet;
import soot.jimple.spark.sets.DoublePointsToSet;
import soot.jimple.spark.sets.EmptyPointsToSet;
import soot.jimple.spark.sets.HashPointsToSet;
import soot.jimple.spark.sets.HybridPointsToSet;
import soot.jimple.spark.sets.P2SetFactory;
import soot.jimple.spark.sets.P2SetVisitor;
import soot.jimple.spark.sets.PointsToSetInternal;
import soot.jimple.spark.sets.SharedHybridSet;
import soot.jimple.spark.sets.SharedListSet;
import soot.jimple.spark.sets.SortedArraySet;
import java.util.*;

import soot.jimple.*;
import soot.*;
import soot.jimple.spark.sets.*;
import soot.jimple.spark.solver.OnFlyCallGraph;
import soot.jimple.spark.internal.*;
import soot.jimple.spark.builder.*;
import soot.jimple.toolkits.callgraph.Edge;
import soot.jimple.toolkits.pointer.util.NativeMethodDriver;
import soot.options.CGOptions;
import soot.util.*;
import soot.util.queue.*;
import soot.options.SparkOptions;
import soot.tagkit.LinkTag;
import soot.tagkit.StringTag;
import soot.tagkit.Tag;
import soot.tagkit.*;
import soot.toolkits.scalar.Pair;
import soot.util.ArrayNumberer;
import soot.util.HashMultiMap;
import soot.util.LargeNumberedMap;
import soot.util.queue.ChunkedQueue;
import soot.util.queue.QueueReader;

/** Pointer assignment graph.
* @author Ondrej Lhotak
*/
public class PAG implements PointsToAnalysis {
protected boolean usingReflectionTrace = false;

public PAG( final SparkOptions opts ) {
CGOptions cgOpts = new CGOptions( PhaseOptions.v().getPhaseOptions("cg") );
usingReflectionTrace = (cgOpts.reflection_log()!=null);

this.opts = opts;
if( opts.add_tags() ) {
nodeToTag = new HashMap<Node, Tag>();
Expand Down Expand Up @@ -813,13 +765,7 @@ final public void addCallTarget( Edge e ) {
Node cls = srcmpag.nodeFactory().getNode( iie.getBase() );
cls = srcmpag.parameterize( cls, e.srcCtxt() );
cls = cls.getReplacement();

Node newObject;
if(!usingReflectionTrace) {
newObject = nodeFactory.caseNewInstance( (VarNode) cls );
} else {
newObject = nodeFactory.caseNewInstanceWithReflLog( (VarNode) cls, e.getSrc().method() );
}
Node newObject = nodeFactory.caseNewInstance( (VarNode) cls );

Node initThis = tgtmpag.nodeFactory().caseThis();
initThis = tgtmpag.parameterize( initThis, e.tgtCtxt() );
Expand Down Expand Up @@ -900,10 +846,11 @@ final public void addCallTarget( Edge e ) {
addEdge( ret, lhs );
callAssigns.put(ie, new Pair(ret, lhs));
}
} else if( e.kind() == Kind.REFL_NEWINSTANCE ) {
} 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) create edges passing the contents of the arguments array of the call
// (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
Expand All @@ -930,25 +877,27 @@ final public void addCallTarget( Edge e ) {
addEdge( newObject, initThis );

//(3)
Value arg = iie.getArg(0);
SootMethod tgt = e.getTgt().method();
//if "null" is passed in, or target has no parameters, omit the 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 );
callAssigns.put(iie, new Pair(parm1contents, tgtParmI));
if(e.kind() == Kind.REFL_CONSTR_NEWINSTANCE) {
Value arg = iie.getArg(0);
SootMethod tgt = e.getTgt().method();
//if "null" is passed in, or target has no parameters, omit the 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 );
callAssigns.put(iie, new Pair(parm1contents, tgtParmI));
}
}
}

Expand Down
21 changes: 16 additions & 5 deletions src/soot/jimple/toolkits/callgraph/OnFlyCallGraphBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,17 @@
*/

package soot.jimple.toolkits.callgraph;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
Expand All @@ -49,6 +55,7 @@
import soot.SootMethodRef;
import soot.Transform;
import soot.Type;
import soot.Unit;
import soot.Value;
import soot.javaToJimple.LocalGenerator;
import soot.jimple.AssignStmt;
Expand All @@ -69,6 +76,8 @@
import soot.jimple.spark.pag.PAG;
import soot.jimple.toolkits.reflection.ReflectionTraceInfo;
import soot.options.CGOptions;
import soot.tagkit.Host;
import soot.tagkit.SourceLnPosTag;
import soot.util.LargeNumberedMap;
import soot.util.NumberedString;
import soot.util.SmallNumberedMap;
Expand Down Expand Up @@ -209,7 +218,7 @@ private TraceBasedReflectionModel() {
if(logFile==null) {
throw new InternalError("Trace based refection model enabled but no trace file given!?");
} else {
reflectionInfo = ReflectionTraceInfo.v();
reflectionInfo = new ReflectionTraceInfo(logFile);
}
}

Expand Down Expand Up @@ -240,14 +249,15 @@ public void classNewInstance(SootMethod container, Stmt newInstanceInvokeStmt) {
for (String clsName : classNames) {
SootClass cls = Scene.v().getSootClass(clsName);
if( cls.declaresMethod(sigInit) ) {
addEdge( container, newInstanceInvokeStmt, cls.getMethod(sigInit), Kind.NEWINSTANCE );
SootMethod constructor = cls.getMethod(sigInit);
addEdge( container, newInstanceInvokeStmt, constructor, Kind.REFL_CLASS_NEWINSTANCE );
}
}
}
}

/**
* Adds a special edge of kind {@link Kind#REFL_NEWINSTANCE} to all possible target constructors
* Adds a special edge of kind {@link Kind#REFL_CONSTR_NEWINSTANCE} to all possible target constructors
* of this call to {@link Constructor#newInstance(Object...)}.
* Those kinds of edges are treated specially in terms of how parameters are assigned,
* as parameters to the reflective call are passed into the argument array of
Expand All @@ -261,7 +271,7 @@ public void contructorNewInstance(SootMethod container, Stmt newInstanceInvokeSt
} else {
for (String constructorSignature : constructorSignatures) {
SootMethod constructor = Scene.v().getMethod(constructorSignature);
addEdge( container, newInstanceInvokeStmt, constructor, Kind.REFL_NEWINSTANCE );
addEdge( container, newInstanceInvokeStmt, constructor, Kind.REFL_CONSTR_NEWINSTANCE );
}
}
}
Expand Down Expand Up @@ -383,7 +393,8 @@ private void insertGuard(Guard guard) {

private final ChunkedQueue targetsQueue = new ChunkedQueue();
private final QueueReader targets = targetsQueue.reader();



public OnFlyCallGraphBuilder( ContextManager cm, ReachableMethods rm ) {
this.cm = cm;
this.rm = rm;
Expand Down
Loading

0 comments on commit 16efdd0

Please sign in to comment.