1 19 20 package soot.jimple.spark.pag; 21 import java.util.*; 22 23 import soot.*; 24 import soot.jimple.*; 25 import soot.jimple.spark.*; 26 import soot.jimple.spark.builder.*; 27 import soot.jimple.spark.internal.*; 28 import soot.util.*; 29 import soot.util.queue.*; 30 import soot.toolkits.scalar.Pair; 31 import soot.jimple.toolkits.pointer.util.NativeMethodDriver; 32 33 34 37 public final class MethodPAG { 38 private PAG pag; 39 public PAG pag() { return pag; } 40 41 protected MethodPAG( PAG pag, SootMethod m ) { 42 this.pag = pag; 43 this.method = m; 44 this.nodeFactory = new MethodNodeFactory( pag, this ); 45 } 46 47 private Set addedContexts; 48 49 51 public void addToPAG( Context varNodeParameter ) { 52 if( !hasBeenBuilt ) throw new RuntimeException (); 53 if( varNodeParameter == null ) { 54 if( hasBeenAdded ) return; 55 hasBeenAdded = true; 56 } else { 57 if( addedContexts == null ) addedContexts = new HashSet(); 58 if( !addedContexts.add( varNodeParameter ) ) return; 59 } 60 QueueReader reader = (QueueReader) internalReader.clone(); 61 while(reader.hasNext()) { 62 Node src = (Node) reader.next(); 63 src = parameterize( src, varNodeParameter ); 64 Node dst = (Node) reader.next(); 65 dst = parameterize( dst, varNodeParameter ); 66 pag.addEdge( src, dst ); 67 } 68 reader = (QueueReader) inReader.clone(); 69 while(reader.hasNext()) { 70 Node src = (Node) reader.next(); 71 Node dst = (Node) reader.next(); 72 dst = parameterize( dst, varNodeParameter ); 73 pag.addEdge( src, dst ); 74 } 75 reader = (QueueReader) outReader.clone(); 76 while(reader.hasNext()) { 77 Node src = (Node) reader.next(); 78 src = parameterize( src, varNodeParameter ); 79 Node dst = (Node) reader.next(); 80 pag.addEdge( src, dst ); 81 } 82 } 83 public void addInternalEdge( Node src, Node dst ) { 84 if( src == null ) return; 85 internalEdges.add( src ); 86 internalEdges.add( dst ); 87 } 88 public void addInEdge( Node src, Node dst ) { 89 if( src == null ) return; 90 inEdges.add( src ); 91 inEdges.add( dst ); 92 } 93 public void addOutEdge( Node src, Node dst ) { 94 if( src == null ) return; 95 outEdges.add( src ); 96 outEdges.add( dst ); 97 } 98 private ChunkedQueue internalEdges = new ChunkedQueue(); 99 private ChunkedQueue inEdges = new ChunkedQueue(); 100 private ChunkedQueue outEdges = new ChunkedQueue(); 101 private QueueReader internalReader = internalEdges.reader(); 102 private QueueReader inReader = inEdges.reader(); 103 private QueueReader outReader = outEdges.reader(); 104 105 SootMethod method; 106 public SootMethod getMethod() { return method; } 107 protected MethodNodeFactory nodeFactory; 108 public MethodNodeFactory nodeFactory() { return nodeFactory; } 109 110 public static MethodPAG v( PAG pag, SootMethod m ) { 111 MethodPAG ret = (MethodPAG) G.v().MethodPAG_methodToPag.get( m ); 112 if( ret == null ) { 113 ret = new MethodPAG( pag, m ); 114 G.v().MethodPAG_methodToPag.put( m, ret ); 115 } 116 return ret; 117 } 118 119 public void build() { 120 if( hasBeenBuilt ) return; 121 hasBeenBuilt = true; 122 if( method.isNative() ) { 123 if( pag().getOpts().simulate_natives() ) { 124 buildNative(); 125 } 126 } else { 127 if( method.isConcrete() && !method.isPhantom() ) { 128 buildNormal(); 129 } 130 } 131 addMiscEdges(); 132 } 133 134 protected VarNode parameterize( LocalVarNode vn, Context varNodeParameter ) { 135 SootMethod m = vn.getMethod(); 136 if( m != method && m != null ) throw new RuntimeException ( "VarNode "+vn+" with method "+m+" parameterized in method "+method ); 137 return pag().makeContextVarNode( vn, varNodeParameter ); 139 } 140 protected FieldRefNode parameterize( FieldRefNode frn, Context varNodeParameter ) { 141 return pag().makeFieldRefNode( 142 (VarNode) parameterize( frn.getBase(), varNodeParameter ), 143 frn.getField() ); 144 } 145 public Node parameterize( Node n, Context varNodeParameter ) { 146 if( varNodeParameter == null ) return n; 147 if( n instanceof LocalVarNode ) 148 return parameterize( (LocalVarNode) n, varNodeParameter); 149 if( n instanceof FieldRefNode ) 150 return parameterize( (FieldRefNode) n, varNodeParameter); 151 return n; 152 } 153 protected boolean hasBeenAdded = false; 154 protected boolean hasBeenBuilt = false; 155 156 protected void buildNormal() { 157 Body b = method.retrieveActiveBody(); 158 Iterator unitsIt = b.getUnits().iterator(); 159 while( unitsIt.hasNext() ) 160 { 161 Stmt s = (Stmt) unitsIt.next(); 162 nodeFactory.handleStmt( s ); 163 } 164 } 165 protected void buildNative() { 166 ValNode thisNode = null; 167 ValNode retNode = null; 168 if( !method.isStatic() ) { 169 thisNode = (ValNode) nodeFactory.caseThis(); 170 } 171 if( method.getReturnType() instanceof RefLikeType ) { 172 retNode = (ValNode) nodeFactory.caseRet(); 173 } 174 ValNode[] args = new ValNode[ method.getParameterCount() ]; 175 for( int i = 0; i < method.getParameterCount(); i++ ) { 176 if( !( method.getParameterType(i) instanceof RefLikeType ) ) continue; 177 args[i] = (ValNode) nodeFactory.caseParm(i); 178 } 179 pag.nativeMethodDriver.process( method, thisNode, retNode, args ); 180 } 181 182 protected void addMiscEdges() { 183 if( method.getSubSignature().equals( SootMethod.getSubSignature( "main", new SingletonList( ArrayType.v(RefType.v("java.lang.String"), 1) ), VoidType.v() ) ) ) { 185 addInEdge( pag().nodeFactory().caseArgv(), nodeFactory.caseParm(0) ); 186 } 187 188 if( method.getSignature().equals( 189 "<java.lang.Thread: void <init>(java.lang.ThreadGroup,java.lang.String)>" ) ) { 190 addInEdge( pag().nodeFactory().caseMainThread(), nodeFactory.caseThis() ); 191 addInEdge( pag().nodeFactory().caseMainThreadGroup(), nodeFactory.caseParm( 0 ) ); 192 } 193 194 if( method.getSubSignature().equals( 195 "java.lang.Class loadClass(java.lang.String)" ) ) { 196 SootClass c = method.getDeclaringClass(); 197 outer: do { 198 while( !c.getName().equals( "java.lang.ClassLoader" ) ) { 199 if( !c.hasSuperclass() ) { 200 break outer; 201 } 202 c = c.getSuperclass(); 203 } 204 addInEdge( pag().nodeFactory().caseDefaultClassLoader(), 205 nodeFactory.caseThis() ); 206 addInEdge( pag().nodeFactory().caseMainClassNameString(), 207 nodeFactory.caseParm(0) ); 208 } while( false ); 209 } 210 } 211 } 212 213 | Popular Tags |