internal static void Main(string[] args) { if (args.Length < 1) { Console.Error.WriteLine("COULD NOT COMPILE: no path provided"); return; } // If /s option is provided, put code out as C# string if (args.Length > 1 && args[1] == "/s") { ProgramBuilder builder = new ProgramBuilder(args[0]); builder.BuildProgram(); Console.Write(builder.ProgramText); return; } // Otherwise, compile the program string errors = ""; bool succeeded = Compile(args[0], ref errors); if (succeeded) { Console.WriteLine("Complete"); } else { Console.Error.WriteLine("Could not compile.\nERRORS:\n\n"); Console.Error.WriteLine(errors); } }
public void TerAddressOf() { var pb = new ProgramBuilder(); pb.Add("AddressOf", m => { var foo = new Identifier("foo", new UnknownType(), new MemoryStorage()); var r1 = m.Reg32("r1", 1); m.Declare(r1, m.AddrOf(foo)); m.Store(r1, m.Word16(0x1234)); m.Store(m.IAdd(r1, 4), m.Byte(0x0A)); m.Return(); }); RunTest(pb.BuildProgram()); }
public void TerAddNonConstantToPointer() { ProgramBuilder pb = new ProgramBuilder(); pb.Add("proc1", m => { Identifier i = m.Local16("i"); Identifier p = m.Local16("p"); m.MStore(p, m.Word16(4)); m.MStore(m.IAdd(p, 4), m.Word16(4)); m.Assign(p, m.IAdd(p, i)); }); RunTest(pb.BuildProgram(), "Typing/TerAddNonConstantToPointer.txt"); }
public void CpaConstantMemberPointer() { ProgramBuilder program = new ProgramBuilder(); ProcedureBuilder m = new ProcedureBuilder(); Identifier ds = m.Local16("ds"); ds.DataType = PrimitiveType.SegmentSelector; Identifier bx = m.Local16("bx"); m.Assign(bx, 0x1234); m.Store(m.SegMem16(ds, bx), m.Word16(0x0042)); program.Add(m); RunTest(program.BuildProgram(), "Typing/CpaConstantMemberPointer.txt"); }
public void TerAddress() { var pb = new ProgramBuilder(); pb.Add("fn", m => { m.MStore(Address.Ptr32(0x001028), m.Cast(PrimitiveType.Real32, m.Mem(PrimitiveType.Real64, Address.Ptr32(0x001020)))); m.Return(); }); var program = pb.BuildProgram(); RunTest(program, "Typing/" + nameof(TerAddress) + ".txt"); }
public void TerAddressOf() { var pb = new ProgramBuilder(); pb.Add("AddressOf", m => { var foo = Identifier.Global("foo", new UnknownType()); var r1 = m.Reg32("r1", 1); m.Declare(r1, m.AddrOf(PrimitiveType.Ptr32, foo)); m.MStore(r1, m.Word16(0x1234)); m.MStore(m.IAdd(r1, 4), m.Byte(0x0A)); m.Return(); }); RunTest(pb.BuildProgram(), "Typing/TerAddressOf.txt"); }
public void TrcoStaggeredArraysMock() { ProgramBuilder mock = new ProgramBuilder(); mock.Add(new StaggeredArraysFragment()); Program prog = mock.BuildProgram(); coll = CreateCollector(prog); en.Transform(prog); eqb.Build(prog); coll.CollectProgramTraits(prog); Verify(prog, "Typing/TrcoStaggeredArraysMock.txt"); }
public void TycoStructMembers() { ProgramBuilder pp = new ProgramBuilder(); pp.Add("Fn", m => { Identifier ptr = m.Local32("ptr"); Identifier b16 = m.Local16("b16"); Identifier c16 = m.Local16("c16"); m.MStore(m.IAdd(ptr, 200), m.Word32(0x1234)); m.MStore(m.IAdd(ptr, 12), m.Word32(0x5678)); m.Assign(b16, m.Or(m.Mem16(m.IAdd(ptr, 14)), m.Word16(0x00FF))); }); RunTest(pp.BuildProgram(), "Typing/TycoStructMembers.txt"); }
public void TycoSignedUnsignedAdd() { ProgramBuilder pp = new ProgramBuilder(); pp.Add("Fn", m => { Identifier a = m.Local32("a"); Identifier b = m.Local32("b"); Identifier c = m.Local32("c"); a.DataType = PrimitiveType.Int32; b.DataType = PrimitiveType.UInt32; m.Assign(c, m.IAdd(a, b)); }); RunTest(pp.BuildProgram(), "Typing/TycoSignedUnsignedAdd.txt"); }
public void OnLoad(ConfigNode node) { try { var scriptBuilder = new StringBuilder(); foreach (ConfigNode contextNode in node.GetNodes("context")) { foreach (ConfigNode varNode in contextNode.GetNodes("variables")) { foreach (ConfigNode.Value value in varNode.values) { string varValue = PersistenceUtilities.DecodeLine(value.value); scriptBuilder.AppendLine(string.Format("set {0} to {1}.", value.name, varValue)); } } } if (shared.ScriptHandler == null || scriptBuilder.Length <= 0) { return; } var programBuilder = new ProgramBuilder(); // TODO: figure out how to store the filename and reload it for arg 1 below: // (Possibly all of OnLoad needs work because it never seemed to bring // back the context fully right anyway, which is why this hasn't been // addressed yet). try { SafeHouse.Logger.Log("Parsing Context:\n\n" + scriptBuilder); programBuilder.AddRange(shared.ScriptHandler.Compile("reloaded file", 1, scriptBuilder.ToString())); List <Opcode> program = programBuilder.BuildProgram(); RunProgram(program, true); } catch (NullReferenceException ex) { SafeHouse.Logger.Log("program builder failed on load. " + ex.Message); } } catch (Exception e) { if (shared.Logger != null) { shared.Logger.Log(e); } } }
public static bool Compile(string path, ref string errors) { ProgramBuilder builder = new ProgramBuilder(path); builder.BuildProgram(); CSharpCodeProvider csc = new CSharpCodeProvider(new Dictionary<string, string>() { { "CompilerVersion", "v3.5" } }); CompilerParameters parameters = new CompilerParameters(new[] { "mscorlib.dll", "System.Core.dll" }, builder.ProgramName + ".exe", true); parameters.GenerateExecutable = true; parameters.ReferencedAssemblies.Add("Rottytooth.Esolang.Folders.Runtime.dll"); string entireProgram = @"using System; using System.IO; using Rottytooth.Esolang.Folders.Runtime; public static class Program { private static VarManager _varManager; static Program() { _varManager = new VarManager(""" + builder.ProgramName + @"""); } " + builder.Declarations + @" public static void Main(string[] args) { " + builder.ProgramText + @" } }"; CompilerResults results = csc.CompileAssemblyFromSource(parameters, entireProgram); // output any errors StringBuilder errorList = new StringBuilder(); results.Errors.Cast<CompilerError>().ToList().ForEach(error => errorList.AppendLine(error.ErrorText)); if (errorList.Length > 0) { errors = errorList.ToString(); return false; } // we have successfully compiled return true; }
private void RunTest(string sExp) { var sw = new StringWriter(); program = p.BuildProgram(arch); RunTest(program, sw); try { Assert.AreEqual(sExp, sw.ToString()); } catch { Console.WriteLine(sw); throw; } }
public void TtranSegmentedArray() { var pb = new ProgramBuilder(); pb.Add("SegmentedArray", m => { var ds = m.Temp(PrimitiveType.SegmentSelector, "ds"); var bx = m.Temp(PrimitiveType.Word16, "bx"); m.SStore( ds, m.Word16(0x1234), m.SegMem16( ds, m.IAdd(m.IMul(bx, 2), m.Word16(0x5388)))); }); RunTest(pb.BuildProgram(), "Typing/TtranSegmentedArray.txt"); }
private void RunTest() { this.program = builder.BuildProgram(); this.dataFlow = new ProgramDataFlow(program); var sscf = new SccFinder <Procedure>(new ProcedureGraph(program), ProcessScc); foreach (var procedure in program.Procedures.Values) { sscf.Find(procedure); } var sbActual = new StringBuilder(); var sw = new StringWriter(); foreach (var procedure in program.Procedures.Values) { var flow = dataFlow[procedure]; sw.WriteLine("== {0} ====", procedure.Name); sw.Write("Preserved: "); sw.WriteLine(string.Join(",", flow.Preserved.OrderBy(p => p.ToString()))); sw.Write("Trashed: "); sw.WriteLine(string.Join(",", flow.Trashed.OrderBy(p => p.ToString()))); if (flow.Constants.Count > 0) { sw.Write("Constants: "); sw.Write(string.Join( ",", flow.Constants .OrderBy(kv => kv.Key.ToString()) .Select(kv => string.Format( "{0}:{1}", kv.Key, kv.Value)))); } sw.WriteLine(); } var sExp = sbExpected.ToString(); var sActual = sw.ToString(); if (sActual != sExp) { foreach (var proc in program.Procedures.Values) { Debug.Print("------"); proc.Dump(true); } Debug.WriteLine(sActual); Assert.AreEqual(sExp, sActual); } }
private void RunTest(ProgramBuilder p, string sExp) { prog = p.BuildProgram(arch); flow = new ProgramDataFlow(prog); trf = CreateTrashedRegisterFinder(); trf.Compute(); var summary = DumpProcedureSummaries().Trim(); if (sExp == summary) { return; } Console.WriteLine(summary); Assert.AreEqual(sExp, summary); }
public void TerFlatDereferenceSignedCompare() { ProgramBuilder program = CreateProgramBuilder(0x5400, 0x1000); program.Add("proc1", m => { Identifier ds = m.Local32("ds"); Identifier ds2 = m.Local32("ds2"); m.Assign(ds2, ds); m.MStore( m.IAdd(ds, m.Word32(0x5400)), m.Lt( m.Mem16(m.IAdd(m.Mem32(m.IAdd(ds, m.Word32(0x5404))), 4)), m.Word16(20))); m.MStore(m.IAdd(m.Mem32(m.IAdd(ds2, m.Word32(0x5404))), 4), m.Word16(0)); }); RunTest(program.BuildProgram(), "Typing/TerFlatDereferenceSignedCompare.txt"); }
public void TerSignedCompare() { ProgramBuilder program = new ProgramBuilder(); program.Add("proc1", m => { Identifier ds = m.Local16("ds"); ds.DataType = PrimitiveType.SegmentSelector; Identifier ds2 = m.Local16("ds2"); ds2.DataType = PrimitiveType.SegmentSelector; m.Assign(ds2, ds); m.Store( m.SegMem(PrimitiveType.Bool, ds, m.Word16(0x5400)), m.Lt(m.SegMem16(ds, m.Word16(0x5404)), m.Word16(20))); m.Store(m.SegMem16(ds2, m.Word16(0x5404)), m.Word16(0)); }); RunTest(program.BuildProgram(), "Typing/TerSignedCompare.txt"); }
public void EP_TestCondition() { var p = new ProgramBuilder(); p.Add("main", (m) => { m.Label("foo"); m.BranchCc(ConditionCode.EQ, "foo"); m.Return(); }); var proc = p.BuildProgram().Procedures.Values.First(); var ctx = new SymbolicEvaluationContext(new IntelArchitecture(ProcessorMode.Protected32), proc.Frame); var simplifier = new ExpressionSimplifier(ctx); var ep = new ExpressionPropagator(null, simplifier, ctx, new ProgramDataFlow()); var newInstr = proc.EntryBlock.Succ[0].Statements[0].Instruction.Accept(ep); Assert.AreEqual("branch Test(EQ,Z) foo", newInstr.ToString()); }
public void DtbSignedCompare() { ProcedureBuilder m = new ProcedureBuilder(); Identifier ds = m.Local16("ds"); ds.DataType = PrimitiveType.SegmentSelector; Identifier ds2 = m.Local16("ds2"); ds.DataType = PrimitiveType.SegmentSelector; m.Assign(ds2, ds); m.Store( m.SegMem(PrimitiveType.Bool, ds, m.Word16(0x5400)), m.Lt(m.SegMemW(ds, m.Word16(0x5404)), m.Word16(20))); m.Store(m.SegMemW(ds2, m.Word16(0x5404)), m.Word16(0)); ProgramBuilder prog = new ProgramBuilder(); prog.Add(m); RunTest(prog.BuildProgram(), "Typing/DtbSignedCompare.txt"); }
public void DtbStructurePointerPassedToFunction() { ProgramBuilder pp = new ProgramBuilder(); pp.Add("Fn1", m => { Identifier p = m.Local32("p"); m.Store(m.IAdd(p, 4), m.Word32(0x42)); m.SideEffect(m.Fn("Fn2", p)); m.Return(); }); pp.Add("Fn2", m => { Identifier arg1 = m.Local32("arg1"); m.Procedure.Signature = new ProcedureSignature(null, new Identifier[] { arg1 }); m.Store(m.IAdd(arg1, 8), m.Int32(0x23)); m.Return(); }); RunTest(pp.BuildProgram(), "Typing/DtbStructurePointerPassedToFunction.txt"); }
public void TerDereferenceSignedCompare() { ProgramBuilder pb = CreateProgramBuilder(0x5000, 0x1000); pb.Add("proc1", m => { Identifier ds = m.Local16("ds"); ds.DataType = PrimitiveType.SegmentSelector; Identifier ds2 = m.Local16("ds2"); ds2.DataType = PrimitiveType.SegmentSelector; m.Assign(ds2, ds); m.Store( m.SegMem(PrimitiveType.Bool, ds, m.Word16(0x5400)), m.Lt( m.SegMem16(ds, m.IAdd(m.SegMem16(ds, m.Word16(0x5404)), 4)), m.Word16(20))); m.SStore(ds2, m.IAdd(m.SegMem16(ds2, m.Word16(0x5404)), 4), m.Word16(0)); m.Return(); }); RunTest(pb.BuildProgram(), "Typing/TerDereferenceSignedCompare.txt"); }
public void TtranArrayAssignment() { var pp = new ProgramBuilder(); pp.Add("Fn", m => { Identifier rbx_18 = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rbx_18"); Identifier rdx = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rdx"); Identifier rax_22 = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rax_22"); Identifier rsi = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rsi"); Identifier rdi = m.Local(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), "rdi"); m.Label("l000000000040EC30"); m.Declare(rbx_18, m.ISub(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x1))); m.BranchIf(m.Eq(rdx, Constant.Create(PrimitiveType.Create(Domain.Integer | Domain.Real | Domain.Pointer, 64), 0x0)), "l000000000040EC69"); m.Label("l000000000040EC40"); m.Declare(rax_22, m.Word64(0x10000040)); m.Label("l000000000040EC50"); m.MStore(m.IAdd(rdi, rbx_18), m.Convert(m.Mem32( m.IAdd(m.Mem64(rax_22), m.IMul( m.Convert( m.Convert( m.Mem8(m.IAdd(rsi, rbx_18)), PrimitiveType.Byte, PrimitiveType.Word32), PrimitiveType.Word32, PrimitiveType.Word64), Constant.Create(PrimitiveType.Word64, 0x4)))), PrimitiveType.Word32, PrimitiveType.Byte)); m.Assign(rbx_18, m.ISub(rbx_18, Constant.Create(PrimitiveType.Word64, 0x1))); m.BranchIf(m.Ne(rbx_18, Constant.Create(PrimitiveType.Word64, 0xFFFFFFFFFFFFFFFF)), "l000000000040EC50"); m.Label("l000000000040EC69"); m.Return(); }); RunTest(pp.BuildProgram(), $"Typing/{nameof(TtranArrayAssignment)}.txt"); }
public void TerPassARefToFunction() { var sExp = @"// Before /////// // main // Return size: 0 define main main_entry: // succ: l1 l1: r1 = Mem0[r0 + 0<32>:word32] r1 = Mem0[r0 + r1 * 4<32>:word32] main_exit: // After /////// // main // Return size: 0 define main main_entry: // succ: l1 l1: r1 = r0[0<i32>] r1 = r0[r1] main_exit: "; var pb = new ProgramBuilder(); pb.Add("main", m => { var r0 = m.Register("r0"); var r1 = m.Register("r1"); var r2 = m.Register("r2"); var r3 = m.Register("r3"); m.Assign(r1, m.Mem32(m.IAdd(r0, 0))); m.Assign(r1, m.Mem32(m.IAdd(r0, m.IMul(r1, 4)))); }); RunStringTest(pb.BuildProgram(), sExp); }
public void DtbFn1CallFn2() { ProgramBuilder pp = new ProgramBuilder(); pp.Add("Fn1", m => { Identifier loc1 = m.Local32("loc1"); Identifier loc2 = m.Local32("loc2"); m.Assign(loc2, m.Fn("Fn2", loc1)); m.Return(); }); pp.Add("Fn2", m => { Identifier arg1 = m.Local32("arg1"); Identifier ret = m.Register(1); m.Procedure.Signature = new ProcedureSignature(ret, new Identifier[] { arg1 }); m.Procedure.Signature.Parameters[0] = arg1; m.Assign(ret, m.IAdd(arg1, 1)); m.Return(ret); }); RunTest(pp.BuildProgram(), "Typing/DtbFn1CallFn2.txt"); }
public void TtranTypedAddressOf() { var pb = new ProgramBuilder(); pb.Add("TypedAddressOf", m => { var str = new TypeReference("foo", new StructureType("foo", 0) { Fields = { { 0, PrimitiveType.Int16, "word00" }, { 4, PrimitiveType.Byte, "byte004" } } }); var foo = Identifier.Global("foo", str); var r1 = m.Reg32("r1", 1); m.Declare(r1, m.AddrOf(PrimitiveType.Ptr32, foo)); m.MStore(r1, m.Word16(0x1234)); m.MStore(m.IAdd(r1, 4), m.Byte(0x0A)); m.Return(); }); RunTest(pb.BuildProgram(), "Typing/TtranTypedAddressOf.txt"); }
public void TerTypedAddressOf() { var pb = new ProgramBuilder(); pb.Add("TypedAddressOf", m => { var str = new TypeReference("foo", new StructureType("foo", 0) { Fields = { { 0, PrimitiveType.Int16, "word00" }, { 4, PrimitiveType.Byte, "byte004" } } }); var foo = new Identifier("foo", str, new MemoryStorage()); var r1 = m.Reg32("r1", 1); m.Declare(r1, m.AddrOf(foo)); m.MStore(r1, m.Word16(0x1234)); m.MStore(m.IAdd(r1, 4), m.Byte(0x0A)); m.Return(); }); RunTest(pb.BuildProgram()); }
public static Program BuildSample() { var pb = new ProgramBuilder(); pb.Add("fact", m => { var sp = m.Register(m.Architecture.StackRegister); var r1 = m.Register(1); var r2 = m.Register(2); var r3 = m.Register(3); var cc = m.Flags("cc"); m.Assign(sp, m.Frame.FramePointer); m.Assign(r2, r1); m.Assign(r1, 1); m.Assign(cc, m.Cond(m.ISub(r2, r1))); m.BranchIf(m.Test(ConditionCode.LE, cc), "m_done"); m.Assign(sp, m.ISub(sp, 4)); m.MStore(sp, r2); m.Assign(r1, m.ISub(r2, r1)); m.Call("fact", 0); m.Assign(r2, m.Mem32(sp)); m.Assign(sp, m.IAdd(sp, 4)); m.Assign(r1, m.IMul(r1, r2)); m.Label("m_done"); m.Return(); }); pb.Add("main", m => { var r1 = m.Register(1); m.Assign(r1, 10); m.Call("fact", 0); m.MStore(m.Word32(0x400000), r1); }); return(pb.BuildProgram()); }
public void Regp_Preserve() { var pb = new ProgramBuilder(new FakeArchitecture()); pb.Add("test", m => { var r1 = m.Register(1); m.Assign(r1, m.Mem32(m.Word32(0x3000))); m.Return(); }); program = pb.BuildProgram(); RunTest(program.Procedures.Values); var sExp = #region Expected @"// test // Return size: 0 void test() test_entry: def Mem0 // succ: l1 l1: r1_1 = Mem0[0x00003000:word32] return // succ: test_exit test_exit: use Mem0 use r1_1 test: Preserved: Global memory Trashed: r1 "; #endregion AssertProgram(sExp, program.Procedures.Values); }
private void RunTest(ProgramBuilder p, string sExp) { program = p.BuildProgram(arch); flow = new ProgramDataFlow(program); trf = CreateTrashedRegisterFinder(); trf.Compute(); var summary = DumpProcedureSummaries().Trim(); if (sExp == summary) { return; } try { Assert.AreEqual(sExp, summary); } catch { Debug.Print("{0}", summary); throw; } }
/// <summary> /// This program has a cross procedural jump /// that should result in a cloned procedure, since the jumped-to code is a simple linear block /// followed by a return statement. /// </summary> /// <returns></returns> private Program CrossJumpLinearReturn() { var b = new ProgramBuilder(); b.Add("bob", m => { var r1 = m.Reg32("r1", 1); var r2 = m.Reg32("r2", 2); m.Label("bob_1"); m.Assign(r1, 0); m.Label("Real_entry"); m.MStore(r2, r1); m.Return(); }); b.Add("ext", m => { var r1 = m.Reg32("r1", 1); m.Label("ext_1"); m.Assign(r1, 4); m.Goto("Real_entry"); }); return(b.BuildProgram()); }
public void Dfa2_FactorialReg() { pb = new ProgramBuilder(); pb.Add("fact", m => { var sp = m.Register(m.Architecture.StackRegister); var r1 = m.Register(1); var r2 = m.Register(2); var r3 = m.Register(3); var cc = m.Flags(0xF, "cc"); m.Assign(sp, m.Frame.FramePointer); m.Assign(r2, r1); m.Assign(r1, 1); m.Assign(cc, m.Cond(m.ISub(r2, r1))); m.BranchIf(m.Test(ConditionCode.LE, cc), "done"); m.Assign(sp, m.ISub(sp, 4)); m.Store(sp, r2); m.Assign(r1, m.ISub(r2, r1)); m.Call("fact", 0); m.Assign(r2, m.LoadDw(sp)); m.Assign(sp, m.IAdd(sp, 4)); m.Assign(r1, m.IMul(r1, r2)); m.Label("done"); m.Return(); }); var dfa = new DataFlowAnalysis(pb.BuildProgram(), new FakeDecompilerEventListener()); dfa.UntangleProcedures2(); var sExp = @"@@@"; AssertProgram(sExp, pb); }
private void RunTest(ProgramBuilder p, string output) { SaveRunOutput(p.BuildProgram(), RunTest, output); }