001: package dk.brics.paddle;
002:
003: import java.util.Collection;
004: import java.util.HashMap;
005: import java.util.Iterator;
006: import java.util.Map;
007:
008: import soot.EntryPoints;
009: import soot.Local;
010: import soot.PointsToSet;
011: import soot.Scene;
012: import soot.SootClass;
013: import soot.SootField;
014: import soot.SootMethod;
015: import soot.Value;
016: import soot.ValueBox;
017: import soot.jimple.JimpleBody;
018: import soot.jimple.Stmt;
019: import soot.jimple.paddle.PaddleTransformer;
020: import soot.jimple.spark.SparkTransformer;
021: import soot.options.PaddleOptions;
022: import soot.tagkit.LineNumberTag;
023:
024: public class PointsToAnalysis {
025:
026: // Make sure we get line numbers and whole program analysis
027: static {
028: soot.options.Options.v().set_keep_line_number(true);
029: soot.options.Options.v().set_whole_program(true);
030: soot.options.Options.v().setPhaseOption("cg", "verbose:true");
031: }
032:
033: private static SootClass loadClass(String name, boolean main) {
034: SootClass c = Scene.v().loadClassAndSupport(name);
035: c.setApplicationClass();
036: if (main)
037: Scene.v().setMainClass(c);
038: return c;
039: }
040:
041: public static void main(String[] args) {
042: loadClass("Item", false);
043: loadClass("Container", false);
044: SootClass c = loadClass(args[1], true);
045:
046: soot.Scene.v().loadNecessaryClasses();
047: soot.Scene.v().setEntryPoints(EntryPoints.v().all());
048:
049: if (args[0].equals("paddle"))
050: setPaddlePointsToAnalysis();
051: else if (args[0].equals("spark"))
052: setSparkPointsToAnalysis();
053:
054: SootField f = getField("Container", "item");
055: Map/*<Local>*/ls = getLocals(c, args[2], "Container");
056:
057: printLocalIntersects(ls);
058: printFieldIntersects(ls, f);
059: }
060:
061: static void setSparkPointsToAnalysis() {
062: System.out.println("[spark] Starting analysis ...");
063:
064: HashMap opt = new HashMap();
065: opt.put("enabled", "true");
066: opt.put("verbose", "true");
067: opt.put("ignore-types", "false");
068: opt.put("force-gc", "false");
069: opt.put("pre-jimplify", "false");
070: opt.put("vta", "false");
071: opt.put("rta", "false");
072: opt.put("field-based", "false");
073: opt.put("types-for-sites", "false");
074: opt.put("merge-stringbuffer", "true");
075: opt.put("string-constants", "false");
076: opt.put("simulate-natives", "true");
077: opt.put("simple-edges-bidirectional", "false");
078: opt.put("on-fly-cg", "true");
079: opt.put("simplify-offline", "false");
080: opt.put("simplify-sccs", "false");
081: opt.put("ignore-types-for-sccs", "false");
082: opt.put("propagator", "worklist");
083: opt.put("set-impl", "double");
084: opt.put("double-set-old", "hybrid");
085: opt.put("double-set-new", "hybrid");
086: opt.put("dump-html", "false");
087: opt.put("dump-pag", "false");
088: opt.put("dump-solution", "false");
089: opt.put("topo-sort", "false");
090: opt.put("dump-types", "true");
091: opt.put("class-method-var", "true");
092: opt.put("dump-answer", "false");
093: opt.put("add-tags", "false");
094: opt.put("set-mass", "false");
095:
096: SparkTransformer.v().transform("", opt);
097:
098: System.out.println("[spark] Done!");
099: }
100:
101: private static void setPaddlePointsToAnalysis() {
102: System.out.println("[paddle] Starting analysis ...");
103:
104: System.err.println("Soot version string: "
105: + soot.Main.v().versionString);
106:
107: HashMap opt = new HashMap();
108: opt.put("enabled", "true");
109: opt.put("verbose", "true");
110: opt.put("bdd", "true");
111: opt.put("backend", "buddy");
112: opt.put("context", "kcfa");
113: opt.put("k", "2");
114: // opt.put("context-heap","true");
115: opt.put("propagator", "auto");
116: opt.put("conf", "ofcg");
117: opt.put("order", "32");
118: opt.put("q", "auto");
119: opt.put("set-impl", "double");
120: opt.put("double-set-old", "hybrid");
121: opt.put("double-set-new", "hybrid");
122: opt.put("pre-jimplify", "false");
123:
124: PaddleTransformer pt = new PaddleTransformer();
125: PaddleOptions paddle_opt = new PaddleOptions(opt);
126: pt.setup(paddle_opt);
127: pt.solve(paddle_opt);
128: soot.jimple.paddle.Results.v().makeStandardSootResults();
129:
130: System.out.println("[paddle] Done!");
131: }
132:
133: private static int getLineNumber(Stmt s) {
134: Iterator ti = s.getTags().iterator();
135: while (ti.hasNext()) {
136: Object o = ti.next();
137: if (o instanceof LineNumberTag)
138: return Integer.parseInt(o.toString());
139: }
140: return -1;
141: }
142:
143: private static SootField getField(String classname, String fieldname) {
144: Collection app = Scene.v().getApplicationClasses();
145: Iterator ci = app.iterator();
146: while (ci.hasNext()) {
147: SootClass sc = (SootClass) ci.next();
148: if (sc.getName().equals(classname))
149: return sc.getFieldByName(fieldname);
150: }
151: throw new RuntimeException("Field " + fieldname
152: + " was not found in class " + classname);
153: }
154:
155: private static Map/*<Integer,Local>*/getLocals(SootClass sc,
156: String methodname, String typename) {
157: Map res = new HashMap();
158: Iterator mi = sc.getMethods().iterator();
159: while (mi.hasNext()) {
160: SootMethod sm = (SootMethod) mi.next();
161: System.err.println(sm.getName());
162: if (true && sm.getName().equals(methodname)
163: && sm.isConcrete()) {
164: JimpleBody jb = (JimpleBody) sm.retrieveActiveBody();
165: Iterator ui = jb.getUnits().iterator();
166: while (ui.hasNext()) {
167: Stmt s = (Stmt) ui.next();
168: int line = getLineNumber(s);
169: // find definitions
170: Iterator bi = s.getDefBoxes().iterator();
171: while (bi.hasNext()) {
172: Object o = bi.next();
173: if (o instanceof ValueBox) {
174: Value v = ((ValueBox) o).getValue();
175: if (v.getType().toString().equals(typename)
176: && v instanceof Local)
177: res.put(new Integer(line), v);
178: }
179: }
180: }
181: }
182: }
183:
184: return res;
185: }
186:
187: private static void printLocalIntersects(Map/*<Integer,Local>*/ls) {
188: soot.PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
189: Iterator i1 = ls.entrySet().iterator();
190: while (i1.hasNext()) {
191: Map.Entry e1 = (Map.Entry) i1.next();
192: int p1 = ((Integer) e1.getKey()).intValue();
193: Local l1 = (Local) e1.getValue();
194: PointsToSet r1 = pta.reachingObjects(l1);
195: Iterator i2 = ls.entrySet().iterator();
196: while (i2.hasNext()) {
197: Map.Entry e2 = (Map.Entry) i2.next();
198: int p2 = ((Integer) e2.getKey()).intValue();
199: Local l2 = (Local) e2.getValue();
200: PointsToSet r2 = pta.reachingObjects(l2);
201: if (p1 <= p2)
202: System.out.println("[" + p1 + "," + p2
203: + "]\t Container intersect? "
204: + r1.hasNonEmptyIntersection(r2));
205: }
206: }
207: }
208:
209: private static void printFieldIntersects(Map/*<Integer,Local>*/ls,
210: SootField f) {
211: soot.PointsToAnalysis pta = Scene.v().getPointsToAnalysis();
212: Iterator i1 = ls.entrySet().iterator();
213: while (i1.hasNext()) {
214: Map.Entry e1 = (Map.Entry) i1.next();
215: int p1 = ((Integer) e1.getKey()).intValue();
216: Local l1 = (Local) e1.getValue();
217: PointsToSet r1 = pta.reachingObjects(l1, f);
218: Iterator i2 = ls.entrySet().iterator();
219: while (i2.hasNext()) {
220: Map.Entry e2 = (Map.Entry) i2.next();
221: int p2 = ((Integer) e2.getKey()).intValue();
222: Local l2 = (Local) e2.getValue();
223: PointsToSet r2 = pta.reachingObjects(l2, f);
224: if (p1 <= p2)
225: System.out.println("[" + p1 + "," + p2
226: + "]\t Container.item intersect? "
227: + r1.hasNonEmptyIntersection(r2));
228: }
229: }
230: }
231:
232: }
|