1 19 20 package soot.jimple.spark.pag; 21 import java.util.*; 22 import soot.jimple.spark.*; 23 import soot.*; 24 import soot.jimple.spark.sets.*; 25 import java.io.*; 26 import soot.jimple.spark.solver.TopoSorter; 27 import soot.jimple.spark.sets.PointsToSetInternal; 28 29 32 public class PAGDumper { 33 public PAGDumper( PAG pag , String output_dir ) { 34 this.pag = pag; 35 this.output_dir = output_dir; 36 } 37 public void dumpPointsToSets() { 38 try { 39 final PrintWriter file = new PrintWriter( 40 new FileOutputStream( new File(output_dir, "solution") ) ); 41 file.println( "Solution:" ); 42 for( Iterator vnIt = pag.getVarNodeNumberer().iterator(); vnIt.hasNext(); ) { 43 final VarNode vn = (VarNode) vnIt.next(); 44 if( vn.getReplacement() != vn ) { 45 continue; 46 } 47 PointsToSetInternal p2set = vn.getP2Set(); 48 if( p2set == null ) continue; 49 p2set.forall( new P2SetVisitor() { 50 public final void visit( Node n ) { 51 try { 52 dumpNode( vn, file ); 53 file.print( " " ); 54 dumpNode( n, file ); 55 file.println( "" ); 56 } catch( IOException e ) { 57 throw new RuntimeException ( "Couldn't dump solution."+e ); 58 } 59 } 60 } ); 61 } 62 file.close(); 63 } catch( IOException e ) { 64 throw new RuntimeException ( "Couldn't dump solution."+e ); 65 } 66 } 67 public void dump() { 68 try { 69 PrintWriter file = new PrintWriter( 70 new FileOutputStream( new File(output_dir, "pag") ) ); 71 72 if( pag.getOpts().topo_sort() ) { 73 new TopoSorter( pag, false ).sort(); 74 } 75 file.println( "Allocations:" ); 76 for( Iterator nIt = pag.allocSources().iterator(); nIt.hasNext(); ) { 77 final AllocNode n = (AllocNode) nIt.next(); 78 if( n.getReplacement() != n ) continue; 79 Node[] succs = pag.allocLookup( n ); 80 for( int i = 0; i < succs.length; i++ ) { 81 dumpNode( n, file ); 82 file.print( " "); 83 dumpNode( succs[i], file ); 84 file.println( ""); 85 } 86 } 87 88 file.println( "Assignments:" ); 89 for( Iterator nIt = pag.simpleSources().iterator(); nIt.hasNext(); ) { 90 final VarNode n = (VarNode) nIt.next(); 91 if( n.getReplacement() != n ) continue; 92 Node[] succs = pag.simpleLookup( n ); 93 for( int i = 0; i < succs.length; i++ ) { 94 dumpNode( n, file ); 95 file.print( " "); 96 dumpNode( succs[i], file ); 97 file.println( ""); 98 } 99 } 100 101 file.println( "Loads:" ); 102 for( Iterator nIt = pag.loadSources().iterator(); nIt.hasNext(); ) { 103 final FieldRefNode n = (FieldRefNode) nIt.next(); 104 Node[] succs = pag.loadLookup( n ); 105 for( int i = 0; i < succs.length; i++ ) { 106 dumpNode( n, file ); 107 file.print( " "); 108 dumpNode( succs[i], file ); 109 file.println( ""); 110 } 111 } 112 file.println( "Stores:" ); 113 for( Iterator nIt = pag.storeSources().iterator(); nIt.hasNext(); ) { 114 final VarNode n = (VarNode) nIt.next(); 115 if( n.getReplacement() != n ) continue; 116 Node[] succs = pag.storeLookup( n ); 117 for( int i = 0; i < succs.length; i++ ) { 118 dumpNode( n, file ); 119 file.print( " "); 120 dumpNode( succs[i], file ); 121 file.println( ""); 122 } 123 } 124 if( pag.getOpts().dump_types() ) { 125 dumpTypes( file ); 126 } 127 file.close(); 128 } catch( IOException e ) { 129 throw new RuntimeException ( "Couldn't dump PAG."+e ); 130 } 131 } 132 133 134 135 136 137 protected PAG pag; 138 protected String output_dir; 139 protected int fieldNum = 0; 140 protected HashMap fieldMap = new HashMap(); 141 protected ObjectNumberer root = new ObjectNumberer( null, 0 ); 142 143 protected void dumpTypes( PrintWriter file ) throws IOException { 144 HashSet declaredTypes = new HashSet(); 145 HashSet actualTypes = new HashSet(); 146 HashSet allFields = new HashSet(); 147 for( Iterator nIt = pag.getVarNodeNumberer().iterator(); nIt.hasNext(); ) { 148 final Node n = (Node) nIt.next(); 149 Type t = n.getType(); 150 if( t != null ) declaredTypes.add( t ); 151 } 152 for( Iterator nIt = pag.loadSources().iterator(); nIt.hasNext(); ) { 153 final Node n = (Node) nIt.next(); 154 if( n.getReplacement() != n ) continue; 155 Type t = n.getType(); 156 if( t != null ) declaredTypes.add( t ); 157 allFields.add( ((FieldRefNode) n ).getField() ); 158 } 159 for( Iterator nIt = pag.storeInvSources().iterator(); nIt.hasNext(); ) { 160 final Node n = (Node) nIt.next(); 161 if( n.getReplacement() != n ) continue; 162 Type t = n.getType(); 163 if( t != null ) declaredTypes.add( t ); 164 allFields.add( ((FieldRefNode) n ).getField() ); 165 } 166 for( Iterator nIt = pag.allocSources().iterator(); nIt.hasNext(); ) { 167 final Node n = (Node) nIt.next(); 168 if( n.getReplacement() != n ) continue; 169 Type t = n.getType(); 170 if( t != null ) actualTypes.add( t ); 171 } 172 HashMap typeToInt = new HashMap(); 173 int nextint = 1; 174 for( Iterator it = declaredTypes.iterator(); it.hasNext(); ) { 175 typeToInt.put( it.next(), new Integer ( nextint++ ) ); 176 } 177 for( Iterator tIt = actualTypes.iterator(); tIt.hasNext(); ) { 178 final Type t = (Type) tIt.next(); 179 if( !typeToInt.containsKey( t ) ) { 180 typeToInt.put( t, new Integer ( nextint++ ) ); 181 } 182 } 183 file.println( "Declared Types:" ); 184 for( Iterator declTypeIt = declaredTypes.iterator(); declTypeIt.hasNext(); ) { 185 final Type declType = (Type) declTypeIt.next(); 186 for( Iterator actTypeIt = actualTypes.iterator(); actTypeIt.hasNext(); ) { 187 final Type actType = (Type) actTypeIt.next(); 188 if( pag.getTypeManager().castNeverFails( actType, declType ) ) { 189 file.println( ""+typeToInt.get( declType )+" "+typeToInt.get( actType ) ); 190 } 191 } 192 } 193 file.println( "Allocation Types:" ); 194 for( Iterator nIt = pag.allocSources().iterator(); nIt.hasNext(); ) { 195 final Node n = (Node) nIt.next(); 196 if( n.getReplacement() != n ) continue; 197 Type t = n.getType(); 198 dumpNode( n, file ); 199 if( t == null ) { 200 throw new RuntimeException ( "allocnode with null type" ); 201 } else { 203 file.println( " "+typeToInt.get( t ) ); 204 } 205 } 206 file.println( "Variable Types:" ); 207 for( Iterator nIt = pag.getVarNodeNumberer().iterator(); nIt.hasNext(); ) { 208 final Node n = (Node) nIt.next(); 209 if( n.getReplacement() != n ) continue; 210 Type t = n.getType(); 211 dumpNode( n, file ); 212 if( t == null ) { 213 file.println( " 0" ); 214 } else { 215 file.println( " "+typeToInt.get( t ) ); 216 } 217 } 218 } 219 protected int fieldToNum( SparkField f ) { 220 Integer ret = (Integer ) fieldMap.get( f ); 221 if( ret == null ) { 222 ret = new Integer ( ++ fieldNum ); 223 fieldMap.put( f, ret ); 224 } 225 return ret.intValue(); 226 } 227 protected void dumpNode( Node n, PrintWriter out ) throws IOException { 228 if( n.getReplacement() != n ) throw new RuntimeException ( "Attempt to dump collapsed node." ); 229 if( n instanceof FieldRefNode ) { 230 FieldRefNode fn = (FieldRefNode) n; 231 dumpNode( fn.getBase(), out ); 232 out.print( " "+fieldToNum( fn.getField() ) ); 233 } else if( pag.getOpts().class_method_var() && n instanceof VarNode ) { 234 VarNode vn = (VarNode) n; 235 SootMethod m = null; 236 if( vn instanceof LocalVarNode ) { 237 m = ((LocalVarNode)vn).getMethod(); 238 } 239 SootClass c = null; 240 if( m != null ) c = m.getDeclaringClass(); 241 ObjectNumberer cl = root.findOrAdd( c ); 242 ObjectNumberer me = cl.findOrAdd( m ); 243 ObjectNumberer vr = me.findOrAdd( vn ); 244 250 out.print( ""+cl.num+" "+me.num+" "+vr.num ); 251 } else if( pag.getOpts().topo_sort() && n instanceof VarNode ) { 252 out.print( ""+((VarNode) n).finishingNumber ); 253 } else { 254 out.print( ""+n.getNumber() ); 255 } 256 } 257 258 class ObjectNumberer { 259 Object o = null; 260 int num = 0; 261 int nextChildNum = 1; 262 HashMap children = null; 263 264 ObjectNumberer( Object o, int num ) { 265 this.o = o; this.num = num; 266 } 267 268 ObjectNumberer findOrAdd( Object child ) { 269 if( children == null ) children = new HashMap(); 270 ObjectNumberer ret = (ObjectNumberer) children.get( child ); 271 if( ret == null ) { 272 ret = new ObjectNumberer( child, nextChildNum++ ); 273 children.put( child, ret ); 274 } 275 return ret; 276 } 277 } 278 } 279 280 | Popular Tags |