From 73ae926c66d5b6fed096f3a29d8f0889d2effae3 Mon Sep 17 00:00:00 2001 From: Signior-X Date: Sun, 25 Sep 2022 15:18:25 +0530 Subject: [PATCH 1/8] Make changes in bash file, remove Library methods --- .gitignore | 2 ++ .vscode/settings.json | 6 ++++++ scripts/run.sh | 12 +++++++++--- src/analyser/StaticAnalyser.java | 4 ++++ 4 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 93fff4ccf..f68a0a678 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ .idea/ stava.iml .DS_Store + +out diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..0b75109cc --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "java.project.referencedLibraries": [ + "lib/**/*.jar", + "soot/sootclasses-trunk-jar-with-dependencies.jar" + ] +} \ No newline at end of file diff --git a/scripts/run.sh b/scripts/run.sh index 318dd0e82..32f771271 100755 --- a/scripts/run.sh +++ b/scripts/run.sh @@ -3,8 +3,14 @@ # Sample script to be used to run the project on non-benchmark code. # Set the paths according to your installation. All paths must be full paths. # Instructions: ./run.sh ClassName + +if [ -z "$1" ]; then + echo "No TestCase Number Provided"; + exit +fi + # Installed path of Java 8 JDK -java_install_path="/usr/lib/jvm/java-8-oracle/" +java_install_path="/usr/lib/jvm/java-8-openjdk-amd64/" # The soot jar to be used. soot_path=`realpath ../soot/sootclasses-trunk-jar-with-dependencies.jar` @@ -13,10 +19,10 @@ soot_path=`realpath ../soot/sootclasses-trunk-jar-with-dependencies.jar` stava_path=`realpath ..` # The directory to be analysed. -test_path=`realpath ../tests/test20/` +test_path=`realpath ../tests/test$1/` # The directory inside which stava will output the results. -output_path=`realpath ../out/testcase/` +output_path=`realpath ../out/testcase$1/` java_compiler="${java_install_path}/bin/javac" java_vm="${java_install_path}/bin/java" diff --git a/src/analyser/StaticAnalyser.java b/src/analyser/StaticAnalyser.java index d07487aea..92f60dd6e 100644 --- a/src/analyser/StaticAnalyser.java +++ b/src/analyser/StaticAnalyser.java @@ -93,6 +93,10 @@ protected void internalTransform(Body body, String phasename, Map")){ // System.out.println("Skipping this method"); From cccd66c10d589c44bee87ef72eede310c12d416f Mon Sep 17 00:00:00 2001 From: Signior-X Date: Mon, 26 Sep 2022 20:22:39 +0530 Subject: [PATCH 2/8] Create structure for topoOrder --- src/analyser/StaticAnalyser.java | 1 + src/config/StoreEscape.java | 2 +- src/main/GetSootArgs.java | 1 + src/main/Main.java | 61 ++++++++++++++++++++++++++++---- 4 files changed, 57 insertions(+), 8 deletions(-) diff --git a/src/analyser/StaticAnalyser.java b/src/analyser/StaticAnalyser.java index 92f60dd6e..acaf3296e 100644 --- a/src/analyser/StaticAnalyser.java +++ b/src/analyser/StaticAnalyser.java @@ -27,6 +27,7 @@ public class StaticAnalyser extends BodyTransformer { private boolean allNonEscaping; public static Map ptgs; public static Map> summaries; + public static Map> stackOrders; public static LinkedHashMap analysis; public static List noBCIMethods; String[] ignoreFuncs = { diff --git a/src/config/StoreEscape.java b/src/config/StoreEscape.java index b1185bd80..8d595cbd2 100644 --- a/src/config/StoreEscape.java +++ b/src/config/StoreEscape.java @@ -1,7 +1,7 @@ package config; public class StoreEscape { - public static boolean MarkStoreEscaping = true; + public static boolean MarkStoreEscaping = false; public static boolean ReduceParamDependence = true; public static boolean MarkParamReturnEscaping = false; } diff --git a/src/main/GetSootArgs.java b/src/main/GetSootArgs.java index adb992a9b..a1e13877c 100644 --- a/src/main/GetSootArgs.java +++ b/src/main/GetSootArgs.java @@ -213,6 +213,7 @@ private String[] normal(String[] args){ "-p","cg.spark","on", "-p","cg","all-reachable", "-keep-offset", + "-f","J", // "-soot-classpath", cp, //"-prepend-classpath", "-keep-line-number", "-main-class", args[3], diff --git a/src/main/Main.java b/src/main/Main.java index c1f7c7328..4033db9a8 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -113,7 +113,9 @@ public static void main(String[] args) { System.out.println("Static Analysis is done!"); System.out.println("Time Taken:"+(analysis_end-analysis_start)/1000F); - + // Now we are going to find the stack ordering of the non escaping functions + CreateStackOrdering(); + boolean useNewResolver = true; long res_start = System.currentTimeMillis(); // printSummary(staticAnalyser.summaries); @@ -137,9 +139,9 @@ public static void main(String[] args) { HashMap> resolved = (HashMap) kill(sr.solvedSummaries); - printAllInfo(StaticAnalyser.ptgs, resolved, args[4]); + // printAllInfo(StaticAnalyser.ptgs, resolved, args[4]); - saveStats(sr.existingSummaries, resolved, args[4], staticAnalyser.ptgs); + // saveStats(sr.existingSummaries, resolved, args[4], staticAnalyser.ptgs); printResForJVM(sr.solvedSummaries, args[2], args[4]); } @@ -154,13 +156,58 @@ public static void main(String[] args) { HashMap> resolved = (HashMap) kill(sr.solvedSummaries); - printAllInfo(StaticAnalyser.ptgs, staticAnalyser.summaries, args[4]); + // printAllInfo(StaticAnalyser.ptgs, staticAnalyser.summaries, args[4]); - printAllInfo(StaticAnalyser.ptgs, resolved, args[4]); + // printAllInfo(StaticAnalyser.ptgs, resolved, args[4]); - saveStats(sr.existingSummaries, resolved, args[4], staticAnalyser.ptgs); + // saveStats(sr.existingSummaries, resolved, args[4], staticAnalyser.ptgs); - printResForJVM(sr.solvedSummaries, args[2], args[4]); + // printResForJVM(sr.solvedSummaries, args[2], args[4]); + } + } + + /** + * Performs dfs and finds the topological order + * @param node - Starting node of the dfs + * @param ptg - Points to graph + * @param visited - A visited array to have an idea of dfs + * @param topoOrder - The final result of the dfs - Topological Order + */ + static void topologicalSortDfs( + ObjectNode node, + PointsToGraph ptg, + HashSet visited, + ArrayList topoOrder) { + + } + + /** + * Create Stack ordering for each ptg in the Static Analyser + */ + static void CreateStackOrdering() { + // We assumed that the PTGs exist in the StaticAnalyser + + System.out.println("PRIYAM - Starting topological sorting"); + for(SootMethod method : StaticAnalyser.ptgs.keySet()) { + System.out.println("PRIYAM: " + method); + + PointsToGraph ptg = StaticAnalyser.ptgs.get(method); + + // TODO - First check if it is a DAG + // Perform topological sort for the ptg + System.out.println(ptg); + + HashSet visited = new HashSet(); + ArrayList topoOrder = new ArrayList(); + + for(Set objectNodeSet : ptg.vars.values()) { + for (ObjectNode object : objectNodeSet) { + if (!visited.contains(object)) { + // System.out.println("PRIYAM object" + object); + topologicalSortDfs(object, ptg, visited, topoOrder); + } + } + } } } From e7e88a406468cbbda48b4e81c926f130ebb38b31 Mon Sep 17 00:00:00 2001 From: Signior-X Date: Mon, 26 Sep 2022 20:47:45 +0530 Subject: [PATCH 3/8] TopoSort implemented --- src/main/Main.java | 15 +++++++++++++++ tests/test1/Main.java | 5 ++--- tests/test23/Main.java | 13 +++++++++++++ tests/test23/Node.java | 3 +++ 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 tests/test23/Main.java create mode 100644 tests/test23/Node.java diff --git a/src/main/Main.java b/src/main/Main.java index 4033db9a8..7a743e74f 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -178,7 +178,20 @@ static void topologicalSortDfs( PointsToGraph ptg, HashSet visited, ArrayList topoOrder) { + visited.add(node); + + Map> objectNodesMap = ptg.fields.get(node); + if (objectNodesMap != null) { + for (SootField sootField : objectNodesMap.keySet()) { + for (ObjectNode nextObject : objectNodesMap.get(sootField)) { + if (!visited.contains(nextObject)) { + topologicalSortDfs(nextObject, ptg, visited, topoOrder); + } + } + } + } + topoOrder.add(node); } /** @@ -208,6 +221,8 @@ static void CreateStackOrdering() { } } } + + System.out.println("PRIYAM TopoOrder : " + topoOrder); } } diff --git a/tests/test1/Main.java b/tests/test1/Main.java index 64b3938fa..6ca52a26a 100644 --- a/tests/test1/Main.java +++ b/tests/test1/Main.java @@ -5,8 +5,7 @@ public static void main(String[] args) { Node C = new Node(); Node D = new Node(); A.n = B; - B.n = C; - C.n = D; - D.n = B; + B.n = D; + D.n = C; } } diff --git a/tests/test23/Main.java b/tests/test23/Main.java new file mode 100644 index 000000000..efd4fe0fd --- /dev/null +++ b/tests/test23/Main.java @@ -0,0 +1,13 @@ +public class Main { + public static void main(String[] args) { + Node A = new Node(); + Node B = new Node(); + Node C = new Node(); + Node D = new Node(); + Node E = new Node(); + A.n = B; + B.n = D; + B.n = E; + D.n = C; + } +} diff --git a/tests/test23/Node.java b/tests/test23/Node.java new file mode 100644 index 000000000..04f5b0175 --- /dev/null +++ b/tests/test23/Node.java @@ -0,0 +1,3 @@ +public class Node { + public Node n; +} From e92cb08b6182a169b126208c33ca9d9b995685c5 Mon Sep 17 00:00:00 2001 From: Signior-X Date: Tue, 18 Oct 2022 19:40:05 +0530 Subject: [PATCH 4/8] Create interprocedural linking --- .vscode/launch.json | 21 +++ src/analyser/StackOrderAnalyser.java | 184 ++++++++++++++++++++++++ src/analyser/StaticAnalyser.java | 7 +- src/main/Main.java | 104 +++++++------- src/utils/GetListOfNoEscapeObjects.java | 16 ++- tests/test23/Main.java | 2 +- tests/test23/Node.java | 1 + tests/test24/Main.java | 20 +++ tests/test24/Node.java | 4 + tests/test25/Main.java | 26 ++++ tests/test25/Node.java | 4 + tests/test26/Main.java | 33 +++++ tests/test26/Node.java | 4 + 13 files changed, 366 insertions(+), 60 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 src/analyser/StackOrderAnalyser.java create mode 100644 tests/test24/Main.java create mode 100644 tests/test24/Node.java create mode 100644 tests/test25/Main.java create mode 100644 tests/test25/Node.java create mode 100644 tests/test26/Main.java create mode 100644 tests/test26/Node.java diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..dda89494c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "java", + "name": "Launch Current File", + "request": "launch", + "mainClass": "${file}" + }, + { + "type": "java", + "name": "Launch Main", + "request": "launch", + "mainClass": "Main", + "projectName": "stava_862dc55b" + } + ] +} \ No newline at end of file diff --git a/src/analyser/StackOrderAnalyser.java b/src/analyser/StackOrderAnalyser.java new file mode 100644 index 000000000..a05fa3f7f --- /dev/null +++ b/src/analyser/StackOrderAnalyser.java @@ -0,0 +1,184 @@ +package analyser; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +import soot.*; +import es.ConditionalValue; +import es.EscapeStatus; +import main.CHATransform; +import ptg.ObjectNode; +import ptg.ObjectType; +import ptg.PointsToGraph; +import soot.jimple.Constant; +import soot.jimple.InstanceInvokeExpr; +import soot.jimple.InvokeExpr; +import soot.jimple.internal.JInvokeStmt; +import soot.jimple.internal.JStaticInvokeExpr; +import soot.jimple.toolkits.callgraph.CallGraph; +import soot.jimple.toolkits.callgraph.Edge; + +public class StackOrderAnalyser extends BodyTransformer { + public static ConcurrentHashMap > nativeLocals = new ConcurrentHashMap<>(); + + public static ArrayList whitelistedNatives = new ArrayList<> ( + Arrays.asList("") + ); + + public static ArrayList blacklistedNatives = new ArrayList<> ( + Arrays.asList("", + "", + "") + ); + + + private Set methodsProcessed; + private Set methodsProcessing; + + public StackOrderAnalyser() { + methodsProcessed = new HashSet(); + methodsProcessing = new HashSet(); + } + + @Override + protected void internalTransform(Body body, String phasename, Map options) { + SootMethod method = body.getMethod(); + + if (body.getMethod().isJavaLibraryMethod()) { + return; + } + + if (methodsProcessed.contains(method)) { + // Method already computed + // we have the results ready + return; + } + + if (methodsProcessing.contains(method)) { + // Recursive loop + // TODO - See what to do + return; + } + + methodsProcessing.add(method); + processMethod(body); + methodsProcessed.add(method); + } + + private static void processMethod(Body body) { + System.out.println("PRIYAM Method Name: "+ body.getMethod().getBytecodeSignature() + ":"+body.getMethod().getName()); + PatchingChain units = body.getUnits(); + + for (Unit u : units) { + if (u instanceof JInvokeStmt) { + JInvokeStmt stmt = (JInvokeStmt) u; + InvokeExpr expr = stmt.getInvokeExpr(); + handleExpr(body.getMethod(), u, expr); + } + } + } + + public static void handleExpr( + SootMethod m, Unit u, InvokeExpr expr) { + PointsToGraph ptg = StaticAnalyser.ptgs.get(m); + CallGraph cg = Scene.v().getCallGraph(); + + Iterator iedges = cg.edgesOutOf(u); + List args = expr.getArgs(); + + List edges = new ArrayList<>(); + if (!iedges.hasNext()) { + iedges = CHATransform.getCHA().edgesOutOf(u); + } + + while (iedges.hasNext()) { + edges.add(iedges.next()); + } + + if (edges.size() == 0) { + // System.out.println("Empty edges: " + expr + ", function incoming edges: " + cg.edgesInto(m).hasNext() + + // " Method: " + m.getBytecodeSignature()); + edges.add(new Edge(m, u, expr.getMethod(), Kind.SPECIAL)); + } + + if (expr instanceof InstanceInvokeExpr) { + // ASK - No need to handle instance invoke expr? + } else if (expr instanceof JStaticInvokeExpr) { + } else { + System.err.println("Unidentified invoke expr: " + expr.toString()); + throw new IllegalArgumentException(expr.toString()); + } + + for (Edge edge : edges) { + /* 1. + * We traverse and find the caller callie relationship + * between ObjectNodes + */ + SootMethod method = edge.tgt(); + int paramCount = method.getParameterCount(); + + // TODO - Add a recursion to first process the method + // if not already processed + + Map> paramMapping = new HashMap>(); + for (int i = 0; i < paramCount; i++) { + ObjectNode obj = new ObjectNode(i, ObjectType.parameter); + // ConditionalValue cv = new ConditionalValue(method, obj, true); + + if (edge.kind() == Kind.REFL_INVOKE) + paramMapping.put(obj, ptg.vars.get((Local) args.get(1))); + else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE) + paramMapping.put(obj, ptg.vars.get((Local) args.get(0))); + else { + Value arg = args.get(i); + if (arg.getType() instanceof RefType || arg.getType() instanceof ArrayType) + if (!(arg instanceof Constant)) { // Notice the not(!) + // ptg.addParametricEdge((Local) args.get(i), cv); + paramMapping.put(obj, ptg.vars.get((Local) args.get(i))); + } + } + } + + // System.out.println("PRIYAM PARAMS MAPPING: " + paramMapping); + + /* 2. + * Now, loop in the callie method's ptg to find if there + * exists any relationship/node between the params + * If exists, add the realtion for corresponding values in + * paramsMapping also + */ + PointsToGraph calliePTG = StaticAnalyser.ptgs.get(method); + // System.out.println("PRIYAM PTGS: " + StaticAnalyser.ptgs); + // System.out.println("PRIYAM calliePTG: " + calliePTG); + // If ptg gives error, ensure StaticAnalysis has been done + + for (int i = 0; i < paramCount; i++) { + ObjectNode obj = new ObjectNode(i, ObjectType.parameter); + Map> pointingTo = calliePTG.fields.get(obj); + + if (pointingTo == null) { + continue; + } + + for (Map.Entry> entry : pointingTo.entrySet()) { + for (ObjectNode fieldObj : entry.getValue()) { + System.out.println("There exists an edge from: " + obj + " to " + fieldObj + " by " + entry.getKey()); + if (fieldObj.type == ObjectType.parameter) { + continue; + } + + // Find paramsMapping for obj + // Find paramsMapping for fieldObj + // Add an edge from objs to fieldObjs + for (ObjectNode objInCaller : paramMapping.get(obj)) { + for (ObjectNode fieldObjInCaller : paramMapping.get(fieldObj)) { + // System.out.println("There should exists an edge from: " + objInCaller + " to " + fieldObjInCaller + " by " + entry.getKey()); + ptg.WEAK_makeField(objInCaller, entry.getKey(), fieldObjInCaller); + } + } + } + } + } + } + } +} diff --git a/src/analyser/StaticAnalyser.java b/src/analyser/StaticAnalyser.java index acaf3296e..2ac53da81 100644 --- a/src/analyser/StaticAnalyser.java +++ b/src/analyser/StaticAnalyser.java @@ -75,6 +75,7 @@ public StaticAnalyser() { analysis = new LinkedHashMap<>(); ptgs = new ConcurrentHashMap<>(); summaries = new ConcurrentHashMap<>(); + stackOrders = new ConcurrentHashMap<>(); noBCIMethods = new ArrayList<>(); allNonEscaping = false; } @@ -98,7 +99,7 @@ protected void internalTransform(Body body, String phasename, Map")){ // System.out.println("Skipping this method"); // return; @@ -337,6 +338,10 @@ private void setParamsAsEscaping(SootMethod m, Map sum public void apply(SootMethod m, Unit u, PointsToGraph ptg, Map summary) { // System.err.println(u+" "+u.getClass().getName()); + + // System.out.println("PRIYAM soot unit " + u); + // System.out.println("PRIYAM soot ptg " + ptg); + if (u instanceof JAssignStmt) { JAssignStmtHandler.handle(m, u, ptg, summary); } else if (u instanceof JIdentityStmt) { diff --git a/src/main/Main.java b/src/main/Main.java index 7a743e74f..e1b656d28 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -1,5 +1,6 @@ package main; +import analyser.StackOrderAnalyser; import analyser.StaticAnalyser; import config.StoreEscape; import es.*; @@ -27,7 +28,6 @@ import java.util.Map; import java.util.*; import java.io.*; -import java.lang.*; import static utils.KillCallerOnly.kill; @@ -50,7 +50,7 @@ static void setStoreEscapeOptions(String[] args) { } } public static void main(String[] args) { - + // Generating soot args GetSootArgs g = new GetSootArgs(); String[] sootArgs = g.get(args); setStoreEscapeOptions(args); @@ -58,22 +58,18 @@ public static void main(String[] args) { System.out.println("Unable to generate args for soot!"); return; } + StaticAnalyser staticAnalyser = new StaticAnalyser(); + StackOrderAnalyser stackOrderAnalyser = new StackOrderAnalyser(); CHATransform prepass = new CHATransform(); PackManager.v().getPack("wjap").add(new Transform("wjap.pre", prepass)); PackManager.v().getPack("jtp").add(new Transform("jtp.sample", staticAnalyser)); + long analysis_start = System.currentTimeMillis(); Options.v().parse(sootArgs); Scene.v().loadNecessaryClasses(); Scene.v().loadDynamicClasses(); List entryPoints = Scene.v().getEntryPoints(); - // SootClass sc = Scene.v().loadClassAndSupport("java.lang.CharacterData"); - // System.out.println(sc.getMethods()); - // Scene.v().forceResolve(sc.getName(), SootClass.BODIES); - // SootMethod tobeAdded = sc.getMethodByName("toUpperCaseEx"); - // System.out.println("Method: "+tobeAdded); - // // SootMethod tobeAdded = Scene.v().getMethod(""); - // entryPoints.add(tobeAdded); Chain appClasses = Scene.v().getClasses(); Iterator appClassItertator = appClasses.iterator(); @@ -92,58 +88,47 @@ public static void main(String[] args) { // System.out.println("SuperClass: "+aclass.getSuperclass()); } } - // aclass = Scene.v().loadClassAndSupport(aclass.getName()); - // aclass = Scene.v().forceResolve(aclass.getName(), SootClass.BODIES); - // // if (aclass.getName().contains("spec.validity.Digests")) { - // // System.out.println("Aclass spec: "+aclass.getName()+" : "+aclass.getMethodByName("crunch_jars")); - // // } - // System.out.println("Aclass: "+aclass.getName()+ " phantom: "+aclass.isPhantomClass()+" app: "+aclass.isApplicationClass()+" Concrete: "+ - // aclass.isConcrete()+" : " + aclass.getMethods()); - // // System.out.println(aclass.getMethods()); - // entryPoints.addAll(aclass.getMethods()); } - // System.out.println(entryPoints); - // if (true) - // return; - Scene.v().setEntryPoints(entryPoints); + Scene.v().setEntryPoints(entryPoints); PackManager.v().runPacks(); - // soot.Main.main(sootArgs); + long analysis_end = System.currentTimeMillis(); System.out.println("Static Analysis is done!"); System.out.println("Time Taken:"+(analysis_end-analysis_start)/1000F); + System.out.println("BEFORE InterProcedural Linking"); + printAllInfo(StaticAnalyser.ptgs, StaticAnalyser.summaries, StaticAnalyser.stackOrders, args[4]); + + // First, we add edges created due to callie function during method call + analysis_start = System.currentTimeMillis(); + PackManager.v().getPack("jtp").add(new Transform("jtp.stackOrder", stackOrderAnalyser)); + PackManager.v().runPacks(); + // Now we are going to find the stack ordering of the non escaping functions CreateStackOrdering(); + analysis_end = System.currentTimeMillis(); + System.out.println("InterProcedural Linking is done!"); + System.out.println("Time Taken:"+(analysis_end-analysis_start)/1000F); boolean useNewResolver = true; long res_start = System.currentTimeMillis(); - // printSummary(staticAnalyser.summaries); - // System.err.println(staticAnalyser.ptgs); - printAllInfo(StaticAnalyser.ptgs, staticAnalyser.summaries, args[4]); - // if (true) - // return; - // printCFG(); + System.out.println("BEFORE Resolver"); + printAllInfo(StaticAnalyser.ptgs, StaticAnalyser.summaries, StaticAnalyser.stackOrders, args[4]); if(useNewResolver) { - ReworkedResolver sr = new ReworkedResolver(staticAnalyser.summaries, - staticAnalyser.ptgs, - staticAnalyser.noBCIMethods); + ReworkedResolver sr = new ReworkedResolver( + StaticAnalyser.summaries, + StaticAnalyser.ptgs, + StaticAnalyser.noBCIMethods); long res_end = System.currentTimeMillis(); System.out.println("Resolution is done"); System.out.println("Time Taken in phase 1:"+(analysis_end-analysis_start)/1000F); System.out.println("Time Taken in phase 2:"+(res_end-res_start)/1000F); - - // System.out.println(staticAnalyser.summaries.size()+ " "+staticAnalyser.ptgs.size()); - - HashMap> resolved = (HashMap) kill(sr.solvedSummaries); - - // printAllInfo(StaticAnalyser.ptgs, resolved, args[4]); - - // saveStats(sr.existingSummaries, resolved, args[4], staticAnalyser.ptgs); - - printResForJVM(sr.solvedSummaries, args[2], args[4]); + System.out.println("AFTER Resolver"); + printAllInfo(StaticAnalyser.ptgs, StaticAnalyser.summaries, StaticAnalyser.stackOrders, args[4]); + printResForJVM(sr.solvedSummaries, StaticAnalyser.stackOrders, args[2], args[4]); } else { SummaryResolver sr = new SummaryResolver(); @@ -202,13 +187,12 @@ static void CreateStackOrdering() { System.out.println("PRIYAM - Starting topological sorting"); for(SootMethod method : StaticAnalyser.ptgs.keySet()) { - System.out.println("PRIYAM: " + method); - PointsToGraph ptg = StaticAnalyser.ptgs.get(method); // TODO - First check if it is a DAG + // TO ASK - Peform a check before or combine with the + // topological dfs // Perform topological sort for the ptg - System.out.println(ptg); HashSet visited = new HashSet(); ArrayList topoOrder = new ArrayList(); @@ -222,7 +206,7 @@ static void CreateStackOrdering() { } } - System.out.println("PRIYAM TopoOrder : " + topoOrder); + StaticAnalyser.stackOrders.put(method, topoOrder); } } @@ -277,8 +261,11 @@ public int compare(EscapeState a, EscapeState b) } } - private static void printAllInfo(Map ptgs, - Map> summaries, String opDir) { + private static void printAllInfo( + Map ptgs, + Map> summaries, + Map> stackOrders, + String opDir) { Path p_opDir = Paths.get(opDir); for (Map.Entry entry : ptgs.entrySet()) { @@ -291,7 +278,15 @@ private static void printAllInfo(Map ptgs, output.append("PTG:\n"); output.append(ptg.toString()); output.append("\nSummary\n"); - output.append(summaries.get(method).toString() + "\n"); + output.append(summaries.get(method).toString()); + + if (stackOrders.containsKey(method)) { + output.append("\nStackOrder\n"); + output.append(stackOrders.get(method).toString() + "\n\n"); + } else { + output.append("\nNo stack Ordering exists for : " + method + "\n\n"); + } + try { Files.write(p_opFile, output.toString().getBytes(StandardCharsets.UTF_8), Files.exists(p_opFile) ? StandardOpenOption.APPEND : StandardOpenOption.CREATE); @@ -302,6 +297,7 @@ private static void printAllInfo(Map ptgs, } } } + static String transformFuncSignature(String inputString) { StringBuilder finalString = new StringBuilder(); for(int i=1;i> summaries, String ipDir, String opDir) { + + static void printResForJVM( + Map> summaries, + Map> stackOrders, + String ipDir, + String opDir) { // Open File Path p_ipDir = Paths.get(ipDir); Path p_opDir = Paths.get(opDir); @@ -328,9 +329,10 @@ static void printResForJVM(Map> su HashMap summary = entry.getValue(); sb.append(transformFuncSignature(method.getBytecodeSignature())); sb.append(" "); - sb.append(GetListOfNoEscapeObjects.get(summary)); + sb.append(GetListOfNoEscapeObjects.get(summary, stackOrders.get(method))); sb.append("\n"); } + try { System.out.println("Trying to write to:" + p_opFile); Files.write(p_opFile, sb.toString().getBytes(StandardCharsets.UTF_8), diff --git a/src/utils/GetListOfNoEscapeObjects.java b/src/utils/GetListOfNoEscapeObjects.java index 021f268d0..46ce44a13 100644 --- a/src/utils/GetListOfNoEscapeObjects.java +++ b/src/utils/GetListOfNoEscapeObjects.java @@ -10,16 +10,18 @@ import java.util.Map; public class GetListOfNoEscapeObjects { - public static String get(HashMap summary) { + public static String get( + HashMap summary, + ArrayList stackOrder) { ArrayList arr = new ArrayList<>(); - for (Map.Entry entry : summary.entrySet()) { - ObjectNode obj = entry.getKey(); - if(obj.type != ObjectType.internal) + for (ObjectNode obj : stackOrder) { + if (obj.type != ObjectType.internal) continue; - EscapeStatus es = entry.getValue(); - if (es.containsNoEscape()) arr.add(obj.ref); + EscapeStatus es = summary.get(obj); + if (es.containsNoEscape()) + arr.add(obj.ref); } - Collections.sort(arr); + String _ret = arr.toString(); return _ret; } diff --git a/tests/test23/Main.java b/tests/test23/Main.java index efd4fe0fd..9cf2b64ff 100644 --- a/tests/test23/Main.java +++ b/tests/test23/Main.java @@ -7,7 +7,7 @@ public static void main(String[] args) { Node E = new Node(); A.n = B; B.n = D; - B.n = E; + B.m = E; D.n = C; } } diff --git a/tests/test23/Node.java b/tests/test23/Node.java index 04f5b0175..391eba7af 100644 --- a/tests/test23/Node.java +++ b/tests/test23/Node.java @@ -1,3 +1,4 @@ public class Node { public Node n; + public Node m; } diff --git a/tests/test24/Main.java b/tests/test24/Main.java new file mode 100644 index 000000000..c60622ac7 --- /dev/null +++ b/tests/test24/Main.java @@ -0,0 +1,20 @@ +public class Main { + public static void main(String[] args) { + } + + static void foo(Node node1, Node node2) { + Node A = new Node(); + Node B = new Node(); + Node C = new Node(); + Node D = new Node(); + Node E = new Node(); + bar(A, B); + bar(A, C); + bar(D, E); + bar(node1, node2); + } + + static void bar(Node n1, Node n2) { + n1.n = n2; + } +} diff --git a/tests/test24/Node.java b/tests/test24/Node.java new file mode 100644 index 000000000..391eba7af --- /dev/null +++ b/tests/test24/Node.java @@ -0,0 +1,4 @@ +public class Node { + public Node n; + public Node m; +} diff --git a/tests/test25/Main.java b/tests/test25/Main.java new file mode 100644 index 000000000..ad5635f25 --- /dev/null +++ b/tests/test25/Main.java @@ -0,0 +1,26 @@ +public class Main { + public static void main(String[] args) { + } + + static void foo(Node node1, Node node2) { + Node A = new Node(); + Node B = new Node(); + Node C = new Node(); + Node D = new Node(); + Node E = new Node(); + bar(A, B); + bar(A, C); + bar(D, E); + bar(node1, node2); + } + + static void bar(Node n1, Node n2) { + Node F = new Node(); + n1.n = F; // we need to heapify F (address check) + F.n = n2; // no heapfication + + + // Theory -- If two objects are directly connected + // Then only we need stack order, else, we will not be needing any stack order + } +} diff --git a/tests/test25/Node.java b/tests/test25/Node.java new file mode 100644 index 000000000..391eba7af --- /dev/null +++ b/tests/test25/Node.java @@ -0,0 +1,4 @@ +public class Node { + public Node n; + public Node m; +} diff --git a/tests/test26/Main.java b/tests/test26/Main.java new file mode 100644 index 000000000..e790590a7 --- /dev/null +++ b/tests/test26/Main.java @@ -0,0 +1,33 @@ +public class Main { + public static void main(String[] args) { + foo(); + } + + static void foo() { + Node A = new Node(); + Node B = new Node(); + bar(A, B); + + Node D = new Node(); + Node E = new Node(); + bar(D, E); + } + + static void bar(Node n1, Node n2) { + n1.n = n2; + + bas(n1); + } + + static void bas(Node x) { + Node x1 = new Node(); + + x.n = x1; + + int i = bat(); + } + + static int bat() { + return 5; + } +} diff --git a/tests/test26/Node.java b/tests/test26/Node.java new file mode 100644 index 000000000..391eba7af --- /dev/null +++ b/tests/test26/Node.java @@ -0,0 +1,4 @@ +public class Node { + public Node n; + public Node m; +} From 6311454b82e6600ad77b1146805d3b9815ddbb92 Mon Sep 17 00:00:00 2001 From: Signior-X Date: Tue, 18 Oct 2022 23:27:01 +0530 Subject: [PATCH 5/8] Complete stack ordering and added tests --- src/analyser/StackOrderAnalyser.java | 41 +++++++++++++++++++--------- src/analyser/StaticAnalyser.java | 2 +- tests/test26/Main.java | 30 ++++++-------------- tests/test27/Main.java | 32 ++++++++++++++++++++++ tests/test27/Node.java | 4 +++ 5 files changed, 73 insertions(+), 36 deletions(-) create mode 100644 tests/test27/Main.java create mode 100644 tests/test27/Node.java diff --git a/src/analyser/StackOrderAnalyser.java b/src/analyser/StackOrderAnalyser.java index a05fa3f7f..521ab426d 100644 --- a/src/analyser/StackOrderAnalyser.java +++ b/src/analyser/StackOrderAnalyser.java @@ -43,8 +43,11 @@ public StackOrderAnalyser() { @Override protected void internalTransform(Body body, String phasename, Map options) { SootMethod method = body.getMethod(); + processMethod(method); + } - if (body.getMethod().isJavaLibraryMethod()) { + private void processMethod(SootMethod method) { + if (method.isJavaLibraryMethod()) { return; } @@ -56,29 +59,30 @@ protected void internalTransform(Body body, String phasename, Map units = body.getUnits(); for (Unit u : units) { + // System.out.println("PRIYAM unit: " + u); if (u instanceof JInvokeStmt) { JInvokeStmt stmt = (JInvokeStmt) u; InvokeExpr expr = stmt.getInvokeExpr(); - handleExpr(body.getMethod(), u, expr); + handleExpr(method, u, expr); } } + + methodsProcessing.remove(method); + methodsProcessed.add(method); } - public static void handleExpr( + public void handleExpr( SootMethod m, Unit u, InvokeExpr expr) { PointsToGraph ptg = StaticAnalyser.ptgs.get(m); CallGraph cg = Scene.v().getCallGraph(); @@ -119,6 +123,9 @@ public static void handleExpr( // TODO - Add a recursion to first process the method // if not already processed + if (!methodsProcessed.contains(method)) { + processMethod(method); + } Map> paramMapping = new HashMap>(); for (int i = 0; i < paramCount; i++) { @@ -148,8 +155,9 @@ else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE) * paramsMapping also */ PointsToGraph calliePTG = StaticAnalyser.ptgs.get(method); - // System.out.println("PRIYAM PTGS: " + StaticAnalyser.ptgs); - // System.out.println("PRIYAM calliePTG: " + calliePTG); + System.out.println("PRIYAM METHOD: " + method); + System.out.println("PRIYAM PTGS: " + StaticAnalyser.ptgs); + System.out.println("PRIYAM calliePTG: " + calliePTG); // If ptg gives error, ensure StaticAnalysis has been done for (int i = 0; i < paramCount; i++) { @@ -163,22 +171,29 @@ else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE) for (Map.Entry> entry : pointingTo.entrySet()) { for (ObjectNode fieldObj : entry.getValue()) { System.out.println("There exists an edge from: " + obj + " to " + fieldObj + " by " + entry.getKey()); - if (fieldObj.type == ObjectType.parameter) { + if (fieldObj.type != ObjectType.parameter) { continue; } + if (!paramMapping.containsKey(obj) || !paramMapping.containsKey(fieldObj)) { + // If paramsMapping does not have the object, it can happen if null is passed + continue; + } + // Find paramsMapping for obj // Find paramsMapping for fieldObj // Add an edge from objs to fieldObjs for (ObjectNode objInCaller : paramMapping.get(obj)) { for (ObjectNode fieldObjInCaller : paramMapping.get(fieldObj)) { - // System.out.println("There should exists an edge from: " + objInCaller + " to " + fieldObjInCaller + " by " + entry.getKey()); + System.out.println("There should exists an edge from: " + objInCaller + " to " + fieldObjInCaller + " by " + entry.getKey()); ptg.WEAK_makeField(objInCaller, entry.getKey(), fieldObjInCaller); } } } } } + + System.out.println("AFTER PRIYAM PTGS: " + StaticAnalyser.ptgs + "\n"); } } } diff --git a/src/analyser/StaticAnalyser.java b/src/analyser/StaticAnalyser.java index 2ac53da81..541671788 100644 --- a/src/analyser/StaticAnalyser.java +++ b/src/analyser/StaticAnalyser.java @@ -302,7 +302,7 @@ protected void internalTransform(Body body, String phasename, Map nativeList, Map summary, PointsToGraph ptg) { diff --git a/tests/test26/Main.java b/tests/test26/Main.java index e790590a7..39b7ecb7d 100644 --- a/tests/test26/Main.java +++ b/tests/test26/Main.java @@ -1,33 +1,19 @@ public class Main { public static void main(String[] args) { - foo(); + Node x = new Node(); + Node y = new Node(); + foo(x, y); // There should come a linking for x and y from baz } - static void foo() { - Node A = new Node(); - Node B = new Node(); - bar(A, B); - - Node D = new Node(); - Node E = new Node(); - bar(D, E); + static void foo(Node node1, Node node2) { + bar(node1, node2); } static void bar(Node n1, Node n2) { - n1.n = n2; - - bas(n1); - } - - static void bas(Node x) { - Node x1 = new Node(); - - x.n = x1; - - int i = bat(); + baz(n1, n2); } - static int bat() { - return 5; + static void baz(Node p, Node q) { + p.n = q; // Linking the objects here } } diff --git a/tests/test27/Main.java b/tests/test27/Main.java new file mode 100644 index 000000000..60829bb79 --- /dev/null +++ b/tests/test27/Main.java @@ -0,0 +1,32 @@ +public class Main { + public static void main(String[] args) { + // A recursive and multiple params test + } + + static void foo(Node node1, Node node2) { + Node A = new Node(); + Node B = new Node(); + Node C = new Node(); + Node D = new Node(); + Node E = new Node(); + Node F = new Node(); + Node G = new Node(); + + Main obj = new Main(); + obj.bar(A, B, C, D, E, F, G); + } + + void bar(Node n1, Node n2, Node n3, Node n4, Node n5, Node n6, Node n7) { + if (n7 == null) { + return; + } + + n1.n = n3; + n4.n = n5; + n5.n = n6; + n6.n = n2; + n2.n = n3; + + bar(n2, n3, n4, n5, n6, n7, null); + } +} diff --git a/tests/test27/Node.java b/tests/test27/Node.java new file mode 100644 index 000000000..391eba7af --- /dev/null +++ b/tests/test27/Node.java @@ -0,0 +1,4 @@ +public class Node { + public Node n; + public Node m; +} From 1f16acad8b43dc0d7d9ca71432a3aee6c8ccec19 Mon Sep 17 00:00:00 2001 From: Signior-X Date: Thu, 3 Nov 2022 10:27:32 +0530 Subject: [PATCH 6/8] Left in between --- src/analyser/MethodsLinkingAnalyser.java | 211 +++++++++++++++++++++++ src/main/Main.java | 20 ++- src/stackOrdering/StackOrderer.java | 5 + tests/test24/Main.java | 17 +- tests/test25/Main.java | 2 +- 5 files changed, 246 insertions(+), 9 deletions(-) create mode 100644 src/analyser/MethodsLinkingAnalyser.java create mode 100644 src/stackOrdering/StackOrderer.java diff --git a/src/analyser/MethodsLinkingAnalyser.java b/src/analyser/MethodsLinkingAnalyser.java new file mode 100644 index 000000000..4f424e273 --- /dev/null +++ b/src/analyser/MethodsLinkingAnalyser.java @@ -0,0 +1,211 @@ +package analyser; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +import soot.*; +import main.CHATransform; +import ptg.ObjectNode; +import ptg.ObjectType; +import ptg.PointsToGraph; +import soot.jimple.Constant; +import soot.jimple.InstanceInvokeExpr; +import soot.jimple.InvokeExpr; +import soot.jimple.internal.JInvokeStmt; +import soot.jimple.internal.JStaticInvokeExpr; +import soot.jimple.toolkits.callgraph.CallGraph; +import soot.jimple.toolkits.callgraph.Edge; + +public class MethodsLinkingAnalyser extends SceneTransformer { + public static ConcurrentHashMap > nativeLocals = new ConcurrentHashMap<>(); + + public static ArrayList whitelistedNatives = new ArrayList<> ( + Arrays.asList("") + ); + + public static ArrayList blacklistedNatives = new ArrayList<> ( + Arrays.asList("", + "", + "") + ); + + + private Set methodsProcessed; + private Set methodsProcessing; + + public MethodsLinkingAnalyser() { + methodsProcessed = new HashSet(); + methodsProcessing = new HashSet(); + } + + @Override + protected void internalTransform(String arg0, Map arg1) { + // Get the call graph, and start processing the methods + CallGraph cg = Scene.v().getCallGraph(); + Iterator callerEdges = cg.sourceMethods(); + + while (callerEdges.hasNext()) { + SootMethod methodCaller = (SootMethod) callerEdges.next(); + // System.out.println("PRIYAM method caller: " + methodCaller); + processMethod(methodCaller); + } + } + + private void processMethod(SootMethod methodCaller) { + if (methodCaller.isJavaLibraryMethod()) { + return; + } + + if (methodsProcessed.contains(methodCaller)) { + // Method already computed + // we have the results ready + return; + } + + if (methodsProcessing.contains(methodCaller)) { + // Recursive loop + // ASK - See what to do + return; + } + + methodsProcessing.add(methodCaller); + + System.out.println("PRIYAM Method Name: "+ methodCaller.getBytecodeSignature() + ":" + methodCaller.getName()); + Body body = methodCaller.getActiveBody(); + PatchingChain units = body.getUnits(); + + for (Unit u : units) { + // System.out.println("PRIYAM unit: " + u); + if (u instanceof JInvokeStmt) { + JInvokeStmt stmt = (JInvokeStmt) u; + InvokeExpr expr = stmt.getInvokeExpr(); + handleExpr(methodCaller, u, expr); + } + } + + methodsProcessing.remove(methodCaller); + methodsProcessed.add(methodCaller); + } + + public void handleExpr( + SootMethod methodCaller, Unit u, InvokeExpr expr) { + PointsToGraph ptg = StaticAnalyser.ptgs.get(methodCaller); + + if (ptg == null) { + // If no points to graph, no need to process further + return; + } + + CallGraph cg = Scene.v().getCallGraph(); + + Iterator iedges = cg.edgesOutOf(u); + List args = expr.getArgs(); + + List edges = new ArrayList<>(); + if (!iedges.hasNext()) { + iedges = CHATransform.getCHA().edgesOutOf(u); + } + + while (iedges.hasNext()) { + edges.add(iedges.next()); + } + + if (edges.size() == 0) { + // System.out.println("Empty edges: " + expr + ", function incoming edges: " + cg.edgesInto(methodCaller).hasNext() + + // " Method: " + methodCaller.getBytecodeSignature()); + edges.add(new Edge(methodCaller, u, expr.getMethod(), Kind.SPECIAL)); + } + + if (expr instanceof InstanceInvokeExpr) { + // ASK - No need to handle instance invoke expr? + } else if (expr instanceof JStaticInvokeExpr) { + } else { + System.err.println("Unidentified invoke expr: " + expr.toString()); + throw new IllegalArgumentException(expr.toString()); + } + + for (Edge edge : edges) { + /* 1. + * We traverse and find the caller callie relationship + * between ObjectNodes + */ + SootMethod method = edge.tgt(); + int paramCount = method.getParameterCount(); + + // Recursion to first process the method + // if not already processed + if (!methodsProcessed.contains(method)) { + processMethod(method); + } + + Map> paramMapping = new HashMap>(); + for (int i = 0; i < paramCount; i++) { + ObjectNode obj = new ObjectNode(i, ObjectType.parameter); + // ConditionalValue cv = new ConditionalValue(method, obj, true); + + if (edge.kind() == Kind.REFL_INVOKE) + paramMapping.put(obj, ptg.vars.get((Local) args.get(1))); + else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE) + paramMapping.put(obj, ptg.vars.get((Local) args.get(0))); + else { + Value arg = args.get(i); + if (arg.getType() instanceof RefType || arg.getType() instanceof ArrayType) + if (!(arg instanceof Constant)) { // Notice the not(!) + // ptg.addParametricEdge((Local) args.get(i), cv); + System.out.println("args get i: " + args.get(i)); + paramMapping.put(obj, ptg.vars.get((Local) args.get(i))); + } + } + } + + // System.out.println("PRIYAM PARAMS MAPPING: " + paramMapping); + + /* 2. + * Now, loop in the callie method's ptg to find if there + * exists any relationship/node between the params + * If exists, add the realtion for corresponding values in + * paramsMapping also + */ + PointsToGraph calliePTG = StaticAnalyser.ptgs.get(method); + System.out.println("PRIYAM METHOD: " + method); + System.out.println("PRIYAM PTGS: " + StaticAnalyser.ptgs); + System.out.println("PRIYAM calliePTG: " + calliePTG); + // If ptg gives error, ensure StaticAnalysis has been done + + for (int i = 0; i < paramCount; i++) { + ObjectNode obj = new ObjectNode(i, ObjectType.parameter); + Map> pointingTo = calliePTG.fields.get(obj); + + if (pointingTo == null) { + continue; + } + + for (Map.Entry> entry : pointingTo.entrySet()) { + for (ObjectNode fieldObj : entry.getValue()) { + System.out.println("There exists an edge from: " + obj + " to " + fieldObj + " by " + entry.getKey()); + if (fieldObj.type != ObjectType.parameter) { + continue; + } + + if (!paramMapping.containsKey(obj) || !paramMapping.containsKey(fieldObj)) { + // If paramsMapping does not have the object, it can happen if null is passed + continue; + } + + // Find paramsMapping for obj + // Find paramsMapping for fieldObj + // Add an edge from objs to fieldObjs + for (ObjectNode objInCaller : paramMapping.get(obj)) { + for (ObjectNode fieldObjInCaller : paramMapping.get(fieldObj)) { + System.out.println("There should exists an edge from: " + objInCaller + " to " + fieldObjInCaller + " by " + entry.getKey()); + ptg.WEAK_makeField(objInCaller, entry.getKey(), fieldObjInCaller); + } + } + } + } + } + + System.out.println("AFTER PRIYAM PTGS: " + StaticAnalyser.ptgs + "\n"); + } + } +} diff --git a/src/main/Main.java b/src/main/Main.java index e1b656d28..1032a6e0a 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -1,5 +1,6 @@ package main; +import analyser.MethodsLinkingAnalyser; import analyser.StackOrderAnalyser; import analyser.StaticAnalyser; import config.StoreEscape; @@ -60,7 +61,6 @@ public static void main(String[] args) { } StaticAnalyser staticAnalyser = new StaticAnalyser(); - StackOrderAnalyser stackOrderAnalyser = new StackOrderAnalyser(); CHATransform prepass = new CHATransform(); PackManager.v().getPack("wjap").add(new Transform("wjap.pre", prepass)); PackManager.v().getPack("jtp").add(new Transform("jtp.sample", staticAnalyser)); @@ -98,12 +98,20 @@ public static void main(String[] args) { System.out.println("Time Taken:"+(analysis_end-analysis_start)/1000F); System.out.println("BEFORE InterProcedural Linking"); - printAllInfo(StaticAnalyser.ptgs, StaticAnalyser.summaries, StaticAnalyser.stackOrders, args[4]); + // printAllInfo(StaticAnalyser.ptgs, StaticAnalyser.summaries, StaticAnalyser.stackOrders, args[4]); + + // // Problem - not processing methods + + // // First, we add edges created due to callie function during method call + // analysis_start = System.currentTimeMillis(); + // // How to use spark here? + // // MethodsLinkingAnalyser methodsLinkingAnalyser = new MethodsLinkingAnalyser(); + // // PackManager.v().getPack("wjtp").add(new Transform("wjtp.ada", methodsLinkingAnalyser)); + // StackOrderAnalyser stackOrderAnalyser = new StackOrderAnalyser(); + // PackManager.v().getPack("jtp").add(new Transform("jtp.order", stackOrderAnalyser)); + // Scene.v().setEntryPoints(entryPoints); + // PackManager.v().runPacks(); - // First, we add edges created due to callie function during method call - analysis_start = System.currentTimeMillis(); - PackManager.v().getPack("jtp").add(new Transform("jtp.stackOrder", stackOrderAnalyser)); - PackManager.v().runPacks(); // Now we are going to find the stack ordering of the non escaping functions CreateStackOrdering(); diff --git a/src/stackOrdering/StackOrderer.java b/src/stackOrdering/StackOrderer.java new file mode 100644 index 000000000..15e40829a --- /dev/null +++ b/src/stackOrdering/StackOrderer.java @@ -0,0 +1,5 @@ +package stackOrdering; + +public class StackOrderer { + +} diff --git a/tests/test24/Main.java b/tests/test24/Main.java index c60622ac7..bd8185af7 100644 --- a/tests/test24/Main.java +++ b/tests/test24/Main.java @@ -8,8 +8,21 @@ static void foo(Node node1, Node node2) { Node C = new Node(); Node D = new Node(); Node E = new Node(); - bar(A, B); - bar(A, C); + // bar(A, B); + A.n = B; + + // if I make channges in staticAnalyser? + + Node x = A.n; + + // r10=[, ] + // Assumption 1 + // we do replacement of assignment + // statements after the whole pass + // How to consider for if else branch? + // For different branches? + + bar(x, C); bar(D, E); bar(node1, node2); } diff --git a/tests/test25/Main.java b/tests/test25/Main.java index ad5635f25..e9b503f51 100644 --- a/tests/test25/Main.java +++ b/tests/test25/Main.java @@ -19,7 +19,7 @@ static void bar(Node n1, Node n2) { n1.n = F; // we need to heapify F (address check) F.n = n2; // no heapfication - + // Assumption 2 // Theory -- If two objects are directly connected // Then only we need stack order, else, we will not be needing any stack order } From b0ab1d7007c13f49bacbcd458f573f21af1c9c5d Mon Sep 17 00:00:00 2001 From: Signior-X Date: Thu, 3 Nov 2022 18:43:24 +0530 Subject: [PATCH 7/8] Left in between --- src/analyser/MethodsLinkingAnalyser.java | 12 +++++++----- src/main/Main.java | 14 +++++++------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/analyser/MethodsLinkingAnalyser.java b/src/analyser/MethodsLinkingAnalyser.java index 4f424e273..531f9477b 100644 --- a/src/analyser/MethodsLinkingAnalyser.java +++ b/src/analyser/MethodsLinkingAnalyser.java @@ -42,13 +42,15 @@ public MethodsLinkingAnalyser() { protected void internalTransform(String arg0, Map arg1) { // Get the call graph, and start processing the methods CallGraph cg = Scene.v().getCallGraph(); - Iterator callerEdges = cg.sourceMethods(); + SootClass mainClass = Scene.v().getMainClass(); + SootMethod methodCaller = mainClass.getMethodByName("main"); + // Iterator callerEdges = cg.sourceMethods(); - while (callerEdges.hasNext()) { - SootMethod methodCaller = (SootMethod) callerEdges.next(); - // System.out.println("PRIYAM method caller: " + methodCaller); + // while (callerEdges.hasNext()) { + // SootMethod methodCaller = (SootMethod) callerEdges.next(); + // System.out.println("PRIYAM method caller: " + methodCaller); processMethod(methodCaller); - } + // } } private void processMethod(SootMethod methodCaller) { diff --git a/src/main/Main.java b/src/main/Main.java index 1032a6e0a..6f351ea59 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -102,15 +102,15 @@ public static void main(String[] args) { // // Problem - not processing methods - // // First, we add edges created due to callie function during method call - // analysis_start = System.currentTimeMillis(); - // // How to use spark here? - // // MethodsLinkingAnalyser methodsLinkingAnalyser = new MethodsLinkingAnalyser(); - // // PackManager.v().getPack("wjtp").add(new Transform("wjtp.ada", methodsLinkingAnalyser)); + // First, we add edges created due to callie function during method call + analysis_start = System.currentTimeMillis(); + // How to use spark here? + MethodsLinkingAnalyser methodsLinkingAnalyser = new MethodsLinkingAnalyser(); + PackManager.v().getPack("wjtp").add(new Transform("wjtp.ada", methodsLinkingAnalyser)); // StackOrderAnalyser stackOrderAnalyser = new StackOrderAnalyser(); // PackManager.v().getPack("jtp").add(new Transform("jtp.order", stackOrderAnalyser)); - // Scene.v().setEntryPoints(entryPoints); - // PackManager.v().runPacks(); + Scene.v().setEntryPoints(entryPoints); + PackManager.v().runPacks(); // Now we are going to find the stack ordering of the non escaping functions From dc01e1f12f5cb48e326c6b96ac27286f5205070f Mon Sep 17 00:00:00 2001 From: Signior-X Date: Wed, 23 Nov 2022 16:07:47 +0530 Subject: [PATCH 8/8] Left in between --- examples/Case1.java | 28 ++++ examples/Case2.java | 27 +++ examples/Case3.java | 22 +++ examples/Challenge1.java | 30 ++++ examples/Node.java | 5 + scripts/benchmark.sh | 2 +- src/analyser/MethodsLinkingAnalyser.java | 141 +++++++++------- src/analyser/StackOrderAnalyser.java | 199 ----------------------- src/analyser/StaticAnalyser.java | 30 ++-- src/data/GlobalAnalysisData.java | 29 ++++ src/main/Main.java | 46 +++--- tests/test24/Main.java | 20 +-- tests/test28/Main.java | 34 ++++ tests/test28/Node.java | 4 + 14 files changed, 304 insertions(+), 313 deletions(-) create mode 100644 examples/Case1.java create mode 100644 examples/Case2.java create mode 100644 examples/Case3.java create mode 100644 examples/Challenge1.java create mode 100644 examples/Node.java delete mode 100644 src/analyser/StackOrderAnalyser.java create mode 100644 src/data/GlobalAnalysisData.java create mode 100644 tests/test28/Main.java create mode 100644 tests/test28/Node.java diff --git a/examples/Case1.java b/examples/Case1.java new file mode 100644 index 000000000..54a6df892 --- /dev/null +++ b/examples/Case1.java @@ -0,0 +1,28 @@ +package examples; + +public class Case1 { + public static void main(String[] args) { + Case1 obj = new Case1(); + obj.m1(); + } + + // Consider Both A and B are in their respective function stack + public void m1() { + Node A = new Node(); // A is in lower function call stackframe + m2(A); + } + + public void m2(Node A) { + Node B = new Node(); // B is in higher function call stackframe + // Thus B's lifetime is less than A + m3(A, B); + } + + public void m3(Node A, Node B) { + A.f = B; // Object pointed to by B must escape as B's lifetime is less than A's + // lifetime Else, A.f will become undefined, and will not point to any + // object once m2's function stack is poped out. + } + + // Object pointed to by B should be Heapified! +} diff --git a/examples/Case2.java b/examples/Case2.java new file mode 100644 index 000000000..85ba64f6c --- /dev/null +++ b/examples/Case2.java @@ -0,0 +1,27 @@ +package examples; + +public class Case2 { + public static void main(String[] args) { + Case1 obj = new Case1(); + obj.m1(); + } + + // Consider Both A and B are in their respective function stack + public void m1() { + Node B = new Node(); // B is in lower function call stackframe + m2(B); + } + + public void m2(Node B) { + Node A = new Node(); // A is in higher function call stackframe + // Thus B's lifetime is more than A + m3(A, B); + } + + public void m3(Node A, Node B) { + A.f = B; // Object pointed to by B need not escape as B's lifetime is more than A's + // lifetime. So, if B will not be popped before A in anycase. + } + + // Object pointed to by B need not be Heapified! +} diff --git a/examples/Case3.java b/examples/Case3.java new file mode 100644 index 000000000..75ea26770 --- /dev/null +++ b/examples/Case3.java @@ -0,0 +1,22 @@ +package examples; + +public class Case3 { + public static void main(String[] args) { + Case1 obj = new Case1(); + obj.m1(); + } + + // Consider Both A and B are in their respective function stack + public void m2() { + Node A = new Node(); + Node B = new Node(); // A and B are in the same stack frame + m3(A, B); + } + + public void m3(Node A, Node B) { + A.f = B; // Object pointed to by B need not escape as B's lifetime is equal to A's + // lifetime. So, A and B will be popped out at the same time. + } + + // Object pointed to by B need not be Heapified! +} diff --git a/examples/Challenge1.java b/examples/Challenge1.java new file mode 100644 index 000000000..235e5b8e7 --- /dev/null +++ b/examples/Challenge1.java @@ -0,0 +1,30 @@ +package examples; + +public class Challenge1 { + public static void main(String[] args) { + Challenge1 obj = new Challenge1(); + obj.m1(); + } + + public void m1() { + int x = 3; + Node A = new Node(); + Node B = new Node(); + + m2(A, B, x); + } + + public void m2(Node p1, Node p2, int x) { + if (x == 0) return; + + m3(p1, p2, x - 1); + p1.f = p2; + } + + public void m3(Node p1, Node p2, int x) { + Node C = new Node(); + Node D = new Node(); + + m2(C, D, x); + } +} diff --git a/examples/Node.java b/examples/Node.java new file mode 100644 index 000000000..402112453 --- /dev/null +++ b/examples/Node.java @@ -0,0 +1,5 @@ +package examples; + +public class Node { + public Node f; +} diff --git a/scripts/benchmark.sh b/scripts/benchmark.sh index 67ec6a063..dace39cdb 100755 --- a/scripts/benchmark.sh +++ b/scripts/benchmark.sh @@ -3,7 +3,7 @@ # Set the paths according to your installation. All paths must be full paths. # Arguments: 1) name of benchmark # Installed path of Java 8 JDK -java_install_path="/usr/lib/jvm/java-8-oracle/" +java_install_path="/usr/lib/jvm/java-8-openjdk-amd64/" # java_install_path="" # java_install_path="/wd/users/t17041/benchmarks/jdk-11.0.8/" # Path to the directory containing all benchmarks. The subdirectories here must diff --git a/src/analyser/MethodsLinkingAnalyser.java b/src/analyser/MethodsLinkingAnalyser.java index 531f9477b..10065b649 100644 --- a/src/analyser/MethodsLinkingAnalyser.java +++ b/src/analyser/MethodsLinkingAnalyser.java @@ -3,6 +3,9 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import data.GlobalAnalysisData; +import handlers.JAssignStmt.JAssignStmtHandler; +import handlers.JAssignStmt.StoreStmt; import soot.*; import main.CHATransform; import ptg.ObjectNode; @@ -11,46 +14,30 @@ import soot.jimple.Constant; import soot.jimple.InstanceInvokeExpr; import soot.jimple.InvokeExpr; +import soot.jimple.internal.JAssignStmt; import soot.jimple.internal.JInvokeStmt; import soot.jimple.internal.JStaticInvokeExpr; import soot.jimple.toolkits.callgraph.CallGraph; import soot.jimple.toolkits.callgraph.Edge; +import utils.AnalysisError; public class MethodsLinkingAnalyser extends SceneTransformer { - public static ConcurrentHashMap > nativeLocals = new ConcurrentHashMap<>(); + public static ConcurrentHashMap> nativeLocals = new ConcurrentHashMap<>(); - public static ArrayList whitelistedNatives = new ArrayList<> ( - Arrays.asList("") - ); + public static ArrayList whitelistedNatives = new ArrayList<>( + Arrays.asList("")); - public static ArrayList blacklistedNatives = new ArrayList<> ( - Arrays.asList("", - "", - "") - ); - - - private Set methodsProcessed; - private Set methodsProcessing; - - public MethodsLinkingAnalyser() { - methodsProcessed = new HashSet(); - methodsProcessing = new HashSet(); - } + public static ArrayList blacklistedNatives = new ArrayList<>( + Arrays.asList("", + "", + "")); @Override protected void internalTransform(String arg0, Map arg1) { - // Get the call graph, and start processing the methods - CallGraph cg = Scene.v().getCallGraph(); + // Get the call graph, and start processing from the main method SootClass mainClass = Scene.v().getMainClass(); SootMethod methodCaller = mainClass.getMethodByName("main"); - // Iterator callerEdges = cg.sourceMethods(); - - // while (callerEdges.hasNext()) { - // SootMethod methodCaller = (SootMethod) callerEdges.next(); - // System.out.println("PRIYAM method caller: " + methodCaller); - processMethod(methodCaller); - // } + processMethod(methodCaller); } private void processMethod(SootMethod methodCaller) { @@ -58,21 +45,20 @@ private void processMethod(SootMethod methodCaller) { return; } - if (methodsProcessed.contains(methodCaller)) { - // Method already computed - // we have the results ready + if (GlobalAnalysisData.methodsProcessed.contains(methodCaller)) { + // Method already computed, we have the results return; } - if (methodsProcessing.contains(methodCaller)) { - // Recursive loop - // ASK - See what to do + if (GlobalAnalysisData.methodsProcessing.contains(methodCaller)) { + // Recursive loop, we for now use the intraprocedural results for recursion + // cases, a less precise answer return; } - methodsProcessing.add(methodCaller); + GlobalAnalysisData.methodsProcessing.add(methodCaller); - System.out.println("PRIYAM Method Name: "+ methodCaller.getBytecodeSignature() + ":" + methodCaller.getName()); + System.out.println("PRIYAM Method Name: " + methodCaller.getBytecodeSignature() + ":" + methodCaller.getName()); Body body = methodCaller.getActiveBody(); PatchingChain units = body.getUnits(); @@ -81,31 +67,52 @@ private void processMethod(SootMethod methodCaller) { if (u instanceof JInvokeStmt) { JInvokeStmt stmt = (JInvokeStmt) u; InvokeExpr expr = stmt.getInvokeExpr(); - handleExpr(methodCaller, u, expr); + handleInvokeExpr(methodCaller, u, expr); + } else if (u instanceof JAssignStmt) { + handleAssignExpr(methodCaller, u); } } - methodsProcessing.remove(methodCaller); - methodsProcessed.add(methodCaller); + GlobalAnalysisData.methodsProcessing.remove(methodCaller); + GlobalAnalysisData.methodsProcessed.add(methodCaller); } - public void handleExpr( - SootMethod methodCaller, Unit u, InvokeExpr expr) { - PointsToGraph ptg = StaticAnalyser.ptgs.get(methodCaller); + private void handleAssignExpr(SootMethod methodCaller, Unit u) { + JAssignStmt stmt = (JAssignStmt) u; + Value lhs = stmt.getLeftOp(); + Value rhs = stmt.getRightOp(); + if (lhs.getType() instanceof PrimType) { + if (rhs instanceof InvokeExpr) { + handleInvokeExpr(methodCaller, u, (InvokeExpr) rhs); + } + return; + } else { + JAssignStmtHandler.handle(methodCaller, u, GlobalAnalysisData.ptgs.get(methodCaller), + GlobalAnalysisData.summaries.get(methodCaller)); + } + } + + private void handleInvokeExpr(SootMethod methodCaller, Unit u, InvokeExpr expr) { + PointsToGraph ptg = GlobalAnalysisData.ptgs.get(methodCaller); if (ptg == null) { // If no points to graph, no need to process further + // System.out.println("PTG: " + ptg); + System.out.println("PRIYAM handleExpr PTG null, returning for: " + u); return; } CallGraph cg = Scene.v().getCallGraph(); + // System.out.println("PRIYAM handlExpr: " + u); Iterator iedges = cg.edgesOutOf(u); List args = expr.getArgs(); + // System.out.println("PRIYAM handlExpr" + u); + List edges = new ArrayList<>(); if (!iedges.hasNext()) { - iedges = CHATransform.getCHA().edgesOutOf(u); + iedges = CHATransform.getSpark().edgesOutOf(u); } while (iedges.hasNext()) { @@ -113,9 +120,12 @@ public void handleExpr( } if (edges.size() == 0) { - // System.out.println("Empty edges: " + expr + ", function incoming edges: " + cg.edgesInto(methodCaller).hasNext() + - // " Method: " + methodCaller.getBytecodeSignature()); + // System.out.println("Empty edges: " + expr + ", function incoming edges: " + + // cg.edgesInto(methodCaller).hasNext() + + // " Method: " + methodCaller.getBytecodeSignature()); edges.add(new Edge(methodCaller, u, expr.getMethod(), Kind.SPECIAL)); + } else { + // System.out.println("Edges for u: " + u + ": " + edges); } if (expr instanceof InstanceInvokeExpr) { @@ -127,7 +137,8 @@ public void handleExpr( } for (Edge edge : edges) { - /* 1. + /* + * 1. * We traverse and find the caller callie relationship * between ObjectNodes */ @@ -136,14 +147,14 @@ public void handleExpr( // Recursion to first process the method // if not already processed - if (!methodsProcessed.contains(method)) { + if (!GlobalAnalysisData.methodsProcessed.contains(method)) { processMethod(method); } - Map> paramMapping = new HashMap>(); + Map> paramMapping = new HashMap>(); for (int i = 0; i < paramCount; i++) { ObjectNode obj = new ObjectNode(i, ObjectType.parameter); - // ConditionalValue cv = new ConditionalValue(method, obj, true); + // ConditionalValue cv = new ConditionalValue(method, obj, true); if (edge.kind() == Kind.REFL_INVOKE) paramMapping.put(obj, ptg.vars.get((Local) args.get(1))); @@ -154,24 +165,25 @@ else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE) if (arg.getType() instanceof RefType || arg.getType() instanceof ArrayType) if (!(arg instanceof Constant)) { // Notice the not(!) // ptg.addParametricEdge((Local) args.get(i), cv); - System.out.println("args get i: " + args.get(i)); + // System.out.println("args get i: " + args.get(i)); paramMapping.put(obj, ptg.vars.get((Local) args.get(i))); } } } - // System.out.println("PRIYAM PARAMS MAPPING: " + paramMapping); - - /* 2. + // System.out.println("PRIYAM PARAMS MAPPING: " + paramMapping); + + /* + * 2. * Now, loop in the callie method's ptg to find if there * exists any relationship/node between the params * If exists, add the realtion for corresponding values in * paramsMapping also */ - PointsToGraph calliePTG = StaticAnalyser.ptgs.get(method); - System.out.println("PRIYAM METHOD: " + method); - System.out.println("PRIYAM PTGS: " + StaticAnalyser.ptgs); - System.out.println("PRIYAM calliePTG: " + calliePTG); + PointsToGraph calliePTG = GlobalAnalysisData.ptgs.get(method); + // System.out.println("PRIYAM METHOD: " + method); + // System.out.println("PRIYAM PTGS: " + GlobalAnalysisData.ptgs); + // System.out.println("PRIYAM calliePTG: " + calliePTG); // If ptg gives error, ensure StaticAnalysis has been done for (int i = 0; i < paramCount; i++) { @@ -184,9 +196,10 @@ else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE) for (Map.Entry> entry : pointingTo.entrySet()) { for (ObjectNode fieldObj : entry.getValue()) { - System.out.println("There exists an edge from: " + obj + " to " + fieldObj + " by " + entry.getKey()); + System.out.println("There exists an edge from: " + obj + " to " + fieldObj + " by " + + entry.getKey() + " when calling from " + methodCaller + " to " + method); if (fieldObj.type != ObjectType.parameter) { - continue; + continue; } if (!paramMapping.containsKey(obj) || !paramMapping.containsKey(fieldObj)) { @@ -194,20 +207,26 @@ else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE) continue; } + // System.out.println("Param Mapping for obj: " + paramMapping.get(obj)); + // System.out.println("Param Mapping for fieldObj: " + + // paramMapping.get(fieldObj)); + // Find paramsMapping for obj // Find paramsMapping for fieldObj // Add an edge from objs to fieldObjs for (ObjectNode objInCaller : paramMapping.get(obj)) { for (ObjectNode fieldObjInCaller : paramMapping.get(fieldObj)) { - System.out.println("There should exists an edge from: " + objInCaller + " to " + fieldObjInCaller + " by " + entry.getKey()); + System.out.println("There should exists an edge from: " + objInCaller + " to " + + fieldObjInCaller + " by " + entry.getKey()); ptg.WEAK_makeField(objInCaller, entry.getKey(), fieldObjInCaller); + // System.out.println("AFTER MAKE FIELD" + ptg); } - } + } } } } - System.out.println("AFTER PRIYAM PTGS: " + StaticAnalyser.ptgs + "\n"); + // System.out.println("AFTER PRIYAM PTGS: " + GlobalAnalysisData.ptgs + "\n"); } } } diff --git a/src/analyser/StackOrderAnalyser.java b/src/analyser/StackOrderAnalyser.java deleted file mode 100644 index 521ab426d..000000000 --- a/src/analyser/StackOrderAnalyser.java +++ /dev/null @@ -1,199 +0,0 @@ -package analyser; - -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; - -import soot.*; -import es.ConditionalValue; -import es.EscapeStatus; -import main.CHATransform; -import ptg.ObjectNode; -import ptg.ObjectType; -import ptg.PointsToGraph; -import soot.jimple.Constant; -import soot.jimple.InstanceInvokeExpr; -import soot.jimple.InvokeExpr; -import soot.jimple.internal.JInvokeStmt; -import soot.jimple.internal.JStaticInvokeExpr; -import soot.jimple.toolkits.callgraph.CallGraph; -import soot.jimple.toolkits.callgraph.Edge; - -public class StackOrderAnalyser extends BodyTransformer { - public static ConcurrentHashMap > nativeLocals = new ConcurrentHashMap<>(); - - public static ArrayList whitelistedNatives = new ArrayList<> ( - Arrays.asList("") - ); - - public static ArrayList blacklistedNatives = new ArrayList<> ( - Arrays.asList("", - "", - "") - ); - - - private Set methodsProcessed; - private Set methodsProcessing; - - public StackOrderAnalyser() { - methodsProcessed = new HashSet(); - methodsProcessing = new HashSet(); - } - - @Override - protected void internalTransform(Body body, String phasename, Map options) { - SootMethod method = body.getMethod(); - processMethod(method); - } - - private void processMethod(SootMethod method) { - if (method.isJavaLibraryMethod()) { - return; - } - - if (methodsProcessed.contains(method)) { - // Method already computed - // we have the results ready - return; - } - - if (methodsProcessing.contains(method)) { - // Recursive loop - // ASK - See what to do - return; - } - - methodsProcessing.add(method); - - System.out.println("PRIYAM Method Name: "+ method.getBytecodeSignature() + ":" + method.getName()); - Body body = method.getActiveBody(); - PatchingChain units = body.getUnits(); - - for (Unit u : units) { - // System.out.println("PRIYAM unit: " + u); - if (u instanceof JInvokeStmt) { - JInvokeStmt stmt = (JInvokeStmt) u; - InvokeExpr expr = stmt.getInvokeExpr(); - handleExpr(method, u, expr); - } - } - - methodsProcessing.remove(method); - methodsProcessed.add(method); - } - - public void handleExpr( - SootMethod m, Unit u, InvokeExpr expr) { - PointsToGraph ptg = StaticAnalyser.ptgs.get(m); - CallGraph cg = Scene.v().getCallGraph(); - - Iterator iedges = cg.edgesOutOf(u); - List args = expr.getArgs(); - - List edges = new ArrayList<>(); - if (!iedges.hasNext()) { - iedges = CHATransform.getCHA().edgesOutOf(u); - } - - while (iedges.hasNext()) { - edges.add(iedges.next()); - } - - if (edges.size() == 0) { - // System.out.println("Empty edges: " + expr + ", function incoming edges: " + cg.edgesInto(m).hasNext() + - // " Method: " + m.getBytecodeSignature()); - edges.add(new Edge(m, u, expr.getMethod(), Kind.SPECIAL)); - } - - if (expr instanceof InstanceInvokeExpr) { - // ASK - No need to handle instance invoke expr? - } else if (expr instanceof JStaticInvokeExpr) { - } else { - System.err.println("Unidentified invoke expr: " + expr.toString()); - throw new IllegalArgumentException(expr.toString()); - } - - for (Edge edge : edges) { - /* 1. - * We traverse and find the caller callie relationship - * between ObjectNodes - */ - SootMethod method = edge.tgt(); - int paramCount = method.getParameterCount(); - - // TODO - Add a recursion to first process the method - // if not already processed - if (!methodsProcessed.contains(method)) { - processMethod(method); - } - - Map> paramMapping = new HashMap>(); - for (int i = 0; i < paramCount; i++) { - ObjectNode obj = new ObjectNode(i, ObjectType.parameter); - // ConditionalValue cv = new ConditionalValue(method, obj, true); - - if (edge.kind() == Kind.REFL_INVOKE) - paramMapping.put(obj, ptg.vars.get((Local) args.get(1))); - else if (edge.kind() == Kind.REFL_CONSTR_NEWINSTANCE) - paramMapping.put(obj, ptg.vars.get((Local) args.get(0))); - else { - Value arg = args.get(i); - if (arg.getType() instanceof RefType || arg.getType() instanceof ArrayType) - if (!(arg instanceof Constant)) { // Notice the not(!) - // ptg.addParametricEdge((Local) args.get(i), cv); - paramMapping.put(obj, ptg.vars.get((Local) args.get(i))); - } - } - } - - // System.out.println("PRIYAM PARAMS MAPPING: " + paramMapping); - - /* 2. - * Now, loop in the callie method's ptg to find if there - * exists any relationship/node between the params - * If exists, add the realtion for corresponding values in - * paramsMapping also - */ - PointsToGraph calliePTG = StaticAnalyser.ptgs.get(method); - System.out.println("PRIYAM METHOD: " + method); - System.out.println("PRIYAM PTGS: " + StaticAnalyser.ptgs); - System.out.println("PRIYAM calliePTG: " + calliePTG); - // If ptg gives error, ensure StaticAnalysis has been done - - for (int i = 0; i < paramCount; i++) { - ObjectNode obj = new ObjectNode(i, ObjectType.parameter); - Map> pointingTo = calliePTG.fields.get(obj); - - if (pointingTo == null) { - continue; - } - - for (Map.Entry> entry : pointingTo.entrySet()) { - for (ObjectNode fieldObj : entry.getValue()) { - System.out.println("There exists an edge from: " + obj + " to " + fieldObj + " by " + entry.getKey()); - if (fieldObj.type != ObjectType.parameter) { - continue; - } - - if (!paramMapping.containsKey(obj) || !paramMapping.containsKey(fieldObj)) { - // If paramsMapping does not have the object, it can happen if null is passed - continue; - } - - // Find paramsMapping for obj - // Find paramsMapping for fieldObj - // Add an edge from objs to fieldObjs - for (ObjectNode objInCaller : paramMapping.get(obj)) { - for (ObjectNode fieldObjInCaller : paramMapping.get(fieldObj)) { - System.out.println("There should exists an edge from: " + objInCaller + " to " + fieldObjInCaller + " by " + entry.getKey()); - ptg.WEAK_makeField(objInCaller, entry.getKey(), fieldObjInCaller); - } - } - } - } - } - - System.out.println("AFTER PRIYAM PTGS: " + StaticAnalyser.ptgs + "\n"); - } - } -} diff --git a/src/analyser/StaticAnalyser.java b/src/analyser/StaticAnalyser.java index 541671788..b87bf762c 100644 --- a/src/analyser/StaticAnalyser.java +++ b/src/analyser/StaticAnalyser.java @@ -22,14 +22,12 @@ import java.util.regex.*; +import data.GlobalAnalysisData; + public class StaticAnalyser extends BodyTransformer { private boolean allNonEscaping; - public static Map ptgs; - public static Map> summaries; - public static Map> stackOrders; - public static LinkedHashMap analysis; - public static List noBCIMethods; + String[] ignoreFuncs = { // "", // "", @@ -72,11 +70,6 @@ public class StaticAnalyser extends BodyTransformer { public StaticAnalyser() { super(); - analysis = new LinkedHashMap<>(); - ptgs = new ConcurrentHashMap<>(); - summaries = new ConcurrentHashMap<>(); - stackOrders = new ConcurrentHashMap<>(); - noBCIMethods = new ArrayList<>(); allNonEscaping = false; } @@ -99,6 +92,13 @@ protected void internalTransform(Body body, String phasename, Map")){ // System.out.println("Skipping this method"); @@ -228,9 +228,9 @@ protected void internalTransform(Body body, String phasename, Map 10000) // return; } catch (IllegalBCIException e) { - noBCIMethods.add(body.getMethod()); + GlobalAnalysisData.noBCIMethods.add(body.getMethod()); setParamsAsEscaping(body.getMethod(),summary); - summaries.put(body.getMethod(), summary); + GlobalAnalysisData.summaries.put(body.getMethod(), summary); String s = "->*** Error at: " + u.toString() + " of " + body.getMethod().getBytecodeSignature(); System.err.println(s); System.err.println(e); @@ -296,12 +296,12 @@ protected void internalTransform(Body body, String phasename, Map elem = iterator.next(); while (iterator.hasNext()) elem = iterator.next(); PointsToGraph ptg = elem.getValue().getOut(); - ptgs.put(body.getMethod(), ptg); + GlobalAnalysisData.ptgs.put(body.getMethod(), ptg); if (allNonEscaping) { markAsNonEscaping(summary); markAsEscaping(JInvokeStmtHandler.nativeLocals.get(body.getMethod()), summary, ptg); } - summaries.put(body.getMethod(), summary); + GlobalAnalysisData.summaries.put(body.getMethod(), summary); System.out.println("Static Method Name: "+ body.getMethod().getBytecodeSignature() + ":"+body.getMethod().getName()); } @@ -365,7 +365,7 @@ public void apply(SootMethod m, Unit u, PointsToGraph ptg, Map entry : analysis.entrySet()) { + for (Map.Entry entry : GlobalAnalysisData.analysis.entrySet()) { System.out.println("Class: " + entry.getKey().getMethod().getDeclaringClass()); System.out.println("Method: " + entry.getKey().getMethod().getName()); System.out.println("Analysis:\n" + entry.getValue()); diff --git a/src/data/GlobalAnalysisData.java b/src/data/GlobalAnalysisData.java new file mode 100644 index 000000000..327c36f53 --- /dev/null +++ b/src/data/GlobalAnalysisData.java @@ -0,0 +1,29 @@ +package data; + +import es.EscapeStatus; +import ptg.*; +import soot.*; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class GlobalAnalysisData { + public static Map ptgs; + public static Map> summaries; + public static Map> stackOrders; + public static LinkedHashMap analysis; + public static List noBCIMethods; + + // If the methods have been processed interprocedurally + public static Set methodsProcessed; + public static Set methodsProcessing; + + public GlobalAnalysisData() { + analysis = new LinkedHashMap<>(); + ptgs = new ConcurrentHashMap<>(); + summaries = new ConcurrentHashMap<>(); + stackOrders = new ConcurrentHashMap<>(); + noBCIMethods = new ArrayList<>(); + methodsProcessed = new HashSet(); + methodsProcessing = new HashSet(); + } +} diff --git a/src/main/Main.java b/src/main/Main.java index 6f351ea59..95bb9012b 100644 --- a/src/main/Main.java +++ b/src/main/Main.java @@ -1,9 +1,9 @@ package main; import analyser.MethodsLinkingAnalyser; -import analyser.StackOrderAnalyser; import analyser.StaticAnalyser; import config.StoreEscape; +import data.GlobalAnalysisData; import es.*; import ptg.ObjectNode; import ptg.PointsToGraph; @@ -60,8 +60,10 @@ public static void main(String[] args) { return; } + GlobalAnalysisData globalAnlaysisData = new GlobalAnalysisData(); StaticAnalyser staticAnalyser = new StaticAnalyser(); CHATransform prepass = new CHATransform(); + MethodsLinkingAnalyser methodsLinkingAnalyser = new MethodsLinkingAnalyser(); PackManager.v().getPack("wjap").add(new Transform("wjap.pre", prepass)); PackManager.v().getPack("jtp").add(new Transform("jtp.sample", staticAnalyser)); @@ -90,7 +92,8 @@ public static void main(String[] args) { } } - Scene.v().setEntryPoints(entryPoints); + // Scene.v().setEntryPoints(entryPoints); + // System.out.println("All Packs" + PackManager.v().allPacks()); PackManager.v().runPacks(); long analysis_end = System.currentTimeMillis(); @@ -98,20 +101,19 @@ public static void main(String[] args) { System.out.println("Time Taken:"+(analysis_end-analysis_start)/1000F); System.out.println("BEFORE InterProcedural Linking"); - // printAllInfo(StaticAnalyser.ptgs, StaticAnalyser.summaries, StaticAnalyser.stackOrders, args[4]); + printAllInfo(GlobalAnalysisData.ptgs, GlobalAnalysisData.summaries, GlobalAnalysisData.stackOrders, args[4]); // // Problem - not processing methods // First, we add edges created due to callie function during method call analysis_start = System.currentTimeMillis(); // How to use spark here? - MethodsLinkingAnalyser methodsLinkingAnalyser = new MethodsLinkingAnalyser(); - PackManager.v().getPack("wjtp").add(new Transform("wjtp.ada", methodsLinkingAnalyser)); // StackOrderAnalyser stackOrderAnalyser = new StackOrderAnalyser(); // PackManager.v().getPack("jtp").add(new Transform("jtp.order", stackOrderAnalyser)); - Scene.v().setEntryPoints(entryPoints); - PackManager.v().runPacks(); + // Scene.v().setEntryPoints(entryPoints); + PackManager.v().getPack("wjtp").add(new Transform("wjtp.lfc", methodsLinkingAnalyser)); + PackManager.v().runPacks(); // Now we are going to find the stack ordering of the non escaping functions CreateStackOrdering(); @@ -122,38 +124,38 @@ public static void main(String[] args) { boolean useNewResolver = true; long res_start = System.currentTimeMillis(); System.out.println("BEFORE Resolver"); - printAllInfo(StaticAnalyser.ptgs, StaticAnalyser.summaries, StaticAnalyser.stackOrders, args[4]); + printAllInfo(GlobalAnalysisData.ptgs, GlobalAnalysisData.summaries, GlobalAnalysisData.stackOrders, args[4]); if(useNewResolver) { ReworkedResolver sr = new ReworkedResolver( - StaticAnalyser.summaries, - StaticAnalyser.ptgs, - StaticAnalyser.noBCIMethods); + GlobalAnalysisData.summaries, + GlobalAnalysisData.ptgs, + GlobalAnalysisData.noBCIMethods); long res_end = System.currentTimeMillis(); System.out.println("Resolution is done"); System.out.println("Time Taken in phase 1:"+(analysis_end-analysis_start)/1000F); System.out.println("Time Taken in phase 2:"+(res_end-res_start)/1000F); System.out.println("AFTER Resolver"); - printAllInfo(StaticAnalyser.ptgs, StaticAnalyser.summaries, StaticAnalyser.stackOrders, args[4]); - printResForJVM(sr.solvedSummaries, StaticAnalyser.stackOrders, args[2], args[4]); + printAllInfo(GlobalAnalysisData.ptgs, GlobalAnalysisData.summaries, GlobalAnalysisData.stackOrders, args[4]); + printResForJVM(sr.solvedSummaries, GlobalAnalysisData.stackOrders, args[2], args[4]); } else { SummaryResolver sr = new SummaryResolver(); - sr.resolve(staticAnalyser.summaries, staticAnalyser.ptgs); + sr.resolve(GlobalAnalysisData.summaries, GlobalAnalysisData.ptgs); long res_end = System.currentTimeMillis(); System.out.println("Resolution is done"); System.out.println("Time Taken:"+(res_end-res_start)/1000F); - // System.out.println(staticAnalyser.summaries.size()+ " "+staticAnalyser.ptgs.size()); + // System.out.println(GlobalAnalysisData.summaries.size()+ " "+GlobalAnalysisData.ptgs.size()); HashMap> resolved = (HashMap) kill(sr.solvedSummaries); - // printAllInfo(StaticAnalyser.ptgs, staticAnalyser.summaries, args[4]); + // printAllInfo(GlobalAnalysisData.ptgs, GlobalAnalysisData.summaries, args[4]); - // printAllInfo(StaticAnalyser.ptgs, resolved, args[4]); + // printAllInfo(GlobalAnalysisData.ptgs, resolved, args[4]); - // saveStats(sr.existingSummaries, resolved, args[4], staticAnalyser.ptgs); + // saveStats(sr.existingSummaries, resolved, args[4], GlobalAnalysisData.ptgs); // printResForJVM(sr.solvedSummaries, args[2], args[4]); } @@ -191,11 +193,11 @@ static void topologicalSortDfs( * Create Stack ordering for each ptg in the Static Analyser */ static void CreateStackOrdering() { - // We assumed that the PTGs exist in the StaticAnalyser + // We assumed that the PTGs exist in the GlobalAnalysisData System.out.println("PRIYAM - Starting topological sorting"); - for(SootMethod method : StaticAnalyser.ptgs.keySet()) { - PointsToGraph ptg = StaticAnalyser.ptgs.get(method); + for(SootMethod method : GlobalAnalysisData.ptgs.keySet()) { + PointsToGraph ptg = GlobalAnalysisData.ptgs.get(method); // TODO - First check if it is a DAG // TO ASK - Peform a check before or combine with the @@ -214,7 +216,7 @@ static void CreateStackOrdering() { } } - StaticAnalyser.stackOrders.put(method, topoOrder); + GlobalAnalysisData.stackOrders.put(method, topoOrder); } } diff --git a/tests/test24/Main.java b/tests/test24/Main.java index bd8185af7..88678ebb1 100644 --- a/tests/test24/Main.java +++ b/tests/test24/Main.java @@ -1,5 +1,6 @@ public class Main { public static void main(String[] args) { + foo(null, null); } static void foo(Node node1, Node node2) { @@ -8,23 +9,12 @@ static void foo(Node node1, Node node2) { Node C = new Node(); Node D = new Node(); Node E = new Node(); - // bar(A, B); - A.n = B; - - // if I make channges in staticAnalyser? - - Node x = A.n; - - // r10=[, ] - // Assumption 1 - // we do replacement of assignment - // statements after the whole pass - // How to consider for if else branch? - // For different branches? - - bar(x, C); + bar(A, B); + bar(A, C); bar(D, E); bar(node1, node2); + + // see next test28 } static void bar(Node n1, Node n2) { diff --git a/tests/test28/Main.java b/tests/test28/Main.java new file mode 100644 index 000000000..10ade0f0b --- /dev/null +++ b/tests/test28/Main.java @@ -0,0 +1,34 @@ +public class Main { + public static void main(String[] args) { + foo(null, null); + } + + static void foo(Node node1, Node node2) { + Node A = new Node(); + Node B = new Node(); + Node C = new Node(); + Node D = new Node(); + Node E = new Node(); + bar(A, B); + // A.n = B; + + // if I make channges in staticAnalyser? + + Node x = A.n; + + // r10=[, ] + // Assumption 1 + // we do replacement of assignment + // statements after the whole pass + // How to consider for if else branch? + // For different branches? + + bar(x, C); + bar(D, E); + bar(node1, node2); + } + + static void bar(Node n1, Node n2) { + n1.n = n2; + } +} diff --git a/tests/test28/Node.java b/tests/test28/Node.java new file mode 100644 index 000000000..391eba7af --- /dev/null +++ b/tests/test28/Node.java @@ -0,0 +1,4 @@ +public class Node { + public Node n; + public Node m; +}