public ILScanner(AppAssembler aAsmblr, TypeResolver typeResolver) { mAsmblr = aAsmblr; mReader = new ILReader(); mPlugManager = new PlugManager(LogException, LogWarning, typeResolver); }
public ILScanner(AppAssembler aAsmblr) { mAsmblr = aAsmblr; mReader = new ILReader(); mPlugManager = new PlugManager(this.LogException, this.ScanMethod, this.Queue); }
public ILScanner(AppAssembler aAsmblr) { mAsmblr = aAsmblr; mReader = new ILReader(); mPlugManager = new PlugManager(LogException, LogWarning); }
private static void DoScan() { var xSW = new Stopwatch(); xSW.Start(); string MDFFile = AppDomain.CurrentDomain.BaseDirectory + "TestKernel.mdf"; if (File.Exists(MDFFile)) File.Delete(MDFFile); var outFile = AppDomain.CurrentDomain.BaseDirectory + "TestKernel.out"; if (File.Exists(outFile)) File.Delete(outFile); var logFile = AppDomain.CurrentDomain.BaseDirectory + "TestKernel.log"; if (File.Exists(logFile)) File.Delete(logFile); var xAsmblr = new AppAssembler(1, "Cosmos.Assembler.Log"); using (var xScanner = new ILScanner(xAsmblr)) { xScanner.LogException = (Exception e) => { Console.WriteLine("ILScanner exception : " + e.Message); }; using (var xDebugInfo = new DebugInfo(MDFFile, true, true)) { xAsmblr.DebugInfo = xDebugInfo; xAsmblr.DebugEnabled = true; xAsmblr.DebugMode = DebugMode.Source; xAsmblr.TraceAssemblies = TraceAssemblies.All; xAsmblr.IgnoreDebugStubAttribute = false; xAsmblr.Assembler.Initialize(); //TODO: Add plugs into the scanning equation to profile scanning them too //System.Reflection.MethodInfo[] name = typeof(SSchockeTest.Kernel).GetMethods(); Type xFoundType = typeof(FakeKernel); var xCtor = xFoundType.GetConstructor(Type.EmptyTypes); typeof(Cosmos.System.Plugs.System.ConsoleImpl).IsSubclassOf(typeof(object)); var xEntryPoint = typeof(Kernel).GetMethod("Start", BindingFlags.Public | BindingFlags.Instance); //var xEntryPoint = typeof(Program).GetMethod("ScannerEntryPoint", BindingFlags.NonPublic | BindingFlags.Static); //EnableLogging(pathToLogFile) xScanner.EnableLogging(logFile); //xScanner.TempDebug += new Action<string>(xScanner_TempDebug); //xScanner. xScanner.QueueMethod(xEntryPoint); xScanner.Execute(xCtor); using (var xOut = new StreamWriter(outFile, false)) { //if (EmitDebugSymbols) { xAsmblr.Assembler.FlushText(xOut); xAsmblr.FinalizeDebugInfo(); } xSW.Stop(); Console.WriteLine("Total time : {0}", xSW.Elapsed); Console.WriteLine("Method count: {0}", xScanner.MethodCount); //Console.WriteLine("Instruction count: {0}", xScanner.InstructionCount); } } }
public ILScanner(AppAssembler aAsmblr, TypeResolver typeResolver, Action <Exception> aLogException, Action <string> aLogWarning) { mAsmblr = aAsmblr; mReader = new ILReader(); LogException = aLogException; LogWarning = aLogWarning; mPlugManager = new PlugManager(LogException, LogWarning, typeResolver); VTablesImplRefs.GetTypeId = GetTypeUID; // we need this to figure out which ids object, valuetype and enum have in the vmt }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { ILOpCodes.OpSwitch OpSw = (ILOpCodes.OpSwitch)aOpCode; XS.Pop(XSRegisters.EAX); for (int i = 0; i < OpSw.BranchLocations.Length; i++) { XS.Compare(XSRegisters.EAX, ( uint )i); //string DestLabel = AssemblerNasm.TmpBranchLabel( aMethod, new ILOpCodes.OpBranch( ILOpCode.Code.Jmp, aOpCode.Position, OpSw.BranchLocations[ i ] ) ); string xDestLabel = AppAssembler.TmpPosLabel(aMethod, OpSw.BranchLocations[i]); XS.Jump(CPUx86.ConditionalTestEnum.Equal, xDestLabel); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { // apparently, Roslyn changed something to the output. We now have to figure out where to jump to. if (aOpCode.CurrentExceptionRegion.Kind.HasFlag(ExceptionRegionKind.Finally) && aOpCode.CurrentExceptionRegion.HandlerOffset > aOpCode.Position) { XS.Set(aMethod.MethodBase.GetFullName() + "_" + "LeaveAddress_" + aOpCode.CurrentExceptionRegion.HandlerOffset.ToString("X2"), Assembler.CurrentIlLabel + "." + (Assembler.AsmIlIdx + 2).ToString("X2"), destinationIsIndirect: true, size: RegisterSize.Int32); XS.Jump(AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionRegion.HandlerOffset)); } XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode)); }
public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) { // apparently, Roslyn changed something to the output. We now have to figure out where to jump to. if (aOpCode.CurrentExceptionHandler.Flags.HasFlag(ExceptionHandlingClauseOptions.Finally) && aOpCode.CurrentExceptionHandler.HandlerOffset > aOpCode.Position) { new CPUx86.Jump { DestinationLabel = AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionHandler.HandlerOffset) }; } else { new CPUx86.Jump { DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { string jumpTarget = AppAssembler.TmpBranchLabel(aMethod, aOpCode); // apparently, Roslyn changed something to the output. We now have to figure out where to jump to. if (aOpCode.CurrentExceptionRegion.Kind.HasFlag(ExceptionRegionKind.Finally) && aOpCode.CurrentExceptionRegion.HandlerOffset > aOpCode.Position) { string destination = $"{aMethod.MethodBase.GetFullName()}_LeaveAddress_{aOpCode.CurrentExceptionRegion.HandlerOffset:X2}"; string source = AppAssembler.TmpBranchLabel(aMethod, aOpCode); XS.Set(destination, source, destinationIsIndirect: true, size: RegisterSize.Int32); XS.Jump(AppAssembler.TmpPosLabel(aMethod, aOpCode.CurrentExceptionRegion.HandlerOffset)); } else { XS.Jump(jumpTarget); } }
public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) { ILOpCodes.OpSwitch OpSw = (ILOpCodes.OpSwitch)aOpCode; new CPUx86.Pop { DestinationReg = CPUx86.Registers.EAX }; for (int i = 0; i < OpSw.BranchLocations.Length; i++) { new CPUx86.Compare { DestinationReg = CPUx86.Registers.EAX, SourceValue = ( uint )i }; //string DestLabel = AssemblerNasm.TmpBranchLabel( aMethod, new ILOpCodes.OpBranch( ILOpCode.Code.Jmp, aOpCode.Position, OpSw.BranchLocations[ i ] ) ); string xDestLabel = AppAssembler.TmpPosLabel(aMethod, OpSw.BranchLocations[i]); new CPUx86.ConditionalJump { Condition = CPUx86.ConditionalTestEnum.Equal , DestinationLabel = xDestLabel }; } }
public void TestStackAnalysis(Type aType, string aMethodName, Type[] aArgs) { if (aArgs is null) { aArgs = Array.Empty <Type>(); } var method = aType.GetMethod(aMethodName, 0, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, aArgs, null); var methodBase = new _MethodInfo(method, 1, _MethodInfo.TypeEnum.Normal, null); var appAssembler = new AppAssembler(null, new VoidTextWriter(), "") { DebugMode = Cosmos.Build.Common.DebugMode.None }; var ilReader = new ILReader(); var opCodes = ilReader.ProcessMethod(method); var mSequence = appAssembler.GenerateDebugSequencePoints(methodBase, Cosmos.Build.Common.DebugMode.None); var iMethod = new ILMethod(opCodes, mSequence); Assert.DoesNotThrow(() => iMethod.Analyse()); }
public void TestGenerateGroups(Type aType, string aMethodName, int aExpectedGroups, Type[] aArgs) { if (aArgs is null) { aArgs = Array.Empty <Type>(); } var method = aType.GetMethod(aMethodName, 0, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static, null, aArgs, null); var methodBase = new _MethodInfo(method, 1, _MethodInfo.TypeEnum.Normal, null); var appAssembler = new AppAssembler(null, new VoidTextWriter(), "") { DebugMode = Cosmos.Build.Common.DebugMode.None }; var ilReader = new ILReader(); var opCodes = ilReader.ProcessMethod(method); var mSequence = appAssembler.GenerateDebugSequencePoints(methodBase, Cosmos.Build.Common.DebugMode.None); var iMethod = new ILMethod(opCodes, mSequence); var groups = ILGroup.GenerateGroups(iMethod, mSequence); Assert.AreEqual(aExpectedGroups, groups.Count); }
public bool Execute() { try { LogMessage("Executing IL2CPU on assembly"); if (!Initialize()) { return(false); } LogTime("Engine execute started"); // Find the kernel's entry point. We are looking for a public class Kernel, with public static void Boot() var xInitMethod = LoadAssemblies(); if (xInitMethod == null) { return(false); } var xOutputFilename = Path.Combine(Path.GetDirectoryName(OutputFilename), Path.GetFileNameWithoutExtension(OutputFilename)); if (!DebugEnabled) { // Default of 1 is in Cosmos.Targets. Need to change to use proj props. DebugCom = 0; } using (var xAsm = new AppAssembler(DebugCom)) { using (var xDebugInfo = new DebugInfo(xOutputFilename + ".cdb", true)) { xAsm.DebugInfo = xDebugInfo; xAsm.DebugEnabled = DebugEnabled; xAsm.StackCorruptionDetection = StackCorruptionDetectionEnabled; xAsm.DebugMode = mDebugMode; xAsm.TraceAssemblies = mTraceAssemblies; xAsm.IgnoreDebugStubAttribute = IgnoreDebugStubAttribute; if (DebugEnabled == false) { xAsm.ShouldOptimize = true; } xAsm.Assembler.Initialize(); using (var xScanner = new ILScanner(xAsm)) { xScanner.LogException = LogException; xScanner.TempDebug += x => LogMessage(x); if (EnableLogging) { var xLogFile = xOutputFilename + ".log.html"; if (false == xScanner.EnableLogging(xLogFile)) { // file creation not possible EnableLogging = false; LogWarning("Could not create the file \"" + xLogFile + "\"! No log will be created!"); } } xScanner.QueueMethod(xInitMethod.DeclaringType.BaseType.GetMethod("Start")); xScanner.Execute(xInitMethod); AppAssemblerRingsCheck.Execute(xScanner); using (var xOut = new StreamWriter(OutputFilename, false, Encoding.ASCII, 128 * 1024)) { //if (EmitDebugSymbols) { xAsm.Assembler.FlushText(xOut); xAsm.FinalizeDebugInfo(); //// for now: write debug info to console //Console.WriteLine("Wrote {0} instructions and {1} datamembers", xAsm.Assembler.Instructions.Count, xAsm.Assembler.DataMembers.Count); //var dict = new Dictionary<string, long>(StringComparer.OrdinalIgnoreCase); //foreach (var instr in xAsm.Assembler.Instructions) //{ // var mn = instr.Mnemonic ?? ""; // if (dict.ContainsKey(mn)) // { // dict[mn] = dict[mn] + 1; // } // else // { // dict[mn] = 1; // } //} //foreach (var entry in dict) //{ // Console.WriteLine("{0}|{1}", entry.Key, entry.Value); //} } } // If you want to uncomment this line make sure to enable PERSISTANCE_PROFILING symbol in // DebugInfo.cs file. //LogMessage(string.Format("DebugInfo flatening {0} seconds, persistance : {1} seconds", // (int)xDebugInfo.FlateningDuration.TotalSeconds, // (int)xDebugInfo.PersistanceDuration.TotalSeconds)); } } LogTime("Engine execute finished"); return(true); } catch (Exception ex) { LogException(ex); LogMessage("Loaded assemblies: "); foreach (var xAsm in AppDomain.CurrentDomain.GetAssemblies()) { // HACK: find another way to skip dynamic assemblies (which belong to dynamic methods) try { LogMessage(xAsm.Location); } catch { } } return(false); } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xOp = aOpCode.OpCode; var xBranchLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode); var xStackType = aOpCode.StackPopTypes[0]; var xSize = SizeOfType(xStackType); var xIsFloat = TypeIsFloat(xStackType); if (xOp == ILOpCode.Code.Brtrue || xOp == ILOpCode.Code.Brfalse) { if (xIsFloat) { throw new NotSupportedException(); } if (xSize <= 4) { XS.Pop(EAX); XS.Compare(EAX, 0); XS.Jump(xOp == ILOpCode.Code.Brtrue ? ConditionalTestEnum.NotEqual : ConditionalTestEnum.Equal, xBranchLabel); } else if (xSize <= 8) { XS.Pop(EAX); XS.Pop(EBX); if (xOp == ILOpCode.Code.Brtrue) { XS.Compare(EAX, 0); XS.Jump(ConditionalTestEnum.NotEqual, xBranchLabel); XS.Compare(EBX, 0); XS.Jump(ConditionalTestEnum.NotEqual, xBranchLabel); } else { var xEndLabel = GetLabel(aMethod, aOpCode) + ".End"; XS.Compare(EAX, 0); XS.Jump(ConditionalTestEnum.NotEqual, xEndLabel); XS.Compare(EBX, 0); XS.Jump(ConditionalTestEnum.Equal, xBranchLabel); XS.Label(xEndLabel); } } else if (xSize > 8) { throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: StackSize > 8 not supported"); } return; } if (xIsFloat) { var xTestOp = SseCompareOPs[xOp]; var xIsUnordered = xOp == ILOpCode.Code.Bge_Un || xOp == ILOpCode.Code.Bgt_Un || xOp == ILOpCode.Code.Ble_Un || xOp == ILOpCode.Code.Blt_Un || xOp == ILOpCode.Code.Bne_Un; if (xSize <= 4) { XS.SSE.MoveSS(XMM0, ESP, sourceIsIndirect: true); XS.Add(ESP, 4); XS.SSE.MoveSS(XMM1, ESP, sourceIsIndirect: true); XS.Add(ESP, 4); if (xIsUnordered) { XS.SSE.MoveSS(XMM2, XMM1); XS.SSE.CompareSS(XMM2, XMM0, ComparePseudoOpcodes.Unordered); XS.MoveD(EAX, XMM2); XS.Compare(EAX, 0); XS.Jump(ConditionalTestEnum.NotEqual, xBranchLabel); } XS.SSE.CompareSS(XMM1, XMM0, xTestOp); XS.MoveD(EAX, XMM1); XS.Compare(EAX, 0); XS.Jump(ConditionalTestEnum.NotEqual, xBranchLabel); } else if (xSize <= 8) { XS.SSE2.MoveSD(XMM0, ESP, sourceIsIndirect: true); XS.Add(ESP, 8); XS.SSE2.MoveSD(XMM1, ESP, sourceIsIndirect: true); XS.Add(ESP, 8); if (xIsUnordered) { XS.SSE2.MoveSD(XMM2, XMM1); XS.SSE2.CompareSD(XMM2, XMM0, ComparePseudoOpcodes.Unordered); XS.MoveD(EAX, XMM2); XS.Compare(EAX, 0); XS.Jump(ConditionalTestEnum.NotEqual, xBranchLabel); } XS.SSE2.CompareSD(XMM1, XMM0, xTestOp); XS.MoveD(EAX, XMM1); XS.Compare(EAX, 0); XS.Jump(ConditionalTestEnum.NotEqual, xBranchLabel); } } else { var xTestOp = TestOPs[xOp]; if (xSize <= 4) { XS.Pop(EAX); XS.Pop(EBX); XS.Compare(EBX, EAX); XS.Jump(xTestOp, xBranchLabel); } else if (xSize <= 8) { var xEndLabel = GetLabel(aMethod, aOpCode) + ".End"; XS.Pop(EAX); XS.Pop(EDX); XS.Pop(EBX); XS.Pop(ECX); switch (xOp) { case ILOpCode.Code.Beq: case ILOpCode.Code.Bne_Un: XS.Compare(ECX, EDX); XS.Jump(ConditionalTestEnum.NotEqual, xOp == ILOpCode.Code.Beq ? xEndLabel : xBranchLabel); XS.Compare(EBX, EAX); XS.Jump(xTestOp, xBranchLabel); break; case ILOpCode.Code.Bge: case ILOpCode.Code.Bgt: XS.Compare(ECX, EDX); XS.Jump(ConditionalTestEnum.GreaterThan, xBranchLabel); XS.Jump(ConditionalTestEnum.NotEqual, xEndLabel); XS.Compare(EBX, EAX); XS.Jump(xTestOp, xBranchLabel); break; case ILOpCode.Code.Ble: case ILOpCode.Code.Blt: XS.Compare(ECX, EDX); XS.Jump(ConditionalTestEnum.LessThan, xBranchLabel); XS.Jump(ConditionalTestEnum.NotEqual, xEndLabel); XS.Compare(EBX, EAX); XS.Jump(xTestOp, xBranchLabel); break; case ILOpCode.Code.Bge_Un: case ILOpCode.Code.Bgt_Un: XS.Compare(ECX, EDX); XS.Jump(ConditionalTestEnum.Above, xBranchLabel); XS.Jump(ConditionalTestEnum.NotEqual, xEndLabel); XS.Compare(EBX, EAX); XS.Jump(xTestOp, xBranchLabel); break; case ILOpCode.Code.Ble_Un: case ILOpCode.Code.Blt_Un: XS.Compare(ECX, EDX); XS.Jump(ConditionalTestEnum.Below, xBranchLabel); XS.Jump(ConditionalTestEnum.NotEqual, xEndLabel); XS.Compare(EBX, EAX); XS.Jump(xTestOp, xBranchLabel); break; } XS.Label(xEndLabel); } } if (xSize > 8) { throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: StackSize > 8 not supported"); } }
public virtual bool TryCreateAppAssembler(byte debugCom, string assemblerLog, out AppAssembler result) { result = null; return(false); }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode)); //new CPU.Jump { DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { var xIsSingleCompare = true; switch (aOpCode.OpCode) { case ILOpCode.Code.Beq: case ILOpCode.Code.Bge: case ILOpCode.Code.Bgt: case ILOpCode.Code.Bge_Un: case ILOpCode.Code.Bgt_Un: case ILOpCode.Code.Ble: case ILOpCode.Code.Ble_Un: case ILOpCode.Code.Bne_Un: case ILOpCode.Code.Blt: case ILOpCode.Code.Blt_Un: xIsSingleCompare = false; break; } var xStackContent = aOpCode.StackPopTypes[0]; var xStackContentSize = SizeOfType(xStackContent); if (xStackContentSize > 8) { throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: StackSize > 8 not supported"); } CPU.ConditionalTestEnum xTestOp; // all conditions are inverted here? switch (aOpCode.OpCode) { case ILOpCode.Code.Beq: xTestOp = CPU.ConditionalTestEnum.Zero; break; case ILOpCode.Code.Bge: xTestOp = CPU.ConditionalTestEnum.GreaterThanOrEqualTo; break; case ILOpCode.Code.Bgt: xTestOp = CPU.ConditionalTestEnum.GreaterThan; break; case ILOpCode.Code.Ble: xTestOp = CPU.ConditionalTestEnum.LessThanOrEqualTo; break; case ILOpCode.Code.Blt: xTestOp = CPU.ConditionalTestEnum.LessThan; break; case ILOpCode.Code.Bne_Un: xTestOp = CPU.ConditionalTestEnum.NotEqual; break; case ILOpCode.Code.Bge_Un: xTestOp = CPU.ConditionalTestEnum.AboveOrEqual; break; case ILOpCode.Code.Bgt_Un: xTestOp = CPU.ConditionalTestEnum.Above; break; case ILOpCode.Code.Ble_Un: xTestOp = CPU.ConditionalTestEnum.BelowOrEqual; break; case ILOpCode.Code.Blt_Un: xTestOp = CPU.ConditionalTestEnum.Below; break; case ILOpCode.Code.Brfalse: xTestOp = CPU.ConditionalTestEnum.Zero; break; case ILOpCode.Code.Brtrue: xTestOp = CPU.ConditionalTestEnum.NotZero; break; default: throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Unknown OpCode for conditional branch."); } if (!xIsSingleCompare) { if (xStackContentSize <= 4) { //if (xStackContent.IsFloat) //{ // throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Comparison of floats (System.Single) is not yet supported!"); //} //else //{ XS.Pop(XSRegisters.EAX); XS.Pop(XSRegisters.EBX); XS.Compare(XSRegisters.EBX, XSRegisters.EAX); new ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; //} } else { //if (xStackContent.IsFloat) //{ // throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Comparison of doubles (System.Double) is not yet supported!"); //} //else //{ var xNoJump = GetLabel(aMethod, aOpCode) + "__NoBranch"; // value 2 EBX:EAX XS.Pop(XSRegisters.EAX); XS.Pop(XSRegisters.EBX); // value 1 EDX:ECX XS.Pop(XSRegisters.ECX); XS.Pop(XSRegisters.EDX); switch (xTestOp) { case ConditionalTestEnum.Zero: // Equal case ConditionalTestEnum.NotEqual: // NotZero XS.Xor(XSRegisters.EAX, XSRegisters.ECX); new ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Xor(XSRegisters.EBX, XSRegisters.EDX); new ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; case ConditionalTestEnum.GreaterThanOrEqualTo: XS.Compare(XSRegisters.EDX, XSRegisters.EBX); XS.Jump(ConditionalTestEnum.LessThan, xNoJump); new ConditionalJump { Condition = ConditionalTestEnum.GreaterThan, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Compare(XSRegisters.ECX, XSRegisters.EAX); XS.Jump(ConditionalTestEnum.Below, xNoJump); break; case ConditionalTestEnum.GreaterThan: XS.Compare(XSRegisters.EDX, XSRegisters.EBX); XS.Jump(ConditionalTestEnum.LessThan, xNoJump); new ConditionalJump { Condition = ConditionalTestEnum.GreaterThan, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Compare(XSRegisters.ECX, XSRegisters.EAX); XS.Jump(ConditionalTestEnum.BelowOrEqual, xNoJump); break; case ConditionalTestEnum.LessThanOrEqualTo: XS.Compare(XSRegisters.EDX, XSRegisters.EBX); new ConditionalJump { Condition = ConditionalTestEnum.LessThan, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Jump(ConditionalTestEnum.GreaterThan, xNoJump); XS.Compare(XSRegisters.ECX, XSRegisters.EAX); new ConditionalJump { Condition = ConditionalTestEnum.BelowOrEqual, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; case ConditionalTestEnum.LessThan: XS.Compare(XSRegisters.EDX, XSRegisters.EBX); new ConditionalJump { Condition = ConditionalTestEnum.LessThan, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Jump(ConditionalTestEnum.GreaterThan, xNoJump); XS.Compare(XSRegisters.ECX, XSRegisters.EAX); new ConditionalJump { Condition = ConditionalTestEnum.Below, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; // from here all unsigned case ConditionalTestEnum.AboveOrEqual: XS.Compare(XSRegisters.EDX, XSRegisters.EBX); new ConditionalJump { Condition = ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Compare(XSRegisters.ECX, XSRegisters.EAX); XS.Jump(ConditionalTestEnum.Below, xNoJump); break; case ConditionalTestEnum.Above: XS.Compare(XSRegisters.EDX, XSRegisters.EBX); new ConditionalJump { Condition = ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Compare(XSRegisters.ECX, XSRegisters.EAX); XS.Jump(ConditionalTestEnum.BelowOrEqual, xNoJump); break; case ConditionalTestEnum.BelowOrEqual: XS.Compare(XSRegisters.EDX, XSRegisters.EBX); new ConditionalJump { Condition = ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Jump(ConditionalTestEnum.Below, xNoJump); XS.Compare(XSRegisters.ECX, XSRegisters.EAX); new ConditionalJump { Condition = ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; case ConditionalTestEnum.Below: XS.Compare(XSRegisters.EDX, XSRegisters.EBX); new ConditionalJump { Condition = ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Jump(ConditionalTestEnum.Below, xNoJump); XS.Compare(XSRegisters.ECX, XSRegisters.EAX); new ConditionalJump { Condition = ConditionalTestEnum.AboveOrEqual, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; default: throw new Exception("Unknown OpCode for conditional branch in 64-bit."); } XS.Label(xNoJump); //} } } else { //if (xStackContent.IsFloat) //{ // throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Simple comparison of floating point numbers is not yet supported!"); //} //else //{ // todo: improve code clarity if (xStackContentSize <= 4) { XS.Pop(XSRegisters.EAX); if (xTestOp == ConditionalTestEnum.Zero) { XS.Compare(XSRegisters.EAX, 0); new ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; } else if (xTestOp == ConditionalTestEnum.NotZero) { XS.Compare(XSRegisters.EAX, 0); new ConditionalJump { Condition = ConditionalTestEnum.NotEqual, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; } else { throw new NotSupportedException("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Situation not supported yet! (In the Simple Comparison)"); } } else { if (TypeIsReferenceType(xStackContent)) { XS.Add(XSRegisters.ESP, 4); XS.Pop(XSRegisters.EAX); } else { XS.Pop(XSRegisters.EAX); XS.Pop(XSRegisters.EBX); } switch (xTestOp) { case ConditionalTestEnum.Zero: // Equal case ConditionalTestEnum.NotZero: // NotEqual if (TypeIsReferenceType(xStackContent)) { XS.Xor(XSRegisters.EAX, 0); new ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; } else { XS.Xor(XSRegisters.EAX, 0); new ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; XS.Xor(XSRegisters.EBX, 0); new ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; } break; default: throw new NotImplementedException("Cosmos.IL2CPU.X86.IL.Branch: Simple branch " + aOpCode.OpCode + " not implemented for operand "); } } } //} }
public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) { new CPUx86.Jump { DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; }
private static void DoScan() { var xSW = new Stopwatch(); xSW.Start(); string MDFFile = AppContext.BaseDirectory + "TestKernel.mdf"; if (File.Exists(MDFFile)) { File.Delete(MDFFile); } var outFile = AppContext.BaseDirectory + "TestKernel.out"; if (File.Exists(outFile)) { File.Delete(outFile); } var logFile = AppContext.BaseDirectory + "TestKernel.log"; if (File.Exists(logFile)) { File.Delete(logFile); } var xAsmblr = new AppAssembler(1, "Cosmos.Assembler.Log"); using (var xScanner = new ILScanner(xAsmblr)) { xScanner.LogException = (Exception e) => { Console.WriteLine("ILScanner exception : " + e.Message); }; using (var xDebugInfo = new DebugInfo(MDFFile, true, true)) { xAsmblr.DebugInfo = xDebugInfo; xAsmblr.DebugEnabled = true; xAsmblr.DebugMode = DebugMode.Source; xAsmblr.TraceAssemblies = TraceAssemblies.All; xAsmblr.IgnoreDebugStubAttribute = false; xAsmblr.Assembler.Initialize(); //TODO: Add plugs into the scanning equation to profile scanning them too Type xFoundType = typeof(FakeKernel); var xCtor = xFoundType.GetConstructor(Type.EmptyTypes); var xEntryPoint = typeof(Kernel).GetMethod("Start", BindingFlags.Public | BindingFlags.Instance); xScanner.EnableLogging(logFile); xScanner.QueueMethod(xEntryPoint); xScanner.Execute(xCtor); using (var xOut = new StreamWriter(File.OpenWrite(outFile))) { xAsmblr.Assembler.FlushText(xOut); xAsmblr.FinalizeDebugInfo(); } xSW.Stop(); Console.WriteLine("Total time : {0}", xSW.Elapsed); Console.WriteLine("Method count: {0}", xScanner.MethodCount); //Console.WriteLine("Instruction count: {0}", xScanner.InstructionCount); } } }
public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode) { XS.Jump(AppAssembler.TmpBranchLabel(aMethod, aOpCode)); }
private static void DoScan() { var xSW = new Stopwatch(); xSW.Start(); string MDFFile = AppDomain.CurrentDomain.BaseDirectory + "TestKernel.mdf"; if (File.Exists(MDFFile)) { File.Delete(MDFFile); } var outFile = AppDomain.CurrentDomain.BaseDirectory + "TestKernel.out"; if (File.Exists(outFile)) { File.Delete(outFile); } var logFile = AppDomain.CurrentDomain.BaseDirectory + "TestKernel.log"; if (File.Exists(logFile)) { File.Delete(logFile); } var xAsmblr = new AppAssembler(1, "Cosmos.Assembler.Log"); using (var xScanner = new ILScanner(xAsmblr)) { xScanner.LogException = (Exception e) => { Console.WriteLine("ILScanner exception : " + e.Message); }; using (var xDebugInfo = new DebugInfo(MDFFile, true)) { xAsmblr.DebugInfo = xDebugInfo; xAsmblr.DebugEnabled = true; xAsmblr.DebugMode = DebugMode.Source; xAsmblr.TraceAssemblies = TraceAssemblies.All; xAsmblr.IgnoreDebugStubAttribute = false; xAsmblr.Assembler.Initialize(); //TODO: Add plugs into the scanning equation to profile scanning them too //System.Reflection.MethodInfo[] name = typeof(SSchockeTest.Kernel).GetMethods(); Type xFoundType = typeof(FakeKernel); var xCtor = xFoundType.GetConstructor(Type.EmptyTypes); typeof(Cosmos.System.Plugs.System.ConsoleImpl).IsSubclassOf(typeof(object)); var xEntryPoint = typeof(Kernel).GetMethod("Start", BindingFlags.Public | BindingFlags.Instance); //var xEntryPoint = typeof(Program).GetMethod("ScannerEntryPoint", BindingFlags.NonPublic | BindingFlags.Static); //EnableLogging(pathToLogFile) xScanner.EnableLogging(logFile); //xScanner.TempDebug += new Action<string>(xScanner_TempDebug); //xScanner. xScanner.QueueMethod(xEntryPoint); xScanner.Execute(xCtor); using (var xOut = new StreamWriter(outFile, false)) { //if (EmitDebugSymbols) { xAsmblr.Assembler.FlushText(xOut); xAsmblr.FinalizeDebugInfo(); } xSW.Stop(); Console.WriteLine("Total time : {0}", xSW.Elapsed); Console.WriteLine("Method count: {0}", xScanner.MethodCount); //Console.WriteLine("Instruction count: {0}", xScanner.InstructionCount); } } }
public override void Execute(MethodInfo aMethod, ILOpCode aOpCode) { var xIsSingleCompare = true; switch (aOpCode.OpCode) { case ILOpCode.Code.Beq: case ILOpCode.Code.Bge: case ILOpCode.Code.Bgt: case ILOpCode.Code.Bge_Un: case ILOpCode.Code.Bgt_Un: case ILOpCode.Code.Ble: case ILOpCode.Code.Ble_Un: case ILOpCode.Code.Bne_Un: case ILOpCode.Code.Blt: case ILOpCode.Code.Blt_Un: xIsSingleCompare = false; break; } var xStackContent = aOpCode.StackPopTypes[0]; var xStackContentSize = SizeOfType(xStackContent); if (xStackContentSize > 8) { throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: StackSize > 8 not supported"); } CPU.ConditionalTestEnum xTestOp; // all conditions are inverted here? switch (aOpCode.OpCode) { case ILOpCode.Code.Beq: xTestOp = CPU.ConditionalTestEnum.Zero; break; case ILOpCode.Code.Bge: xTestOp = CPU.ConditionalTestEnum.GreaterThanOrEqualTo; break; case ILOpCode.Code.Bgt: xTestOp = CPU.ConditionalTestEnum.GreaterThan; break; case ILOpCode.Code.Ble: xTestOp = CPU.ConditionalTestEnum.LessThanOrEqualTo; break; case ILOpCode.Code.Blt: xTestOp = CPU.ConditionalTestEnum.LessThan; break; case ILOpCode.Code.Bne_Un: xTestOp = CPU.ConditionalTestEnum.NotEqual; break; case ILOpCode.Code.Bge_Un: xTestOp = CPU.ConditionalTestEnum.AboveOrEqual; break; case ILOpCode.Code.Bgt_Un: xTestOp = CPU.ConditionalTestEnum.Above; break; case ILOpCode.Code.Ble_Un: xTestOp = CPU.ConditionalTestEnum.BelowOrEqual; break; case ILOpCode.Code.Blt_Un: xTestOp = CPU.ConditionalTestEnum.Below; break; case ILOpCode.Code.Brfalse: xTestOp = CPU.ConditionalTestEnum.Zero; break; case ILOpCode.Code.Brtrue: xTestOp = CPU.ConditionalTestEnum.NotZero; break; default: throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Unknown OpCode for conditional branch."); } if (!xIsSingleCompare) { if (xStackContentSize <= 4) { //if (xStackContent.IsFloat) //{ // throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Comparison of floats (System.Single) is not yet supported!"); //} //else //{ new CPU.Pop { DestinationReg = CPU.Registers.EAX }; new CPU.Pop { DestinationReg = CPU.Registers.EBX }; new CPU.Compare { DestinationReg = CPU.Registers.EBX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; //} } else { //if (xStackContent.IsFloat) //{ // throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Comparison of doubles (System.Double) is not yet supported!"); //} //else //{ var xNoJump = GetLabel(aMethod, aOpCode) + "__NoBranch"; // value 2 EBX:EAX new CPU.Pop { DestinationReg = CPU.Registers.EAX }; new CPU.Pop { DestinationReg = CPU.Registers.EBX }; // value 1 EDX:ECX new CPU.Pop { DestinationReg = CPU.Registers.ECX }; new CPU.Pop { DestinationReg = CPU.Registers.EDX }; switch (xTestOp) { case ConditionalTestEnum.Zero: // Equal case ConditionalTestEnum.NotEqual: // NotZero new CPU.Xor { DestinationReg = CPU.Registers.EAX, SourceReg = CPU.Registers.ECX }; new CPU.ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.Xor { DestinationReg = CPU.Registers.EBX, SourceReg = CPU.Registers.EDX }; new CPU.ConditionalJump { Condition = xTestOp, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; case ConditionalTestEnum.GreaterThanOrEqualTo: new CPU.Compare { DestinationReg = CPU.Registers.EDX, SourceReg = CPU.Registers.EBX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.LessThan, DestinationLabel = xNoJump }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.GreaterThan, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.Compare { DestinationReg = CPU.Registers.ECX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Below, DestinationLabel = xNoJump }; break; case ConditionalTestEnum.GreaterThan: new CPU.Compare { DestinationReg = CPU.Registers.EDX, SourceReg = CPU.Registers.EBX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.LessThan, DestinationLabel = xNoJump }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.GreaterThan, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.Compare { DestinationReg = CPU.Registers.ECX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.BelowOrEqual, DestinationLabel = xNoJump }; break; case ConditionalTestEnum.LessThanOrEqualTo: new CPU.Compare { DestinationReg = CPU.Registers.EDX, SourceReg = CPU.Registers.EBX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.LessThan, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.GreaterThan, DestinationLabel = xNoJump }; new CPU.Compare { DestinationReg = CPU.Registers.ECX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.BelowOrEqual, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; case ConditionalTestEnum.LessThan: new CPU.Compare { DestinationReg = CPU.Registers.EDX, SourceReg = CPU.Registers.EBX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.LessThan, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.GreaterThan, DestinationLabel = xNoJump }; new CPU.Compare { DestinationReg = CPU.Registers.ECX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Below, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; // from here all unsigned case ConditionalTestEnum.AboveOrEqual: new CPU.Compare { DestinationReg = CPU.Registers.EDX, SourceReg = CPU.Registers.EBX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.Compare { DestinationReg = CPU.Registers.ECX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Below, DestinationLabel = xNoJump }; break; case ConditionalTestEnum.Above: new CPU.Compare { DestinationReg = CPU.Registers.EDX, SourceReg = CPU.Registers.EBX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.Compare { DestinationReg = CPU.Registers.ECX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.BelowOrEqual, DestinationLabel = xNoJump }; break; case ConditionalTestEnum.BelowOrEqual: new CPU.Compare { DestinationReg = CPU.Registers.EDX, SourceReg = CPU.Registers.EBX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Below, DestinationLabel = xNoJump }; new CPU.Compare { DestinationReg = CPU.Registers.ECX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; case ConditionalTestEnum.Below: new CPU.Compare { DestinationReg = CPU.Registers.EDX, SourceReg = CPU.Registers.EBX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Above, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.Below, DestinationLabel = xNoJump }; new CPU.Compare { DestinationReg = CPU.Registers.ECX, SourceReg = CPU.Registers.EAX }; new CPU.ConditionalJump { Condition = CPU.ConditionalTestEnum.AboveOrEqual, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; break; default: throw new Exception("Unknown OpCode for conditional branch in 64-bit."); } new Label(xNoJump); //} } } else { //if (xStackContent.IsFloat) //{ // throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Simple comparison of floating point numbers is not yet supported!"); //} //else //{ // todo: improve code clarity if (xStackContentSize > 4) { throw new Exception("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Simple branches are not yet supported on operands > 4 bytes!"); } new CPU.Pop { DestinationReg = CPU.Registers.EAX }; if (xTestOp == ConditionalTestEnum.Zero) { new CPU.Compare { DestinationReg = CPU.Registers.EAX, SourceValue = 0 }; new CPU.ConditionalJump { Condition = ConditionalTestEnum.Equal, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; } else if (xTestOp == ConditionalTestEnum.NotZero) { new CPU.Compare { DestinationReg = CPU.Registers.EAX, SourceValue = 0 }; new CPU.ConditionalJump { Condition = ConditionalTestEnum.NotEqual, DestinationLabel = AppAssembler.TmpBranchLabel(aMethod, aOpCode) }; } else { throw new NotSupportedException("Cosmos.IL2CPU.x86->IL->Branch.cs->Error: Situation not supported yet! (In the Simple Comparison)"); } } //} }
public override bool TryCreateAppAssembler(byte debugCom, string assemblerLog, out AppAssembler result) { return(base.TryCreateAppAssembler(debugCom, assemblerLog, out result)); }