From: jjenista Date: Tue, 22 Jun 2010 18:37:39 +0000 (+0000) Subject: Getting taints to propagate in new analysis, no parameter taints, RBLOCK taints only X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=f3e0b2bea5e6e44fa3c1b49666594f65dd8a4475;p=IRC.git Getting taints to propagate in new analysis, no parameter taints, RBLOCK taints only --- diff --git a/Robust/src/Analysis/Disjoint/Canonical.java b/Robust/src/Analysis/Disjoint/Canonical.java index 372ff3b1..1caa1de7 100644 --- a/Robust/src/Analysis/Disjoint/Canonical.java +++ b/Robust/src/Analysis/Disjoint/Canonical.java @@ -892,125 +892,6 @@ abstract public class Canonical { } - /* - public static ReachSet toCalleeContext( ReachSet rs, - AllocSite as ) { - assert rs != null; - assert as != null; - assert rs.isCanonical(); - assert as.isCanonical(); - - CanonicalOp op = - new CanonicalOp( CanonicalOp.REACHSET_TOCALLEECONTEXT_ALLOCSITE, - rs, - as ); - - Canonical result = op2result.get( op ); - if( result != null ) { - return (ReachSet) result; - } - - // otherwise, no cached result... - ReachSet out = ReachSet.factory(); - Iterator itr = rs.iterator(); - while( itr.hasNext() ) { - ReachState state = itr.next(); - out = Canonical.add( out, - Canonical.toCalleeContext( state, as ) - ); - } - - assert out.isCanonical(); - op2result.put( op, out ); - return out; - } - */ - - /* - public static ReachState toCalleeContext( ReachState state, - AllocSite as ) { - assert state != null; - assert as != null; - assert state.isCanonical(); - assert as.isCanonical(); - - CanonicalOp op = - new CanonicalOp( CanonicalOp.REACHSTATE_TOCALLEECONTEXT_ALLOCSITE, - state, - as ); - - Canonical result = op2result.get( op ); - if( result != null ) { - return (ReachState) result; - } - - // otherwise, no cached result... - ReachState out = ReachState.factory(); - Iterator itr = state.iterator(); - while( itr.hasNext() ) { - ReachTuple rt = itr.next(); - - int age = as.getAgeCategory( rt.getHrnID() ); - - // this is the current mapping, where 0, 1, 2S were allocated - // in the current context, 0?, 1? and 2S? were allocated in a - // previous context, and we're translating to a future context - // - // 0 -> 0? - // 1 -> 1? - // 2S -> 2S? - // 2S* -> 2S?* - // - // 0? -> 2S? - // 1? -> 2S? - // 2S? -> 2S? - // 2S?* -> 2S?* - - if( age == AllocSite.AGE_notInThisSite ) { - // things not from the site just go back in - out = Canonical.union( out, rt ); - - } else if( age == AllocSite.AGE_summary || - rt.isOutOfContext() - ) { - // the in-context summary and all existing out-of-context - // stuff all become - out = Canonical.union( out, - ReachTuple.factory( as.getSummary(), - true, // multi - rt.getArity(), - true // out-of-context - ) - ); - } else { - // otherwise everything else just goes to an out-of-context - // version, everything else the same - Integer I = as.getAge( rt.getHrnID() ); - assert I != null; - - assert !rt.isMultiObject(); - - out = Canonical.union( out, - ReachTuple.factory( rt.getHrnID(), - rt.isMultiObject(), - rt.getArity(), - true // out-of-context - ) - ); - } - } - - out = Canonical.attach( out, - state.getPreds() - ); - - assert out.isCanonical(); - op2result.put( op, out ); - return out; - } - */ - - public static ReachSet toCallerContext( ReachSet rs, AllocSite as ) { assert rs != null; @@ -1372,6 +1253,35 @@ abstract public class Canonical { } + public static Taint attach( Taint t, + ExistPredSet preds ) { + assert t != null; + assert preds != null; + assert t.isCanonical(); + assert preds.isCanonical(); + + CanonicalOp op = + new CanonicalOp( CanonicalOp.TAINT_ATTACH_EXISTPREDSET, + t, + preds ); + + Canonical result = op2result.get( op ); + if( result != null ) { + return (Taint) result; + } + + // otherwise, no cached result... + Taint out = new Taint( t.sese, + t.insetVar, + t.allocSite ); + out.preds = Canonical.join( t.preds, + preds ); + + out = (Taint) makeCanonical( out ); + op2result.put( op, out ); + return out; + } + public static TaintSet add( TaintSet ts, Taint t ) { assert ts != null; @@ -1427,9 +1337,7 @@ abstract public class Canonical { Taint t2 = ts2.containsIgnorePreds( t1 ); if( t2 != null ) { - out.taints.add( Taint.factory( t1.callSite, - t1.paramIndex, - t1.sese, + out.taints.add( Taint.factory( t1.sese, t1.insetVar, t1.allocSite, Canonical.join( t1.preds, @@ -1457,4 +1365,60 @@ abstract public class Canonical { return out; } + public static TaintSet unionORpreds( TaintSet ts1, + TaintSet ts2 ) { + assert ts1 != null; + assert ts2 != null; + assert ts1.isCanonical(); + assert ts2.isCanonical(); + + CanonicalOp op = + new CanonicalOp( CanonicalOp.TAINTSET_UNIONORPREDS_TAINTSET, + ts1, + ts2 ); + + Canonical result = op2result.get( op ); + if( result != null ) { + return (TaintSet) result; + } + + // otherwise, no cached result... + TaintSet out = new TaintSet(); + + // first add everything from 1, and if it was also in 2 + // take the OR of the predicates + Iterator tItr = ts1.iterator(); + while( tItr.hasNext() ) { + Taint t1 = tItr.next(); + Taint t2 = ts2.containsIgnorePreds( t1 ); + + if( t2 != null ) { + out.taints.add( Taint.factory( t1.sese, + t1.insetVar, + t1.allocSite, + Canonical.join( t1.preds, + t2.preds + ) + ) ); + } else { + out.taints.add( t1 ); + } + } + + // then add everything in 2 that wasn't in 1 + tItr = ts2.iterator(); + while( tItr.hasNext() ) { + Taint t2 = tItr.next(); + Taint t1 = ts1.containsIgnorePreds( t2 ); + + if( t1 == null ) { + out.taints.add( t2 ); + } + } + + out = (TaintSet) makeCanonical( out ); + op2result.put( op, out ); + return out; + } + } diff --git a/Robust/src/Analysis/Disjoint/CanonicalOp.java b/Robust/src/Analysis/Disjoint/CanonicalOp.java index c32390cd..35afa5a9 100644 --- a/Robust/src/Analysis/Disjoint/CanonicalOp.java +++ b/Robust/src/Analysis/Disjoint/CanonicalOp.java @@ -34,9 +34,10 @@ public class CanonicalOp { public static final int REACHSTATE_UNSHADOW_ALLOCSITE = 0x08ef; public static final int REACHSTATE_MAKEPREDSTRUE = 0x0b9c; public static final int REACHSET_MAKEPREDSTRUE = 0xdead; + public static final int TAINT_ATTACH_EXISTPREDSET = 0xcce2; public static final int TAINTSET_ADD_TAINT = 0xcd17; public static final int TAINTSET_UNION_TAINTSET = 0xa835; - + public static final int TAINTSET_UNIONORPREDS_TAINTSET = 0x204f; protected int opCode; protected Canonical operand1; diff --git a/Robust/src/Analysis/Disjoint/ReachGraph.java b/Robust/src/Analysis/Disjoint/ReachGraph.java index 7c13cd45..2b554894 100644 --- a/Robust/src/Analysis/Disjoint/ReachGraph.java +++ b/Robust/src/Analysis/Disjoint/ReachGraph.java @@ -338,7 +338,12 @@ public class ReachGraph { edgeNew.getPreds() ) ); - + edgeExisting.setTaints( + Canonical.unionORpreds( edgeExisting.getTaints(), + edgeNew.getTaints() + ) + ); + } else { addRefEdge( src, dst, edgeNew ); } @@ -1401,6 +1406,12 @@ public class ReachGraph { ) { ReachSet out = ReachSet.factory(); + // when the mapping is null it means there were no + // predicates satisfied + if( calleeStatesSatisfied == null ) { + return out; + } + Iterator itr = rs.iterator(); while( itr.hasNext() ) { ReachState stateCallee = itr.next(); @@ -1439,67 +1450,57 @@ public class ReachGraph { } - // used below to convert a TaintSet's parameter index taints to - // a TaintSet of caller taints + // used below to convert a ReachSet to an equivalent + // version with shadow IDs merged into unshadowed IDs + protected ReachSet unshadow( ReachSet rs ) { + ReachSet out = rs; + Iterator asItr = allocSites.iterator(); + while( asItr.hasNext() ) { + AllocSite as = asItr.next(); + out = Canonical.unshadow( out, as ); + } + assert out.isCanonical(); + return out; + } + + + // used below to convert a TaintSet to its caller-context + // equivalent, just eliminate Taints with bad preds protected TaintSet - toCallerContext( TaintSet ts, - FlatCall fc, - FlatMethod fmCallee + toCallerContext( TaintSet ts, + Hashtable calleeTaintsSatisfied ) { - TaintSet out = TaintSet.factory(); + // when the mapping is null it means there were no + // predicates satisfied + if( calleeTaintsSatisfied == null ) { + return out; + } + Iterator itr = ts.iterator(); while( itr.hasNext() ) { - Taint t = itr.next(); - - if( !t.isParamTaint() ) { - // throw out non-parameter taints from callee - continue; - } - - // what argument does this taint map to? - TempDescriptor tdArg = - fc.getArgMatchingParamIndex( fmCallee, - t.getParamIndex() ); - VariableNode vnArg = td2vn.get( tdArg ); + Taint tCallee = itr.next(); - // what allocation site does this taint refer to? - AllocSite as = t.getAllocSite(); - - // look at the allocation sites that the - // arg references in the caller context--if - // the parameter taint matches, use the taints - // of the argument reference to grow the output set - Iterator reItr = vnArg.iteratorToReferencees(); - while( reItr.hasNext() ) { - RefEdge re = reItr.next(); + if( calleeTaintsSatisfied.containsKey( tCallee ) ) { - if( as.equals( re.getDst().getAllocSite() ) ) { - out = Canonical.union( out, - re.getTaints() - ); - } - } + Taint tCaller = + Canonical.attach( Taint.factory( tCallee.sese, + tCallee.insetVar, + tCallee.allocSite ), + calleeTaintsSatisfied.get( tCallee ) + ); + out = Canonical.add( out, + tCaller + ); + } } - + assert out.isCanonical(); return out; } - // used below to convert a ReachSet to an equivalent - // version with shadow IDs merged into unshadowed IDs - protected ReachSet unshadow( ReachSet rs ) { - ReachSet out = rs; - Iterator asItr = allocSites.iterator(); - while( asItr.hasNext() ) { - AllocSite as = asItr.next(); - out = Canonical.unshadow( out, as ); - } - assert out.isCanonical(); - return out; - } // use this method to make a new reach graph that is @@ -1700,17 +1701,8 @@ public class ReachGraph { ExistPredSet preds = ExistPredSet.factory( pred ); - Taint paramTaint = - Taint.factory( fc, - index, - null, - null, - hrnDstCallee.getAllocSite(), - preds - ); - TaintSet taints = - TaintSet.factory( paramTaint ); + TaintSet.factory(); RefEdge reCallee = new RefEdge( vnCallee, @@ -2053,15 +2045,21 @@ public class ReachGraph { Hashtable calleeEdgesSatisfied = new Hashtable(); - Hashtable calleeStatesSatisfied = - new Hashtable(); + Hashtable< HeapRegionNode, Hashtable > + calleeNode2calleeStatesSatisfied = + new Hashtable< HeapRegionNode, Hashtable >(); + + Hashtable< RefEdge, Hashtable > + calleeEdge2calleeStatesSatisfied = + new Hashtable< RefEdge, Hashtable >(); + + Hashtable< RefEdge, Hashtable > + calleeEdge2calleeTaintsSatisfied = + new Hashtable< RefEdge, Hashtable >(); Hashtable< RefEdge, Set > calleeEdges2oocCallerSrcMatches = new Hashtable< RefEdge, Set >(); - //Hashtable taintsSatisfied = - // new Hashtable(); - Iterator meItr = rgCallee.id2hrn.entrySet().iterator(); while( meItr.hasNext() ) { @@ -2095,17 +2093,14 @@ public class ReachGraph { stateCallee.getPreds().isSatisfiedBy( this, callerNodeIDsCopiedToCallee ); - if( predsIfSatis != null ) { - ExistPredSet predsAlready = calleeStatesSatisfied.get( stateCallee ); - if( predsAlready == null ) { - calleeStatesSatisfied.put( stateCallee, predsIfSatis ); - } else { - calleeStatesSatisfied.put( stateCallee, - Canonical.join( predsIfSatis, - predsAlready - ) - ); - } + if( predsIfSatis != null ) { + assert calleeNode2calleeStatesSatisfied.get( hrnCallee ) == null; + + Hashtable calleeStatesSatisfied = + new Hashtable(); + calleeStatesSatisfied.put( stateCallee, predsIfSatis ); + + calleeNode2calleeStatesSatisfied.put( hrnCallee, calleeStatesSatisfied ); } } @@ -2251,16 +2246,34 @@ public class ReachGraph { callerNodeIDsCopiedToCallee ); if( predsIfSatis != null ) { - ExistPredSet predsAlready = calleeStatesSatisfied.get( stateCallee ); - if( predsAlready == null ) { - calleeStatesSatisfied.put( stateCallee, predsIfSatis ); - } else { - calleeStatesSatisfied.put( stateCallee, - Canonical.join( predsIfSatis, - predsAlready - ) - ); - } + assert calleeEdge2calleeStatesSatisfied.get( reCallee ) == null; + + Hashtable calleeStatesSatisfied = + new Hashtable(); + calleeStatesSatisfied.put( stateCallee, predsIfSatis ); + + calleeEdge2calleeStatesSatisfied.put( reCallee, calleeStatesSatisfied ); + } + } + + // since the edge is coming over, find out which taints + // on it should come over, too + Iterator tItr = reCallee.getTaints().iterator(); + while( tItr.hasNext() ) { + Taint tCallee = tItr.next(); + + predsIfSatis = + tCallee.getPreds().isSatisfiedBy( this, + callerNodeIDsCopiedToCallee + ); + if( predsIfSatis != null ) { + assert calleeEdge2calleeTaintsSatisfied.get( reCallee ) == null; + + Hashtable calleeTaintsSatisfied = + new Hashtable(); + calleeTaintsSatisfied.put( tCallee, predsIfSatis ); + + calleeEdge2calleeTaintsSatisfied.put( reCallee, calleeTaintsSatisfied ); } } } @@ -2356,7 +2369,7 @@ public class ReachGraph { hrnCallee.getType(), // type hrnCallee.getAllocSite(), // allocation site toCallerContext( hrnCallee.getInherent(), - calleeStatesSatisfied ), // inherent reach + calleeNode2calleeStatesSatisfied.get( hrnCallee ) ), // inherent reach null, // current reach predsEmpty, // predicates hrnCallee.getDescription() // description @@ -2366,7 +2379,7 @@ public class ReachGraph { } hrnCaller.setAlpha( toCallerContext( hrnCallee.getAlpha(), - calleeStatesSatisfied + calleeNode2calleeStatesSatisfied.get( hrnCallee ) ) ); @@ -2492,11 +2505,10 @@ public class ReachGraph { reCallee.getType(), reCallee.getField(), toCallerContext( reCallee.getBeta(), - calleeStatesSatisfied ), + calleeEdge2calleeStatesSatisfied.get( reCallee ) ), preds, toCallerContext( reCallee.getTaints(), - fc, - fmCallee ) + calleeEdge2calleeTaintsSatisfied.get( reCallee ) ) ); ChangeSet cs = ChangeSet.factory(); @@ -2525,28 +2537,16 @@ public class ReachGraph { ); } } - - // look to see if an edge with same field exists - // and merge with it, otherwise just add the edge - RefEdge edgeExisting = rsnCaller.getReferenceTo( hrnDstCaller, - reCallee.getType(), - reCallee.getField() - ); - if( edgeExisting != null ) { - edgeExisting.setBeta( - Canonical.unionORpreds( edgeExisting.getBeta(), - reCaller.getBeta() - ) - ); - edgeExisting.setPreds( - Canonical.join( edgeExisting.getPreds(), - reCaller.getPreds() - ) - ); - - // for reach propagation - if( !cs.isEmpty() ) { + // we're just going to use the convenient "merge-if-exists" + // edge call below, but still take a separate look if there + // is an existing caller edge to build change sets properly + if( !cs.isEmpty() ) { + RefEdge edgeExisting = rsnCaller.getReferenceTo( hrnDstCaller, + reCallee.getType(), + reCallee.getField() + ); + if( edgeExisting != null ) { ChangeSet csExisting = edgePlannedChanges.get( edgeExisting ); if( csExisting == null ) { csExisting = ChangeSet.factory(); @@ -2555,19 +2555,16 @@ public class ReachGraph { Canonical.union( csExisting, cs ) - ); - } - - } else { - addRefEdge( rsnCaller, hrnDstCaller, reCaller ); - - // for reach propagation - if( !cs.isEmpty() ) { + ); + } else { edgesForPropagation.add( reCaller ); assert !edgePlannedChanges.containsKey( reCaller ); - edgePlannedChanges.put( reCaller, cs ); + edgePlannedChanges.put( reCaller, cs ); } } + + // then add new caller edge or merge + addEdgeOrMergeWithExisting( reCaller ); } } diff --git a/Robust/src/Analysis/Disjoint/Taint.java b/Robust/src/Analysis/Disjoint/Taint.java index 1f9f1ead..06ac9a9d 100644 --- a/Robust/src/Analysis/Disjoint/Taint.java +++ b/Robust/src/Analysis/Disjoint/Taint.java @@ -25,7 +25,7 @@ import java.io.*; // a taint is applied to a reference edge, and // is used to associate an effect with an -// sese (rblock) and in- +// sese (rblock) and live variable public class Taint extends Canonical { @@ -34,10 +34,6 @@ public class Taint extends Canonical { // an sese (rblock) and an in-set var // only one set of identifying objects // will be non-null - - // identify a parameter index - protected FlatCall callSite; - protected Integer paramIndex; // identify an sese (rblock) + inset var protected FlatSESEEnterNode sese; @@ -53,65 +49,36 @@ public class Taint extends Canonical { protected ExistPredSet preds; - public static Taint factory( FlatCall fc, - Integer pi, - FlatSESEEnterNode s, + public static Taint factory( FlatSESEEnterNode s, TempDescriptor iv, AllocSite as ) { - Taint out = new Taint( fc, pi, s, iv, as ); + Taint out = new Taint( s, iv, as ); out.preds = ExistPredSet.factory(); out = (Taint) Canonical.makeCanonical( out ); return out; } - public static Taint factory( FlatCall fc, - Integer pi, - FlatSESEEnterNode s, + public static Taint factory( FlatSESEEnterNode s, TempDescriptor iv, AllocSite as, ExistPredSet eps ) { - Taint out = new Taint( fc, pi, s, iv, as ); + Taint out = new Taint( s, iv, as ); out.preds = eps; out = (Taint) Canonical.makeCanonical( out ); return out; } - protected Taint( FlatCall fc, - Integer pi, - FlatSESEEnterNode s, + protected Taint( FlatSESEEnterNode s, TempDescriptor iv, - AllocSite as ) { - - // either fc and pi are non-null, OR s and iv are non-null - assert - (fc != null && pi != null && s == null && iv == null) || - (fc == null && pi == null && s != null && iv != null); - + AllocSite as ) { + assert s != null; + assert iv != null; assert as != null; - - callSite = fc; - paramIndex = pi; sese = s; insetVar = iv; allocSite = as; } - public boolean isParamTaint() { - return callSite != null; - } - - public boolean isSESETaint() { - return sese != null; - } - - public FlatCall getCallSite() { - return callSite; - } - - public Integer getParamIndex() { - return paramIndex; - } - public FlatSESEEnterNode getSESE() { return sese; } @@ -148,69 +115,24 @@ public class Taint extends Canonical { Taint t = (Taint) o; - boolean fcMatches = true; - if( callSite == null ) { - fcMatches = t.callSite == null; - } else { - fcMatches = callSite.equals( t.callSite ); - } - - boolean piMatches = true; - if( paramIndex == null ) { - piMatches = t.paramIndex == null; - } else { - piMatches = paramIndex.equals( t.paramIndex ); - } - - boolean sMatches = true; - if( sese == null ) { - sMatches = t.sese == null; - } else { - sMatches = sese.equals( t.sese ); - } - - boolean ivMatches = true; - if( insetVar == null ) { - ivMatches = t.insetVar == null; - } else { - ivMatches = insetVar.equals( t.insetVar ); - } - - return allocSite.equals( t.allocSite ) && - piMatches && sMatches && ivMatches; + return + sese .equals( t.sese ) && + insetVar .equals( t.insetVar ) && + allocSite.equals( t.allocSite ); } public int hashCodeSpecific() { int hash = allocSite.hashCode(); - - if( callSite != null ) { - hash = hash ^ callSite.hashCode(); - } - - if( paramIndex != null ) { - hash = hash ^ paramIndex.hashCode(); - } - - if( sese != null ) { - hash = hash ^ sese.hashCode(); - } - - if( insetVar != null ) { - hash = hash ^ insetVar.hashCode(); - } - + hash = hash ^ sese.hashCode(); + hash = hash ^ insetVar.hashCode(); return hash; } public String toString() { - String s = "("; - - if( isParamTaint() ) { - s += "cs"+callSite.nodeid+"-"+paramIndex; - } else { - s += sese.toPrettyString()+"-"+insetVar; - } - - return s+", "+allocSite.toStringBrief()+"):"+preds; + return + "("+sese.toPrettyString()+ + "-"+insetVar+ + ", "+allocSite.toStringBrief()+ + "):"+preds; } }