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); }
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); }
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(); }
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)); } } }
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); }
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"); }
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)); }
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)); }
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()); }
/// <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; }
/// <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; }