@@ -9,6 +9,7 @@ private import codeql.util.Unit
99private import codeql.util.Void
1010private import semmle.code.binary.ast.ir.internal.TransformInstruction.TransformInstruction
1111private import semmle.code.binary.ast.ir.internal.Instruction1.Instruction1
12+ private import codeql.ssa.Ssa as SsaImpl
1213
1314private signature module ControlFlowReachableInputSig {
1415 class FlowState ;
@@ -149,6 +150,8 @@ private module ControlFlowReachable<ControlFlowReachableInputSig Input> {
149150 * sub rax, rbx
150151 * jz label
151152 * ```
153+ *
154+ * It also synthesises parameter instructions.
152155 */
153156private module InstructionInput implements Transform< Instruction1 > :: TransformInputSig {
154157 // ------------------------------------------------
@@ -174,10 +177,10 @@ private module InstructionInput implements Transform<Instruction1>::TransformInp
174177
175178 class LocalVariableTag = Void ;
176179
177- private newtype TVariableTag = ZeroVarTag ( )
180+ private newtype TTempVariableTag = ZeroVarTag ( )
178181
179- class VariableTag extends TVariableTag {
180- VariableTag ( ) { this = ZeroVarTag ( ) }
182+ class TempVariableTag extends TTempVariableTag {
183+ TempVariableTag ( ) { this = ZeroVarTag ( ) }
181184
182185 string toString ( ) { result = "ZeroVarTag" }
183186 }
@@ -191,6 +194,11 @@ private module InstructionInput implements Transform<Instruction1>::TransformInp
191194 this = CmpDefTag ( k ) and
192195 result = "CmpDefTag(" + stringOfConditionKind ( k ) + ")"
193196 )
197+ or
198+ exists ( Instruction1:: Variable v |
199+ this = InitializeParameterTag ( v ) and
200+ result = "InitializeParameterTag(" + v .toString ( ) + ")"
201+ )
194202 }
195203 }
196204
@@ -213,21 +221,21 @@ private module InstructionInput implements Transform<Instruction1>::TransformInp
213221 }
214222
215223 private newtype TTranslatedElementVariablePair =
216- MkTranslatedElementVariablePair ( TranslatedElement te , VariableTag tag ) {
224+ MkTranslatedElementVariablePair ( TranslatedElement te , TempVariableTag tag ) {
217225 te .hasTempVariable ( tag )
218226 }
219227
220228 class TranslatedElementVariablePair extends TTranslatedElementVariablePair {
221229 TranslatedElement te ;
222- VariableTag tag ;
230+ TempVariableTag tag ;
223231
224232 TranslatedElementVariablePair ( ) { this = MkTranslatedElementVariablePair ( te , tag ) }
225233
226234 string toString ( ) { none ( ) }
227235
228236 TranslatedElement getTranslatedElement ( ) { result = te }
229237
230- VariableTag getVariableTag ( ) { result = tag }
238+ TempVariableTag getVariableTag ( ) { result = tag }
231239 }
232240
233241 private newtype TFunctionLocalVariablePair =
@@ -328,13 +336,106 @@ private module InstructionInput implements Transform<Instruction1>::TransformInp
328336 cjump .getKind ( ) = kind
329337 }
330338
339+ private module SsaInput implements SsaImpl:: InputSig< Location , Instruction1:: BasicBlock > {
340+ class SourceVariable = Instruction1:: Variable ;
341+
342+ predicate variableWrite ( Instruction1:: BasicBlock bb , int i , SourceVariable v , boolean certain ) {
343+ bb .getNode ( i ) .asInstruction ( ) .getResultVariable ( ) = v and
344+ certain = true
345+ }
346+
347+ predicate variableRead ( Instruction1:: BasicBlock bb , int i , SourceVariable v , boolean certain ) {
348+ bb .getNode ( i ) .asOperand ( ) .getVariable ( ) = v and
349+ certain = true
350+ }
351+ }
352+
353+ private module Ssa {
354+ private module Ssa = SsaImpl:: Make< Location , Instruction1:: BinaryCfg , SsaInput > ;
355+
356+ class Definition extends Ssa:: Definition {
357+ Instruction1:: Instruction getInstruction ( ) {
358+ exists ( Instruction1:: BasicBlock bb , int i |
359+ this .definesAt ( _, bb , i ) and
360+ bb .getNode ( i ) .asInstruction ( ) = result
361+ )
362+ }
363+
364+ Instruction1:: Operand getARead ( ) {
365+ exists ( Instruction1:: BasicBlock bb , int i |
366+ Ssa:: ssaDefReachesRead ( _, this , bb , i ) and
367+ result = bb .getNode ( i ) .asOperand ( )
368+ )
369+ }
370+
371+ override string toString ( ) {
372+ result = "SSA def(" + this .getInstruction ( ) + ")"
373+ or
374+ not exists ( this .getInstruction ( ) ) and
375+ result = super .toString ( )
376+ }
377+ }
378+
379+ class PhiNode extends Definition , Ssa:: PhiNode {
380+ override string toString ( ) { result = Ssa:: PhiNode .super .toString ( ) }
381+
382+ Definition getInput ( Instruction1:: BasicBlock bb ) {
383+ Ssa:: phiHasInputFromBlock ( this , result , bb )
384+ }
385+
386+ Definition getAnInput ( ) { result = this .getInput ( _) }
387+ }
388+
389+ class SourceVariable = SsaInput:: SourceVariable ;
390+
391+ pragma [ nomagic]
392+ predicate ssaDefReachesRead (
393+ Instruction1:: Variable v , Definition def , Instruction1:: BasicBlock bb , int i
394+ ) {
395+ Ssa:: ssaDefReachesRead ( v , def , bb , i )
396+ }
397+
398+ pragma [ nomagic]
399+ predicate phiHasInputFromBlock ( PhiNode phi , Definition input , Instruction1:: BasicBlock bb ) {
400+ Ssa:: phiHasInputFromBlock ( phi , input , bb )
401+ }
402+
403+ pragma [ nomagic]
404+ Instruction1:: Instruction getADef ( Instruction1:: Operand op ) {
405+ exists ( Instruction1:: Variable v , Ssa:: Definition def , Instruction1:: BasicBlock bb , int i |
406+ def = getDef ( op ) and
407+ def .definesAt ( v , bb , i ) and
408+ result = bb .getNode ( i ) .asInstruction ( )
409+ )
410+ }
411+
412+ pragma [ nomagic]
413+ Ssa:: Definition getDef ( Instruction1:: Operand op ) {
414+ exists ( Instruction1:: Variable v , Instruction1:: BasicBlock bbRead , int iRead |
415+ ssaDefReachesRead ( v , result , bbRead , iRead ) and
416+ op = bbRead .getNode ( iRead ) .asOperand ( )
417+ )
418+ }
419+ }
420+
421+ private predicate isReadBeforeInitialization (
422+ Instruction1:: LocalVariable v , Instruction1:: Function f
423+ ) {
424+ exists ( Instruction1:: Operand op |
425+ op .getVariable ( ) = v and
426+ op .getEnclosingFunction ( ) = f and
427+ not any ( Ssa:: Definition def ) .getARead ( ) = op
428+ )
429+ }
430+
331431 // ------------------------------------------------
332432 private newtype TTranslatedElement =
333433 TTranslatedComparisonInstruction (
334434 Instruction1:: Instruction i , Instruction1:: CJumpInstruction cjump , ConditionKind kind
335435 ) {
336436 controlFlowsToCmp ( i , cjump , kind )
337- }
437+ } or
438+ TTranslatedInitializeParameters ( Instruction1:: Function f ) { isReadBeforeInitialization ( _, f ) }
338439
339440 abstract class TranslatedElement extends TTranslatedElement {
340441 abstract EitherInstructionTranslatedElementTagPair getSuccessor (
@@ -359,7 +460,7 @@ private module InstructionInput implements Transform<Instruction1>::TransformInp
359460
360461 predicate hasJumpCondition ( InstructionTag tag , ConditionKind kind ) { none ( ) }
361462
362- predicate hasTempVariable ( VariableTag tag ) { none ( ) }
463+ predicate hasTempVariable ( TempVariableTag tag ) { none ( ) }
363464
364465 predicate hasLocalVariable ( LocalVariableTag tag ) { none ( ) }
365466
@@ -423,7 +524,7 @@ private module InstructionInput implements Transform<Instruction1>::TransformInp
423524
424525 override predicate producesResult ( ) { none ( ) }
425526
426- override predicate hasTempVariable ( VariableTag tag ) { tag = ZeroVarTag ( ) }
527+ override predicate hasTempVariable ( TempVariableTag tag ) { tag = ZeroVarTag ( ) }
427528
428529 override EitherVariableOrTranslatedElementVariablePair getVariableOperand (
429530 InstructionTag tag , OperandTag operandTag
@@ -467,6 +568,88 @@ private module InstructionInput implements Transform<Instruction1>::TransformInp
467568 override EitherInstructionTranslatedElementTagPair getEntry ( ) { result .asLeft ( ) = instr }
468569 }
469570
571+ private predicate parameterHasIndex ( Instruction1:: Variable v , Instruction1:: Function f , int index ) {
572+ v =
573+ rank [ index + 1 ] ( Instruction1:: LocalVariable cand |
574+ cand .getEnclosingFunction ( ) = f and
575+ isReadBeforeInitialization ( cand , f )
576+ |
577+ cand order by cand .toString ( ) // TODO: Use the right argument ordering. This depends on the calling conventions.
578+ )
579+ }
580+
581+ private Instruction1:: Variable getFirstParameter ( Instruction1:: Function f ) {
582+ parameterHasIndex ( result , f , 0 )
583+ }
584+
585+ private Instruction1:: InitInstruction getStackPointerInitialize ( Instruction1:: Function f ) {
586+ result .getResultVariable ( ) instanceof Instruction1:: StackPointer and
587+ result .getEnclosingFunction ( ) = f
588+ }
589+
590+ private class TranslatedInitializeParameters extends TranslatedInstruction ,
591+ TTranslatedInitializeParameters
592+ {
593+ Instruction1:: Function func ;
594+
595+ TranslatedInitializeParameters ( ) { this = TTranslatedInitializeParameters ( func ) }
596+
597+ final override Instruction1:: Function getEnclosingFunction ( ) { result = func }
598+
599+ override EitherInstructionTranslatedElementTagPair getInstructionSuccessor (
600+ Instruction1:: Instruction i , SuccessorType succType
601+ ) {
602+ i = getStackPointerInitialize ( func ) and
603+ succType instanceof DirectSuccessor and
604+ result .asRight ( ) .getTranslatedElement ( ) = this and
605+ result .asRight ( ) .getInstructionTag ( ) = InitializeParameterTag ( getFirstParameter ( func ) )
606+ }
607+
608+ override EitherInstructionTranslatedElementTagPair getSuccessor (
609+ InstructionTag tag , SuccessorType succType
610+ ) {
611+ succType instanceof DirectSuccessor and
612+ exists ( Instruction1:: Variable v , int index |
613+ tag = InitializeParameterTag ( v ) and
614+ parameterHasIndex ( v , func , index )
615+ |
616+ exists ( Instruction1:: Variable u |
617+ parameterHasIndex ( u , func , index + 1 ) and
618+ result .asRight ( ) .getTranslatedElement ( ) = this and
619+ result .asRight ( ) .getInstructionTag ( ) = InitializeParameterTag ( u )
620+ )
621+ or
622+ not parameterHasIndex ( _, func , index + 1 ) and
623+ result .asLeft ( ) = getStackPointerInitialize ( func ) .getSuccessor ( succType )
624+ )
625+ }
626+
627+ override predicate producesResult ( ) { none ( ) }
628+
629+ override predicate hasTempVariable ( TempVariableTag tag ) { none ( ) }
630+
631+ override EitherVariableOrTranslatedElementVariablePair getVariableOperand (
632+ InstructionTag tag , OperandTag operandTag
633+ ) {
634+ none ( )
635+ }
636+
637+ override predicate hasInstruction (
638+ Opcode opcode , InstructionTag tag , OptionEitherVariableOrTranslatedElementPair v
639+ ) {
640+ opcode instanceof Init and
641+ exists ( Instruction1:: Variable var |
642+ isReadBeforeInitialization ( var , func ) and
643+ tag = InitializeParameterTag ( var ) and
644+ v .asSome ( ) .asLeft ( ) = var
645+ )
646+ }
647+
648+ override string toString ( ) { result = "Initialize parameters in " + func .toString ( ) }
649+
650+ override EitherInstructionTranslatedElementTagPair getEntry ( ) { none ( ) }
651+ }
652+
470653 class TranslatedOperand extends TranslatedElement {
471654 TranslatedOperand ( ) { none ( ) }
472655
0 commit comments