Skip to content

Commit

Permalink
Adding a points to analysis plugin framework and a simple
Browse files Browse the repository at this point in the history
(local-flow-sensitive/field-sensitive only) points-to analysis.
Points-to analysis automatically runs after Atlas indexer if installed.
  • Loading branch information
benjholla committed Feb 6, 2016
1 parent c7769e5 commit 54c48b6
Show file tree
Hide file tree
Showing 19 changed files with 361 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CREDITS
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Ben Holland
Jon Mathews
Tom Deering
Empty file.
7 changes: 7 additions & 0 deletions com.ensoftcorp.open.pointsto/.classpath
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>
1 change: 1 addition & 0 deletions com.ensoftcorp.open.pointsto/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/bin/
28 changes: 28 additions & 0 deletions com.ensoftcorp.open.pointsto/.project
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>com.ensoftcorp.open.pointsto</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
11 changes: 11 additions & 0 deletions com.ensoftcorp.open.pointsto/.settings/org.eclipse.jdt.core.prefs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
14 changes: 14 additions & 0 deletions com.ensoftcorp.open.pointsto/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Points-to Toolbox
Bundle-SymbolicName: com.ensoftcorp.open.pointsto;singleton:=true
Bundle-Version: 2.7.1.qualifier
Bundle-Vendor: EnSoft Corp.
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle:
org.eclipse.debug.ui,
com.ensoftcorp.open.toolbox.commons;bundle-version="2.5.2";visibility:=reexport
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: .
Bundle-Activator: com.ensoftcorp.open.Activator
Export-Package: com.ensoftcorp.open.pointsto.common
8 changes: 8 additions & 0 deletions com.ensoftcorp.open.pointsto/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
source.. = src/
output.. = bin/
bin.includes = .,\
plugin.xml,\
META-INF/,\
icons/
jars.compile.order = .

Binary file added com.ensoftcorp.open.pointsto/icons/main-icon.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions com.ensoftcorp.open.pointsto/plugin.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>

<extension
point="com.ensoftcorp.atlas.core.ToolboxExtensionPoint">
<indexer
class="com.ensoftcorp.open.pointsto.map.CodemapStage">
</indexer>
</extension>

</plugin>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.ensoftcorp.open;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

/**
* The activator class controls the plug-in life cycle
* @author Ben Holland
*/
public class Activator extends AbstractUIPlugin {

// The plug-in ID
public static final String PLUGIN_ID = "Points-to Toolbox"; //$NON-NLS-1$

// The shared instance
private static Activator plugin;

/**
* The constructor
*/
public Activator() {}

/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
}

/*
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {
plugin = null;
super.stop(context);
}

/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {
return plugin;
}

/**
* Returns an image descriptor for the image file at the given
* plug-in relative path
*
* @param path the path
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.ensoftcorp.open.pointsto.analysis;

import java.util.HashSet;
import java.util.LinkedList;

import com.ensoftcorp.atlas.core.db.graph.GraphElement;
import com.ensoftcorp.atlas.core.db.set.AtlasSet;
import com.ensoftcorp.atlas.core.query.Q;
import com.ensoftcorp.atlas.core.script.Common;
import com.ensoftcorp.atlas.core.xcsg.XCSG;
import com.ensoftcorp.open.pointsto.utilities.PointsToAnalysis;

public class JimplePointsTo extends PointsTo {

private int id = 0;

// a set of assignment relationships
private Q dataFlowEdges = Common.universe().edgesTaggedWithAny(XCSG.LocalDataFlow, XCSG.InterproceduralDataFlow);

// a worklist of nodes to propagate information from
private LinkedList<GraphElement> worklist = new LinkedList<GraphElement>();

@Override
protected void runAnalysis() {
Q instantiations = Common.universe().nodesTaggedWithAny(XCSG.Instantiation); // new allocations
AtlasSet<GraphElement> instantiationNodes = instantiations.eval().nodes();

// create a unique id for each allocation site and add
// the allocation site to the worklist to propagate
// information forward from
for(GraphElement instantiation : instantiationNodes){
HashSet<Integer> pointsToIds = PointsToAnalysis.getPointsToSet(instantiation);
pointsToIds.add(id++);
worklist.add(instantiation);
}

// keep propagating allocation ids forward along assignments
// until there is nothing more to propagate
while(!worklist.isEmpty()){
GraphElement from = worklist.removeFirst();
propagatePointsTo(from);
}
}

/**
* Propagates points-to information forward from the given node
* to all nodes that this node is directly assigned to. Each node
* that receives new information is added back to the worklist
* @param from
*/
private void propagatePointsTo(GraphElement from){
AtlasSet<GraphElement> toNodes = dataFlowEdges.successors(Common.toQ(from)).eval().nodes();
for(GraphElement to : toNodes){
HashSet<Integer> fromPointsToSet = PointsToAnalysis.getPointsToSet(from);
HashSet<Integer> toPointsToSet = PointsToAnalysis.getPointsToSet(to);
// if the to set learned something from the from set,
// then add the to node to the worklist because it may
// have something to teach its children
if(toPointsToSet.addAll(fromPointsToSet)){
worklist.add(to);
}
}
}

}

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.ensoftcorp.open.pointsto.analysis;

import com.ensoftcorp.atlas.core.log.Log;

public abstract class PointsTo {

private boolean hasRun = false;

/**
* Runs the points to analysis (if it hasn't been run already)
* and returns the time in milliseconds to complete the analysis
* @return
*/
public long run(){
if(hasRun){
return 0;
} else {
long start = System.currentTimeMillis();
Log.info("Starting " + getClass().getSimpleName() + " Points-to Analysis");
runAnalysis();
Log.info("Finished " + getClass().getSimpleName() + " Points-to Analysis");
hasRun = true;
return start - System.currentTimeMillis();
}
}

/**
* Runs the points to analysis
*/
protected abstract void runAnalysis();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ensoftcorp.open.pointsto.common;

public class Constants {

public static final String POINTS_TO_SET = "points-to";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package com.ensoftcorp.open.pointsto.common;

import java.io.IOException;

import com.ensoftcorp.atlas.core.db.graph.GraphElement;
import com.ensoftcorp.atlas.core.db.set.AtlasSet;
import com.ensoftcorp.atlas.core.script.Common;
import com.ensoftcorp.atlas.core.xcsg.XCSG;
import com.ensoftcorp.open.pointsto.utilities.PointsToAnalysis;
import com.ensoftcorp.open.toolbox.commons.FormattedSourceCorrespondence;

public class PointsToResults {

/**
* Computes the average size of each points to set
* @return
*/
public static double getAverageSizeOfPointsToSets(){
AtlasSet<GraphElement> allNodesWithPointsToSets = Common.universe().selectNode(Constants.POINTS_TO_SET).eval().nodes();
double sum = 0;
for(GraphElement nodeWithPointsToSet : allNodesWithPointsToSets){
sum += PointsToAnalysis.getPointsToSet(nodeWithPointsToSet).size();
}
return sum/allNodesWithPointsToSets.size();
}

/**
* Returns an entry in the points to table as a string
* @param ge
* @return
* @throws IOException
*/
public static String getPointsToTableEntry(GraphElement ge) throws IOException {
FormattedSourceCorrespondence fsc = FormattedSourceCorrespondence.getSourceCorrespondent(ge);
String file = fsc.getRelativeFile();
String line = fsc.getLineNumbers();
String variable = ge.getAttr(XCSG.name).toString();
String pointsTo = PointsToAnalysis.getPointsToSet(ge).toString();
return file + "," + line + "," + variable + "," + pointsTo;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.ensoftcorp.open.pointsto.map;

import org.eclipse.core.runtime.IProgressMonitor;

import com.ensoftcorp.atlas.core.indexing.providers.ToolboxIndexingStage;
import com.ensoftcorp.atlas.core.log.Log;
import com.ensoftcorp.open.pointsto.analysis.JimplePointsTo;

public class CodemapStage implements ToolboxIndexingStage {

@Override
public String displayName() {
return "Points-to Analysis";
}

@Override
public void performIndexing(IProgressMonitor monitor) {
try {
JimplePointsTo jimplePointsTo = new JimplePointsTo();
jimplePointsTo.run();
} catch (Exception e) {
Log.error("Error performing points-to analysis", e);
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ensoftcorp.open.pointsto.ui;

public class PointsToPreferences {

// TODO: implement

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.ensoftcorp.open.pointsto.utilities;

public class GraphEnhancements {

// TODO: implement enhancements to original graph based on points-to results

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.ensoftcorp.open.pointsto.utilities;

import java.util.HashSet;

import com.ensoftcorp.atlas.core.db.graph.GraphElement;
import com.ensoftcorp.open.pointsto.common.Constants;

public class PointsToAnalysis {

/**
* Gets or creates the points to set for a graph element.
* Returns a reference to the points to set so that updates to the
* set will also update the set on the graph element.
* @param ge
* @return
*/
@SuppressWarnings("unchecked")
public static HashSet<Integer> getPointsToSet(GraphElement ge){
if(ge.hasAttr(Constants.POINTS_TO_SET)){
return (HashSet<Integer>) ge.getAttr(Constants.POINTS_TO_SET);
} else {
HashSet<Integer> pointsToIds = new HashSet<Integer>();
ge.putAttr(Constants.POINTS_TO_SET, pointsToIds);
return pointsToIds;
}
}

}

0 comments on commit 54c48b6

Please sign in to comment.