1 19 20 package soot.javaToJimple; 21 22 import java.util.*; 23 24 public class Util { 25 26 public static void addInnerClassTag(soot.SootClass sc, String innerName, String outerName, String simpleName, int access){ 27 29 innerName = soot.util.StringTools.replaceAll(innerName, ".", "/"); 30 if (outerName != null){ 31 outerName = soot.util.StringTools.replaceAll(outerName, ".", "/"); 32 } 33 sc.addTag(new soot.tagkit.InnerClassTag( 34 innerName, 35 outerName, 36 simpleName, 37 access)); 38 39 } 40 41 public static String getParamNameForClassLit(polyglot.types.Type type){ 42 String name = ""; 43 if (type.isArray()){ 44 int dims = ((polyglot.types.ArrayType)type).dims(); 45 polyglot.types.Type arrType = ((polyglot.types.ArrayType)type).base(); 46 while (arrType instanceof polyglot.types.ArrayType) { 47 arrType = ((polyglot.types.ArrayType)arrType).base(); 48 } 49 String fieldName = ""; 50 if (arrType.isBoolean()){ 51 fieldName = "Z"; 52 } 53 else if (arrType.isByte()){ 54 fieldName = "B"; 55 } 56 else if (arrType.isChar()){ 57 fieldName = "C"; 58 } 59 else if (arrType.isDouble()){ 60 fieldName = "D"; 61 } 62 else if (arrType.isFloat()){ 63 fieldName = "F"; 64 } 65 else if (arrType.isInt()){ 66 fieldName = "I"; 67 } 68 else if (arrType.isLong()){ 69 fieldName = "J"; 70 } 71 else if (arrType.isShort()){ 72 fieldName = "S"; 73 } 74 else { 75 String typeSt = getSootType(arrType).toString(); 76 fieldName = "L"+typeSt; 77 } 78 79 for (int i = 0; i < dims; i++){ 80 name += "["; 81 } 82 name += fieldName; 83 if (!arrType.isPrimitive()){ 84 name += ";"; 85 } 86 } 87 else { 88 name = getSootType(type).toString(); 89 } 90 return name; 91 } 92 93 public static String getFieldNameForClassLit(polyglot.types.Type type){ 94 String fieldName = ""; 95 if (type.isArray()){ 96 int dims = ((polyglot.types.ArrayType)type).dims(); 97 polyglot.types.Type arrType = ((polyglot.types.ArrayType)type).base(); 98 while (arrType instanceof polyglot.types.ArrayType) { 99 arrType = ((polyglot.types.ArrayType)arrType).base(); 100 } 101 fieldName = "array$"; 102 for (int i = 0; i < (dims - 1); i++){ 103 fieldName += "$"; 104 } 105 if (arrType.isBoolean()){ 106 fieldName += "Z"; 107 } 108 else if (arrType.isByte()){ 109 fieldName += "B"; 110 } 111 else if (arrType.isChar()){ 112 fieldName += "C"; 113 } 114 else if (arrType.isDouble()){ 115 fieldName += "D"; 116 } 117 else if (arrType.isFloat()){ 118 fieldName += "F"; 119 } 120 else if (arrType.isInt()){ 121 fieldName += "I"; 122 } 123 else if (arrType.isLong()){ 124 fieldName += "J"; 125 } 126 else if (arrType.isShort()){ 127 fieldName += "S"; 128 } 129 else { 130 String typeSt = getSootType(arrType).toString(); 131 typeSt = soot.util.StringTools.replaceAll(typeSt, ".", "$"); 132 133 fieldName = fieldName+"L"+typeSt; 134 } 135 } 136 else { 137 fieldName = "class$"; 138 String typeSt = getSootType(type).toString(); 139 typeSt = soot.util.StringTools.replaceAll(typeSt, ".", "$"); 140 fieldName = fieldName+typeSt; 141 } 142 143 return fieldName; 144 } 145 146 public static String getSourceFileOfClass(soot.SootClass sootClass){ 147 String name = sootClass.getName(); 148 int index = name.indexOf("$"); 149 150 if (index != -1){ 152 name = name.substring(0, index); 153 } 154 return name; 155 } 156 157 public static void addLnPosTags(soot.tagkit.Host host, polyglot.util.Position pos) { 158 if (pos != null) { 159 addLnPosTags(host, pos.line(), pos.endLine(), pos.column(), pos.endColumn()); 160 } 161 } 162 163 public static void addLnPosTags(soot.tagkit.Host host, int sline, int eline, int spos, int epos) { 164 if (soot.options.Options.v().keep_line_number()){ 165 host.addTag(new soot.tagkit.SourceLnPosTag(sline, eline, spos, epos)); 166 } 167 } 168 169 172 public static void addPosTag(soot.tagkit.Host host, polyglot.util.Position pos) { 173 if (pos != null) { 174 addPosTag(host, pos.column(), pos.endColumn()); 175 } 176 } 177 178 public static void addMethodPosTag(soot.tagkit.Host meth, int start, int end){ 179 180 meth.addTag(new soot.tagkit.SourcePositionTag(start, end)); 181 } 182 183 186 public static void addPosTag(soot.tagkit.Host host, int sc, int ec) { 187 188 host.addTag(new soot.tagkit.SourcePositionTag(sc, ec)); 189 } 190 191 public static void addMethodLineTag(soot.tagkit.Host host, int sline, int eline){ 192 if (soot.options.Options.v().keep_line_number()){ 193 host.addTag(new soot.tagkit.SourceLineNumberTag(sline, eline)); 194 } 195 } 196 197 200 public static void addLineTag(soot.tagkit.Host host, polyglot.ast.Node node) { 201 202 if (soot.options.Options.v().keep_line_number()){ 203 if (node.position() != null) { 204 host.addTag(new soot.tagkit.SourceLineNumberTag(node.position().line(), node.position().line())); 205 206 } 207 } 208 } 209 210 213 public static void addLineTag(soot.tagkit.Host host, int sLine, int eLine) { 214 215 host.addTag(new soot.tagkit.SourceLineNumberTag(sLine, eLine)); 216 217 } 218 219 220 221 public static soot.Local getThis(soot.Type sootType, soot.Body body, HashMap getThisMap, LocalGenerator lg){ 222 223 if (InitialResolver.v().hierarchy() == null){ 224 InitialResolver.v().hierarchy(new soot.FastHierarchy()); 225 } 226 227 soot.FastHierarchy fh = InitialResolver.v().hierarchy(); 228 229 soot.Local specialThisLocal = body.getThisLocal(); 235 if (specialThisLocal.getType().equals(sootType)) { 237 238 getThisMap.put(sootType, specialThisLocal); 239 return specialThisLocal; 240 } 241 242 if (bodyHasLocal(body, sootType)){ 246 soot.Local l = getLocalOfType(body, sootType); 247 getThisMap.put(sootType, l); 248 return l; 249 } 250 251 soot.SootClass classToInvoke = ((soot.RefType)specialThisLocal.getType()).getSootClass(); 253 soot.SootField outerThisField = classToInvoke.getFieldByName("this$0"); 254 soot.Local t1 = lg.generateLocal(outerThisField.getType()); 255 256 soot.jimple.FieldRef fieldRef = soot.jimple.Jimple.v().newInstanceFieldRef(specialThisLocal, outerThisField.makeRef()); 257 soot.jimple.AssignStmt fieldAssignStmt = soot.jimple.Jimple.v().newAssignStmt(t1, fieldRef); 258 body.getUnits().add(fieldAssignStmt); 259 260 if (fh.canStoreType(t1.getType(), sootType)){ 261 getThisMap.put(sootType, t1); 262 return t1; 263 } 264 265 273 274 soot.Local t2 = t1; 276 277 return getThisGivenOuter(sootType, getThisMap, body, lg, t2); 278 } 279 280 private static soot.Local getLocalOfType(soot.Body body, soot.Type type) { 281 soot.FastHierarchy fh = InitialResolver.v().hierarchy(); 282 Iterator stmtsIt = body.getUnits().iterator(); 283 soot.Local correctLocal = null; 284 while (stmtsIt.hasNext()){ 285 soot.jimple.Stmt s = (soot.jimple.Stmt)stmtsIt.next(); 286 if (s instanceof soot.jimple.IdentityStmt && (s.hasTag("EnclosingTag") || s.hasTag("QualifyingTag"))){ 287 Iterator it = s.getDefBoxes().iterator(); 288 while (it.hasNext()){ 289 soot.ValueBox vb = (soot.ValueBox)it.next(); 290 if ((vb.getValue() instanceof soot.Local) && (fh.canStoreType(type, vb.getValue().getType()))){ correctLocal = (soot.Local)vb.getValue(); 292 } 293 } 294 } 295 } 296 return correctLocal; 297 } 298 299 private static boolean bodyHasLocal(soot.Body body, soot.Type type) { 300 soot.FastHierarchy fh = InitialResolver.v().hierarchy(); 301 Iterator stmtsIt = body.getUnits().iterator(); 302 soot.Local correctLocal = null; 303 while (stmtsIt.hasNext()){ 304 soot.jimple.Stmt s = (soot.jimple.Stmt)stmtsIt.next(); 305 if (s instanceof soot.jimple.IdentityStmt && (s.hasTag("EnclosingTag") || s.hasTag("QualifyingTag"))){ 306 Iterator it = s.getDefBoxes().iterator(); 307 while (it.hasNext()){ 308 soot.ValueBox vb = (soot.ValueBox)it.next(); 309 if ((vb.getValue() instanceof soot.Local) && (fh.canStoreType(type, vb.getValue().getType()))){ return true; 311 } 312 } 313 } 314 } 315 return false; 316 325 } 326 327 328 public static soot.Local getThisGivenOuter(soot.Type sootType, HashMap getThisMap, soot.Body body, LocalGenerator lg, soot.Local t2){ 329 330 if (InitialResolver.v().hierarchy() == null){ 331 InitialResolver.v().hierarchy(new soot.FastHierarchy()); 332 } 333 334 soot.FastHierarchy fh = InitialResolver.v().hierarchy(); 335 336 while (!fh.canStoreType(t2.getType(),sootType)){ 337 soot.SootClass classToInvoke = ((soot.RefType)t2.getType()).getSootClass(); 338 soot.SootMethod methToInvoke = makeOuterThisAccessMethod(classToInvoke); 341 342 soot.Local t3 = lg.generateLocal(methToInvoke.getReturnType()); 344 ArrayList methParams = new ArrayList(); 345 methParams.add(t2); 346 soot.Local res = getPrivateAccessFieldInvoke(methToInvoke.makeRef(), methParams, body, lg); 347 soot.jimple.AssignStmt assign = soot.jimple.Jimple.v().newAssignStmt(t3, res); 348 body.getUnits().add(assign); 349 t2 = t3; 350 } 351 352 getThisMap.put(sootType, t2); 353 354 return t2; 355 } 356 357 358 private static soot.SootMethod makeOuterThisAccessMethod(soot.SootClass classToInvoke){ 359 String name = "access$"+soot.javaToJimple.InitialResolver.v().getNextPrivateAccessCounter()+"00"; 360 ArrayList paramTypes = new ArrayList(); 361 paramTypes.add(classToInvoke.getType()); 362 363 soot.SootMethod meth = new soot.SootMethod(name, paramTypes, classToInvoke.getFieldByName("this$0").getType(), soot.Modifier.STATIC); 364 365 classToInvoke.addMethod(meth); 366 PrivateFieldAccMethodSource src = new PrivateFieldAccMethodSource( 367 classToInvoke.getFieldByName("this$0").getType(), 368 "this$0", 369 classToInvoke.getFieldByName("this$0").isStatic(), 370 classToInvoke 371 ); 372 meth.setActiveBody(src.getBody(meth, null)); 373 meth.addTag(new soot.tagkit.SyntheticTag()); 374 return meth; 375 } 376 377 public static soot.Local getPrivateAccessFieldInvoke(soot.SootMethodRef toInvoke, ArrayList params, soot.Body body, LocalGenerator lg){ 378 soot.jimple.InvokeExpr invoke = soot.jimple.Jimple.v().newStaticInvokeExpr(toInvoke, params); 379 380 soot.Local retLocal = lg.generateLocal(toInvoke.returnType()); 381 382 soot.jimple.AssignStmt stmt = soot.jimple.Jimple.v().newAssignStmt(retLocal, invoke); 383 body.getUnits().add(stmt); 384 385 return retLocal; 386 } 387 388 public static boolean isSubType(polyglot.types.ClassType type, polyglot.types.ClassType superType){ 389 if (type.equals(superType)) return true; 390 if (type.superType() == null) return false; 391 return isSubType((polyglot.types.ClassType)type.superType(), superType); 392 } 393 394 397 public static soot.Type getSootType(polyglot.types.Type type) { 398 399 if (type == null){ 400 throw new RuntimeException ("Trying to get soot type for null polyglot type"); 401 } 402 soot.Type sootType = null; 403 404 if (type.isInt()){ 405 sootType = soot.IntType.v(); 406 } 407 else if (type.isArray()){ 408 409 polyglot.types.Type polyglotBase = ((polyglot.types.ArrayType)type).base(); 410 while (polyglotBase instanceof polyglot.types.ArrayType) { 411 polyglotBase = ((polyglot.types.ArrayType)polyglotBase).base(); 412 } 413 soot.Type baseType = getSootType(polyglotBase); 414 int dims = ((polyglot.types.ArrayType)type).dims(); 415 416 sootType = soot.ArrayType.v(baseType, dims); 418 } 419 else if (type.isBoolean()){ 420 sootType = soot.BooleanType.v(); 421 } 422 else if (type.isByte()){ 423 sootType = soot.ByteType.v(); 424 } 425 else if (type.isChar()){ 426 sootType = soot.CharType.v(); 427 } 428 else if (type.isDouble()){ 429 sootType = soot.DoubleType.v(); 430 } 431 else if (type.isFloat()){ 432 sootType = soot.FloatType.v(); 433 } 434 else if (type.isLong()){ 435 sootType = soot.LongType.v(); 436 } 437 else if (type.isShort()){ 438 sootType = soot.ShortType.v(); 439 } 440 else if (type.isNull()){ 441 sootType = soot.NullType.v(); 442 } 443 else if (type.isVoid()){ 444 sootType = soot.VoidType.v(); 445 } 446 else if (type.isClass()){ 447 polyglot.types.ClassType classType = (polyglot.types.ClassType)type; 448 String className; 449 if (classType.isNested()) { 450 if (classType.isAnonymous() && (soot.javaToJimple.InitialResolver.v().getAnonTypeMap() != null) && soot.javaToJimple.InitialResolver.v().getAnonTypeMap().containsKey(new polyglot.util.IdentityKey(classType))){ 451 className = (String )soot.javaToJimple.InitialResolver.v().getAnonTypeMap().get(new polyglot.util.IdentityKey(classType)); 452 } 453 else if (classType.isLocal() && (soot.javaToJimple.InitialResolver.v().getLocalTypeMap() != null) && soot.javaToJimple.InitialResolver.v().getLocalTypeMap().containsKey(new polyglot.util.IdentityKey(classType))) { 454 className = (String )soot.javaToJimple.InitialResolver.v().getLocalTypeMap().get(new polyglot.util.IdentityKey(classType)); 455 } 456 else { 457 String fullName = classType.fullName(); 458 String pkgName = ""; 459 if (classType.package_() != null){ 460 pkgName = classType.package_().fullName(); 461 } 462 className = classType.name(); 463 464 if (classType.outer().isAnonymous() || classType.outer().isLocal()){ 465 className = getSootType(classType.outer()).toString()+"$"+className; 466 } 467 else { 468 while (classType.outer() != null){ 469 className = classType.outer().name()+"$"+className; 470 classType = classType.outer(); 471 } 472 473 if (!pkgName.equals("")){ 474 className = pkgName+"."+className; 475 } 476 } 477 } 478 } 479 else { 480 className = classType.fullName(); 481 } 482 483 sootType = soot.RefType.v(className); 484 } 485 else{ 486 throw new RuntimeException ("Unknown Type"); 487 } 488 return sootType; 489 } 490 491 492 495 public static int getModifier(polyglot.types.Flags flags) { 496 497 int modifier = 0; 498 499 if (flags.isPublic()){ 500 modifier = modifier | soot.Modifier.PUBLIC; 501 } 502 if (flags.isPrivate()){ 503 modifier = modifier | soot.Modifier.PRIVATE; 504 } 505 if (flags.isProtected()){ 506 modifier = modifier | soot.Modifier.PROTECTED; 507 } 508 if (flags.isFinal()){ 509 modifier = modifier | soot.Modifier.FINAL; 510 } 511 if (flags.isStatic()){ 512 modifier = modifier | soot.Modifier.STATIC; 513 } 514 if (flags.isNative()){ 515 modifier = modifier | soot.Modifier.NATIVE; 516 } 517 if (flags.isAbstract()){ 518 modifier = modifier | soot.Modifier.ABSTRACT; 519 } 520 if (flags.isVolatile()){ 521 modifier = modifier | soot.Modifier.VOLATILE; 522 } 523 if (flags.isTransient()){ 524 modifier = modifier | soot.Modifier.TRANSIENT; 525 } 526 if (flags.isSynchronized()){ 527 modifier = modifier | soot.Modifier.SYNCHRONIZED; 528 } 529 if (flags.isInterface()){ 530 modifier = modifier | soot.Modifier.INTERFACE; 531 } 532 if (flags.isStrictFP()) { 533 modifier = modifier | soot.Modifier.STRICTFP; 534 } 535 return modifier; 536 } 537 } 538
| Popular Tags
|