Example #1
0
        public void VpLoop()
        {
            var b = new ProgramBuilder();

            b.Add("main", m =>
            {
                var r  = m.Reg32("r0", 0);
                var zf = m.Flags("Z");
                m.Label("l0000");
                m.MStore(r, m.Word32(0));
                m.Assign(r, m.ISub(r, 4));
                m.Assign(zf, m.Cond(r));
                m.BranchCc(ConditionCode.NE, "l0000");

                m.Label("l0001");
                m.Assign(r, 42);

                m.Label("l0002");
                m.MStore(r, m.Word32(12));
                m.Assign(r, m.ISub(r, 4));
                m.BranchIf(m.Eq0(r), "l0002");

                m.Return();
            });
            RunFileTest(b.BuildProgram(), "Analysis/VpLoop.txt");
        }
        public void Cab_GuessStackParameter()
        {
            var m  = new SsaProcedureBuilder(nameof(Cab_Sequence));
            var sp = m.Reg("sp", m.Procedure.Architecture.StackRegister);

            m.AddDefToEntryBlock(sp);
            var r2_1 = m.Reg("r2_1", reg2);
            var r3_2 = m.Reg("r3_2", reg3);

            m.MStore(sp, m.Word32(0x0001234));
            m.MStore(m.IAdd(sp, 4), m.Word32(0x5678ABCD));
            var sigCallee = FunctionType.Action(
                new Identifier("arg04", PrimitiveType.Word32,
                               new StackArgumentStorage(4, PrimitiveType.Word32)),
                new Identifier("arg08", PrimitiveType.Word32,
                               new StackArgumentStorage(8, PrimitiveType.Word32)));

            sigCallee.ReturnAddressOnStack = 4;
            var callee = new ProcedureConstant(
                PrimitiveType.Ptr32,
                new ExternalProcedure("callee", sigCallee));
            var stmCall = m.Call(callee, 0,
                                 new Identifier[] { sp },
                                 new Identifier[] { });

            m.Return();

            var cab = new CallApplicationBuilder(
                m.Ssa,
                stmCall,
                (CallInstruction)stmCall.Instruction,
                callee,
                true);
            var instr = cab.CreateInstruction(sigCallee, null);

            Assert.AreEqual("callee(Mem4[sp:word32], Mem4[sp + 4<i32>:word32])", instr.ToString());
            m.Ssa.Validate(s => Assert.Fail(s));
        }
Example #3
0
        public void DeadCallDefinition()
        {
            var sExp =
                #region Expected
                @"// ProcedureBuilder
// Return size: 0
define ProcedureBuilder
ProcedureBuilder_entry:
	def r1
	// succ:  l1
l1:
	call foo (retsize: 4;)
		uses: r1:r1
		defs: r1:r1_2
	Mem4[0x00123400:word32] = r1_2
	return
	// succ:  ProcedureBuilder_exit
ProcedureBuilder_exit:
";

            #endregion
            RunTest(sExp, m =>
            {
                var _r1 = new RegisterStorage("r1", 1, 0, PrimitiveType.Word32);
                var _r2 = new RegisterStorage("r2", 2, 0, PrimitiveType.Word32);
                var foo = Given_Procedure_With_Flow(m,
                                                    "foo",
                                                    new Storage[] { _r1 },
                                                    new Storage[] { _r1, _r2 });

                var r1   = m.Frame.EnsureRegister(_r1);
                var r2   = m.Frame.EnsureRegister(_r2);
                var call = m.Call(foo, 4);
                m.MStore(m.Word32(0x123400), r1);
                m.Return();
            });
        }
Example #4
0
        public void DeadDpbApplication()
        {
            var dead = m.Reg32("dead");

            m.Assign(dead, m.Dpb(m.Word32(0), m.Fn("foo", Constant.Word32(1)), 0));

            EliminateDeadCode();

            var sExp =
                @"
foo(1<32>)
";

            AssertProcedureCode(sExp);
        }
Example #5
0
        public void Spbp_LinearProcedure()
        {
            var m = new SsaProcedureBuilder(nameof(Spbp_LinearProcedure));

            var fp = m.Ssa.Identifiers.Add(m.Frame.FramePointer, null, null, false).Identifier;

            Given_StackPointer(m);
            var sp_1 = m.Reg("sp_1", m.Architecture.StackRegister);
            var sp_2 = m.Reg("sp_2", m.Architecture.StackRegister);
            var sp_3 = m.Reg("sp_3", m.Architecture.StackRegister);

            m.AddDefToEntryBlock(fp);

            m.Assign(sp_1, m.ISub(fp, m.Int32(4)));
            // Indirect call = hell node
            var ci = m.Call(m.Mem32(m.Word32(0x2)), 4,
                            new[] { sp_1 },
                            new[] { sp_2 });

            m.Assign(sp_3, m.IAdd(sp_2, m.Int32(4)));
            m.Return();

            m.AddUseToExitBlock(sp_3);

            RunTest(m.Ssa);

            var sExp =
                #region Expected
                @"Spbp_LinearProcedure_entry:
	def fp
l1:
	sp_1 = fp - 4
	call Mem4[0x00000002:word32] (retsize: 4;)
		uses: sp:sp_1
	sp_2 = fp - 4
	sp_3 = fp
	return
Spbp_LinearProcedure_exit:
	use sp_3
";

            #endregion
            AssertStringsEqual(sExp, m.Ssa);
        }
Example #6
0
        public void CoaAcrossComment()
        {
            var a = m.Reg32("a");
            var b = m.Reg32("b");

            m.Assign(a, m.Mem32(m.Word32(0x00123400)));
            m.Comment("This is a comment");
            m.Assign(b, m.Mem32(a));

            RunCoalescer();

            var sExp =
                @"
// This is a comment
b = Mem3[Mem2[0x123400<32>:word32]:word32]
";

            AssertProcedureCode(sExp);
        }
        public void UfuserLittleEndianSequence()
        {
            var r8  = m.Reg32("r8");
            var r14 = m.Reg32("r14");
            var r13 = m.Reg32("r13");
            var r9  = m.Reg32("r9");
            var r4  = m.Reg32("r4");

            __swl(m.Mem32(m.IAdd(r8, 0x13)), r14);
            __swl(m.Mem32(m.IAdd(r8, 0x17)), r13);
            __swl(m.Mem32(m.IAdd(r8, 0x1B)), m.Word32(0x00));
            __swl(m.Mem32(m.IAdd(r8, 0x1F)), m.Word32(0x00));
            __swl(m.Mem32(m.IAdd(r8, 0x2B)), m.Word32(0x00));
            __swl(m.Mem32(m.IAdd(r8, 0x2F)), r9);
            __swl(m.Mem32(m.IAdd(r8, 0x33)), m.Word32(0x00));
            m.Assign(r4, m.IAdd(r8, 0x0010));
            __swr(m.Mem32(m.IAdd(r8, 0x10)), r14);
            __swr(m.Mem32(m.IAdd(r8, 0x14)), r13);
            __swr(m.Mem32(m.IAdd(r8, 0x18)), m.Word32(0x00));
            __swr(m.Mem32(m.IAdd(r8, 0x1C)), m.Word32(0x00));
            __swr(m.Mem32(m.IAdd(r8, 0x28)), m.Word32(0x00));
            __swr(m.Mem32(m.IAdd(r8, 44)), r9);
            __swr(m.Mem32(m.IAdd(r8, 0x30)), m.Word32(0x00));
            m.Return();

            var ssa  = RunTest(m);
            var sExp =
                #region Expected
                @"r8:r8
    def:  def r8
    uses: r4_18 = r8 + 0x00000010
          Mem20[r8 + 0x00000010:word32] = r14
          Mem22[r8 + 0x00000014:word32] = r13
          Mem24[r8 + 0x00000018:word32] = 0x00000000
          Mem26[r8 + 0x0000001C:word32] = 0x00000000
          Mem28[r8 + 0x00000028:word32] = 0x00000000
          Mem30[r8 + 0x0000002C:word32] = r9
          Mem32[r8 + 0x00000030:word32] = 0x00000000
Mem5:Global memory
    def:  def Mem5
r14:r14
    def:  def r14
    uses: Mem20[r8 + 0x00000010:word32] = r14
Mem3: orig: Mem5
Mem6:Global memory
    def:  def Mem6
r13:r13
    def:  def r13
    uses: Mem22[r8 + 0x00000014:word32] = r13
Mem6: orig: Mem6
Mem7:Global memory
    def:  def Mem7
Mem8: orig: Mem7
Mem8:Global memory
    def:  def Mem8
Mem10: orig: Mem8
Mem9:Global memory
    def:  def Mem9
Mem12: orig: Mem9
Mem10:Global memory
    def:  def Mem10
r9:r9
    def:  def r9
    uses: Mem30[r8 + 0x0000002C:word32] = r9
Mem15: orig: Mem10
Mem11:Global memory
    def:  def Mem11
Mem17: orig: Mem11
r4_18: orig: r4
    def:  r4_18 = r8 + 0x00000010
Mem12:Global memory
    def:  def Mem12
Mem20: orig: Mem12
    def:  Mem20[r8 + 0x00000010:word32] = r14
Mem13:Global memory
    def:  def Mem13
Mem22: orig: Mem13
    def:  Mem22[r8 + 0x00000014:word32] = r13
Mem14:Global memory
    def:  def Mem14
Mem24: orig: Mem14
    def:  Mem24[r8 + 0x00000018:word32] = 0x00000000
Mem15:Global memory
    def:  def Mem15
Mem26: orig: Mem15
    def:  Mem26[r8 + 0x0000001C:word32] = 0x00000000
Mem16:Global memory
    def:  def Mem16
Mem28: orig: Mem16
    def:  Mem28[r8 + 0x00000028:word32] = 0x00000000
Mem17:Global memory
    def:  def Mem17
Mem30: orig: Mem17
    def:  Mem30[r8 + 0x0000002C:word32] = r9
Mem18:Global memory
    def:  def Mem18
Mem32: orig: Mem18
    def:  Mem32[r8 + 0x00000030:word32] = 0x00000000
// SsaProcedureBuilder
// Return size: 0
void SsaProcedureBuilder()
SsaProcedureBuilder_entry:
	def r8
	def Mem5
	def r14
	def Mem6
	def r13
	def Mem7
	def Mem8
	def Mem9
	def Mem10
	def r9
	def Mem11
	def Mem12
	def Mem13
	def Mem14
	def Mem15
	def Mem16
	def Mem17
	def Mem18
	// succ:  l1
l1:
	r4_18 = r8 + 0x00000010
	Mem20[r8 + 0x00000010:word32] = r14
	Mem22[r8 + 0x00000014:word32] = r13
	Mem24[r8 + 0x00000018:word32] = 0x00000000
	Mem26[r8 + 0x0000001C:word32] = 0x00000000
	Mem28[r8 + 0x00000028:word32] = 0x00000000
	Mem30[r8 + 0x0000002C:word32] = r9
	Mem32[r8 + 0x00000030:word32] = 0x00000000
	return
	// succ:  SsaProcedureBuilder_exit
SsaProcedureBuilder_exit:
";

            #endregion
            AssertStringsEqual(sExp, ssa);
        }
Example #8
0
        public void Spbp_SpaceOnStack()
        {
            var m = new SsaProcedureBuilder(nameof(Spbp_SpaceOnStack));

            var fp = m.Ssa.Identifiers.Add(m.Frame.FramePointer, null, null, false).Identifier;

            Given_StackPointer(m);
            var sp_1 = m.Reg("sp_1", sp);
            var sp_2 = m.Reg("sp_2", sp);
            var sp_3 = m.Reg("sp_3", sp);
            var sp_4 = m.Reg("sp_4", sp);
            var sp_5 = m.Reg("sp_5", sp);
            var sp_6 = m.Reg("sp_6", sp);
            var sp_7 = m.Reg("sp_7", sp);
            var sp_8 = m.Reg("sp_8", sp);
            var a    = m.Reg("a", new RegisterStorage("a", 1, 0, PrimitiveType.Word32));
            var b    = m.Reg("b", new RegisterStorage("b", 2, 0, PrimitiveType.Word32));
            var a_1  = m.Reg("a_1", (RegisterStorage)a.Storage);
            var b_1  = m.Reg("b_1", (RegisterStorage)b.Storage);

            m.AddDefToEntryBlock(fp);

            m.Assign(sp_2, m.ISub(fp, 4));  // space for a
            m.MStore(sp_2, a);
            m.Assign(sp_3, m.ISub(fp, 4));  // space for b
            m.MStore(sp_3, b);
            m.Assign(sp_4, m.ISub(fp, 40)); // 40 bytes of stack space
            m.MStore(sp_4, m.Word32(0xDEADBABE));
            m.Call(m.Mem32(m.Word32(0x00123400)), 4,
                   new[] { sp_4 },
                   new[] { sp_5 });
            m.Assign(sp_6, m.IAdd(sp_5, 40));
            m.Assign(b_1, m.Mem32(sp_6));
            m.Assign(sp_7, m.IAdd(sp_6, 4));
            m.Assign(a_1, m.Mem32(sp_7));
            m.Assign(sp_8, m.IAdd(sp_7, 4));
            m.Return();
            m.AddUseToExitBlock(sp_8);

            RunTest(m.Ssa);

            var sExp =
                #region Expected
                @"Spbp_SpaceOnStack_entry:
	def fp
l1:
	sp_2 = fp - 0x00000004
	Mem13[sp_2:word32] = a
	sp_3 = fp - 0x00000004
	Mem14[sp_3:word32] = b
	sp_4 = fp - 0x00000028
	Mem15[sp_4:word32] = 0xDEADBABE
	call Mem16[0x00123400:word32] (retsize: 4;)
		uses: sp:sp_4
	sp_5 = fp - 48
	sp_6 = fp - 8
	b_1 = Mem17[sp_6:word32]
	sp_7 = fp - 4
	a_1 = Mem18[sp_7:word32]
	sp_8 = fp
	return
Spbp_SpaceOnStack_exit:
	use sp_8
";

            #endregion

            this.AssertStringsEqual(sExp, m.Ssa);
        }
Example #9
0
        public void Spbp_TwoExits()
        {
            var m = new SsaProcedureBuilder(nameof(Spbp_TwoExits));

            Given_FramePointer(m);
            Given_StackPointer(m);
            var sp_1 = m.Reg("sp_1", m.Architecture.StackRegister);
            var sp_2 = m.Reg("sp_2", m.Architecture.StackRegister);
            var sp_3 = m.Reg("sp_3", m.Architecture.StackRegister);
            var sp_4 = m.Reg("sp_4", m.Architecture.StackRegister);
            var sp_5 = m.Reg("sp_5", m.Architecture.StackRegister);
            var sp_6 = m.Reg("sp_6", m.Architecture.StackRegister);

            m.AddDefToEntryBlock(fp);

            m.Assign(sp_1, m.ISub(fp, m.Int32(4)));
            m.BranchIf(m.Eq0(m.Mem32(m.Word32(0x1))), "m_eq0");

            m.Label("m_ne0");
            // Indirect call = hell node
            m.Call(m.Mem32(m.Word32(0x4)), 4,
                   new[] { sp_1 },
                   new[] { sp_2 });
            m.Assign(sp_3, m.IAdd(sp_2, m.Int32(4)));
            m.Return();

            m.Label("m_eq0");
            // Indirect call = hell node
            m.Call(m.Mem32(m.Word32(0x8)), 4,
                   new[] { sp_1 },
                   new[] { sp_4 });
            m.Assign(sp_5, m.IAdd(sp_4, m.Int32(4)));
            m.Return();

            m.AddPhiToExitBlock(sp_6, (sp_3, "m_ne0"), (sp_5, "m_eq0"));
            m.AddUseToExitBlock(sp_6);

            RunTest(m.Ssa);

            var sExp =
                #region Expected
                @"Spbp_TwoExits_entry:
	def fp
l1:
	sp_1 = fp - 4
	branch Mem7[0x00000001:word32] == 0x00000000 m_eq0
	goto m_ne0
m_eq0:
	call Mem9[0x00000008:word32] (retsize: 4;)
		uses: sp:sp_1
	sp_4 = fp - 4
	sp_5 = fp
	return
m_ne0:
	call Mem8[0x00000004:word32] (retsize: 4;)
		uses: sp:sp_1
	sp_2 = fp - 4
	sp_3 = fp
	return
Spbp_TwoExits_exit:
	sp_6 = PHI((sp_3, m_ne0), (sp_5, m_eq0))
	use sp_6
";

            #endregion
            AssertStringsEqual(sExp, m.Ssa);
        }