Skip to content

Commit 6df1d0f

Browse files
committed
fixes for the merge from njupt-moon
1 parent 2de2d17 commit 6df1d0f

File tree

3 files changed

+172
-124
lines changed

3 files changed

+172
-124
lines changed

src/soot/Kind.java

+143-114
Original file line numberDiff line numberDiff line change
@@ -18,121 +18,150 @@
1818
*/
1919

2020
package soot;
21-
import soot.util.*;
2221

23-
/** Enumeration type representing the kind of a call graph edge.
22+
import soot.util.Numberable;
23+
24+
/**
25+
* Enumeration type representing the kind of a call graph edge.
26+
*
2427
* @author Ondrej Lhotak
2528
*/
26-
public final class Kind implements Numberable
27-
{
28-
public static final Kind INVALID = new Kind( "INVALID" );
29-
/** Due to explicit invokestatic instruction. */
30-
public static final Kind STATIC = new Kind( "STATIC" );
31-
/** Due to explicit invokevirtual instruction. */
32-
public static final Kind VIRTUAL = new Kind( "VIRTUAL" );
33-
/** Due to explicit invokeinterface instruction. */
34-
public static final Kind INTERFACE = new Kind( "INTERFACE" );
35-
/** Due to explicit invokespecial instruction. */
36-
public static final Kind SPECIAL = new Kind( "SPECIAL" );
37-
/** Implicit call to static initializer. */
38-
public static final Kind CLINIT = new Kind( "CLINIT" );
39-
/** Implicit call to Thread.run() due to Thread.start() call. */
40-
public static final Kind THREAD = new Kind( "THREAD" );
41-
/** Implicit call to java.lang.Runnable.run() due to Executor.execute() call. */
42-
public static final Kind EXECUTOR = new Kind( "EXECUTOR" );
43-
/** Implicit call to AsyncTask.doInBackground() due to AsyncTask.execute() call. */
44-
public static final Kind ASYNCTASK = new Kind( "ASYNCTASK" );
45-
/** Implicit call to java.lang.ref.Finalizer.register from new bytecode. */
46-
public static final Kind FINALIZE = new Kind( "FINALIZE" );
47-
/** Implicit call to finalize() from java.lang.ref.Finalizer.invokeFinalizeMethod(). */
48-
public static final Kind INVOKE_FINALIZE = new Kind( "INVOKE_FINALIZE" );
49-
/** Implicit call to run() through AccessController.doPrivileged(). */
50-
public static final Kind PRIVILEGED = new Kind( "PRIVILEGED" );
51-
/** Implicit call to constructor from java.lang.Class.newInstance(). */
52-
public static final Kind NEWINSTANCE = new Kind( "NEWINSTANCE" );
53-
/** Due to call to Method.invoke(..). */
54-
public static final Kind REFL_INVOKE = new Kind( "REFL_METHOD_INVOKE" );
55-
/** Due to call to Constructor.newInstance(..). */
56-
public static final Kind REFL_CONSTR_NEWINSTANCE = new Kind( "REFL_CONSTRUCTOR_NEWINSTANCE" );
57-
/** Due to call to Class.newInstance(..) when reflection log is enabled. */
58-
public static final Kind REFL_CLASS_NEWINSTANCE = new Kind( "REFL_CLASS_NEWINSTANCE" );
59-
60-
private Kind( String name ) {
61-
this.name = name;
62-
}
63-
private final String name;
64-
private int num;
65-
66-
public String name() { return name; }
67-
public int getNumber() { return num; }
68-
public void setNumber( int num ) { this.num = num; }
69-
70-
public String toString() { return name(); }
71-
72-
public boolean passesParameters() {
73-
return isExplicit() || this == THREAD || this == EXECUTOR || this == ASYNCTASK || this == FINALIZE ||
74-
this == PRIVILEGED || this == NEWINSTANCE || this == INVOKE_FINALIZE ||
75-
this == REFL_INVOKE || this == REFL_CONSTR_NEWINSTANCE || this == REFL_CLASS_NEWINSTANCE;
76-
}
77-
78-
public boolean isFake() {
79-
return this == THREAD || this == EXECUTOR || this == ASYNCTASK || this == PRIVILEGED;
80-
}
81-
82-
/** Returns true if the call is due to an explicit invoke statement. */
83-
public boolean isExplicit() {
84-
return isInstance() || isStatic();
85-
}
86-
87-
/** Returns true if the call is due to an explicit instance invoke
88-
* statement. */
89-
public boolean isInstance() {
90-
return this == VIRTUAL || this == INTERFACE || this == SPECIAL;
91-
}
92-
93-
/** Returns true if the call is due to an explicit virtual invoke
94-
* statement. */
95-
public boolean isVirtual() {
96-
return this == VIRTUAL;
97-
}
98-
99-
public boolean isSpecial() {
100-
return this == SPECIAL;
101-
}
102-
103-
/** Returns true if the call is to static initializer. */
104-
public boolean isClinit() {
105-
return this == CLINIT;
106-
}
107-
/** Returns true if the call is due to an explicit static invoke
108-
* statement. */
109-
public boolean isStatic() {
110-
return this == STATIC;
111-
}
112-
113-
public boolean isThread() {
114-
return this == THREAD;
115-
}
116-
117-
public boolean isExecutor() {
118-
return this == EXECUTOR;
119-
}
120-
121-
public boolean isAsyncTask() {
122-
return this == ASYNCTASK;
123-
}
124-
125-
public boolean isPrivileged() {
126-
return this == PRIVILEGED;
127-
}
128-
129-
public boolean isReflection() {
130-
return this == REFL_CLASS_NEWINSTANCE || this == REFL_CONSTR_NEWINSTANCE
131-
|| this == REFL_INVOKE;
132-
}
133-
134-
public boolean isReflInvoke() {
135-
return this == REFL_INVOKE;
136-
}
137-
}
29+
public final class Kind implements Numberable {
30+
public static final Kind INVALID = new Kind("INVALID");
31+
/** Due to explicit invokestatic instruction. */
32+
public static final Kind STATIC = new Kind("STATIC");
33+
/** Due to explicit invokevirtual instruction. */
34+
public static final Kind VIRTUAL = new Kind("VIRTUAL");
35+
/** Due to explicit invokeinterface instruction. */
36+
public static final Kind INTERFACE = new Kind("INTERFACE");
37+
/** Due to explicit invokespecial instruction. */
38+
public static final Kind SPECIAL = new Kind("SPECIAL");
39+
/** Implicit call to static initializer. */
40+
public static final Kind CLINIT = new Kind("CLINIT");
41+
/** Implicit call to Thread.run() due to Thread.start() call. */
42+
public static final Kind THREAD = new Kind("THREAD");
43+
/**
44+
* Implicit call to java.lang.Runnable.run() due to Executor.execute() call.
45+
*/
46+
public static final Kind EXECUTOR = new Kind("EXECUTOR");
47+
/**
48+
* Implicit call to AsyncTask.doInBackground() due to AsyncTask.execute()
49+
* call.
50+
*/
51+
public static final Kind ASYNCTASK = new Kind("ASYNCTASK");
52+
/** Implicit call to java.lang.ref.Finalizer.register from new bytecode. */
53+
public static final Kind FINALIZE = new Kind("FINALIZE");
54+
/**
55+
* Implicit call to Handler.handleMessage(android.os.Message) due to
56+
* Handler.sendxxxxMessagexxxx() call.
57+
*/
58+
public static final Kind HANDLER = new Kind("HANDLER");
59+
/**
60+
* Implicit call to finalize() from
61+
* java.lang.ref.Finalizer.invokeFinalizeMethod().
62+
*/
63+
public static final Kind INVOKE_FINALIZE = new Kind("INVOKE_FINALIZE");
64+
/** Implicit call to run() through AccessController.doPrivileged(). */
65+
public static final Kind PRIVILEGED = new Kind("PRIVILEGED");
66+
/** Implicit call to constructor from java.lang.Class.newInstance(). */
67+
public static final Kind NEWINSTANCE = new Kind("NEWINSTANCE");
68+
/** Due to call to Method.invoke(..). */
69+
public static final Kind REFL_INVOKE = new Kind("REFL_METHOD_INVOKE");
70+
/** Due to call to Constructor.newInstance(..). */
71+
public static final Kind REFL_CONSTR_NEWINSTANCE = new Kind("REFL_CONSTRUCTOR_NEWINSTANCE");
72+
/** Due to call to Class.newInstance(..) when reflection log is enabled. */
73+
public static final Kind REFL_CLASS_NEWINSTANCE = new Kind("REFL_CLASS_NEWINSTANCE");
74+
75+
private Kind(String name) {
76+
this.name = name;
77+
}
78+
79+
private final String name;
80+
private int num;
81+
82+
public String name() {
83+
return name;
84+
}
85+
86+
public int getNumber() {
87+
return num;
88+
}
89+
90+
public void setNumber(int num) {
91+
this.num = num;
92+
}
93+
94+
public String toString() {
95+
return name();
96+
}
97+
98+
public boolean passesParameters() {
99+
return isExplicit() || this == THREAD || this == EXECUTOR || this == ASYNCTASK || this == FINALIZE
100+
|| this == PRIVILEGED || this == NEWINSTANCE || this == INVOKE_FINALIZE || this == REFL_INVOKE
101+
|| this == REFL_CONSTR_NEWINSTANCE || this == REFL_CLASS_NEWINSTANCE;
102+
}
103+
104+
public boolean isFake() {
105+
return this == THREAD || this == EXECUTOR || this == ASYNCTASK || this == PRIVILEGED || this == HANDLER;
106+
}
107+
108+
/** Returns true if the call is due to an explicit invoke statement. */
109+
public boolean isExplicit() {
110+
return isInstance() || isStatic();
111+
}
112+
113+
/**
114+
* Returns true if the call is due to an explicit instance invoke statement.
115+
*/
116+
public boolean isInstance() {
117+
return this == VIRTUAL || this == INTERFACE || this == SPECIAL;
118+
}
138119

120+
/**
121+
* Returns true if the call is due to an explicit virtual invoke statement.
122+
*/
123+
public boolean isVirtual() {
124+
return this == VIRTUAL;
125+
}
126+
127+
public boolean isSpecial() {
128+
return this == SPECIAL;
129+
}
130+
131+
/** Returns true if the call is to static initializer. */
132+
public boolean isClinit() {
133+
return this == CLINIT;
134+
}
135+
136+
/**
137+
* Returns true if the call is due to an explicit static invoke statement.
138+
*/
139+
public boolean isStatic() {
140+
return this == STATIC;
141+
}
142+
143+
public boolean isThread() {
144+
return this == THREAD;
145+
}
146+
147+
public boolean isExecutor() {
148+
return this == EXECUTOR;
149+
}
150+
151+
public boolean isAsyncTask() {
152+
return this == ASYNCTASK;
153+
}
154+
155+
public boolean isPrivileged() {
156+
return this == PRIVILEGED;
157+
}
158+
159+
public boolean isReflection() {
160+
return this == REFL_CLASS_NEWINSTANCE || this == REFL_CONSTR_NEWINSTANCE || this == REFL_INVOKE;
161+
}
162+
163+
public boolean isReflInvoke() {
164+
return this == REFL_INVOKE;
165+
}
166+
167+
}

src/soot/jimple/spark/pag/PAG.java

+24-5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import soot.jimple.NewExpr;
5454
import soot.jimple.NullConstant;
5555
import soot.jimple.Stmt;
56+
import soot.jimple.VirtualInvokeExpr;
5657
import soot.jimple.spark.builder.GlobalNodeFactory;
5758
import soot.jimple.spark.builder.MethodNodeFactory;
5859
import soot.jimple.spark.internal.ClientAccessibilityOracle;
@@ -453,7 +454,7 @@ public Node[] loadInvLookup(VarNode key) {
453454
public Node[] storeLookup(VarNode key) {
454455
return lookup(store, key);
455456
}
456-
457+
457458
public Node[] newInstanceLookup(VarNode key) {
458459
return lookup(newInstance, key);
459460
}
@@ -589,7 +590,7 @@ private void addNodeTag(Node node, SootMethod m) {
589590
public AllocNode makeAllocNode(Object newExpr, Type type, SootMethod m) {
590591
if (opts.types_for_sites() || opts.vta())
591592
newExpr = type;
592-
593+
593594
AllocNode ret = valToAllocNode.get(newExpr);
594595
if (newExpr instanceof NewExpr) {
595596
// Do we need to create a new allocation node?
@@ -910,7 +911,7 @@ public boolean addAllocEdge(AllocNode from, VarNode to) {
910911
}
911912
return false;
912913
}
913-
914+
914915
public boolean addNewInstanceEdge(VarNode from, NewInstanceNode to) {
915916
if (!opts.rta()) {
916917
if (doAddNewInstanceEdge(from, to)) {
@@ -944,8 +945,7 @@ public final boolean addEdge(Node from, Node to) {
944945
return addStoreEdge((VarNode) from, (FieldRefNode) to);
945946
} else if (to instanceof NewInstanceNode) {
946947
return addNewInstanceEdge((VarNode) from, (NewInstanceNode) to);
947-
}
948-
else
948+
} else
949949
throw new RuntimeException("Invalid node type");
950950
} else if (from instanceof FieldRefNode) {
951951
return addLoadEdge((FieldRefNode) from, (VarNode) to);
@@ -1082,6 +1082,25 @@ final public void addCallTarget(Edge e) {
10821082
if (virtualCall && !virtualCallsToReceivers.containsKey(ie)) {
10831083
virtualCallsToReceivers.put(ie, parm);
10841084
}
1085+
} else if (e.kind() == Kind.HANDLER) {
1086+
InvokeExpr ie = e.srcStmt().getInvokeExpr();
1087+
boolean virtualCall = callAssigns.containsKey(ie);
1088+
assert virtualCall == true;
1089+
1090+
Node base = srcmpag.nodeFactory().getNode(((VirtualInvokeExpr) ie).getBase());
1091+
base = srcmpag.parameterize(base, e.srcCtxt());
1092+
base = base.getReplacement();
1093+
1094+
Node thiz = tgtmpag.nodeFactory().caseThis();
1095+
thiz = tgtmpag.parameterize(thiz, e.tgtCtxt());
1096+
thiz = thiz.getReplacement();
1097+
1098+
addEdge(base, thiz);
1099+
pval = addInterproceduralAssignment(base, thiz, e);
1100+
callAssigns.put(ie, pval);
1101+
callToMethod.put(ie, srcmpag.getMethod());
1102+
1103+
virtualCallsToReceivers.put(ie, base);
10851104
} else if (e.kind() == Kind.PRIVILEGED) {
10861105
// Flow from first parameter of doPrivileged() invocation
10871106
// to this of target, and from return of target to the

src/soot/jimple/toolkits/callgraph/OnFlyCallGraphBuilder.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -744,11 +744,11 @@ private void findReceivers(SootMethod m, Body b) {
744744
addVirtualCallSite(s, m, (Local) runnable, iie, sigRun, Kind.EXECUTOR);
745745
}
746746
} else if (subSig == sigHandlerSendEmptyMessage || subSig == sigHandlerSendEmptyMessageAtTime
747-
+ || subSig == sigHandlerSendEmptyMessageDelayed || subSig == sigHandlerSendMessage
748-
+ || subSig == sigHandlerSendMessageAtFrontOfQueue || subSig == sigHandlerSendMessageAtTime
749-
+ || subSig == sigHandlerSendMessageDelayed) {
750-
+ addVirtualCallSite(s, m, receiver, iie, sigHandlerHandleMessage, Kind.HANDLER);
751-
+ } else if (subSig == sigExecute) {
747+
|| subSig == sigHandlerSendEmptyMessageDelayed || subSig == sigHandlerSendMessage
748+
|| subSig == sigHandlerSendMessageAtFrontOfQueue || subSig == sigHandlerSendMessageAtTime
749+
|| subSig == sigHandlerSendMessageDelayed) {
750+
addVirtualCallSite(s, m, receiver, iie, sigHandlerHandleMessage, Kind.HANDLER);
751+
} else if (subSig == sigExecute) {
752752
addVirtualCallSite(s, m, receiver, iie, sigDoInBackground, Kind.ASYNCTASK);
753753
}
754754
} else if (ie instanceof DynamicInvokeExpr) {

0 commit comments

Comments
 (0)