Skip to content

Commit

Permalink
result generation
Browse files Browse the repository at this point in the history
  • Loading branch information
kadirayk committed Mar 8, 2023
1 parent c132cd8 commit d006621
Show file tree
Hide file tree
Showing 11 changed files with 370 additions and 31 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@
hs_err_pid*
/.idea
*.iml
/target
/target
/input
/results
23 changes: 23 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,31 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>eval.Main</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

<dependencies>
<dependency>
<groupId>org.soot-oss</groupId>
Expand Down
21 changes: 0 additions & 21 deletions src/main/java/Main.java

This file was deleted.

9 changes: 8 additions & 1 deletion src/main/java/analysis/IDELinearConstantAnalysisProblem.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,24 @@ public class IDELinearConstantAnalysisProblem extends DefaultJimpleIDETabulation

protected InterproceduralCFG<Unit, SootMethod> icfg;

private int numThreads=-1;

private SootMethod entryMethod;

public final static Integer TOP = Integer.MIN_VALUE; // Unknown

public final static Integer BOTTOM = Integer.MAX_VALUE; // Not Constant

@Override
public int numThreads() {
return numThreads!=-1 ? numThreads : super.numThreads();
}

public IDELinearConstantAnalysisProblem(InterproceduralCFG<Unit, SootMethod> icfg, SootMethod entry) {
public IDELinearConstantAnalysisProblem(InterproceduralCFG<Unit, SootMethod> icfg, SootMethod entry, int numThreads) {
super(icfg);
this.icfg = icfg;
this.entryMethod = entry;
this.numThreads = numThreads;
}

public IDELinearConstantAnalysisProblem(InterproceduralCFG<Unit, SootMethod> icfg) {
Expand Down
51 changes: 51 additions & 0 deletions src/main/java/eval/EvalHelper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package eval;

public class EvalHelper {

private static int threadCount = -1;
private static int maxMethod = -1;
private static long totalDuration = 0;
private static long totalPropagationCount = 0;
private static int actualMethodCount = 0;


public static int getThreadCount() {
return threadCount;
}

public static void setThreadCount(int threadCount) {
EvalHelper.threadCount = threadCount;
}

public static long getTotalDuration() {
return totalDuration;
}

public static void setTotalDuration(long totalDuration) {
EvalHelper.totalDuration = totalDuration;
}

public static long getTotalPropagationCount() {
return totalPropagationCount;
}

public static void setTotalPropagationCount(long totalPropagationCount) {
EvalHelper.totalPropagationCount = totalPropagationCount;
}

public static int getActualMethodCount() {
return actualMethodCount;
}

public static void setActualMethodCount(int actualMethodCount) {
EvalHelper.actualMethodCount = actualMethodCount;
}

public static int getMaxMethod() {
return maxMethod;
}

public static void setMaxMethod(int maxMethod) {
EvalHelper.maxMethod = maxMethod;
}
}
118 changes: 118 additions & 0 deletions src/main/java/eval/EvalPrinter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package eval;

import heros.sparse.SparseCFGCache;
import heros.sparse.SparseCFGQueryStat;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

public class EvalPrinter {
private static final String OUT_PUT_DIR = "./results";
private static final String FILE = "sparseide_eval.csv";

private final String targetProgram;
private final String solver;
private int threadCount = 0;
private long totalDuration = 0;
private long totalPropagationCount = 0;
private int methodCount = 0;
private long sparseCFGBuildtime = 0;
private long scfgBuildCount = 0;
private float initalStmtCount = 0;
private float finalStmtCount = 0;


public EvalPrinter(String targetProgram, String solver) {
this.targetProgram = targetProgram;
this.solver = solver;
this.threadCount = EvalHelper.getThreadCount();
this.totalDuration = EvalHelper.getTotalDuration();
this.totalPropagationCount = EvalHelper.getTotalPropagationCount();
this.methodCount = EvalHelper.getActualMethodCount();
if(solver.equalsIgnoreCase("sparse")){
handleSparseQueryStats();
}
}

private void handleSparseQueryStats() {
List<SparseCFGQueryStat> queryStats = SparseCFGCache.getQueryStats();
for (SparseCFGQueryStat queryStat : queryStats) {
if(!queryStat.isRetrievedFromCache()){
sparseCFGBuildtime += queryStat.getDuration().toMillis();
//if (queryStat.getInitialStmtCount() > 0 && queryStat.getFinalStmtCount() > 0) { // check for cache retrieve
initalStmtCount += queryStat.getInitialStmtCount();
finalStmtCount += queryStat.getFinalStmtCount();
scfgBuildCount++;
//}
}
}
}

public void generate() {
File dir = new File(OUT_PUT_DIR);
if (!dir.exists()) {
dir.mkdir();
}
File file = new File(OUT_PUT_DIR + File.separator + FILE);
if(!file.exists()){
try (FileWriter writer = new FileWriter(file)) {
StringBuilder str = new StringBuilder();
str.append("jar");
str.append(",");
str.append("solver");
str.append(",");
str.append("thread");
str.append(",");
str.append("runtime");
str.append(",");
str.append("prop");
str.append(",");
str.append("method");
str.append(",");
str.append("SCFGConst");
str.append(",");
str.append("SCFGCount");
str.append(",");
str.append("DoS");
str.append(System.lineSeparator());
writer.write(str.toString());
} catch (IOException e) {
e.printStackTrace();
}
}
try (FileWriter writer = new FileWriter(file, true)) {
StringBuilder str = new StringBuilder();
str.append(targetProgram);
str.append(",");
str.append(solver);
str.append(",");
str.append(threadCount);
str.append(",");
str.append(totalDuration);
str.append(",");
str.append(totalPropagationCount);
str.append(",");
str.append(methodCount);
str.append(",");
str.append(sparseCFGBuildtime);
str.append(",");
str.append(scfgBuildCount);
str.append(",");
str.append(degreeOfSparsification());
str.append(System.lineSeparator());
writer.write(str.toString());
} catch (IOException e) {
e.printStackTrace();
}
}

private String degreeOfSparsification(){
if(finalStmtCount!=0){
return String.format("%.2f",(initalStmtCount-finalStmtCount)/initalStmtCount);
}
return "0";
}

}
48 changes: 48 additions & 0 deletions src/main/java/eval/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package eval;

import com.google.common.base.Stopwatch;

import java.io.File;
import java.text.MessageFormat;
import java.time.Duration;

public class Main {

public static void main(String[] args){
String jarPath = args[0]; // path to input jar
String solver = args[1]; // solver: default or sparse
int maxMethods = Integer.parseInt(args[2]); // max number of methods to analyze
int numThreads = Runtime.getRuntime().availableProcessors(); // thread count
if(args.length>3){
numThreads = Integer.parseInt(args[3]); // thread count
}


String msg = MessageFormat.format("Running {0} - {1} solver - {2} threads", getJarName(jarPath), solver, numThreads);
System.out.println(msg);
EvalHelper.setMaxMethod(10);
EvalHelper.setThreadCount(numThreads);

SetUp setUp = new SetUp();
Stopwatch stopwatch = Stopwatch.createStarted();
if(solver.equalsIgnoreCase("default")){
setUp.executeStaticAnalysis(jarPath);
EvalHelper.setTotalPropagationCount(setUp.defaultPropCount); // clean later
}else if (solver.equalsIgnoreCase("sparse")){
setUp.executeSparseStaticAnalysis(jarPath);
EvalHelper.setTotalPropagationCount(setUp.sparsePropCount);
}
Duration elapsed = stopwatch.elapsed();
EvalHelper.setTotalDuration(elapsed.toMillis());
new EvalPrinter(getJarName(jarPath), solver).generate();
}

private static String getJarName(String fullpath){
int start = fullpath.lastIndexOf(File.separator);
int endDot = fullpath.lastIndexOf(".");
int endDash = fullpath.lastIndexOf("-");
int latest = endDot<endDash ? endDash : endDot;
return fullpath.substring(start + 1, latest);
}

}
16 changes: 11 additions & 5 deletions src/main/java/SetUp.java → src/main/java/eval/SetUp.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
package eval;

import analysis.IDELinearConstantAnalysisProblem;
import analysis.data.DFF;
import boomerang.scene.jimple.BoomerangPretransformer;
Expand Down Expand Up @@ -25,7 +27,6 @@ public class SetUp {
public long defaultPropCount = 0;
public long sparsePropCount = 0;


protected void executeStaticAnalysis(String jarPath) {
setupSoot(jarPath);
registerSootTransformers();
Expand Down Expand Up @@ -63,8 +64,8 @@ protected Transformer createAnalysisTransformer() {
protected void internalTransform(String phaseName, Map<String, String> options) {
JimpleBasedInterproceduralCFG icfg = new JimpleBasedInterproceduralCFG(false);
for (SootMethod method : entryMethods) {
System.out.println("solving " + method.getSignature());
IDELinearConstantAnalysisProblem problem = new IDELinearConstantAnalysisProblem(icfg, method);
System.out.println("started solving from: " + method.getSignature());
IDELinearConstantAnalysisProblem problem = new IDELinearConstantAnalysisProblem(icfg, method, EvalHelper.getThreadCount());
@SuppressWarnings({"rawtypes", "unchecked"})
JimpleIDESolver<?, ?, ?> solver = new JimpleIDESolver<>(problem);
solver.solve();
Expand All @@ -81,7 +82,7 @@ protected void internalTransform(String phaseName, Map<String, String> options)
JimpleBasedInterproceduralCFG icfg = new JimpleBasedInterproceduralCFG(false);
for (SootMethod method : entryMethods) {
System.out.println("sparse solving " + method.getSignature());
IDELinearConstantAnalysisProblem problem = new IDELinearConstantAnalysisProblem(icfg, method);
IDELinearConstantAnalysisProblem problem = new IDELinearConstantAnalysisProblem(icfg, method, EvalHelper.getThreadCount());
SparseCFGBuilder sparseCFGBuilder = new CPAJimpleSparseCFGBuilder(true);
@SuppressWarnings({"rawtypes", "unchecked"})
JimpleSparseIDESolver<?, ?, ?> solver = new JimpleSparseIDESolver<>(problem, sparseCFGBuilder);
Expand Down Expand Up @@ -134,21 +135,25 @@ private boolean isPublicAPI(SootMethod method){

protected List<SootMethod> getEntryPointMethods() {
List<SootMethod> methods = new ArrayList<>();
l1:
for (SootClass c : Scene.v().getApplicationClasses()) {
for (SootMethod m : c.getMethods()) {
MethodSource source = m.getSource();
if(source!=null){
if(isPublicAPI(m)){
m.retrieveActiveBody();
if (m.hasActiveBody()) {
if(m.getParameterTypes().stream().anyMatch(t->t instanceof IntegerType && !t.equals(BooleanType.v()))){
if(m.getReturnType() instanceof IntegerType && m.getParameterTypes().stream().anyMatch(t->t instanceof IntegerType && !t.equals(BooleanType.v()))){
UnitPatchingChain units = m.getActiveBody().getUnits();
for (Unit unit : units) {
if(unit instanceof DefinitionStmt){
DefinitionStmt assign = (DefinitionStmt) unit;
Value rhs = assign.getRightOp();
if(rhs instanceof IntConstant ){
methods.add(m);
if(methods.size()==EvalHelper.getMaxMethod()){
break l1;
}
}
}
}
Expand All @@ -160,6 +165,7 @@ protected List<SootMethod> getEntryPointMethods() {
}
if(!methods.isEmpty()){
System.out.println(methods.size() + " methods will be used as entry points");
EvalHelper.setActualMethodCount(methods.size());
return methods;
}
throw new RuntimeException("no entry methods found to start");
Expand Down
Loading

0 comments on commit d006621

Please sign in to comment.