public void Setup()
 {
     arch = new FakeArchitecture();
     proc = new Procedure("Test", new Frame(arch.FramePointerType));
     flow = new ProcedureFlow(proc, arch);
     ctx = new SymbolicEvaluationContext(arch, proc.Frame);
     trs = new TrashedRegisterSummarizer(arch, proc, flow, ctx);
 }
Exemplo n.º 2
0
		public void Setup()
		{
			program = new Program();
			program.Architecture = new IntelArchitecture(ProcessorMode.Protected32);
            program.Platform = new DefaultPlatform(null, program.Architecture);
			gcr = new GlobalCallRewriter(program, null);
            proc = new Procedure("foo", program.Architecture.CreateFrame());
			flow = new ProcedureFlow(proc, program.Architecture);
		}
Exemplo n.º 3
0
 public TrashedRegisterSummarizer(IProcessorArchitecture arch, Procedure proc, ProcedureFlow pf, SymbolicEvaluationContext ctx)
 {
     this.arch = arch;
     this.proc = proc;
     this.pf = pf;
     trashed = arch.CreateRegisterBitset();
     preserved = arch.CreateRegisterBitset();
     this.ctx = ctx;
     this.cmp = new ExpressionValueComparer();
 }
Exemplo n.º 4
0
		public ProgramDataFlow(Program prog) : this()
		{
			foreach (Procedure proc in prog.Procedures.Values)
			{
				procFlow[proc] = new ProcedureFlow(proc, prog.Architecture);
				foreach (Block block in proc.ControlGraph.Blocks)
				{
					blockFlow[block] = new BlockFlow(
                        block, 
                        prog.Architecture.CreateRegisterBitset(),
                        new SymbolicEvaluationContext(
                            prog.Architecture,
                            proc.Frame));
				}
			}
		}
Exemplo n.º 5
0
		public void AddStackArgument(int x, Identifier id, ProcedureFlow flow, SignatureBuilder sb)
		{
			object o = flow.StackArguments[id];
			if (o != null)
			{
				int bitWidth = (int) o;
				if (bitWidth < id.DataType.BitSize)
				{
					PrimtiveType pt = id.DataType as PrimtiveType;
					if (pt != null)
					{
						id.DataType = PrimtiveType.Create(pt.Domain, bitWidth/8);
					}
				}
			}
			sb.AddStackArgument(x, id);
		}
Exemplo n.º 6
0
		public void Rl_ProcedureWithTrashedAndPreservedRegisters()
		{
            Procedure proc = new Procedure("test", prog.Architecture.CreateFrame());
			ProcedureFlow pf = new ProcedureFlow(proc, prog.Architecture);
			mpprocflow[proc] = pf;
			pf.TrashedRegisters[Registers.eax.Number] = true;
			pf.TrashedRegisters[Registers.ebx.Number] = true;
			pf.PreservedRegisters[Registers.ebp.Number] = true;
			pf.PreservedRegisters[Registers.bp.Number] = true;

			RegisterLiveness.State st = new RegisterLiveness.ByPassState();
			BlockFlow bf = CreateBlockFlow(proc.ExitBlock, proc.Frame);
			mpprocflow[proc.ExitBlock] = bf;
			st.InitializeBlockFlow(proc.ExitBlock, mpprocflow, true);
			Assert.IsFalse(bf.DataOut[Registers.ebp.Number], "preserved registers cannot be live out");
			Assert.IsFalse(bf.DataOut[Registers.bp.Number], "preserved registers cannot be live out");
			Assert.IsTrue(bf.DataOut[Registers.eax.Number], "trashed registers may be live out");
			Assert.IsTrue(bf.DataOut[Registers.esi.Number], "Unmentioned registers may be live out");
		}
Exemplo n.º 7
0
		public void Rl_MarkLiveStackParameters()
		{
            var callee = new Procedure("callee", prog.Architecture.CreateFrame());
			callee.Frame.ReturnAddressSize = 4;
            callee.Frame.ReturnAddressKnown = true;
			callee.Frame.EnsureStackArgument(0, PrimitiveType.Word32);
			callee.Frame.EnsureStackArgument(4, PrimitiveType.Word32);
			Assert.AreEqual(8, callee.Frame.GetStackArgumentSpace());
			ProcedureFlow pf = new ProcedureFlow(callee, prog.Architecture);
			mpprocflow[callee] = pf;

			Identifier loc08 = m.Frame.EnsureStackLocal(-8, PrimitiveType.Word32);
			Identifier loc0C = m.Frame.EnsureStackLocal(-12, PrimitiveType.Word32);
			Identifier loc10 = m.Frame.EnsureStackLocal(-16, PrimitiveType.Word32);
			rl.CurrentState = new RegisterLiveness.ByPassState();
            var ci = new CallInstruction(
                new ProcedureConstant(PrimitiveType.Pointer32, callee),
                new CallSite(4, 0) { StackDepthOnEntry = 16 });
			rl.Procedure = m.Procedure;
			rl.MarkLiveStackParameters(ci);
			Assert.AreEqual(" Local -000C Local -0010", Dump(rl.IdentifierLiveness));
		}
        public void TrfTerminatingProcedure()
        {
            var eax = m.Procedure.Frame.EnsureRegister(Registers.eax);
            m.Assign(eax, m.Word32(0x40));
            m.Call(exit, 4);

            flow[m.Block] = CreateBlockFlow(m.Block, m.Frame);
            flow[exit] = new ProcedureFlow(exit, prog.Architecture);
            flow[exit].TerminatesProcess = true;
            trf = CreateTrashedRegisterFinder(prog);
            trf.ProcessBlock(m.Block);
            Assert.AreEqual("", DumpValues());
        }
 public void TrfPropagateFlagsToProcedureSummary()
 {
     var proc = new Procedure("proc", prog.Architecture.CreateFrame());
     prog.CallGraph.AddProcedure(proc);
     var flags = prog.Architecture.GetFlagGroup("SZ");
     var sz = m.Frame.EnsureFlagGroup(flags.FlagGroupBits, flags.Name, flags.DataType);
     var stm = m.Assign(sz, m.Int32(3));
     flow[proc] = new ProcedureFlow(proc, prog.Architecture);
     trf = CreateTrashedRegisterFinder(prog);
     CreateBlockFlow(m.Block, m.Frame);
     trf.StartProcessingBlock(m.Block);
     stm.Accept(trf);
     trf.PropagateToProcedureSummary(proc);
     Assert.AreEqual(" SZ", flow[proc].EmitFlagGroup(prog.Architecture, "", flow[proc].grfTrashed));
 }
Exemplo n.º 10
0
        public void TrfPropagateToProcedureSummary()
        {
            Procedure proc = new Procedure("proc", prog.Architecture.CreateFrame());
            prog.CallGraph.AddProcedure(proc);
            Identifier eax = proc.Frame.EnsureRegister(Registers.eax);
            Identifier ebx = proc.Frame.EnsureRegister(Registers.ebx);
            Identifier ecx = proc.Frame.EnsureRegister(Registers.ecx);
            Identifier esi = proc.Frame.EnsureRegister(Registers.esi);
            flow[proc] = new ProcedureFlow(proc, prog.Architecture);

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(proc.ExitBlock, proc.Frame);
            trf.StartProcessingBlock(proc.ExitBlock);

            trf.RegisterSymbolicValues[(RegisterStorage) eax.Storage] = eax;			// preserved
            trf.RegisterSymbolicValues[(RegisterStorage) ebx.Storage] = ecx;			// trashed
            trf.RegisterSymbolicValues[(RegisterStorage) esi.Storage] = Constant.Invalid;				// trashed
            trf.PropagateToProcedureSummary(proc);
            ProcedureFlow pf = flow[proc];
            Assert.AreEqual(" ebx esi", pf.EmitRegisters(prog.Architecture, "", pf.TrashedRegisters));
            Assert.AreEqual(" eax", pf.EmitRegisters(prog.Architecture, "", pf.PreservedRegisters));
        }
Exemplo n.º 11
0
        public void TrfCallInstruction()
        {
            var callee = new Procedure("Callee", prog.Architecture.CreateFrame());
            var stm = m.Call(callee, 4);
            var pf = new ProcedureFlow(callee, prog.Architecture);
            pf.TrashedRegisters[Registers.ebx.Number] = true;
            flow[callee] = pf;

            trf = CreateTrashedRegisterFinder();
            CreateBlockFlow(m.Block, m.Frame);
            trf.StartProcessingBlock(m.Block);

            stm.Instruction.Accept(trf);
            Assert.AreEqual("(ebx:<invalid>)", DumpValues());
        }
Exemplo n.º 12
0
		/// <summary>
		/// Adjusts LiveOut values for use as out registers.
		/// </summary>
		/// <remarks>
		/// LiveOut sets contain registers that aren't modified by the procedure. When determining
		/// the returned registers, those unmodified registers must be filtered away.
		/// </remarks>
		/// <param name="flow"></param>
		private void AdjustLiveOut(ProcedureFlow flow)
		{
			flow.grfLiveOut &= flow.grfTrashed;
			flow.LiveOut &= flow.TrashedRegisters;
		}
Exemplo n.º 13
0
		/// <summary>
		/// Creates a signature for this procedure, and ensures that all registers accessed by the procedure are in the procedure
		/// Frame.
		/// </summary>
		public void EnsureSignature(Procedure proc, ProcedureFlow flow)
		{
			if (proc.Signature != null && proc.Signature.ParametersValid)
				return;

			SignatureBuilder sb = new SignatureBuilder(proc, Program.Architecture);
			Frame frame = proc.Frame;
			if (flow.grfLiveOut != 0)
			{
				sb.AddFlagGroupReturnValue(flow.grfLiveOut, frame);
			}

            var implicitRegs = Program.Platform.CreateImplicitArgumentRegisters();
            BitSet mayUse = flow.MayUse - implicitRegs;
			foreach (int r in mayUse)
			{
				if (!IsSubRegisterOfRegisters(r, mayUse))
				{
					sb.AddRegisterArgument(r);
				}
			}

			foreach (KeyValuePair<int,Identifier> de in GetSortedStackArguments(proc.Frame))
			{
				AddStackArgument(de.Key, de.Value, flow, sb);
			}

            foreach (KeyValuePair<int, Identifier> de in GetSortedFpuStackArguments(proc.Frame, 0))
			{
				sb.AddFpuStackArgument(de.Key, de.Value);
			}

            BitSet liveOut = flow.LiveOut - implicitRegs;
			foreach (int r in liveOut)
			{
				if (!IsSubRegisterOfRegisters(r, liveOut))
				{
					sb.AddArgument(frame.EnsureRegister(Program.Architecture.GetRegister(r)), true);
				}
			}

            foreach (KeyValuePair<int, Identifier> de in GetSortedFpuStackArguments(proc.Frame, -proc.Signature.FpuStackDelta))
			{
				int i = de.Key;
				if (i <= proc.Signature.FpuStackOutArgumentMax)
				{
					sb.AddArgument(frame.EnsureFpuStackVariable(i, de.Value.DataType), true);
				}
			}

            var sig = sb.BuildSignature();
            flow.Signature = sig;
			proc.Signature = sig;
		}