Skip to content

Commit

Permalink
sootup:tests unsound (possibly because of cha <-> spark callgraphalgo)
Browse files Browse the repository at this point in the history
  • Loading branch information
swissiety committed Nov 26, 2024
1 parent fdae53c commit 2526e6a
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 114 deletions.
133 changes: 80 additions & 53 deletions boomerangPDS/src/test/java/test/FrameworkScopeFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
import sootup.core.model.SourceType;
import sootup.core.signatures.MethodSignature;
import sootup.core.transform.BodyInterceptor;
import sootup.java.bytecode.inputlocation.JavaClassPathAnalysisInputLocation;
import sootup.java.bytecode.inputlocation.JrtFileSystemAnalysisInputLocation;
import sootup.interceptors.BytecodeBodyInterceptors;
import sootup.java.bytecode.frontend.inputlocation.JavaClassPathAnalysisInputLocation;
import sootup.java.bytecode.frontend.inputlocation.JrtFileSystemAnalysisInputLocation;
import sootup.java.core.JavaSootClass;
import sootup.java.core.JavaSootMethod;
import sootup.java.core.interceptors.BytecodeBodyInterceptors;
import sootup.java.core.views.JavaView;
import sootup.jimple.frontend.JimpleStringAnalysisInputLocation;

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

SootMethod methodByName = c.getMethodByName("main");
eps.add(methodByName);

for (SootMethod m : sootTestCaseClass.getMethods()) {
if (m.isStaticInitializer()) {
eps.add(m);
}
}

// collect entrypoints
for (SootClass inner : Scene.v().getClasses()) {
classCount++;
if (inner.getName().contains(sootTestCaseClass.getName())) {
inner.setApplicationClass();
for (SootMethod m : inner.getMethods()) {
if (m.isStaticInitializer()) {
eps.add(m);
}
}
}
}
eps.add(methodByName);
// TODO: check if the following block is needed / correct in this branch
/*
// collect entrypoints
for (SootClass inner : Scene.v().getClasses()) {
classCount++;
if (inner.getName().contains(sootTestCaseClass.getName())) {
inner.setApplicationClass();
for (SootMethod m : inner.getMethods()) {
if (m.isStaticInitializer()) {
eps.add(m);
}
}
}
}
*/

if (eps.isEmpty()) {
throw new IllegalStateException(
Expand Down Expand Up @@ -240,7 +245,6 @@ private static String getTargetClass(SootMethod sootTestMethod, String testCaseC
return sootClass.toString();
}


/** SootUp Framework setup TODO: [ms] refactor me! */
private static FrameworkScope getSootUpFrameworkScope(
String pathStr,
Expand Down Expand Up @@ -273,47 +277,70 @@ private static FrameworkScope getSootUpFrameworkScope(
classPathInputLocation, includedPackages),
new ScopedAnalysisInputLocation.DenylistingScopedAnalysisInputLocation(
classPathInputLocation, excludedPackages)));
JavaView javaView = new JavaView(inputLocations);

JavaView javaView;
sootup.callgraph.CallGraph cg;
List<MethodSignature> entypointSignatures;
List<JavaSootMethod> eps = Lists.newArrayList();

if (customEntrypointMethodName == null) {
// collect entrypoints
for (JavaSootClass sootClass : javaView.getClasses()) {
String scStr = sootClass.toString();
if (scStr.equals(className) || (scStr.contains(className + "$"))) {
eps.addAll(sootClass.getMethods());
}
}
List<MethodSignature> entypointSignatures = Lists.newArrayList();

} else {
// build entrypoint
String jimpleClassStr = "class dummyClass\n" +
"{\n" +
" public static void main(java.lang.String[])\n" +
" {\n" +
" "+ className +" dummyObj;\n" +
" java.lang.String[] l0;\n" +
" l0 := @parameter0: java.lang.String[];\n" +
" dummyObj = new "+ className +";\n" +
" virtualinvoke dummyObj.<"+ className +": void "+customEntrypointMethodName+"()>();\n" +
" return;\n" +
" }\n" +
"}";

// new JimpleStringAnalysisInputLocation(jimpleClassStr) // currently in sootup:develop branch

throw new UnsupportedOperationException("implement me!");
if (customEntrypointMethodName == null) {

javaView = new JavaView(inputLocations);
// collect entrypoints
for (JavaSootClass sootClass : javaView.getClasses().collect(Collectors.toList())) {
String scStr = sootClass.toString();
if (scStr.equals(className) || (scStr.contains(className + "$"))) {
sootClass.getMethods().stream()
.map(SootClassMember::getSignature)
.forEach(entypointSignatures::add);
}
}

// initialize CallGraphAlgorithm
entypointSignatures =
eps.stream().map(SootClassMember::getSignature).collect(Collectors.toList());
} else {

// build dummy entrypoint class
String jimpleClassStr =
"class dummyClass\n"
+ "{\n"
+ " public static void main(java.lang.String[])\n"
+ " {\n"
+ " "
+ className
+ " dummyObj;\n"
+ " java.lang.String[] l0;\n"
+ " l0 := @parameter0: java.lang.String[];\n"
+ " dummyObj = new "
+ className
+ ";\n"
+ " virtualinvoke dummyObj.<"
+ className
+ ": void "
+ customEntrypointMethodName
+ "()>();\n"
+ " return;\n"
+ " }\n"
+ "}";

JimpleStringAnalysisInputLocation jimpleStringAnalysisInputLocation =
new JimpleStringAnalysisInputLocation(
jimpleClassStr); // currently in sootup:develop branch
inputLocations.add(jimpleStringAnalysisInputLocation);
javaView = new JavaView(inputLocations);

MethodSignature dummyEntrypoint =
javaView
.getIdentifierFactory()
.parseMethodSignature("<dummyClass: void main(java.lang.String[])>");
assert javaView.getMethod(dummyEntrypoint).isPresent();

entypointSignatures.add(dummyEntrypoint);
}

// TODO: adapt if: --> use spark when available
CallGraphAlgorithm cga = customEntrypointMethodName == null? new ClassHierarchyAnalysisAlgorithm(javaView) : new ClassHierarchyAnalysisAlgorithm(javaView);
// initialize CallGraphAlgorithm
// TODO: use spark when available
CallGraphAlgorithm cga =
customEntrypointMethodName == null
? new ClassHierarchyAnalysisAlgorithm(javaView)
: new ClassHierarchyAnalysisAlgorithm(javaView);
cg = cga.initialize(entypointSignatures);

return new SootUpFrameworkScope(javaView, cg, entypointSignatures);
Expand Down
50 changes: 50 additions & 0 deletions boomerangScope-SootUp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
<groupId>de.fraunhofer.iem</groupId>
<artifactId>boomerangScope</artifactId>
</dependency>
<!-- from the release
<dependency>
<groupId>org.soot-oss</groupId>
<artifactId>sootup.core</artifactId>
Expand All @@ -48,6 +49,55 @@
<artifactId>sootup.analysis</artifactId>
<version>1.3.0</version>
</dependency>
-->

<!-- latest from jitpack -->
<dependency>
<groupId>com.github.soot-oss.SootUp</groupId>
<artifactId>sootup.core</artifactId>
<version>develop-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.soot-oss.SootUp</groupId>
<artifactId>sootup.java.core</artifactId>
<version>develop-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.soot-oss.SootUp</groupId>
<artifactId>sootup.java.bytecode.frontend</artifactId>
<version>develop-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.soot-oss.SootUp</groupId>
<artifactId>sootup.callgraph</artifactId>
<version>develop-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.soot-oss.SootUp</groupId>
<artifactId>sootup.analysis.intraprocedural</artifactId>
<version>develop-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.soot-oss.SootUp</groupId>
<artifactId>sootup.analysis.interprocedural</artifactId>
<version>develop-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.soot-oss.SootUp</groupId>
<artifactId>sootup.interceptors</artifactId>
<version>develop-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.github.soot-oss.SootUp</groupId>
<artifactId>sootup.jimple.frontend</artifactId>
<version>develop-SNAPSHOT</version>
</dependency>
</dependencies>

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,7 @@
import sootup.core.jimple.common.ref.JArrayRef;
import sootup.core.jimple.common.ref.JInstanceFieldRef;
import sootup.core.jimple.common.ref.JStaticFieldRef;
import sootup.core.jimple.common.stmt.JAssignStmt;
import sootup.core.jimple.common.stmt.JIfStmt;
import sootup.core.jimple.common.stmt.JInvokeStmt;
import sootup.core.jimple.common.stmt.JNopStmt;
import sootup.core.jimple.common.stmt.JReturnStmt;
import sootup.core.jimple.common.stmt.Stmt;
import sootup.core.jimple.common.stmt.*;
import sootup.core.model.Body;
import sootup.core.transform.BodyInterceptor;
import sootup.core.views.View;
Expand Down Expand Up @@ -116,7 +111,7 @@ private void transformConstantsAtFieldWrites(Body.BodyBuilder body) {
}
}

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

for (int i = 0; i < stmt.getInvokeExpr().getArgCount(); i++) {
Immediate arg = stmt.getInvokeExpr().getArg(i);
InvokableStmt invStmt = stmt.asInvokableStmt();

AbstractInvokeExpr invokeExpr = invStmt.getInvokeExpr().get();
for (int i = 0; i < invokeExpr.getArgCount(); i++) {
Immediate arg = invokeExpr.getArg(i);

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

newInvokeExpr = staticInvokeExpr.withArgs(newArgs);
} else if (stmt.getInvokeExpr() instanceof AbstractInstanceInvokeExpr) {
AbstractInstanceInvokeExpr instanceInvokeExpr =
(AbstractInstanceInvokeExpr) stmt.getInvokeExpr();
} else if (invokeExpr instanceof AbstractInstanceInvokeExpr) {
AbstractInstanceInvokeExpr instanceInvokeExpr = (AbstractInstanceInvokeExpr) invokeExpr;

newInvokeExpr = instanceInvokeExpr.withArgs(newArgs);
} else {
// TODO Are there other relevant cases?
newInvokeExpr = stmt.getInvokeExpr();
newInvokeExpr = invokeExpr;
}

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

// Consider arguments of invoke expressions
if (stmt.containsInvokeExpr()) {
for (Value arg : stmt.getInvokeExpr().getArgs()) {
if (stmt.isInvokableStmt()) {
for (Value arg : stmt.asInvokableStmt().getInvokeExpr().get().getArgs()) {
if (arg instanceof Constant) {
result.add(stmt);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public boolean containsStaticFieldAccess() {

@Override
public boolean containsInvokeExpr() {
return delegate.containsInvokeExpr();
return delegate.isInvokableStmt();
}

@Override
Expand Down Expand Up @@ -165,7 +165,7 @@ public boolean isPhiStatement() {
public InvokeExpr getInvokeExpr() {
assert containsInvokeExpr();

return new JimpleUpInvokeExpr(delegate.getInvokeExpr(), method);
return new JimpleUpInvokeExpr(delegate.asInvokableStmt().getInvokeExpr().get(), method);
}

@Override
Expand Down
Loading

0 comments on commit 2526e6a

Please sign in to comment.