1 19 20 package soot.jimple.toolkits.annotation.parity; 21 22 import soot.*; 23 import soot.util.*; 24 import java.util.*; 25 import soot.jimple.*; 26 import soot.toolkits.graph.*; 27 import soot.toolkits.scalar.*; 28 import soot.options.*; 29 30 public class ParityAnalysis extends ForwardFlowAnalysis { 42 43 private UnitGraph g; 44 private final static String TOP = "top"; 45 private final static String BOTTOM = "bottom"; 46 private final static String EVEN = "even"; 47 private final static String ODD = "odd"; 48 49 private LiveLocals filter; 50 51 public ParityAnalysis(UnitGraph g, LiveLocals filter) 52 { 53 super(g); 54 this.g = g; 55 56 this.filter = filter; 57 58 filterUnitToBeforeFlow = new HashMap(); 59 buildBeforeFilterMap(); 60 61 filterUnitToAfterFlow = new HashMap(); 62 63 doAnalysis(); 64 65 } 66 67 public ParityAnalysis(UnitGraph g){ 68 super(g); 69 this.g = g; 70 71 doAnalysis(); 72 } 73 74 private void buildBeforeFilterMap(){ 75 76 Iterator it = g.getBody().getUnits().iterator(); 77 while (it.hasNext()){ 78 Stmt s = (Stmt)it.next(); 79 83 List list = filter.getLiveLocalsBefore(s); 85 HashMap map = new HashMap(); 86 Iterator listIt = list.iterator(); 87 while (listIt.hasNext()){ 88 map.put(listIt.next(), BOTTOM); 89 } 90 filterUnitToBeforeFlow.put(s, map); 91 } 92 } 94 95 108 protected void merge(Object in1, Object in2, Object out) 109 { 110 HashMap inMap1 = (HashMap) in1; 111 HashMap inMap2 = (HashMap) in2; 112 HashMap outMap = (HashMap) out; 113 114 Set keys = inMap1.keySet(); 115 Iterator it = keys.iterator(); 116 while (it.hasNext()) { 117 Object var1 = it.next(); 118 String inVal1 = (String )inMap1.get(var1); 120 String inVal2 = (String )inMap2.get(var1); 122 125 if (inVal2 == null){ 126 outMap.put(var1, inVal1); 127 } 128 else if (inVal1.equals(BOTTOM)) { 129 outMap.put(var1, inVal2); 130 } 131 else if (inVal2.equals(BOTTOM)) { 132 outMap.put(var1, inVal1); 133 } 134 else if ((inVal1.equals(EVEN)) && 135 (inVal2.equals(EVEN))) { 136 outMap.put(var1, EVEN); 137 } 138 else if ((inVal1.equals(ODD)) && 139 (inVal2.equals(ODD))) { 140 outMap.put(var1, ODD); 141 } 142 else { 143 outMap.put(var1, TOP); 144 } 145 } 146 147 } 148 149 153 protected void copy(Object source, Object dest) { 154 155 HashMap sourceIn = (HashMap)source; 157 HashMap destOut = (HashMap)dest; 158 destOut.putAll(sourceIn); 161 dest = destOut; 162 163 } 164 165 176 private String getParity(HashMap in, Value val) { 177 if ((val instanceof AddExpr) | (val instanceof SubExpr)) { 179 String resVal1 = getParity(in, ((BinopExpr)val).getOp1()); 180 String resVal2 = getParity(in, ((BinopExpr)val).getOp2()); 181 if (resVal1.equals(TOP) | resVal2.equals(TOP)) { 182 return TOP; 183 } 184 else if (resVal1.equals(BOTTOM) | resVal2.equals(BOTTOM)){ 185 return BOTTOM; 186 } 187 else if (resVal1.equals(resVal2)) { 188 return EVEN; 189 } 190 else { 191 return ODD; 192 } 193 } 194 else if (val instanceof MulExpr) { 195 String resVal1 = getParity(in, ((BinopExpr)val).getOp1()); 196 String resVal2 = getParity(in, ((BinopExpr)val).getOp2()); 197 if (resVal1.equals(TOP) | resVal2.equals(TOP)) { 198 return TOP; 199 } 200 else if (resVal1.equals(BOTTOM) | resVal2.equals(BOTTOM)){ 201 return BOTTOM; 202 } 203 else if (resVal1.equals(ODD) && resVal2.equals(ODD)) { 204 return ODD; 205 } 206 else { 207 return EVEN; 208 } 209 } 210 else if (val instanceof IntConstant) { 211 int value = ((IntConstant)val).value; 212 if ((value % 2) == 0) { 213 return EVEN; 214 } 215 else { 216 return ODD; 217 } 218 } 219 else if (val instanceof LongConstant) { 220 long value = ((LongConstant)val).value; 221 if ((value % 2) == 0) { 222 return EVEN; 223 } 224 else { 225 return ODD; 226 } 227 } 228 else if (in.containsKey(val)) { 229 return (String )in.get(val); 230 } 231 else { 232 return TOP; 233 } 234 235 } 236 237 238 protected void flowThrough(Object inValue, Object unit, 239 Object outValue) 240 { 241 HashMap in = (HashMap) inValue; 242 HashMap out = (HashMap) outValue; 243 Stmt s = (Stmt) unit; 244 245 out.putAll(in); 247 248 251 253 if (s instanceof DefinitionStmt) { 254 Value left = ((DefinitionStmt)s).getLeftOp(); 255 if (left instanceof Local) { 256 if ((left.getType() instanceof IntegerType) || (left.getType() instanceof LongType)){ 257 Value right = ((DefinitionStmt)s).getRightOp(); 259 out.put(left, getParity(out, right)); 260 } 261 } 262 } 263 264 Iterator it = s.getUseAndDefBoxes().iterator(); 267 while (it.hasNext()){ 268 Object next = it.next(); 269 Value val = ((ValueBox)next).getValue(); 270 if (val instanceof ArithmeticConstant){ 272 out.put(val, getParity(out, (ArithmeticConstant)val)); 273 } 275 } 276 277 if (Options.v().interactive_mode()){ 279 buildAfterFilterMap(s); 280 updateAfterFilterMap(s); 281 } 282 } 284 285 private void buildAfterFilterMap(Stmt s){ 286 287 List list = filter.getLiveLocalsAfter(s); 288 HashMap map = new HashMap(); 289 Iterator listIt = list.iterator(); 290 while (listIt.hasNext()){ 291 map.put(listIt.next(), BOTTOM); 292 } 293 filterUnitToAfterFlow.put(s, map); 294 } 296 297 298 protected Object entryInitialFlow() 304 { 305 313 314 return newInitialFlow(); 315 } 316 317 private void updateBeforeFilterMap(){ 318 319 Iterator filterIt = filterUnitToBeforeFlow.keySet().iterator(); 320 while (filterIt.hasNext()){ 321 Stmt s = (Stmt)filterIt.next(); 322 HashMap allData = (HashMap)unitToBeforeFlow.get(s); 323 324 HashMap filterData = (HashMap)filterUnitToBeforeFlow.get(s); 325 326 filterUnitToBeforeFlow.put(s, updateFilter(allData, filterData)); 327 328 } 329 } 330 331 private void updateAfterFilterMap(Stmt s){ 332 333 HashMap allData = (HashMap)unitToAfterFlow.get(s); 334 335 HashMap filterData = (HashMap)filterUnitToAfterFlow.get(s); 336 337 filterUnitToAfterFlow.put(s, updateFilter(allData, filterData)); 338 339 } 340 341 private HashMap updateFilter(HashMap allData, HashMap filterData){ 342 343 if (allData == null) return filterData; 344 Iterator filterVarsIt = filterData.keySet().iterator(); 345 ArrayList toRemove = new ArrayList(); 346 while (filterVarsIt.hasNext()){ 347 Value v = (Value)filterVarsIt.next(); 348 if (allData.get(v) == null){ 349 toRemove.add(v); 350 } 352 else { 353 filterData.put(v, allData.get(v)); 354 } 355 } 356 Iterator removeIt = toRemove.iterator(); 357 while (removeIt.hasNext()){ 358 filterData.remove(removeIt.next()); 359 } 360 361 return filterData; 362 } 363 364 protected Object newInitialFlow() 365 { 366 HashMap initMap = new HashMap(); 367 368 Chain locals = g.getBody().getLocals(); 369 Iterator it = locals.iterator(); 370 while (it.hasNext()) { 371 Local next = (Local)it.next(); 372 if ((next.getType() instanceof IntegerType) || (next.getType() instanceof LongType)){ 374 initMap.put(next, BOTTOM); 375 } 376 } 377 378 Iterator boxIt = g.getBody().getUseAndDefBoxes().iterator(); 379 while (boxIt.hasNext()){ 380 Value val = ((ValueBox)boxIt.next()).getValue(); 381 if (val instanceof ArithmeticConstant) { 382 initMap.put(val, getParity(initMap, val)); 383 } 384 } 385 386 if (Options.v().interactive_mode()){ 387 updateBeforeFilterMap(); 388 } 389 390 return initMap; 391 392 } 393 394 395 } 396 | Popular Tags |