Skip to content

Commit 2526e6a

Browse files
committed
sootup:tests unsound (possibly because of cha <-> spark callgraphalgo)
1 parent fdae53c commit 2526e6a

File tree

7 files changed

+230
-114
lines changed

7 files changed

+230
-114
lines changed

boomerangPDS/src/test/java/test/FrameworkScopeFactory.java

Lines changed: 80 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@
2626
import sootup.core.model.SourceType;
2727
import sootup.core.signatures.MethodSignature;
2828
import sootup.core.transform.BodyInterceptor;
29-
import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
30-
import sootup.java.bytecode.inputlocation.JrtFileSystemAnalysisInputLocation;
29+
import sootup.interceptors.BytecodeBodyInterceptors;
30+
import sootup.java.bytecode.frontend.inputlocation.JavaClassPathAnalysisInputLocation;
31+
import sootup.java.bytecode.frontend.inputlocation.JrtFileSystemAnalysisInputLocation;
3132
import sootup.java.core.JavaSootClass;
32-
import sootup.java.core.JavaSootMethod;
33-
import sootup.java.core.interceptors.BytecodeBodyInterceptors;
3433
import sootup.java.core.views.JavaView;
34+
import sootup.jimple.frontend.JimpleStringAnalysisInputLocation;
3535

3636
// TODO: refactor as parameterized test -> update to junit 5
3737
public class FrameworkScopeFactory {
@@ -156,25 +156,30 @@ private static FrameworkScope getSootFrameworkScope(
156156
}
157157

158158
SootMethod methodByName = c.getMethodByName("main");
159+
eps.add(methodByName);
160+
159161
for (SootMethod m : sootTestCaseClass.getMethods()) {
160162
if (m.isStaticInitializer()) {
161163
eps.add(m);
162164
}
163165
}
164166

165-
// collect entrypoints
166-
for (SootClass inner : Scene.v().getClasses()) {
167-
classCount++;
168-
if (inner.getName().contains(sootTestCaseClass.getName())) {
169-
inner.setApplicationClass();
170-
for (SootMethod m : inner.getMethods()) {
171-
if (m.isStaticInitializer()) {
172-
eps.add(m);
173-
}
174-
}
175-
}
176-
}
177-
eps.add(methodByName);
167+
// TODO: check if the following block is needed / correct in this branch
168+
/*
169+
// collect entrypoints
170+
for (SootClass inner : Scene.v().getClasses()) {
171+
classCount++;
172+
if (inner.getName().contains(sootTestCaseClass.getName())) {
173+
inner.setApplicationClass();
174+
for (SootMethod m : inner.getMethods()) {
175+
if (m.isStaticInitializer()) {
176+
eps.add(m);
177+
}
178+
}
179+
}
180+
}
181+
182+
*/
178183

179184
if (eps.isEmpty()) {
180185
throw new IllegalStateException(
@@ -240,7 +245,6 @@ private static String getTargetClass(SootMethod sootTestMethod, String testCaseC
240245
return sootClass.toString();
241246
}
242247

243-
244248
/** SootUp Framework setup TODO: [ms] refactor me! */
245249
private static FrameworkScope getSootUpFrameworkScope(
246250
String pathStr,
@@ -273,47 +277,70 @@ private static FrameworkScope getSootUpFrameworkScope(
273277
classPathInputLocation, includedPackages),
274278
new ScopedAnalysisInputLocation.DenylistingScopedAnalysisInputLocation(
275279
classPathInputLocation, excludedPackages)));
276-
JavaView javaView = new JavaView(inputLocations);
277280

281+
JavaView javaView;
278282
sootup.callgraph.CallGraph cg;
279-
List<MethodSignature> entypointSignatures;
280-
List<JavaSootMethod> eps = Lists.newArrayList();
281-
282-
if (customEntrypointMethodName == null) {
283-
// collect entrypoints
284-
for (JavaSootClass sootClass : javaView.getClasses()) {
285-
String scStr = sootClass.toString();
286-
if (scStr.equals(className) || (scStr.contains(className + "$"))) {
287-
eps.addAll(sootClass.getMethods());
288-
}
289-
}
283+
List<MethodSignature> entypointSignatures = Lists.newArrayList();
290284

291-
} else {
292-
// build entrypoint
293-
String jimpleClassStr = "class dummyClass\n" +
294-
"{\n" +
295-
" public static void main(java.lang.String[])\n" +
296-
" {\n" +
297-
" "+ className +" dummyObj;\n" +
298-
" java.lang.String[] l0;\n" +
299-
" l0 := @parameter0: java.lang.String[];\n" +
300-
" dummyObj = new "+ className +";\n" +
301-
" virtualinvoke dummyObj.<"+ className +": void "+customEntrypointMethodName+"()>();\n" +
302-
" return;\n" +
303-
" }\n" +
304-
"}";
305-
306-
// new JimpleStringAnalysisInputLocation(jimpleClassStr) // currently in sootup:develop branch
307-
308-
throw new UnsupportedOperationException("implement me!");
285+
if (customEntrypointMethodName == null) {
286+
287+
javaView = new JavaView(inputLocations);
288+
// collect entrypoints
289+
for (JavaSootClass sootClass : javaView.getClasses().collect(Collectors.toList())) {
290+
String scStr = sootClass.toString();
291+
if (scStr.equals(className) || (scStr.contains(className + "$"))) {
292+
sootClass.getMethods().stream()
293+
.map(SootClassMember::getSignature)
294+
.forEach(entypointSignatures::add);
295+
}
309296
}
310297

311-
// initialize CallGraphAlgorithm
312-
entypointSignatures =
313-
eps.stream().map(SootClassMember::getSignature).collect(Collectors.toList());
298+
} else {
299+
300+
// build dummy entrypoint class
301+
String jimpleClassStr =
302+
"class dummyClass\n"
303+
+ "{\n"
304+
+ " public static void main(java.lang.String[])\n"
305+
+ " {\n"
306+
+ " "
307+
+ className
308+
+ " dummyObj;\n"
309+
+ " java.lang.String[] l0;\n"
310+
+ " l0 := @parameter0: java.lang.String[];\n"
311+
+ " dummyObj = new "
312+
+ className
313+
+ ";\n"
314+
+ " virtualinvoke dummyObj.<"
315+
+ className
316+
+ ": void "
317+
+ customEntrypointMethodName
318+
+ "()>();\n"
319+
+ " return;\n"
320+
+ " }\n"
321+
+ "}";
322+
323+
JimpleStringAnalysisInputLocation jimpleStringAnalysisInputLocation =
324+
new JimpleStringAnalysisInputLocation(
325+
jimpleClassStr); // currently in sootup:develop branch
326+
inputLocations.add(jimpleStringAnalysisInputLocation);
327+
javaView = new JavaView(inputLocations);
328+
329+
MethodSignature dummyEntrypoint =
330+
javaView
331+
.getIdentifierFactory()
332+
.parseMethodSignature("<dummyClass: void main(java.lang.String[])>");
333+
assert javaView.getMethod(dummyEntrypoint).isPresent();
334+
335+
entypointSignatures.add(dummyEntrypoint);
336+
}
314337

315-
// TODO: adapt if: --> use spark when available
316-
CallGraphAlgorithm cga = customEntrypointMethodName == null? new ClassHierarchyAnalysisAlgorithm(javaView) : new ClassHierarchyAnalysisAlgorithm(javaView);
338+
// initialize CallGraphAlgorithm
339+
// TODO: use spark when available
340+
CallGraphAlgorithm cga =
341+
customEntrypointMethodName == null
342+
? new ClassHierarchyAnalysisAlgorithm(javaView)
343+
: new ClassHierarchyAnalysisAlgorithm(javaView);
317344
cg = cga.initialize(entypointSignatures);
318345

319346
return new SootUpFrameworkScope(javaView, cg, entypointSignatures);

boomerangScope-SootUp/pom.xml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
<groupId>de.fraunhofer.iem</groupId>
2424
<artifactId>boomerangScope</artifactId>
2525
</dependency>
26+
<!-- from the release
2627
<dependency>
2728
<groupId>org.soot-oss</groupId>
2829
<artifactId>sootup.core</artifactId>
@@ -48,6 +49,55 @@
4849
<artifactId>sootup.analysis</artifactId>
4950
<version>1.3.0</version>
5051
</dependency>
52+
-->
53+
54+
<!-- latest from jitpack -->
55+
<dependency>
56+
<groupId>com.github.soot-oss.SootUp</groupId>
57+
<artifactId>sootup.core</artifactId>
58+
<version>develop-SNAPSHOT</version>
59+
</dependency>
60+
<dependency>
61+
<groupId>com.github.soot-oss.SootUp</groupId>
62+
<artifactId>sootup.java.core</artifactId>
63+
<version>develop-SNAPSHOT</version>
64+
</dependency>
65+
<dependency>
66+
<groupId>com.github.soot-oss.SootUp</groupId>
67+
<artifactId>sootup.java.bytecode.frontend</artifactId>
68+
<version>develop-SNAPSHOT</version>
69+
</dependency>
70+
<dependency>
71+
<groupId>com.github.soot-oss.SootUp</groupId>
72+
<artifactId>sootup.callgraph</artifactId>
73+
<version>develop-SNAPSHOT</version>
74+
</dependency>
75+
<dependency>
76+
<groupId>com.github.soot-oss.SootUp</groupId>
77+
<artifactId>sootup.analysis.intraprocedural</artifactId>
78+
<version>develop-SNAPSHOT</version>
79+
</dependency>
80+
<dependency>
81+
<groupId>com.github.soot-oss.SootUp</groupId>
82+
<artifactId>sootup.analysis.interprocedural</artifactId>
83+
<version>develop-SNAPSHOT</version>
84+
</dependency>
85+
<dependency>
86+
<groupId>com.github.soot-oss.SootUp</groupId>
87+
<artifactId>sootup.interceptors</artifactId>
88+
<version>develop-SNAPSHOT</version>
89+
</dependency>
90+
<dependency>
91+
<groupId>com.github.soot-oss.SootUp</groupId>
92+
<artifactId>sootup.jimple.frontend</artifactId>
93+
<version>develop-SNAPSHOT</version>
94+
</dependency>
5195
</dependencies>
5296

97+
<repositories>
98+
<repository>
99+
<id>jitpack.io</id>
100+
<url>https://jitpack.io</url>
101+
</repository>
102+
</repositories>
53103
</project>

boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/BoomerangPreInterceptor.java

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@
2020
import sootup.core.jimple.common.ref.JArrayRef;
2121
import sootup.core.jimple.common.ref.JInstanceFieldRef;
2222
import sootup.core.jimple.common.ref.JStaticFieldRef;
23-
import sootup.core.jimple.common.stmt.JAssignStmt;
24-
import sootup.core.jimple.common.stmt.JIfStmt;
25-
import sootup.core.jimple.common.stmt.JInvokeStmt;
26-
import sootup.core.jimple.common.stmt.JNopStmt;
27-
import sootup.core.jimple.common.stmt.JReturnStmt;
28-
import sootup.core.jimple.common.stmt.Stmt;
23+
import sootup.core.jimple.common.stmt.*;
2924
import sootup.core.model.Body;
3025
import sootup.core.transform.BodyInterceptor;
3126
import sootup.core.views.View;
@@ -116,7 +111,7 @@ private void transformConstantsAtFieldWrites(Body.BodyBuilder body) {
116111
}
117112
}
118113

119-
if (stmt.containsInvokeExpr()) {
114+
if (stmt.isInvokableStmt()) {
120115
/* Extract constant arguments to new assignments
121116
* - method(10)
122117
* becomes
@@ -125,8 +120,11 @@ private void transformConstantsAtFieldWrites(Body.BodyBuilder body) {
125120
*/
126121
List<Immediate> newArgs = new ArrayList<>();
127122

128-
for (int i = 0; i < stmt.getInvokeExpr().getArgCount(); i++) {
129-
Immediate arg = stmt.getInvokeExpr().getArg(i);
123+
InvokableStmt invStmt = stmt.asInvokableStmt();
124+
125+
AbstractInvokeExpr invokeExpr = invStmt.getInvokeExpr().get();
126+
for (int i = 0; i < invokeExpr.getArgCount(); i++) {
127+
Immediate arg = invokeExpr.getArg(i);
130128

131129
if (arg instanceof Constant && !(arg instanceof ClassConstant)) {
132130
String label = LABEL + replaceCounter++;
@@ -145,18 +143,17 @@ private void transformConstantsAtFieldWrites(Body.BodyBuilder body) {
145143
// Update the invoke expression with new arguments
146144
// TODO: [ms] make use of new ReplaceUseExprVisitor()
147145
AbstractInvokeExpr newInvokeExpr;
148-
if (stmt.getInvokeExpr() instanceof JStaticInvokeExpr) {
149-
JStaticInvokeExpr staticInvokeExpr = (JStaticInvokeExpr) stmt.getInvokeExpr();
146+
if (invokeExpr instanceof JStaticInvokeExpr) {
147+
JStaticInvokeExpr staticInvokeExpr = (JStaticInvokeExpr) invokeExpr;
150148

151149
newInvokeExpr = staticInvokeExpr.withArgs(newArgs);
152-
} else if (stmt.getInvokeExpr() instanceof AbstractInstanceInvokeExpr) {
153-
AbstractInstanceInvokeExpr instanceInvokeExpr =
154-
(AbstractInstanceInvokeExpr) stmt.getInvokeExpr();
150+
} else if (invokeExpr instanceof AbstractInstanceInvokeExpr) {
151+
AbstractInstanceInvokeExpr instanceInvokeExpr = (AbstractInstanceInvokeExpr) invokeExpr;
155152

156153
newInvokeExpr = instanceInvokeExpr.withArgs(newArgs);
157154
} else {
158155
// TODO Are there other relevant cases?
159-
newInvokeExpr = stmt.getInvokeExpr();
156+
newInvokeExpr = invokeExpr;
160157
}
161158

162159
if (stmt instanceof JInvokeStmt) {
@@ -209,8 +206,8 @@ private Collection<Stmt> getStatementsWithConstants(Body.BodyBuilder body) {
209206
}
210207

211208
// Consider arguments of invoke expressions
212-
if (stmt.containsInvokeExpr()) {
213-
for (Value arg : stmt.getInvokeExpr().getArgs()) {
209+
if (stmt.isInvokableStmt()) {
210+
for (Value arg : stmt.asInvokableStmt().getInvokeExpr().get().getArgs()) {
214211
if (arg instanceof Constant) {
215212
result.add(stmt);
216213
}

boomerangScope-SootUp/src/main/java/boomerang/framework/sootup/JimpleUpStatement.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public boolean containsStaticFieldAccess() {
5757

5858
@Override
5959
public boolean containsInvokeExpr() {
60-
return delegate.containsInvokeExpr();
60+
return delegate.isInvokableStmt();
6161
}
6262

6363
@Override
@@ -165,7 +165,7 @@ public boolean isPhiStatement() {
165165
public InvokeExpr getInvokeExpr() {
166166
assert containsInvokeExpr();
167167

168-
return new JimpleUpInvokeExpr(delegate.getInvokeExpr(), method);
168+
return new JimpleUpInvokeExpr(delegate.asInvokableStmt().getInvokeExpr().get(), method);
169169
}
170170

171171
@Override

0 commit comments

Comments
 (0)