Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package soot.jimple.toolkits.infoflow;
/*-
* #%L
* Soot - a J*va Optimization Framework
* %%
* Copyright (C) 1997 - 2018 Raja Vallée-Rai and others
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 2.1 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import soot.Body;
import soot.EquivalentValue;
import soot.RefLikeType;
import soot.Scene;
import soot.SootClass;
import soot.SootField;
import soot.SootFieldRef;
import soot.SootMethod;
import soot.Value;
import soot.jimple.DefinitionStmt;
import soot.jimple.FieldRef;
import soot.jimple.InstanceFieldRef;
import soot.jimple.InstanceInvokeExpr;
import soot.jimple.InvokeExpr;
import soot.jimple.ParameterRef;
import soot.jimple.Ref;
import soot.jimple.StaticFieldRef;
import soot.jimple.Stmt;
import soot.jimple.ThisRef;
import soot.jimple.toolkits.callgraph.Edge;
import soot.jimple.toolkits.callgraph.ReachableMethods;
import soot.toolkits.graph.DirectedGraph;
import soot.toolkits.graph.ExceptionalUnitGraph;
import soot.toolkits.graph.MutableDirectedGraph;
import soot.toolkits.graph.UnitGraph;
import soot.toolkits.scalar.Pair;
// ClassLocalObjectsAnalysis written by Richard L. Halpert, 2007-02-23
// Finds objects that are local to the given scope.
// NOTE THAT THIS ANALYSIS'S RESULTS DO NOT APPLY TO SUBCLASSES OF THE GIVEN CLASS
public class ClassLocalObjectsAnalysis {
private static final Logger logger = LoggerFactory.getLogger(ClassLocalObjectsAnalysis.class);
boolean printdfgs;
LocalObjectsAnalysis loa;
InfoFlowAnalysis dfa;
InfoFlowAnalysis primitiveDfa;
UseFinder uf;
SootClass sootClass;
Map methodToMethodLocalObjectsAnalysis;
Map methodToContext;
List allMethods;
// methods that are called at least once from outside of this class (ie need to be public, protected, or package-private)
List externalMethods;
// methods that are only ever called by other methods in this class (ie could be marked private)
List internalMethods;
// methods that should be used as starting points when determining if a value in a method called from this class is local
// or shared
// for thread-local objects, this would contain just the run method. For structure-local, it should contain all external
// methods
List entryMethods;
List allFields;
List externalFields;
List internalFields;
ArrayList localFields;
ArrayList sharedFields;
ArrayList localInnerFields;
ArrayList sharedInnerFields;
public ClassLocalObjectsAnalysis(LocalObjectsAnalysis loa, InfoFlowAnalysis dfa, UseFinder uf, SootClass sootClass) {
this(loa, dfa, null, uf, sootClass, null);
}
public ClassLocalObjectsAnalysis(LocalObjectsAnalysis loa, InfoFlowAnalysis dfa, InfoFlowAnalysis primitiveDfa,
UseFinder uf, SootClass sootClass, List entryMethods) {
printdfgs = dfa.printDebug();
this.loa = loa;
this.dfa = dfa;
this.primitiveDfa = primitiveDfa;
this.uf = uf;
this.sootClass = sootClass;
this.methodToMethodLocalObjectsAnalysis = new HashMap();
this.methodToContext = null;
this.allMethods = null;
this.externalMethods = null;
this.internalMethods = null;
this.entryMethods = entryMethods;
this.allFields = null;
this.externalFields = null;
this.internalFields = null;
this.localFields = null;
this.sharedFields = null;
this.localInnerFields = null;
this.sharedInnerFields = null;
if (true) // verbose)
{
logger.debug("[local-objects] Analyzing local objects for " + sootClass);
logger.debug("[local-objects] preparing class " + new Date());
}
prepare();
if (true) // verbose)
{
logger.debug("[local-objects] analyzing class " + new Date());
}
doAnalysis();
if (true) // verbose)
{
logger.debug("[local-objects] propagating over call graph " + new Date());
}
propagate();
if (true) {
logger.debug("[local-objects] finished at " + new Date());
logger.debug("[local-objects] (#analyzed/#encountered): " + SmartMethodInfoFlowAnalysis.counter + "/"
+ ClassInfoFlowAnalysis.methodCount);
}
}
private void prepare() {
// Get list of all methods
allMethods = getAllReachableMethods(sootClass);
// Get list of external methods
externalMethods = uf.getExtMethods(sootClass);
SootClass superclass = sootClass;
if (superclass.hasSuperclass()) {
superclass = superclass.getSuperclass();
}
while (superclass.hasSuperclass()) {
if (superclass.isApplicationClass()) {
externalMethods.addAll(uf.getExtMethods(superclass));
}
superclass = superclass.getSuperclass();
}
// Get list of internal methods
internalMethods = new ArrayList();
for (SootMethod method : allMethods) {
if (!externalMethods.contains(method)) {
internalMethods.add(method);
}
}
// Get list of all fields
allFields = getAllFields(sootClass);
// Get list of external fields
externalFields = uf.getExtFields(sootClass);
superclass = sootClass;
if (superclass.hasSuperclass()) {
superclass = superclass.getSuperclass();
}
while (superclass.hasSuperclass()) {
if (superclass.isApplicationClass()) {
externalFields.addAll(uf.getExtFields(superclass));
}
superclass = superclass.getSuperclass();
}
// Get list of internal fields
internalFields = new ArrayList();
for (SootField field : allFields) {
if (!externalFields.contains(field)) {
internalFields.add(field);
}
}
}
// Returns a list of reachable methods in class sc and its superclasses
public static List getAllReachableMethods(SootClass sc) {
ReachableMethods rm = Scene.v().getReachableMethods();
// Get list of reachable methods declared in this class
List allMethods = new ArrayList();
Iterator methodsIt = sc.methodIterator();
while (methodsIt.hasNext()) {
SootMethod method = (SootMethod) methodsIt.next();
if (rm.contains(method)) {
allMethods.add(method);
}
}
// Add reachable methods declared in superclasses
SootClass superclass = sc;
if (superclass.hasSuperclass()) {
superclass = superclass.getSuperclass();
}
while (superclass.hasSuperclass()) // we don't want to process Object
{
Iterator scMethodsIt = superclass.methodIterator();
while (scMethodsIt.hasNext()) {
SootMethod scMethod = (SootMethod) scMethodsIt.next();
if (rm.contains(scMethod)) {
allMethods.add(scMethod);
}
}
superclass = superclass.getSuperclass();
}
return allMethods;
}
// Returns a list of fields in class sc and its superclasses
public static List getAllFields(SootClass sc) {
// Get list of reachable methods declared in this class
// Also get list of fields declared in this class
List allFields = new ArrayList();
for (SootField field : sc.getFields()) {
allFields.add(field);
}
// Add reachable methods and fields declared in superclasses
SootClass superclass = sc;
if (superclass.hasSuperclass()) {
superclass = superclass.getSuperclass();
}
while (superclass.hasSuperclass()) // we don't want to process Object
{
for (SootField scField : superclass.getFields()) {
allFields.add(scField);
}
superclass = superclass.getSuperclass();
}
return allFields;
}
private void doAnalysis() {
// Combine the DFA results for each of this class's methods, using safe
// approximations for which parameters, fields, and globals are shared
// or local.
// Separate fields into shared and local. Initially fields are known to be
// shared if they have any external accesses, or if they're static.
// Methods are iterated over, moving fields to shared if shared data flows to them.
// This is repeated until no fields move for a complete iteration.
// Populate localFields and sharedFields with fields of this class
localFields = new ArrayList();
sharedFields = new ArrayList();
Iterator fieldsIt = allFields.iterator();
while (fieldsIt.hasNext()) {
SootField field = fieldsIt.next();
if (fieldIsInitiallyLocal(field)) {
localFields.add(field);
} else {
sharedFields.add(field);
}
}
// Add inner fields to localFields and sharedFields, if present
localInnerFields = new ArrayList();
sharedInnerFields = new ArrayList();
Iterator methodsIt = allMethods.iterator();
while (methodsIt.hasNext()) {
SootMethod method = methodsIt.next();
// Get data flow summary
MutableDirectedGraph dataFlowSummary;
if (primitiveDfa != null) {
dataFlowSummary = primitiveDfa.getMethodInfoFlowSummary(method);
if (printdfgs && method.getDeclaringClass().isApplicationClass()) {
logger.debug("Attempting to print graphs (will succeed only if ./dfg/ is a valid path)");
DirectedGraph primitiveGraph = primitiveDfa.getMethodInfoFlowAnalysis(method).getMethodAbbreviatedInfoFlowGraph();
InfoFlowAnalysis.printGraphToDotFile(
"dfg/" + method.getDeclaringClass().getShortName() + "_" + method.getName() + "_primitive", primitiveGraph,
method.getName() + "_primitive", false);
DirectedGraph nonPrimitiveGraph = dfa.getMethodInfoFlowAnalysis(method).getMethodAbbreviatedInfoFlowGraph();
InfoFlowAnalysis.printGraphToDotFile("dfg/" + method.getDeclaringClass().getShortName() + "_" + method.getName(),
nonPrimitiveGraph, method.getName(), false);
}
} else {
dataFlowSummary = dfa.getMethodInfoFlowSummary(method);
if (printdfgs && method.getDeclaringClass().isApplicationClass()) {
logger.debug("Attempting to print graph (will succeed only if ./dfg/ is a valid path)");
DirectedGraph nonPrimitiveGraph = dfa.getMethodInfoFlowAnalysis(method).getMethodAbbreviatedInfoFlowGraph();
InfoFlowAnalysis.printGraphToDotFile("dfg/" + method.getDeclaringClass().getShortName() + "_" + method.getName(),
nonPrimitiveGraph, method.getName(), false);
}
}
// Iterate through nodes
Iterator