using System; using System.Collections.Generic; using System.Linq; using System.Text; using Indy.IL2CPU.Assembler; using Indy.IL2CPU.IL.X86.Native.CustomImplementations.System; using Indy.IL2CPU.IL.X86.Native.CustomImplementations.System.Diagnostics; using Mono.Cecil; using Mono.Cecil.Cil; using CPU = Indy.IL2CPU.Assembler.X86; using CPUNative = Indy.IL2CPU.Assembler.X86.Native; namespace Indy.IL2CPU.IL.X86.Native { public class NativeOpCodeMap: X86.X86OpCodeMap { internal static NativeOpCodeMap Instance; public override void Initialize(Indy.IL2CPU.Assembler.Assembler aAssembler, IEnumerable aProjectAssemblies, IEnumerable aPlugs, Func aTypeResolver, Func aAssemblyResolver) { base.Initialize(aAssembler, aProjectAssemblies, aPlugs, aTypeResolver, aAssemblyResolver); base.mMap[Code.Call] = typeof(Call); } public NativeOpCodeMap() { Instance = this; } // public MethodDefinition GetGlueMethod(GlueMethodTypeEnum aMethodType) { // CheckGlueMethod(); // if (!mGlueMethods.ContainsKey(aMethodType)) { // throw new Exception("GlueMethod '" + aMethodType.ToString() + "' not implemented!"); // } // MethodDefinition xResult = mGlueMethods[aMethodType]; // Engine.QueueMethod(xResult); // return xResult; // } // // public MethodDefinition GetGluePlaceholderMethod(GluePlaceholderMethodTypeEnum aMethodType) { // CheckGluePlaceholderMethod(); // if (!mGluePlaceholderMethods.ContainsKey(aMethodType)) { // throw new Exception("GluePlaceholderMethod '" + aMethodType.ToString() + "' not implemented!"); // } // return mGluePlaceholderMethods[aMethodType]; // } // // public FieldDefinition GetGlueField(GlueFieldTypeEnum aFieldType) { // CheckGlueField(); // if (!mGlueFields.ContainsKey(aFieldType)) { // throw new Exception("GlueField '" + aFieldType.ToString() + "' not found!"); // } // return mGlueFields[aFieldType]; // } protected override Type GetCustomMethodImplementationOp() { return typeof(NativeCustomMethodImplementationOp); } protected override Type GetMethodFooterOp() { return typeof(NativeMethodFooterOp); } protected override Type GetMainEntryPointOp() { return typeof(NativeMainEntryMethodOp); } protected override Type GetMethodHeaderOp() { return typeof(NativeMethodHeaderOp); } // private SortedList mGlueMethods; // private SortedList mGluePlaceholderMethods; // private SortedList mGlueFields; // private void CheckGlueMethod() { // if (mGlueMethods != null) { // return; // } // mGlueMethods = new SortedList(); // AssemblyDefinition xCrawledAsm = Engine.GetCrawledAssembly(); // foreach (ModuleDefinition xModule in xCrawledAsm.Modules) { // foreach (TypeDefinition xType in xModule.Types) { // foreach (MethodDefinition xMethod in xType.Methods) { // IEnumerable xAttribs = (from item in xMethod.CustomAttributes.Cast() // where item.Constructor.DeclaringType.FullName == typeof(GlueMethodAttribute).FullName // select item); // if (xAttribs == null || xAttribs.Count() == 0) { // continue; // } // foreach (CustomAttribute xAttrib in xAttribs) { // if (!xAttrib.Resolved) { // if (!xAttrib.Resolve()) { // throw new Exception("Couldn't resolve attribute on method '" + xMethod.GetFullName()); // } // } // mGlueMethods.Add((GlueMethodTypeEnum)xAttrib.Properties["MethodType"], xMethod); // } // } // } // } // } // // private void CheckGluePlaceholderMethod() { // if (mGluePlaceholderMethods != null) { // return; // } // mGluePlaceholderMethods = new SortedList(); // AssemblyDefinition xCrawledAsm = Engine.GetCrawledAssembly(); // foreach (ModuleDefinition xModule in xCrawledAsm.Modules) { // foreach (TypeDefinition xType in xModule.Types) { // foreach (MethodDefinition xMethod in xType.Methods) { // CustomAttribute xAttrib = (from item in xMethod.CustomAttributes.Cast() // where item.Constructor.DeclaringType.FullName == typeof(GluePlaceholderMethodAttribute).FullName // select item).FirstOrDefault(); // if (xAttrib == null) { // continue; // } // if (!xAttrib.Resolved) { // if (!xAttrib.Resolve()) { // throw new Exception("Couldn't resolve attribute on method '" + xMethod.GetFullName()); // } // } // mGluePlaceholderMethods.Add((GluePlaceholderMethodTypeEnum)xAttrib.Properties["MethodType"], xMethod); // } // } // } // } // // private void CheckGlueField() { // if (mGlueFields != null) { // return; // } // mGlueFields = new SortedList(); // AssemblyDefinition xCrawledAsm = Engine.GetCrawledAssembly(); // foreach (ModuleDefinition xModule in xCrawledAsm.Modules) { // foreach (TypeDefinition xType in xModule.Types) { // foreach (FieldDefinition xFieldDefinition in xType.Fields) { // CustomAttribute xAttrib = (from item in xFieldDefinition.CustomAttributes.Cast() // where item.Constructor.DeclaringType.FullName == typeof(GlueFieldAttribute).FullName // select item).FirstOrDefault(); // if (xAttrib == null) { // continue; // } // if (!xAttrib.Resolved) { // if (!xAttrib.Resolve()) { // throw new Exception("Couldn't resolve attribute on method '" + xFieldDefinition.GetFullName()); // } // } // if (mGlueFields.ContainsKey((GlueFieldTypeEnum)xAttrib.Properties["FieldType"])) { // throw new Exception("GlueField of type '" + ((GlueFieldTypeEnum)xAttrib.Properties["FieldType"]).ToString() + "' already found!"); // } // mGlueFields.Add((GlueFieldTypeEnum)xAttrib.Properties["FieldType"], xFieldDefinition); // } // } // } // } protected override IList GetPlugAssemblies() { IList xResult = base.GetPlugAssemblies(); xResult.Add(AssemblyFactory.GetAssembly(typeof(NativeOpCodeMap).Assembly.Location)); return xResult; } public override bool HasCustomAssembleImplementation(MethodInformation aMethodInfo, bool aInMetalMode) { switch (aMethodInfo.LabelName) { case "System_Byte___Indy_IL2CPU_IL_X86_CustomImplementations_System_StringImpl_GetByteFromChar___System_Char___": { if (aInMetalMode) { return true; } break; } case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IDT_LoadArray____": { return true; } case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IDT_RegisterIDT____": { return true; } case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_GDT_LoadArray____": { return true; } case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_GDT_RegisterGDT____": { return true; } case "System_Void___Indy_IL2CPU_RuntimeEngine_Heap_Initialize____": { return true; } case "System_Void___System_Diagnostics_Debugger_Break____": { return true; } case "System_Void___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IO_WriteToPort___System_UInt16__System_Byte__": { return true; } case "System_Byte___Indy_IL2CPU_IL_X86_Native_RuntimeEngineImpl_IO_ReadFromPort___System_UInt16__": { return true; } case "System_Void___Cosmos_Kernel_ConsoleDrv_TestIDT____": { return true; } default: { // CheckGluePlaceholderMethod(); // GluePlaceholderMethodTypeEnum? xMethodType = null; // int xResult = (from item in mGluePlaceholderMethods.Keys // where Label.GenerateLabelName(mGluePlaceholderMethods[item]) == aMethodInfo.LabelName // select item).Count(); // if (xResult > 0) { // return true; // } else { break; // } } } return base.HasCustomAssembleImplementation(aMethodInfo, aInMetalMode); } public override void DoCustomAssembleImplementation(bool aInMetalMode, Assembler.Assembler aAssembler, MethodInformation aMethodInfo) { switch (aMethodInfo.LabelName) { case "System_Byte___Indy_IL2CPU_IL_X86_CustomImplementations_System_StringImpl_GetByteFromChar___System_Char___": { if (aInMetalMode) { DoAssemble_String_GetByteFromChar(aAssembler, aMethodInfo); return; } break; } case "System_Void___Indy_IL2CPU_RuntimeEngine_Heap_Initialize____": { return; } case "System_Void___System_Diagnostics_Debugger_Break____": { //aAssembler.Add(new Literal("xchg bx, bx")); return; } default: { // CheckGluePlaceholderMethod(); // GluePlaceholderMethodTypeEnum? xMethodType = null; // // foreach (GluePlaceholderMethodTypeEnum xTheMethodType in mGluePlaceholderMethods.Keys) { // if (Label.GenerateLabelName(mGluePlaceholderMethods[xTheMethodType]) == aMethodInfo.LabelName) { // xMethodType = xTheMethodType; // break; // } // } // if (xMethodType != null) { // AssembleGluePlaceholderMethod(xMethodType.Value, aAssembler, aMethodInfo); // } break; } } base.DoCustomAssembleImplementation(aInMetalMode, aAssembler, aMethodInfo); } // private void AssembleGluePlaceholderMethod(GluePlaceholderMethodTypeEnum aMethodType, Assembler.Assembler aAssembler, MethodInformation aMethodInfo) { // switch (aMethodType) { // case GluePlaceholderMethodTypeEnum.GDT_LoadArray: { // FieldDefinition xFieldDef = GetGlueField(GlueFieldTypeEnum.GDT_Array); // string xFieldName = Assembler.DataMember.GetStaticFieldName(xFieldDef); // string xFieldData = "0,0,0,0,"; // xFieldData += BitConverter.GetBytes((uint)InstanceTypeEnum.StaticEmbeddedArray).Aggregate("", (b, r) => r + b + ","); // xFieldData += "3,0,0,0,"; // for (int i = 0; i < 3; i++) { // xFieldData += ",0,0,0,0,0,0,0,0"; // } // DataMember xDataItem = (from item in aAssembler.DataMembers // where item.Name == xFieldName // select item).FirstOrDefault(); // aAssembler.DataMembers.Remove(xDataItem); // aAssembler.DataMembers.Add(new DataMember(xFieldName, "dd", xFieldName)); // aAssembler.DataMembers.Add(new DataMember(xFieldName + "___Contents", "db", xFieldData)); // xFieldDef = GetGlueField(GlueFieldTypeEnum.GDT_Pointer); // string xPointerFieldName; // Engine.QueueStaticField(xFieldDef, out xPointerFieldName); // new CPU.Move("eax", xPointerFieldName); // new CPU.Move("word [eax]", "0x" + ((8 * 3) - 1).ToString("X")); // new CPU.Move("ecx", "[" + xFieldName + "]"); // new CPU.Add("ecx", "0xC"); // new CPU.Move("dword [eax + 2]", "ecx"); // break; // } // case GluePlaceholderMethodTypeEnum.GDT_Register: { // FieldDefinition xFieldDef = GetGlueField(GlueFieldTypeEnum.GDT_Pointer); // string xPointerFieldName; // Engine.QueueStaticField(xFieldDef, out xPointerFieldName); // new CPU.Move("eax", xPointerFieldName); // new CPUNative.Lgdt("[eax]"); // new CPU.Move("eax", "0x10"); // new CPU.Move("ds", "ax"); // new CPU.Move("es", "ax"); // new CPU.Move("fs", "ax"); // new CPU.Move("gs", "ax"); // new CPU.Move("ss", "ax"); // new CPU.JumpAlways("0x8:flush____gdt______table__part1"); // new Label("flush____gdt______table__part1"); // break; // } // case GluePlaceholderMethodTypeEnum.IDT_LoadArray: { // MethodDefinition xTheMethod = GetGlueMethod(GlueMethodTypeEnum.IDT_SetHandler); // Engine.QueueMethod(xTheMethod); // mIDTSetHandlerMethodName = Label.GenerateLabelName(xTheMethod); // FieldDefinition xFieldDef = GetGlueField(GlueFieldTypeEnum.IDT_Array); // string xFieldName = Assembler.DataMember.GetStaticFieldName(xFieldDef); // string xFieldData = "0,0,0,0,"; // xFieldData += BitConverter.GetBytes((uint)InstanceTypeEnum.StaticEmbeddedArray).Aggregate("", (b, r) => r + b + ","); // xFieldData += "1,0,0,0"; // for (int i = 0; i < 256; i++) { // xFieldData += ",0,0,0,0,0,0,0,0"; // } // DataMember xDataItem = (from item in aAssembler.DataMembers // where item.Name == xFieldName // select item).FirstOrDefault(); // aAssembler.DataMembers.Remove(xDataItem); // aAssembler.DataMembers.Add(new DataMember(xFieldName, "dd", xFieldName + "___Contents")); // aAssembler.DataMembers.Add(new DataMember(xFieldName + "___Contents", "db", xFieldData)); // xFieldDef = GetGlueField(GlueFieldTypeEnum.IDT_Pointer); // string xPointerFieldName; // Engine.QueueStaticField(xFieldDef, out xPointerFieldName); // new CPU.Move("eax", xPointerFieldName); // new CPU.Move("word [eax]", "0x" + ((8 * 256) - 1).ToString("X")); // new CPU.Move("ecx", xFieldName + "___Contents"); // new CPU.Add("ecx", "0xC"); // new CPU.Move("dword [eax + 2]", "ecx"); // break; // } // case GluePlaceholderMethodTypeEnum.IDT_Register: { // FieldDefinition xFieldDef = GetGlueField(GlueFieldTypeEnum.IDT_Pointer); // string xPointerFieldName; // Engine.QueueStaticField(xFieldDef, out xPointerFieldName); // MethodDefinition xTheMethod = GetGlueMethod(GlueMethodTypeEnum.IDT_SetHandler); // Engine.QueueMethod(xTheMethod); // mIDTSetHandlerMethodName = Label.GenerateLabelName(xTheMethod); // new CPU.Call("___________REGISTER___ISRS_____"); // new CPU.Move("eax", xPointerFieldName); // new CPUNative.Lidt("eax"); // GetGlueMethod(GlueMethodTypeEnum.IDT_InterruptHandler); // break; // } // case GluePlaceholderMethodTypeEnum.IO_ReadByte: { // new CPU.Xor("eax", "eax"); // IL.X86.Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); // new CPU.Pop("edx"); // new CPU.Move("eax", "0"); // new CPUNative.In("al", "dx"); // new CPU.Push("eax"); // break; // } // case GluePlaceholderMethodTypeEnum.IO_WriteByte: { // Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); // new CPU.Pop("edx"); // Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[1]); // new CPU.Pop("eax"); // new CPUNative.Out("dx", "al"); // break; // } // case GluePlaceholderMethodTypeEnum.IDT_EnableInterrupts: { // new CPUNative.Sti(); // break; // } // case GluePlaceholderMethodTypeEnum.GetKernelResource: { // new CPUNative.Break(); // break; // } // default: // throw new NotImplementedException("GluePlaceholderMethod '" + aMethodType.ToString() + "' not implemented!"); // } // } // // private string mIDTSetHandlerMethodName; private static void DoAssemble_String_GetByteFromChar(Assembler.Assembler aAssembler, MethodInformation aMethodInfo) { X86.Ldarg.Ldarg(aAssembler, aMethodInfo.Arguments[0]); } public override void PostProcess(Indy.IL2CPU.Assembler.Assembler aAssembler) { base.PostProcess(aAssembler); // TypeDefinition xRuntimeEngineTypeDef = Engine.GetTypeDefinition(typeof(RuntimeEngineImpl).Assembly.GetName().Name, typeof(RuntimeEngineImpl).FullName); // MethodDefinition xTheMethod = GetGlueMethod(GlueMethodTypeEnum.IDT_SetHandler); // Engine.QueueMethod(xTheMethod); // mIDTSetHandlerMethodName = Label.GenerateLabelName(xTheMethod); // Console.WriteLine("IDTEntry size = {0}", Engine.GetFieldStorageSize(Engine.GetTypeDefinition(typeof(Cosmos.Kernel.Boot.Glue.IDTEntryStruct).Assembly.GetName().Name, typeof(Cosmos.Kernel.Boot.Glue.IDTEntryStruct).FullName))); // X86.X86MethodHeaderOp.AssembleHeader(aAssembler, "___________REGISTER___ISRS_____", new int[0], new MethodInformation.Argument[0]); // string xInterruptHandlerLabel = Label.GenerateLabelName(GetGlueMethod(GlueMethodTypeEnum.IDT_InterruptHandler)); // int[] xInterruptsWithParam = new int[] { 8, 10, 11, 12, 13, 14 }; // for (int i = 0; i < 256; i++) { // new CPU.Pushd("0x" + i.ToString("X")); // new CPU.Pushd("____INTERRUPT_HANDLER___" + i); // new CPU.Pushd("0x08"); // new CPU.Pushd("0x8E"); // new CPU.Call(mIDTSetHandlerMethodName); // } // X86.X86MethodFooterOp.AssembleFooter(0, aAssembler, new MethodInformation.Variable[0], new MethodInformation.Argument[0], 0); // for (int j = 0; j < 256; j++) { // new Label("____INTERRUPT_HANDLER___" + j); // new CPUNative.Cli(); // new CPUNative.Break(); // new CPUNative.Pushad(); // new CPU.Pushd(j.ToString()); // if (!xInterruptsWithParam.Contains(j)/* && !(j >= 0x20 && j <= 0x2F)*/) { // new CPU.Pushd("0"); // } // new CPU.Call(xInterruptHandlerLabel); // new CPUNative.Popad(); // new CPUNative.Break(); // new CPUNative.Sti(); // new CPUNative.IRet(); // } // IEnumerable xAssemblies = Engine.GetAllAssemblies(); // SortedList xResources = new SortedList(); // foreach (AssemblyDefinition xAssembly in xAssemblies) { // foreach (CustomAttribute xAttrib in xAssembly.CustomAttributes) { // if (!xAttrib.Resolved) { // xAttrib.Resolve(); // } // } // IEnumerable> xWantedResources = (from item in xAssembly.CustomAttributes.Cast() // where item.Constructor.DeclaringType.FullName == typeof(KernelResourceAttribute).FullName // select new KeyValuePair((int)item.ConstructorParameters[1], // (string)item.ConstructorParameters[0])); // foreach (KeyValuePair xWantedResource in xWantedResources) { // foreach (ModuleDefinition xModule in xAssembly.Modules) { // foreach (Resource xResource in xModule.Resources) { // if (xResource.Name == xWantedResource.Value) { // EmbeddedResource xEmbedded = xResource as EmbeddedResource; // if (xEmbedded == null) { // throw new Exception("Resource found but was not an embedded resource (Resource Name = '" + xWantedResource.Value + "')"); // } // xResources.Add(xWantedResource.Key, xEmbedded.Data); // } // } // } // } // } // StringBuilder xValue = new StringBuilder(); // DataMember xDataMember; // for (int i = 0; i < xResources.Count; i++) { // xValue.Remove(0, xValue.Length); // xValue.Append("0,0,0,0,2,0,0,0,"); // xValue.Append(BitConverter.GetBytes(xResources.Values[i].Length).Aggregate("", (r, v) => r + v + ",")); // xValue.Append(xResources.Values[i].Aggregate("", (r, v) => r + v + ",")); // xDataMember = new DataMember("embedded_resource_" + xResources.Keys[i] + "_contents", "db", xValue.ToString().TrimEnd(',')); // aAssembler.DataMembers.Add(xDataMember); // } // MethodDefinition xGetResourceMethod = GetGluePlaceholderMethod(GluePlaceholderMethodTypeEnum.GetKernelResource); // MethodInformation xGetResourceMethodInfo = Engine.GetMethodInfo(xGetResourceMethod, xGetResourceMethod, xGetResourceMethod.Name, null); // string xGetResourceLabelName = Label.GenerateLabelName(xGetResourceMethod); // for (int i = 0; i < aAssembler.Instructions.Count; i++) { // if ((aAssembler.Instructions[i] is Label) && ((Label)aAssembler.Instructions[i]).Name == xGetResourceLabelName) { // aAssembler.Instructions.RemoveRange(i, 10); // break; // } // } // NativeMethodHeaderOp.AssembleHeader(aAssembler, xGetResourceLabelName, new int[0], new MethodInformation.Argument[0]); // Op.Ldarg(aAssembler, xGetResourceMethodInfo.Arguments[0]); // new CPU.Pop("eax"); // foreach (int xId in xResources.Keys) { // new CPU.Move("ecx", "0x" + xId.ToString("X")); // new CPU.Compare("eax", "ecx"); // new CPU.JumpIfNotEquals(".__after__" + xId); // new CPU.Push("embedded_resource_" + xId + "_contents"); // new CPU.JumpAlways(".END__OF__METHOD"); // new Label(".__after__" + xId); // } // NativeMethodFooterOp.AssembleFooter(4, aAssembler, new MethodInformation.Variable[0], new MethodInformation.Argument[0], 4); } } }