PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/ded/soot/soot-2.3.0/src/soot/toolkits/scalar/ForwardBranchedFlowAnalysis.java

https://bitbucket.org/shubham4564/apkinspector
Java | 325 lines | 207 code | 55 blank | 63 comment | 30 complexity | 1b72320e59df5e9d716866143b94e276 MD5 | raw file
Possible License(s): GPL-3.0, Apache-2.0, GPL-2.0
  1. /* Soot - a J*va Optimization Framework
  2. * Copyright (C) 1997-2000 Raja Vallee-Rai
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the
  16. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  17. * Boston, MA 02111-1307, USA.
  18. */
  19. /*
  20. * Modified by the Sable Research Group and others 1997-2000.
  21. * See the 'credits' file distributed with Soot for the complete list of
  22. * contributors. (Soot is distributed at http://www.sable.mcgill.ca/soot)
  23. */
  24. /*
  25. 2000, March 20 - Updated code provided by Patrick Lam
  26. <plam@sable.mcgill.ca>
  27. from 1.beta.4.dev.60
  28. to 1.beta.6.dev.34
  29. Plus some bug fixes.
  30. -- Janus <janus@place.org>
  31. KNOWN LIMITATION: the analysis doesn't handle traps since traps
  32. handler statements have predecessors, but they
  33. don't have the trap handler as successor. This
  34. might be a limitation of the CompleteUnitGraph
  35. tho.
  36. */
  37. package soot.toolkits.scalar;
  38. import soot.*;
  39. import soot.toolkits.graph.*;
  40. import soot.util.*;
  41. import java.util.*;
  42. import soot.toolkits.graph.interaction.*;
  43. import soot.options.*;
  44. /** Abstract class providing an engine for branched forward flow analysis.
  45. * WARNING: This does not handle exceptional flow as branches!
  46. * */
  47. public abstract class ForwardBranchedFlowAnalysis<A> extends BranchedFlowAnalysis<Unit, A>
  48. {
  49. public ForwardBranchedFlowAnalysis(UnitGraph graph)
  50. {
  51. super(graph);
  52. }
  53. protected boolean isForward()
  54. {
  55. return true;
  56. }
  57. // Accumulate the previous afterFlow sets.
  58. private void accumulateAfterFlowSets(Unit s, A[] flowRepositories, List<Object> previousAfterFlows)
  59. {
  60. int repCount = 0;
  61. previousAfterFlows.clear();
  62. if (s.fallsThrough())
  63. {
  64. copy(unitToAfterFallFlow.get(s).get(0), flowRepositories[repCount]);
  65. previousAfterFlows.add(flowRepositories[repCount++]);
  66. }
  67. if (s.branches())
  68. {
  69. List<A> l = (unitToAfterBranchFlow.get(s));
  70. Iterator<A> it = l.iterator();
  71. while (it.hasNext())
  72. {
  73. A fs = (it.next());
  74. copy(fs, flowRepositories[repCount]);
  75. previousAfterFlows.add(flowRepositories[repCount++]);
  76. }
  77. }
  78. } // end accumulateAfterFlowSets
  79. protected void doAnalysis()
  80. {
  81. final Map<Unit, Integer> numbers = new HashMap<Unit, Integer>();
  82. List orderedUnits = new PseudoTopologicalOrderer().newList(graph,false);
  83. {
  84. int i = 1;
  85. for( Iterator uIt = orderedUnits.iterator(); uIt.hasNext(); ) {
  86. final Unit u = (Unit) uIt.next();
  87. numbers.put(u, new Integer(i));
  88. i++;
  89. }
  90. }
  91. TreeSet<Unit> changedUnits = new TreeSet<Unit>( new Comparator() {
  92. public int compare(Object o1, Object o2) {
  93. Integer i1 = numbers.get(o1);
  94. Integer i2 = numbers.get(o2);
  95. return (i1.intValue() - i2.intValue());
  96. }
  97. } );
  98. Map<Unit, ArrayList> unitToIncomingFlowSets = new HashMap<Unit, ArrayList>(graph.size() * 2 + 1, 0.7f);
  99. List heads = graph.getHeads();
  100. int numNodes = graph.size();
  101. int numComputations = 0;
  102. int maxBranchSize = 0;
  103. // initialize unitToIncomingFlowSets
  104. {
  105. Iterator it = graph.iterator();
  106. while (it.hasNext())
  107. {
  108. Unit s = (Unit) it.next();
  109. unitToIncomingFlowSets.put(s, new ArrayList());
  110. }
  111. }
  112. // Set initial values and nodes to visit.
  113. // WARNING: DO NOT HANDLE THE CASE OF THE TRAPS
  114. {
  115. Chain sl = ((UnitGraph)graph).getBody().getUnits();
  116. Iterator it = graph.iterator();
  117. while(it.hasNext())
  118. {
  119. Unit s = (Unit) it.next();
  120. changedUnits.add(s);
  121. unitToBeforeFlow.put(s, newInitialFlow());
  122. if (s.fallsThrough())
  123. {
  124. ArrayList<A> fl = new ArrayList<A>();
  125. fl.add((newInitialFlow()));
  126. unitToAfterFallFlow.put(s, fl);
  127. Unit succ=(Unit) sl.getSuccOf(s);
  128. // it's possible for someone to insert some (dead)
  129. // fall through code at the very end of a method body
  130. if(succ!=null) {
  131. List<Object> l = (unitToIncomingFlowSets.get(sl.getSuccOf(s)));
  132. l.addAll(fl);
  133. }
  134. }
  135. else
  136. unitToAfterFallFlow.put(s, new ArrayList<A>());
  137. if (s.branches())
  138. {
  139. ArrayList<A> l = new ArrayList<A>();
  140. List<A> incList;
  141. Iterator boxIt = s.getUnitBoxes().iterator();
  142. while (boxIt.hasNext())
  143. {
  144. A f = (newInitialFlow());
  145. l.add(f);
  146. Unit ss = ((UnitBox) (boxIt.next())).getUnit();
  147. incList = (unitToIncomingFlowSets.get(ss));
  148. incList.add(f);
  149. }
  150. unitToAfterBranchFlow.put(s, l);
  151. }
  152. else
  153. unitToAfterBranchFlow.put(s, new ArrayList<A>());
  154. if (s.getUnitBoxes().size() > maxBranchSize)
  155. maxBranchSize = s.getUnitBoxes().size();
  156. }
  157. }
  158. // Feng Qian: March 07, 2002
  159. // init entry points
  160. {
  161. Iterator<Unit> it = heads.iterator();
  162. while (it.hasNext()) {
  163. Unit s = it.next();
  164. // this is a forward flow analysis
  165. unitToBeforeFlow.put(s, entryInitialFlow());
  166. }
  167. }
  168. if (treatTrapHandlersAsEntries())
  169. {
  170. Iterator trapIt = ((UnitGraph)graph).getBody().
  171. getTraps().iterator();
  172. while(trapIt.hasNext()) {
  173. Trap trap = (Trap) trapIt.next();
  174. Unit handler = trap.getHandlerUnit();
  175. unitToBeforeFlow.put(handler, entryInitialFlow());
  176. }
  177. }
  178. // Perform fixed point flow analysis
  179. {
  180. List<Object> previousAfterFlows = new ArrayList<Object>();
  181. List<Object> afterFlows = new ArrayList<Object>();
  182. A[] flowRepositories = (A[]) new Object[maxBranchSize+1];
  183. for (int i = 0; i < maxBranchSize+1; i++)
  184. flowRepositories[i] = newInitialFlow();
  185. A[] previousFlowRepositories = (A[])new Object[maxBranchSize+1];
  186. for (int i = 0; i < maxBranchSize+1; i++)
  187. previousFlowRepositories[i] = newInitialFlow();
  188. while(!changedUnits.isEmpty())
  189. {
  190. A beforeFlow;
  191. Unit s = changedUnits.first();
  192. changedUnits.remove(s);
  193. boolean isHead = heads.contains(s);
  194. accumulateAfterFlowSets(s, previousFlowRepositories, previousAfterFlows);
  195. // Compute and store beforeFlow
  196. {
  197. List<A> preds = unitToIncomingFlowSets.get(s);
  198. beforeFlow = unitToBeforeFlow.get(s);
  199. if(preds.size() == 1)
  200. copy(preds.get(0), beforeFlow);
  201. else if(preds.size() != 0)
  202. {
  203. Iterator<A> predIt = preds.iterator();
  204. copy(predIt.next(), beforeFlow);
  205. while(predIt.hasNext())
  206. {
  207. A otherBranchFlow = predIt.next();
  208. A newBeforeFlow = newInitialFlow();
  209. merge(beforeFlow, otherBranchFlow, newBeforeFlow);
  210. copy(newBeforeFlow, beforeFlow);
  211. }
  212. }
  213. if(isHead && preds.size() != 0)
  214. merge(beforeFlow, entryInitialFlow());
  215. }
  216. // Compute afterFlow and store it.
  217. {
  218. ArrayList<A> afterFallFlow = unitToAfterFallFlow.get(s);
  219. ArrayList<A> afterBranchFlow = unitToAfterBranchFlow.get(s);
  220. if (Options.v().interactive_mode()){
  221. A savedFlow = newInitialFlow();
  222. copy(beforeFlow, savedFlow);
  223. FlowInfo fi = new FlowInfo(savedFlow, s, true);
  224. if (InteractionHandler.v().getStopUnitList() != null && InteractionHandler.v().getStopUnitList().contains(s)){
  225. InteractionHandler.v().handleStopAtNodeEvent(s);
  226. }
  227. InteractionHandler.v().handleBeforeAnalysisEvent(fi);
  228. }
  229. flowThrough(beforeFlow, s, (List) afterFallFlow, (List) afterBranchFlow);
  230. if (Options.v().interactive_mode()){
  231. ArrayList l = new ArrayList();
  232. if (!((List)afterFallFlow).isEmpty()){
  233. l.addAll((List)afterFallFlow);
  234. }
  235. if (!((List)afterBranchFlow).isEmpty()){
  236. l.addAll((List)afterBranchFlow);
  237. }
  238. /*if (s instanceof soot.jimple.IfStmt){
  239. l.addAll((List)afterFallFlow);
  240. l.addAll((List)afterBranchFlow);
  241. }
  242. else {
  243. l.addAll((List)afterFallFlow);
  244. }*/
  245. FlowInfo fi = new FlowInfo(l, s, false);
  246. InteractionHandler.v().handleAfterAnalysisEvent(fi);
  247. }
  248. numComputations++;
  249. }
  250. accumulateAfterFlowSets(s, flowRepositories, afterFlows);
  251. // Update queue appropriately
  252. if(!afterFlows.equals(previousAfterFlows))
  253. {
  254. Iterator succIt = graph.getSuccsOf(s).iterator();
  255. while(succIt.hasNext())
  256. {
  257. Unit succ = (Unit) succIt.next();
  258. changedUnits.add(succ);
  259. }
  260. }
  261. }
  262. }
  263. // G.v().out.println(graph.getBody().getMethod().getSignature() + " numNodes: " + numNodes +
  264. // " numComputations: " + numComputations + " avg: " + Main.truncatedOf((double) numComputations / numNodes, 2));
  265. Timers.v().totalFlowNodes += numNodes;
  266. Timers.v().totalFlowComputations += numComputations;
  267. } // end doAnalysis
  268. } // end class ForwardBranchedFlowAnalysis