1 20 21 26 27 28 package soot; 29 import soot.*; 30 import soot.options.*; 31 32 import soot.coffi.*; 33 import java.util.*; 34 import java.io.*; 35 import soot.util.*; 36 import soot.jimple.*; 37 import soot.javaToJimple.*; 38 39 40 public class SootResolver 41 { 42 43 private Map classToReferences = new HashMap(); 44 45 46 private LinkedList[] worklist = new LinkedList[4]; 47 48 public SootResolver (Singletons.Global g) { 49 worklist[SootClass.HIERARCHY] = new LinkedList(); 50 worklist[SootClass.SIGNATURES] = new LinkedList(); 51 worklist[SootClass.BODIES] = new LinkedList(); 52 } 53 54 public static SootResolver v() { return G.v().soot_SootResolver();} 55 56 57 private boolean resolveEverything() { 58 return( Options.v().whole_program() || Options.v().whole_shimple() 59 || Options.v().full_resolver() 60 || Options.v().output_format() == Options.v().output_format_dava ); 61 } 62 63 67 public SootClass makeClassRef(String className) 68 { 69 if(Scene.v().containsClass(className)) 70 return Scene.v().getSootClass(className); 71 72 SootClass newClass; 73 newClass = new SootClass(className); 74 newClass.setResolvingLevel(SootClass.DANGLING); 75 Scene.v().addClass(newClass); 76 77 return newClass; 78 } 79 80 81 86 public SootClass resolveClass(String className, int desiredLevel) { 87 SootClass resolvedClass = makeClassRef(className); 88 addToResolveWorklist(resolvedClass, desiredLevel); 89 processResolveWorklist(); 90 return resolvedClass; 91 } 92 93 94 private void processResolveWorklist() { 95 for( int i = SootClass.BODIES; i >= SootClass.HIERARCHY; i-- ) { 96 while( !worklist[i].isEmpty() ) { 97 SootClass sc = (SootClass) worklist[i].removeFirst(); 98 if( resolveEverything() ) { 99 if( sc.isPhantom() ) bringToSignatures(sc); 100 else bringToBodies(sc); 101 } else { 102 switch(i) { 103 case SootClass.BODIES: bringToBodies(sc); break; 104 case SootClass.SIGNATURES: bringToSignatures(sc); break; 105 case SootClass.HIERARCHY: bringToHierarchy(sc); break; 106 } 107 } 108 } 109 } 110 } 111 112 private void addToResolveWorklist(Type type, int level) { 113 if( type instanceof RefType ) 114 addToResolveWorklist(((RefType) type).getClassName(), level); 115 else if( type instanceof ArrayType ) 116 addToResolveWorklist(((ArrayType) type).baseType, level); 117 } 118 private void addToResolveWorklist(String className, int level) { 119 addToResolveWorklist(makeClassRef(className), level); 120 } 121 private void addToResolveWorklist(SootClass sc, int desiredLevel) { 122 if( sc.resolvingLevel() >= desiredLevel ) return; 123 worklist[desiredLevel].add(sc); 124 } 125 126 129 private void bringToHierarchy(SootClass sc) { 130 if(sc.resolvingLevel() >= SootClass.HIERARCHY ) return; 131 if(Options.v().debug_resolver()) 132 G.v().out.println("bringing to HIERARCHY: "+sc); 133 sc.setResolvingLevel(SootClass.HIERARCHY); 134 135 String className = sc.getName(); 136 ClassSource is = SourceLocator.v().getClassSource(className); 137 if( is == null ) { 138 if(!Scene.v().allowsPhantomRefs()) { 139 throw new RuntimeException ("couldn't find class: " + 140 className + " (is your soot-class-path set properly?)"); 141 } else { 142 G.v().out.println( 143 "Warning: " + className + " is a phantom class!"); 144 sc.setPhantomClass(); 145 classToReferences.put( sc, new ArrayList() ); 146 } 147 } else { 148 Collection references = is.resolve(sc); 149 classToReferences.put( sc, new ArrayList(new HashSet(references)) ); 150 } 151 reResolveHierarchy(sc); 152 } 153 154 public void reResolveHierarchy(SootClass sc) { 155 if(sc.hasSuperclass()) 157 addToResolveWorklist(sc.getSuperclass(), SootClass.HIERARCHY); 158 if(sc.hasOuterClass()) 159 addToResolveWorklist(sc.getOuterClass(), SootClass.HIERARCHY); 160 for( Iterator ifaceIt = sc.getInterfaces().iterator(); ifaceIt.hasNext(); ) { 161 final SootClass iface = (SootClass) ifaceIt.next(); 162 addToResolveWorklist(iface, SootClass.HIERARCHY); 163 } 164 165 } 166 167 170 private void bringToSignatures(SootClass sc) { 171 if(sc.resolvingLevel() >= SootClass.SIGNATURES ) return; 172 bringToHierarchy(sc); 173 if(Options.v().debug_resolver()) 174 G.v().out.println("bringing to SIGNATURES: "+sc); 175 sc.setResolvingLevel(SootClass.SIGNATURES); 176 177 for( Iterator fIt = sc.getFields().iterator(); fIt.hasNext(); ) { 178 179 final SootField f = (SootField) fIt.next(); 180 addToResolveWorklist( f.getType(), SootClass.HIERARCHY ); 181 } 182 for( Iterator mIt = sc.getMethods().iterator(); mIt.hasNext(); ) { 183 final SootMethod m = (SootMethod) mIt.next(); 184 addToResolveWorklist( m.getReturnType(), SootClass.HIERARCHY ); 185 for( Iterator ptypeIt = m.getParameterTypes().iterator(); ptypeIt.hasNext(); ) { 186 final Type ptype = (Type) ptypeIt.next(); 187 addToResolveWorklist( ptype, SootClass.HIERARCHY ); 188 } 189 for( Iterator exceptionIt = m.getExceptions().iterator(); exceptionIt.hasNext(); ) { 190 final SootClass exception = (SootClass) exceptionIt.next(); 191 addToResolveWorklist( exception, SootClass.HIERARCHY ); 192 } 193 } 194 195 if(sc.hasSuperclass()) 197 addToResolveWorklist(sc.getSuperclass(), SootClass.SIGNATURES); 198 for( Iterator ifaceIt = sc.getInterfaces().iterator(); ifaceIt.hasNext(); ) { 199 final SootClass iface = (SootClass) ifaceIt.next(); 200 addToResolveWorklist(iface, SootClass.SIGNATURES); 201 } 202 } 203 204 212 private void bringToBodies(SootClass sc) { 213 if(sc.resolvingLevel() >= SootClass.BODIES ) return; 214 bringToSignatures(sc); 215 if(Options.v().debug_resolver()) 216 G.v().out.println("bringing to BODIES: "+sc); 217 sc.setResolvingLevel(SootClass.BODIES); 218 219 Collection references = (Collection) classToReferences.get(sc); 220 if( references == null ) return; 221 222 Iterator it = references.iterator(); 223 while( it.hasNext() ) { 224 final Object o = it.next(); 225 226 if( o instanceof String ) { 227 addToResolveWorklist((String ) o, SootClass.SIGNATURES); 228 } else if( o instanceof Type ) { 229 addToResolveWorklist((Type) o, SootClass.SIGNATURES); 230 } else throw new RuntimeException (o.toString()); 231 } 232 } 233 234 public void reResolve(SootClass cl) { 235 int resolvingLevel = cl.resolvingLevel(); 236 if( resolvingLevel < SootClass.HIERARCHY ) return; 237 reResolveHierarchy(cl); 238 cl.setResolvingLevel(SootClass.HIERARCHY); 239 addToResolveWorklist(cl, resolvingLevel); 240 processResolveWorklist(); 241 } 242 } 243 244 245 | Popular Tags |