Advertisement
Guest User

Untitled

a guest
May 22nd, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.43 KB | None | 0 0
  1. package ch.ethz.sae;
  2.  
  3. import java.util.HashMap;
  4. import java.util.Iterator;
  5. import java.util.List;
  6.  
  7. import apron.Abstract1;
  8. import apron.ApronException;
  9. import apron.Environment;
  10. import apron.Manager;
  11. import apron.MpqScalar;
  12. import apron.Polka;
  13. import apron.Tcons1;
  14. import apron.Texpr1BinNode;
  15. import apron.Texpr1CstNode;
  16. import apron.Texpr1Intern;
  17. import apron.Texpr1Node;
  18. import apron.Texpr1VarNode;
  19. import soot.IntegerType;
  20. import soot.Local;
  21. import soot.SootClass;
  22. import soot.SootField;
  23. import soot.Unit;
  24. import soot.Value;
  25. import soot.jimple.BinopExpr;
  26. import soot.jimple.DefinitionStmt;
  27. import soot.jimple.IntConstant;
  28. import soot.jimple.Stmt;
  29. import soot.jimple.internal.AbstractBinopExpr;
  30. import soot.jimple.internal.JAddExpr;
  31. import soot.jimple.internal.JEqExpr;
  32. import soot.jimple.internal.JGeExpr;
  33. import soot.jimple.internal.JGtExpr;
  34. import soot.jimple.internal.JIfStmt;
  35. import soot.jimple.internal.JLeExpr;
  36. import soot.jimple.internal.JLtExpr;
  37. import soot.jimple.internal.JMulExpr;
  38. import soot.jimple.internal.JNeExpr;
  39. import soot.jimple.internal.JSubExpr;
  40. import soot.jimple.internal.JimpleLocal;
  41. import soot.jimple.toolkits.annotation.logic.Loop;
  42. import soot.toolkits.graph.LoopNestTree;
  43. import soot.toolkits.graph.UnitGraph;
  44. import soot.toolkits.scalar.ForwardBranchedFlowAnalysis;
  45. import soot.util.Chain;
  46.  
  47. /* numerical analysis */
  48. public class Analysis extends ForwardBranchedFlowAnalysis<AWrapper> {
  49.  
  50. /* Apron abstract domain instance */
  51. public static Manager man;
  52.  
  53. /* Apron environment */
  54. public static Environment env;
  55.  
  56. public void run() {
  57. doAnalysis();
  58. }
  59.  
  60. @Override
  61. protected void flowThrough(AWrapper inWrapper, Unit op,
  62. List<AWrapper> fallOutWrappers, List<AWrapper> branchOutWrappers) {
  63.  
  64. Stmt stmt = (Stmt) op;
  65. Abstract1 o_fallout = null, o_branchout = null;
  66.  
  67. try {
  68. o_fallout = new Abstract1(man, inWrapper.get());
  69. o_branchout = new Abstract1(man, inWrapper.get());
  70.  
  71. if (stmt instanceof DefinitionStmt) {
  72. /* assignment statement */
  73. o_fallout = new Abstract1(man, inWrapper.get());
  74. o_branchout = new Abstract1(man, inWrapper.get());
  75.  
  76. DefinitionStmt sd = (DefinitionStmt) stmt;
  77. Value lhs = sd.getLeftOp();
  78. Value rhs = sd.getRightOp();
  79.  
  80. if (lhs instanceof JimpleLocal) {
  81. /* assignment to a local var */
  82. String lhs_varName = ((JimpleLocal) lhs).getName();
  83. System.out.println("debug: lhs = JimpleLocal: lhs_varName: " + lhs_varName);
  84.  
  85. if (rhs instanceof IntConstant) {
  86. /* assign constant to a local var (e.g., n = 10) */
  87. IntConstant c = ((IntConstant) rhs);
  88. System.out.println("debug: IntConstant - consant: " + c);
  89. Texpr1Node rAr = new Texpr1CstNode(new MpqScalar(c.value));
  90. Texpr1Intern xp = new Texpr1Intern(env, rAr);
  91. o_fallout.assign(man, lhs_varName, xp, null);
  92. /* o_branchout does not matter for Definition statements */
  93. }
  94.  
  95. if (rhs instanceof JimpleLocal) {
  96. /* assign local var to a local var */
  97. JimpleLocal var = ((JimpleLocal) rhs);
  98. String rhs_varName = var.getName();
  99. System.out.println("debug: jimplelocal - rhs_varName: " + rhs_varName);
  100. if (env.hasVar(rhs_varName)){ //if is a pointer assignment, we must not change o_fallout (i.e, it stays inWrapper.get())
  101. Texpr1Node rAr = new Texpr1VarNode(rhs_varName);
  102. Texpr1Intern xp = new Texpr1Intern(env, rAr);
  103. o_fallout.assign(man, lhs_varName, xp, null);
  104. }
  105.  
  106. /* o_branchout does not matter for Definition statements */
  107. }
  108.  
  109. if (rhs instanceof BinopExpr) {
  110. /* assign BinOp expression to a local var */
  111. BinopExpr bexpr = ((BinopExpr) rhs);
  112. int o = -1;
  113. if (bexpr instanceof JAddExpr) {
  114. o = Texpr1BinNode.OP_ADD;
  115. } else if (bexpr instanceof JSubExpr) {
  116. o = Texpr1BinNode.OP_SUB;
  117. } else if (bexpr instanceof JMulExpr) {
  118. o = Texpr1BinNode.OP_MUL;
  119. }
  120.  
  121. Value op1 = bexpr.getOp1();
  122. Value op2 = bexpr.getOp2();
  123. System.out.println("debug: BinopExpr - opq1: " + op1 + ", op2: " + op2);
  124. Texpr1Node lAr = null;
  125. Texpr1Node rAr = null;
  126.  
  127. if (op1 instanceof JimpleLocal) {
  128. JimpleLocal var = (JimpleLocal) op1;
  129. String rhs_varName = var.getName();
  130. lAr = new Texpr1VarNode(rhs_varName);
  131. } else if (op1 instanceof IntConstant) {
  132. IntConstant c = ((IntConstant) op1);
  133. lAr = new Texpr1CstNode(new MpqScalar(c.value));
  134. }
  135.  
  136. if (op2 instanceof JimpleLocal) {
  137. JimpleLocal var = (JimpleLocal) op2;
  138. String rhs_varName = var.getName();
  139. rAr = new Texpr1VarNode(rhs_varName);
  140. } else if (op2 instanceof IntConstant) {
  141. IntConstant c = ((IntConstant) op2);
  142. rAr = new Texpr1CstNode(new MpqScalar(c.value));
  143. }
  144. Texpr1Node t = new Texpr1BinNode(o, lAr, rAr);
  145. Texpr1Intern xp = new Texpr1Intern(env, t);
  146. o_fallout.assign(man, lhs_varName, xp, null);
  147. /* o_branchout does not matter for Definition statements */
  148. }
  149. }
  150.  
  151. } else if (stmt instanceof JIfStmt) {
  152. o_fallout = new Abstract1(man, inWrapper.get());
  153. o_branchout = new Abstract1(man, inWrapper.get());
  154.  
  155. JIfStmt ifst = (JIfStmt) stmt;
  156. Value cond = ifst.getCondition();
  157. Stmt target = ifst.getTarget();
  158. System.out.println("debug: lhs = IfStmt: cond = " + cond + ", target = " + target + " ");
  159.  
  160.  
  161. Value op1 = ((AbstractBinopExpr) cond).getOp1();
  162. Value op2 = ((AbstractBinopExpr) cond).getOp2();
  163. Texpr1Node op1Node = null;
  164. Texpr1Node op2Node = null;
  165.  
  166. System.out.println("debug: lhs = IfStmt: op1 = " + op1 + ", op2 = " + op2 + " ");
  167.  
  168. int op1case = 0;
  169. int op2case = 0;
  170.  
  171. if (op1 instanceof JimpleLocal) {
  172. JimpleLocal var = (JimpleLocal) op1;
  173. String rhs_varName = var.getName();
  174. op1Node = new Texpr1VarNode(rhs_varName);
  175. } else if (op1 instanceof IntConstant) {
  176. IntConstant c = ((IntConstant) op1);
  177. op1Node = new Texpr1CstNode(new MpqScalar(c.value));
  178. if (c.value == Integer.MAX_VALUE) {
  179. op1case = 1;
  180. }
  181. if (c.value == Integer.MIN_VALUE) {
  182. op1case = -1;
  183. }
  184. }
  185. if (op2 instanceof JimpleLocal) {
  186. JimpleLocal var = (JimpleLocal) op2;
  187. String rhs_varName = var.getName();
  188. op2Node = new Texpr1VarNode(rhs_varName);
  189. } else if (op2 instanceof IntConstant) {
  190. IntConstant c = ((IntConstant) op2);
  191. op2Node = new Texpr1CstNode(new MpqScalar(c.value));
  192. if (c.value == Integer.MAX_VALUE) {
  193. op2case = 1;
  194. }
  195. if (c.value == Integer.MIN_VALUE) {
  196. op2case = -1;
  197. }
  198. }
  199.  
  200. Texpr1Node binop12 = new Texpr1BinNode(Texpr1BinNode.OP_SUB, op1Node, op2Node);
  201. Texpr1Node binop21 = new Texpr1BinNode(Texpr1BinNode.OP_SUB, op2Node, op1Node);
  202.  
  203. //handling edge cases for != conditions
  204. int k = Tcons1.DISEQ;
  205. Texpr1Node node = binop12;
  206. if (op1case != 0 || op2case != 0) {
  207. //op1case == 1: maxint != op2 <=> maxint > op2 <=> binop12 > 0
  208. //op2case == -1: op1 != minint <=> op1 > minint <=> binop12 > 0
  209. k = Tcons1.SUP;
  210. }
  211. if (op1case == -1 || op2case == 1) {
  212. //op1case == -1: minint != op2 <=> minint < op2 <=> binop21 > 0
  213. //op2case == 1: op1 != maxint <=> op1 < maxint <=> binop21 > 0
  214. node = binop21;
  215. }
  216.  
  217. Tcons1 tconsBR = null;
  218. Tcons1 tconsFT = null;
  219.  
  220. if (cond instanceof JEqExpr) {
  221. tconsBR = new Tcons1(env,Tcons1.EQ,binop12);
  222. tconsFT = new Tcons1(env,k,node);
  223. } else if (cond instanceof JNeExpr) {
  224. tconsBR = new Tcons1(env,k,node);
  225. tconsFT = new Tcons1(env,Tcons1.EQ,binop12);
  226. } else if (cond instanceof JGtExpr) {
  227. tconsBR = new Tcons1(env,Tcons1.SUP,binop12);
  228. tconsFT = new Tcons1(env,Tcons1.SUPEQ,binop21);
  229. } else if (cond instanceof JGeExpr) {
  230. tconsBR = new Tcons1(env,Tcons1.SUPEQ,binop12);
  231. tconsFT = new Tcons1(env,Tcons1.SUP,binop21);
  232. } else if (cond instanceof JLtExpr) {
  233. tconsBR = new Tcons1(env,Tcons1.SUP,binop21);
  234. tconsFT = new Tcons1(env,Tcons1.SUPEQ,binop12);
  235. } else if (cond instanceof JLeExpr) {
  236. tconsBR = new Tcons1(env,Tcons1.SUPEQ,binop21);
  237. tconsFT = new Tcons1(env,Tcons1.SUP,binop12);
  238. }
  239.  
  240. o_fallout.meet(man, tconsFT);
  241. o_branchout.meet(man, tconsBR);
  242.  
  243. }
  244.  
  245.  
  246. /* - code below propagates the o_fallout and o_branchout computed before (as side effect);
  247. * - no need to change anything below;
  248. * - just make sure that o_fallout and o_branchout vars are computed before;
  249. */
  250. for (Iterator<AWrapper> it = fallOutWrappers.iterator(); it.hasNext();) {
  251. AWrapper op1 = it.next();
  252. if (o_fallout != null) {
  253. op1.set(o_fallout);
  254. }
  255. }
  256.  
  257. for (Iterator<AWrapper> it = branchOutWrappers.iterator(); it.hasNext();) {
  258. AWrapper op1 = it.next();
  259. if (o_branchout != null) {
  260. op1.set(o_branchout);
  261. }
  262. }
  263.  
  264. } catch (ApronException e) {
  265. e.printStackTrace();
  266. System.exit(1);
  267. }
  268. }
  269.  
  270. /* ======================================================== */
  271.  
  272. /* no need to use or change the variables and methods below */
  273.  
  274. /* collect all the local int variables in the class */
  275. private void recordIntLocalVars() {
  276.  
  277. Chain<Local> locals = g.getBody().getLocals();
  278.  
  279. int count = 0;
  280. Iterator<Local> it = locals.iterator();
  281. while (it.hasNext()) {
  282. JimpleLocal next = (JimpleLocal) it.next();
  283. if (next.getType() instanceof IntegerType)
  284. count += 1;
  285. }
  286.  
  287. local_ints = new String[count];
  288.  
  289. int i = 0;
  290. it = locals.iterator();
  291. while (it.hasNext()) {
  292. JimpleLocal next = (JimpleLocal) it.next();
  293. String name = next.getName();
  294. if (next.getType() instanceof IntegerType)
  295. local_ints[i++] = name;
  296. }
  297. }
  298.  
  299. /* collect all the int fields of the class */
  300. private void recordIntClassVars() {
  301.  
  302. Chain<SootField> ifields = jclass.getFields();
  303.  
  304. int count = 0;
  305. Iterator<SootField> it = ifields.iterator();
  306. while (it.hasNext()) {
  307. SootField next = it.next();
  308. if (next.getType() instanceof IntegerType)
  309. count += 1;
  310. }
  311.  
  312. class_ints = new String[count];
  313.  
  314. int i = 0;
  315. it = ifields.iterator();
  316. while (it.hasNext()) {
  317. SootField next = it.next();
  318. String name = next.getName();
  319. if (next.getType() instanceof IntegerType)
  320. class_ints[i++] = name;
  321. }
  322. }
  323.  
  324. /* build an environment with integer variables */
  325. public void buildEnvironment() {
  326.  
  327. recordIntLocalVars();
  328. recordIntClassVars();
  329.  
  330. String ints[] = new String[local_ints.length + class_ints.length];
  331.  
  332. /* add local ints */
  333. for (int i = 0; i < local_ints.length; i++) {
  334. ints[i] = local_ints[i];
  335. }
  336.  
  337. /* add class ints */
  338. for (int i = 0; i < class_ints.length; i++) {
  339. ints[local_ints.length + i] = class_ints[i];
  340. }
  341.  
  342. env = new Environment(ints, reals);
  343. }
  344.  
  345. /* instantiate the polyhedra domain */
  346. private void instantiateDomain() {
  347. man = new Polka(true);
  348. }
  349.  
  350. /* constructor */
  351. public Analysis(UnitGraph g, SootClass jc) {
  352. super(g);
  353.  
  354. this.g = g;
  355. this.jclass = jc;
  356.  
  357. buildEnvironment();
  358. instantiateDomain();
  359.  
  360. loopHeads = new HashMap<Unit, Counter>();
  361. backJumps = new HashMap<Unit, Counter>();
  362. for (Loop l : new LoopNestTree(g.getBody())) {
  363. loopHeads.put(l.getHead(), new Counter(0));
  364. backJumps.put(l.getBackJumpStmt(), new Counter(0));
  365. }
  366. }
  367.  
  368. @Override
  369. protected AWrapper entryInitialFlow() {
  370. Abstract1 top = null;
  371. try {
  372. top = new Abstract1(man, env);
  373. } catch (ApronException e) {
  374. e.printStackTrace();
  375. System.exit(1);
  376. }
  377. return new AWrapper(top);
  378. }
  379.  
  380. private static class Counter {
  381. int value;
  382.  
  383. Counter(int v) {
  384. value = v;
  385. }
  386. }
  387.  
  388. @Override
  389. protected void merge(Unit succNode, AWrapper in_w1, AWrapper in_w2, AWrapper out_w) {
  390. Counter count = loopHeads.get(succNode);
  391.  
  392. Abstract1 in1 = in_w1.get();
  393. Abstract1 in2 = in_w2.get();
  394. Abstract1 out = null;
  395.  
  396. try {
  397. if (count != null) {
  398. ++count.value;
  399. if (count.value < WIDENING_THRESHOLD) {
  400. out = in1.joinCopy(man, in2);
  401. } else {
  402. out = in1.widening(man, in1.joinCopy(man, in2));
  403. }
  404. } else {
  405. out = in1.joinCopy(man, in2);
  406. }
  407. out_w.set(out);
  408. } catch (Exception e) {
  409. e.printStackTrace();
  410. System.exit(1);
  411. }
  412. }
  413.  
  414. @Override
  415. protected void merge(AWrapper in_w1, AWrapper in_w2, AWrapper out_w) {
  416.  
  417. Abstract1 in1 = in_w1.get();
  418. Abstract1 in2 = in_w2.get();
  419. Abstract1 out = null;
  420.  
  421. try {
  422. out = in1.joinCopy(man, in2);
  423. } catch (ApronException e) {
  424. e.printStackTrace();
  425. }
  426.  
  427. out_w.set(out);
  428. }
  429.  
  430. @Override
  431. protected AWrapper newInitialFlow() {
  432. Abstract1 bottom = null;
  433.  
  434. try {
  435. bottom = new Abstract1(man, env, true);
  436. } catch (ApronException e) {
  437. }
  438. AWrapper a = new AWrapper(bottom);
  439. a.man = man;
  440. return a;
  441.  
  442. }
  443.  
  444. @Override
  445. protected void copy(AWrapper source, AWrapper dest) {
  446. try {
  447. dest.set(new Abstract1(man, source.get()));
  448. } catch (ApronException e) {
  449. e.printStackTrace();
  450. }
  451. }
  452.  
  453. /* widening threshold and widening points */
  454. private static final int WIDENING_THRESHOLD = 6;
  455. private HashMap<Unit, Counter> loopHeads, backJumps;
  456.  
  457. /* Soot unit graph */
  458. public UnitGraph g;
  459. public SootClass jclass;
  460.  
  461. /* integer local variables of the method; */
  462. public String local_ints[];
  463. /* integer class variables where the method is defined */
  464. private String class_ints[];
  465.  
  466. /* real variables */
  467. public static String reals[] = { "x" };
  468. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement