@@ -2,8 +2,10 @@ private import codeql.util.Boolean
22private import codeql.util.Unit
33private import powershell
44private import semmle.code.powershell.Cfg
5+ private import semmle.code.powershell.dataflow.Ssa
56private import DataFlowPublic
67private import DataFlowDispatch
8+ private import SsaImpl as SsaImpl
79
810/** Gets the callable in which this node occurs. */
911DataFlowCallable nodeGetEnclosingCallable ( Node n ) { result = n .( NodeImpl ) .getEnclosingCallable ( ) }
@@ -39,9 +41,40 @@ private class ExprNodeImpl extends ExprNode, NodeImpl {
3941 override string toStringImpl ( ) { result = this .getExprNode ( ) .toString ( ) }
4042}
4143
44+ /** Gets the SSA definition node corresponding to parameter `p`. */
45+ pragma [ nomagic]
46+ SsaImpl:: DefinitionExt getParameterDef ( Parameter p ) {
47+ exists ( EntryBasicBlock bb , int i |
48+ SsaImpl:: parameterWrite ( bb , i , p ) and
49+ result .definesAt ( p , bb , i , _)
50+ )
51+ }
52+
4253/** Provides logic related to SSA. */
4354module SsaFlow {
44- // TODO
55+ private module Impl = SsaImpl:: DataFlowIntegration;
56+
57+ private ParameterNodeImpl toParameterNode ( SsaImpl:: ParameterExt p ) {
58+ result = TNormalParameterNode ( p .asParameter ( ) )
59+ }
60+
61+ Impl:: Node asNode ( Node n ) {
62+ n = TSsaNode ( result )
63+ or
64+ result .( Impl:: ExprNode ) .getExpr ( ) = n .asExpr ( )
65+ or
66+ result .( Impl:: ExprPostUpdateNode ) .getExpr ( ) = n .( PostUpdateNode ) .getPreUpdateNode ( ) .asExpr ( )
67+ or
68+ n = toParameterNode ( result .( Impl:: ParameterNode ) .getParameter ( ) )
69+ }
70+
71+ predicate localFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo , boolean isUseStep ) {
72+ Impl:: localFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) , isUseStep )
73+ }
74+
75+ predicate localMustFlowStep ( SsaImpl:: DefinitionExt def , Node nodeFrom , Node nodeTo ) {
76+ Impl:: localMustFlowStep ( def , asNode ( nodeFrom ) , asNode ( nodeTo ) )
77+ }
4578}
4679
4780/** Provides predicates related to local data flow. */
@@ -54,19 +87,6 @@ module LocalFlow {
5487 predicate localMustFlowStep ( Node node1 , Node node2 ) { none ( ) }
5588}
5689
57- /** An argument of a call (including qualifier arguments and block arguments). */
58- private class Argument extends CfgNodes:: ExprCfgNode {
59- private CfgNodes:: StmtNodes:: CmdCfgNode call ;
60- private ArgumentPosition arg ;
61-
62- Argument ( ) { none ( ) }
63-
64- /** Holds if this expression is the `i`th argument of `c`. */
65- predicate isArgumentOf ( CfgNodes:: StmtNodes:: CmdCfgNode c , ArgumentPosition pos ) {
66- c = call and pos = arg
67- }
68- }
69-
7090/** Provides logic related to captured variables. */
7191module VariableCapture {
7292 // TODO
@@ -78,8 +98,11 @@ private module Cached {
7898 cached
7999 newtype TNode =
80100 TExprNode ( CfgNodes:: ExprCfgNode n ) or
101+ TSsaNode ( SsaImpl:: DataFlowIntegration:: SsaNode node ) or
102+ TNormalParameterNode ( Parameter p ) or
81103 TExprPostUpdateNode ( CfgNodes:: ExprCfgNode n ) {
82- none ( ) // TODO
104+ n instanceof CfgNodes:: ExprNodes:: ArgumentCfgNode or
105+ n instanceof CfgNodes:: ExprNodes:: QualifierCfgNode
83106 }
84107
85108 cached
@@ -117,6 +140,60 @@ import Cached
117140/** Holds if `n` should be hidden from path explanations. */
118141predicate nodeIsHidden ( Node n ) { none ( ) }
119142
143+ /** An SSA node. */
144+ abstract class SsaNode extends NodeImpl , TSsaNode {
145+ SsaImpl:: DataFlowIntegration:: SsaNode node ;
146+ SsaImpl:: DefinitionExt def ;
147+
148+ SsaNode ( ) {
149+ this = TSsaNode ( node ) and
150+ def = node .getDefinitionExt ( )
151+ }
152+
153+ SsaImpl:: DefinitionExt getDefinitionExt ( ) { result = def }
154+
155+ /** Holds if this node should be hidden from path explanations. */
156+ abstract predicate isHidden ( ) ;
157+
158+ override Location getLocationImpl ( ) { result = node .getLocation ( ) }
159+
160+ override string toStringImpl ( ) { result = node .toString ( ) }
161+ }
162+
163+ /** An (extended) SSA definition, viewed as a node in a data flow graph. */
164+ class SsaDefinitionExtNode extends SsaNode {
165+ override SsaImpl:: DataFlowIntegration:: SsaDefinitionExtNode node ;
166+
167+ /** Gets the underlying variable. */
168+ Variable getVariable ( ) { result = def .getSourceVariable ( ) }
169+
170+ override predicate isHidden ( ) {
171+ not def instanceof Ssa:: WriteDefinition
172+ or
173+ def = getParameterDef ( _)
174+ }
175+
176+ override CfgScope getCfgScope ( ) { result = def .getBasicBlock ( ) .getScope ( ) }
177+ }
178+
179+ class SsaDefinitionNodeImpl extends SsaDefinitionExtNode {
180+ Ssa:: Definition ssaDef ;
181+
182+ SsaDefinitionNodeImpl ( ) { ssaDef = def }
183+
184+ override Location getLocationImpl ( ) { result = ssaDef .getLocation ( ) }
185+
186+ override string toStringImpl ( ) { result = ssaDef .toString ( ) }
187+ }
188+
189+ class SsaInputNode extends SsaNode {
190+ override SsaImpl:: DataFlowIntegration:: SsaInputNode node ;
191+
192+ override predicate isHidden ( ) { any ( ) }
193+
194+ override CfgScope getCfgScope ( ) { result = node .getDefinitionExt ( ) .getBasicBlock ( ) .getScope ( ) }
195+ }
196+
120197private module ParameterNodes {
121198 abstract class ParameterNodeImpl extends NodeImpl {
122199 abstract Parameter getParameter ( ) ;
@@ -130,7 +207,30 @@ private module ParameterNodes {
130207 )
131208 }
132209 }
133- // TODO
210+
211+ /**
212+ * The value of a normal parameter at function entry, viewed as a node in a data
213+ * flow graph.
214+ */
215+ class NormalParameterNode extends ParameterNodeImpl , TNormalParameterNode {
216+ Parameter parameter ;
217+
218+ NormalParameterNode ( ) { this = TNormalParameterNode ( parameter ) }
219+
220+ override Parameter getParameter ( ) { result = parameter }
221+
222+ override predicate isParameterOf ( DataFlowCallable c , ParameterPosition pos ) {
223+ exists ( CfgScope callable , int i |
224+ callable = c .asCfgScope ( ) and pos .isPositional ( i ) and callable .getParameter ( i ) = parameter
225+ )
226+ }
227+
228+ override CfgScope getCfgScope ( ) { result .getAParameter ( ) = parameter }
229+
230+ override Location getLocationImpl ( ) { result = parameter .getLocation ( ) }
231+
232+ override string toStringImpl ( ) { result = parameter .toString ( ) }
233+ }
134234}
135235
136236import ParameterNodes
@@ -252,7 +352,19 @@ abstract class PostUpdateNodeImpl extends Node {
252352}
253353
254354private module PostUpdateNodes {
255- // TODO
355+ class ExprPostUpdateNode extends PostUpdateNodeImpl , NodeImpl , TExprPostUpdateNode {
356+ private CfgNodes:: ExprCfgNode e ;
357+
358+ ExprPostUpdateNode ( ) { this = TExprPostUpdateNode ( e ) }
359+
360+ override ExprNode getPreUpdateNode ( ) { e = result .getExprNode ( ) }
361+
362+ override CfgScope getCfgScope ( ) { result = e .getExpr ( ) .getEnclosingScope ( ) }
363+
364+ override Location getLocationImpl ( ) { result = e .getLocation ( ) }
365+
366+ override string toStringImpl ( ) { result = "[post] " + e .toString ( ) }
367+ }
256368}
257369
258370private import PostUpdateNodes
@@ -276,7 +388,7 @@ class NodeRegion instanceof Unit {
276388 predicate contains ( Node n ) { none ( ) }
277389
278390 /** Gets a best-effort total ordering. */
279- int totalOrder ( ) { none ( ) }
391+ int totalOrder ( ) { result = 1 }
280392}
281393
282394/**
0 commit comments