From 29127d471f86e029a84ac5eac91be0cf18e27de3 Mon Sep 17 00:00:00 2001 From: Matheus Barbosa Date: Wed, 11 Aug 2021 17:46:35 -0300 Subject: [PATCH] feat(#31): run only call graph --- .../InterproceduralOverrideAssignment.java | 76 +++++++++++-------- ...duralOverridingAssignmentAnalysisTest.java | 25 +++--- 2 files changed, 56 insertions(+), 45 deletions(-) diff --git a/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java b/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java index 6a12ea02..d1d7770f 100644 --- a/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java +++ b/src/main/java/br/unb/cic/analysis/ioa/InterproceduralOverrideAssignment.java @@ -28,7 +28,6 @@ public class InterproceduralOverrideAssignment extends SceneTransformer implemen private final AbstractMergeConflictDefinition definition; private final FlowSet left; private final FlowSet right; - private FlowSet abstraction; private final Logger logger; @@ -38,7 +37,6 @@ public InterproceduralOverrideAssignment(AbstractMergeConflictDefinition definit this.conflicts = new HashSet<>(); this.left = new ArraySparseSet<>(); this.right = new ArraySparseSet<>(); - this.abstraction = new ArraySparseSet<>(); this.traversedMethods = new ArrayList<>(); this.pointsToAnalysis = Scene.v().getPointsToAnalysis(); @@ -73,11 +71,11 @@ public void configureEntryPoints() { protected void internalTransform(String s, Map map) { List methods = Scene.v().getEntryPoints(); - methods.forEach(sootMethod -> traverse(this.abstraction, sootMethod, Statement.Type.IN_BETWEEN)); + methods.forEach(sootMethod -> traverse(new ArraySparseSet<>(), sootMethod, Statement.Type.IN_BETWEEN)); logger.log(Level.INFO, () -> String.format("%s", "CONFLICTS: " + getConflicts())); - /*left.forEach(dataFlowAbstraction -> { + /* left.forEach(dataFlowAbstraction -> { String leftStmt = String.format("%s", "LEFT: " + dataFlowAbstraction.getStmt()); logger.log(Level.INFO, leftStmt); }); @@ -85,7 +83,7 @@ protected void internalTransform(String s, Map map) { right.forEach(dataFlowAbstraction -> { String rightStmt = String.format("%s", "RIGHT: " + dataFlowAbstraction.getStmt()); logger.log(Level.INFO, rightStmt); - });*/ + }); */ } /** @@ -95,11 +93,12 @@ protected void internalTransform(String s, Map map) { * @param flowChangeTag This parameter identifies whether the unit under analysis is in the flow of any statement already marked. * Initially it receives the value IN_BETWEEN but changes if the call to the current method (sootMethod) has been marked as SOURCE or SINK. * The remaining statements of the current method that have no markup will be marked according to the flowChangeTag. + * @return the result of applying the analysis considering the income abstraction (in) and the sootMethod */ private FlowSet traverse(FlowSet in, SootMethod sootMethod, Statement.Type flowChangeTag) { //System.out.println(sootMethod); if (this.traversedMethods.contains(sootMethod) || sootMethod.isPhantom()) { - return null; + return in; } this.traversedMethods.add(sootMethod); @@ -107,15 +106,13 @@ private FlowSet traverse(FlowSet in, S Body body = retrieveActiveBodySafely(sootMethod); if (body != null) { - - body.getUnits().forEach(unit -> { - + for (Unit unit : body.getUnits()) { if (isTagged(flowChangeTag, unit)) { - runAnalysisWithTaggedUnit(in, sootMethod, flowChangeTag, unit); + in = runAnalysisWithTaggedUnit(in, sootMethod, flowChangeTag, unit); } else { - runAnalysisWithBaseUnit(in, sootMethod, flowChangeTag, unit); + in = runAnalysisWithBaseUnit(in, sootMethod, flowChangeTag, unit); } - }); + } } this.traversedMethods.remove(sootMethod); @@ -136,8 +133,8 @@ private FlowSet runAnalysisWithTaggedUnit(FlowSet runAnalysisWithBaseUnit(FlowSet in, SootMethod sootMethod, - Statement.Type flowChangeTag, Unit unit) { - return runAnalysis(in, sootMethod, flowChangeTag, unit, false); + Statement.Type flowChangeTag, Unit unit) { + return runAnalysis(in, sootMethod, flowChangeTag, unit, false); } /** @@ -163,14 +160,16 @@ private FlowSet runAnalysis(FlowSet in AssignStmt assignStmt = (AssignStmt) unit; if (assignStmt.containsInvokeExpr()) { - return executeCallGraph(in.clone(), flowChangeTag, unit); + return executeCallGraph(in, flowChangeTag, unit); } if (tagged) { Statement stmt = getStatementAssociatedWithUnit(sootMethod, unit, flowChangeTag); // logger.log(Level.INFO, () -> String.format("%s", "stmt: " + stmt.toString())); + separeteAbstraction(in); gen(in, stmt); } else { + separeteAbstraction(in); kill(in, unit); } @@ -198,35 +197,39 @@ In this case, this condition will be executed for the call to the foo() method a return in; } + private void separeteAbstraction(FlowSet in) { + in.forEach(item -> { + if (isLefAndRightStatement(item.getStmt())) { + right.add(item); + left.add(item); + } else if (isLeftStatement(item.getStmt())) { + left.add(item); + } else if (isRightStatement(item.getStmt())) { + right.add(item); + } + }); + } + private FlowSet executeCallGraph(FlowSet in, Statement.Type flowChangeTag, Unit unit) { CallGraph callGraph = Scene.v().getCallGraph(); Iterator edges = callGraph.edgesOutOf(unit); - List> flowSetList = new ArrayList>(); - FlowSet flowSetUnion = new ArraySparseSet<>(); + List> flowSetList = new ArrayList>(); while (edges.hasNext()) { Edge e = edges.next(); - Statement stmt = getStatementAssociatedWithUnit(e.getTgt().method(), unit, flowChangeTag); + SootMethod method = e.getTgt().method(); + Statement stmt = getStatementAssociatedWithUnit(method, unit, flowChangeTag); - FlowSet traverseResult = traverse(in.clone(), e.getTgt().method(), stmt.getType()); + FlowSet traverseResult = traverse(in.clone(), method, stmt.getType()); flowSetList.add(traverseResult); - /* System.out.println("------traverseResult--------"); - System.out.println("METHOD: " + e.getTgt().method()); - traverseResult.forEach(item -> System.out.println(item.getStmt())); - System.out.println("------traverseResult--------");*/ } + FlowSet flowSetUnion = new ArraySparseSet<>(); flowSetList.forEach(flowSet -> flowSetUnion.union(flowSet)); - System.out.println("--------------flowSetUnion--------------"); - flowSetUnion.forEach(item -> System.out.println(item.getStmt())); - System.out.println("--------------in--------------"); - in.forEach(item -> System.out.println(item.getStmt())); - return flowSetUnion; - } private boolean isTagged(Statement.Type flowChangeTag, Unit unit) { @@ -295,7 +298,8 @@ private void addConflict(Statement left, Statement right) { private void kill(FlowSet in, Unit unit) { unit.getDefBoxes().forEach(valueBox -> removeAll(valueBox, in)); - //unit.getDefBoxes().forEach(valueBox -> removeAll(valueBox, right)); + unit.getDefBoxes().forEach(valueBox -> removeAll(valueBox, left)); + unit.getDefBoxes().forEach(valueBox -> removeAll(valueBox, right)); } private void removeAll(ValueBox valueBox, FlowSet rightOrLeftList) { @@ -340,7 +344,8 @@ private String getArrayRefName(ArrayRef arrayRef) { } private Statement getStatementAssociatedWithUnit(SootMethod sootMethod, Unit u, Statement.Type flowChangeTag) { - if (isLeftAndRightUnit(u) || isInLeftAndRightStatementFlow(flowChangeTag)) { + if (isLeftAndRightUnit(u) || isInLeftAndRightStatementFlow(flowChangeTag) || isBothUnitOrBothStatementFlow(u, + flowChangeTag)) { return createStatement(sootMethod, u, Statement.Type.BOTH); } else if (isLeftUnit(u)) { return findLeftStatement(u); @@ -354,6 +359,15 @@ private Statement getStatementAssociatedWithUnit(SootMethod sootMethod, Unit u, return createStatement(sootMethod, u, Statement.Type.IN_BETWEEN); } + private boolean isBothUnitOrBothStatementFlow(Unit u, Statement.Type flowChangeTag) { + if (isRightUnit(u) && isInLeftStatementFlow(flowChangeTag)) { + return true; + } else if (isLeftUnit(u) && isInRightStatementFlow(flowChangeTag)) { + return true; + } + return false; + } + private boolean isLeftUnit(Unit u) { return definition.getSourceStatements().stream().map(Statement::getUnit).collect(Collectors.toList()).contains(u); } diff --git a/src/test/java/br/unb/cic/analysis/ioa/InterproceduralOverridingAssignmentAnalysisTest.java b/src/test/java/br/unb/cic/analysis/ioa/InterproceduralOverridingAssignmentAnalysisTest.java index 71f0c148..7184776a 100644 --- a/src/test/java/br/unb/cic/analysis/ioa/InterproceduralOverridingAssignmentAnalysisTest.java +++ b/src/test/java/br/unb/cic/analysis/ioa/InterproceduralOverridingAssignmentAnalysisTest.java @@ -4,7 +4,6 @@ import br.unc.cic.analysis.test.DefinitionFactory; import br.unc.cic.analysis.test.MarkingClass; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; import soot.G; import soot.PackManager; @@ -53,20 +52,21 @@ private List configurePackages() { } private List getIncludeList() { - List stringList = new ArrayList(Arrays.asList("java.lang.*", "java.util.*")); //java.util.HashMap + // "java.lang.*" + List stringList = new ArrayList(Arrays.asList("java.util.*")); //java.util.HashMap return stringList; } private static void enableSparkCallGraph() { //Enable Spark HashMap opt = new HashMap(); - opt.put("propagator", "worklist"); // - opt.put("simple-edges-bidirectional", "false"); // + // opt.put("propagator", "worklist"); + // opt.put("simple-edges-bidirectional", "false"); opt.put("on-fly-cg", "true"); - opt.put("set-impl", "double"); // - opt.put("double-set-old", "hybrid"); // - opt.put("double-set-new", "hybrid"); // - opt.put("pre_jimplify", "true"); // + // opt.put("set-impl", "double"); + // opt.put("double-set-old", "hybrid"); + // opt.put("double-set-new", "hybrid"); + // opt.put("pre_jimplify", "true"); SparkTransformer.v().transform("", opt); } @@ -144,7 +144,6 @@ public void containsInvokeExp() { Assert.assertEquals(1, analysis.getConflicts().size()); } - @Ignore @Test public void chainedMethodCallsConflict() { String sampleClassPath = "br.unb.cic.analysis.samples.ioa.ChainedMethodCallsConflictSample"; @@ -152,7 +151,7 @@ public void chainedMethodCallsConflict() { .definition(sampleClassPath, new int[]{13}, new int[]{12}); InterproceduralOverrideAssignment analysis = new InterproceduralOverrideAssignment(definition); configureTest(analysis); - Assert.assertEquals(550, analysis.getConflicts().size()); + Assert.assertEquals(854, analysis.getConflicts().size()); } @Test @@ -248,7 +247,6 @@ public void localVariablesWithParameterNotConflict() { Assert.assertEquals(0, analysis.getConflicts().size()); } - @Ignore @Test public void additionToArrayConflict() { String sampleClassPath = "br.unb.cic.analysis.samples.ioa.AdditionToArrayConflictSample"; @@ -256,10 +254,9 @@ public void additionToArrayConflict() { .definition(sampleClassPath, new int[]{11}, new int[]{12}); InterproceduralOverrideAssignment analysis = new InterproceduralOverrideAssignment(definition); configureTest(analysis); - Assert.assertEquals(57, analysis.getConflicts().size()); + Assert.assertEquals(58, analysis.getConflicts().size()); } - @Ignore @Test public void hashmapConflict() { String sampleClassPath = "br.unb.cic.analysis.samples.ioa.HashmapConflictSample"; @@ -267,7 +264,7 @@ public void hashmapConflict() { .definition(sampleClassPath, new int[]{11}, new int[]{12}); InterproceduralOverrideAssignment analysis = new InterproceduralOverrideAssignment(definition); configureTest(analysis); - Assert.assertEquals(511, analysis.getConflicts().size()); + Assert.assertEquals(510, analysis.getConflicts().size()); }