コード例 #1
0
ファイル: ILMethod.cs プロジェクト: aura-systems/IL2CPU
        public void Analyse()
        {
            var toAnalyse = new List <ILGroup>(StructuredCode);

            while (toAnalyse.Count != 0)
            {
                var analysing = toAnalyse.First(g => g.StartStack != null);
                toAnalyse.Remove(analysing);
                var stack = new Stack <Type>(analysing.StartStack.Reverse());

                uint stackOffset = 0;
                foreach (var item in stack)
                {
                    stackOffset += ILOp.Align(ILOp.SizeOfType(item), 4);
                }

                foreach (var opcode in analysing.OpCodes)
                {
                    if (opcode.CurrentExceptionRegion != null && opcode.CurrentExceptionRegion.TryOffset == opcode.Position)
                    {
                        analysing.PossibleContinuations.First(c => c.StartPosition == opcode.CurrentExceptionRegion.HandlerOffset).StartStack = new Stack <Type>(analysing.StartStack.Reverse());
                    }

                    opcode.DoStackAnalysis(stack, ref stackOffset);
                }
                foreach (var c in analysing.PossibleContinuations)
                {
                    c.StartStack = new Stack <Type>(stack.Reverse());
                }
            }
        }
コード例 #2
0
        public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
        {
            // method signature: $this, object @object, IntPtr method
            var xAssembler  = aAssembler;
            var xMethodInfo = (_MethodInfo)aMethodInfo;

            XS.Comment("Save target ($this) to field");
            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- ldarg 1");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 1);
            XS.Comment("-- stfld _target");
            Stfld.DoExecute(xAssembler, xMethodInfo, "System.Object System.Delegate._target", xMethodInfo.MethodBase.DeclaringType, true, false);
            XS.Comment("Save method pointer to field");
            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- ldarg 2");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 2);
            XS.Comment("-- stfld _methodPtr");
            Stfld.DoExecute(xAssembler, xMethodInfo, "System.IntPtr System.Delegate._methodPtr", xMethodInfo.MethodBase.DeclaringType, true, false);
            XS.Comment("Saving ArgSize to field");
            uint xSize = 0;

            foreach (var xArg in xMethodInfo.MethodBase.DeclaringType.GetMethod("Invoke").GetParameters())
            {
                xSize += ILOp.Align(ILOp.SizeOfType(xArg.ParameterType), 4);
            }

            XS.Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            XS.Comment("-- push argsize");
            XS.Push(xSize);
            XS.Comment("-- stfld ArgSize");
            Stfld.DoExecute(xAssembler, xMethodInfo, "$$ArgSize$$", xMethodInfo.MethodBase.DeclaringType, true, false);
        }
コード例 #3
0
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            // todo: implement exception support.
            var xSize = SizeOfType(aOpCode.StackPopTypes[0]);

            new CPUx86.Add
            {
                DestinationReg = CPUx86.Registers.ESP,
                SourceValue    = ILOp.Align((uint)xSize, 4)
            };
        }
コード例 #4
0
ファイル: And.cs プロジェクト: xsword911/Cosmos
        public override void Execute(MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackContent      = aOpCode.StackPopTypes[0];
            var xStackContentSize  = SizeOfType(xStackContent);
            var xStackContent2     = aOpCode.StackPopTypes[1];
            var xStackContent2Size = SizeOfType(xStackContent2);


            var xSize = Math.Max(xStackContentSize, xStackContent2Size);

            if (ILOp.Align(xStackContentSize, 4u) != ILOp.Align(xStackContent2Size, 4u))
            {
                throw new NotSupportedException("Cosmos.IL2CPU.x86->IL->And.cs->Error: Operands have different size!");
            }
            if (xSize > 8)
            {
                throw new NotImplementedException("Cosmos.IL2CPU.x86->IL->And.cs->Error: StackSize > 8 not supported");
            }

            if (xSize > 4)
            {
                // [ESP] is low part
                // [ESP + 4] is high part
                // [ESP + 8] is low part
                // [ESP + 12] is high part
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EDX
                };
                // [ESP] is low part
                // [ESP + 4] is high part
                new CPUx86.And {
                    DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX
                };
                new CPUx86.And {
                    DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, DestinationDisplacement = 4, SourceReg = CPUx86.Registers.EDX
                };
            }
            else
            {
                new CPUx86.Pop {
                    DestinationReg = CPUx86.Registers.EAX
                };
                new CPUx86.And {
                    DestinationReg = CPUx86.Registers.ESP, DestinationIsIndirect = true, SourceReg = CPUx86.Registers.EAX
                };
            }
        }
コード例 #5
0
        public override void AssembleNew(Cosmos.Assembler.Assembler aAssembler, object aMethodInfo)
        {
            // method signature: $this, object @object, IntPtr method
            var xMethodInfo = (MethodInfo)aMethodInfo;
            var xAssembler  = (NewAssembler)aAssembler;

            new Comment("Save target ($this) to field");
            new Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            //Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            new Comment("-- ldarg 1");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 1);
            new Comment("-- stfld _target");
            Stfld.DoExecute(xAssembler, xMethodInfo, "System.Object System.Delegate._target", xMethodInfo.MethodBase.DeclaringType, true, false);
            new Comment("Save method pointer to field");
            //Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            new Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            new Comment("-- ldarg 2");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 2);
            new Comment("-- stfld _methodPtr");
            Stfld.DoExecute(xAssembler, xMethodInfo, "System.IntPtr System.Delegate._methodPtr", xMethodInfo.MethodBase.DeclaringType, true, false);
            new Comment("Saving ArgSize to field");
            uint xSize = 0;

            foreach (var xArg in xMethodInfo.MethodBase.DeclaringType.GetMethod("Invoke").GetParameters())
            {
                xSize += ILOp.Align(ILOp.SizeOfType(xArg.ParameterType), 4);
            }
            new Comment("-- ldarg 0");
            Ldarg.DoExecute(xAssembler, xMethodInfo, 0);
            if (xMethodInfo.MethodBase.DeclaringType.FullName.Contains("InterruptDelegate"))
            {
                Console.Write("");
            }
            new Comment("-- push argsize");
            new CPUx86.Push {
                DestinationValue = xSize
            };
            new Comment("-- stfld ArgSize");
            Stfld.DoExecute(xAssembler, xMethodInfo, "$$ArgSize$$", xMethodInfo.MethodBase.DeclaringType, true, false);


            //public static void Ctor(Delegate aThis, object aObject, IntPtr aMethod,
            //[FieldAccess(Name = "System.Object System.Delegate._target")] ref object aFldTarget,
            //[FieldAccess(Name = "System.IntPtr System.Delegate._methodPtr")] ref IntPtr aFldMethod) {
        }
コード例 #6
0
ファイル: Or.cs プロジェクト: invisal/Cosmos
        public override void Execute(_MethodInfo aMethod, ILOpCode aOpCode)
        {
            var xStackContent           = aOpCode.StackPopTypes[0];
            var xStackContentSecond     = aOpCode.StackPopTypes[1];
            var xStackContentSize       = SizeOfType(xStackContent);
            var xStackContentSecondSize = SizeOfType(xStackContentSecond);
            var xSize = Math.Max(xStackContentSize, xStackContentSecondSize);

            if (ILOp.Align(xStackContentSize, 4u) != ILOp.Align(xStackContentSecondSize, 4u))
            {
                throw new NotSupportedException("Operands have different size!");
            }
            if (xSize > 8)
            {
                throw new NotImplementedException("StackSize>8 not supported");
            }

            if (xSize > 4)
            {
                // [ESP] is low part
                // [ESP + 4] is high part
                // [ESP + 8] is low part
                // [ESP + 12] is high part
                XS.Pop(XSRegisters.EAX);
                XS.Pop(XSRegisters.EDX);
                // [ESP] is low part
                // [ESP + 4] is high part
                XS.Or(XSRegisters.ESP, XSRegisters.EAX, destinationIsIndirect: true);
                XS.Or(XSRegisters.ESP, XSRegisters.EDX, destinationDisplacement: 4);
            }
            else
            {
                XS.Pop(XSRegisters.EAX);
                XS.Or(XSRegisters.ESP, XSRegisters.EAX, destinationIsIndirect: true);
            }
        }
コード例 #7
0
ファイル: Ldfld.cs プロジェクト: xsword911/Cosmos
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, Type aDeclaringType, string xFieldId, bool aDerefExternalField, bool debugEnabled)
        {
            var xOffset    = GetFieldOffset(aDeclaringType, xFieldId);
            var xFields    = GetFieldsInfo(aDeclaringType);
            var xFieldInfo = (from item in xFields
                              where item.Id == xFieldId
                              select item).Single();

            new Comment("Field = '" + xFieldId + "'");

            DoNullReferenceCheck(Assembler, debugEnabled, 0);

            new CPUx86.Pop {
                DestinationReg = CPUx86.Registers.ECX
            };

#if DOTNETCOMPATIBLE
            // pushed size is always 4 or 8
            var xSize = ILOp.Align(xFieldInfo.Size, 4);
#else
            var xSize = xFieldInfo.Size;
#endif

            new CPUx86.Add {
                DestinationReg = CPUx86.Registers.ECX, SourceValue = (uint)(xOffset)
            };

            if (xFieldInfo.IsExternalValue && aDerefExternalField)
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.ECX, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true
                };
            }

            for (int i = 1; i <= (xSize / 4); i++)
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true, SourceDisplacement = (int)(xSize - (i * 4))
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
            }
            switch (xSize % 4)
            {
            case 1: {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = 0
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.AL, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
                break;
            }

            case 2: {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = 0
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.AX, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
                break;
            }

            case 3: //For Release
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = 0
                };
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true
                };
                new CPUx86.ShiftRight {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = 8
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
                break;
            }

            case 0: {
                break;
            }

            default:
                throw new Exception(string.Format("Remainder size {0:D} {1:D} not supported!", xFieldInfo.FieldType.ToString(), xSize));
            }
        }
コード例 #8
0
        public static void DoExecute(Cosmos.Assembler.Assembler Assembler, Type aDeclaringType, string xFieldId, bool aDerefExternalField, bool debugEnabled, Type aTypeOnStack)
        {
            var xOffset    = GetFieldOffset(aDeclaringType, xFieldId);
            var xFields    = GetFieldsInfo(aDeclaringType, false);
            var xFieldInfo = (from item in xFields
                              where item.Id == xFieldId
                              select item).Single();

            new Comment("Field: " + xFieldInfo.Id);
            new Comment("Type: " + xFieldInfo.FieldType.ToString());
            new Comment("Size: " + xFieldInfo.Size);
            new Comment("Offset: " + xOffset + " (includes object header)");

            if (aDeclaringType.IsValueType && aTypeOnStack == aDeclaringType)
            {
                // the full struct is on the stack, instead of only a pointer to it
                if (xFieldInfo.Size > 4)
                {
                    throw new Exception("For now, loading fields with sizes > 4 bytes from structs on the stack is not possible!");
                }

                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = 0
                };

                switch (xFieldInfo.Size)
                {
                case 1:
                    new CPUx86.Mov {
                        DestinationReg = CPUx86.Registers.AL, SourceReg = CPUx86.Registers.ESP, SourceDisplacement = xOffset, SourceIsIndirect = true
                    };
                    break;

                case 2:
                    new CPUx86.Mov {
                        DestinationReg = CPUx86.Registers.AX, SourceReg = CPUx86.Registers.ESP, SourceDisplacement = xOffset, SourceIsIndirect = true
                    };
                    break;

                case 3:     //For Release
                    new CPUx86.Mov {
                        DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceDisplacement = xOffset, SourceIsIndirect = true
                    };
                    new CPUx86.ShiftRight {
                        DestinationReg = CPUx86.Registers.EAX, SourceValue = 8
                    };
                    break;

                case 4:
                    new CPUx86.Mov {
                        DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ESP, SourceDisplacement = xOffset, SourceIsIndirect = true
                    };
                    break;

                default:
                    throw new Exception(string.Format("Field size {0} not supported!", xFieldInfo.Size));
                }

                // now remove the struct from the stack
                new CPUx86.Add {
                    DestinationReg = CPUx86.Registers.ESP, SourceValue = Align(GetStorageSize(aDeclaringType), 4)
                };

                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };

                return;
            }
            DoNullReferenceCheck(Assembler, debugEnabled, 0);

            new CPUx86.Pop {
                DestinationReg = CPUx86.Registers.ECX
            };

#if DOTNETCOMPATIBLE
            // pushed size is always 4 or 8
            var xSize = ILOp.Align(xFieldInfo.Size, 4);
#else
            var xSize = xFieldInfo.Size;
#endif

            new CPUx86.Add {
                DestinationReg = CPUx86.Registers.ECX, SourceValue = (uint)(xOffset)
            };

            if (xFieldInfo.IsExternalValue && aDerefExternalField)
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.ECX, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true
                };
            }

            for (int i = 1; i <= (xSize / 4); i++)
            {
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true, SourceDisplacement = (int)(xSize - (i * 4))
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
            }

            new CPUx86.Mov {
                DestinationReg = CPUx86.Registers.EAX, SourceValue = 0
            };

            switch (xSize % 4)
            {
            case 1:
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.AL, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
                break;

            case 2:
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.AX, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
                break;

            case 3:     //For Release
                new CPUx86.Mov {
                    DestinationReg = CPUx86.Registers.EAX, SourceReg = CPUx86.Registers.ECX, SourceIsIndirect = true
                };
                new CPUx86.ShiftRight {
                    DestinationReg = CPUx86.Registers.EAX, SourceValue = 8
                };
                new CPUx86.Push {
                    DestinationReg = CPUx86.Registers.EAX
                };
                break;

            case 0:
            {
                break;
            }

            default:
                throw new Exception(string.Format("Remainder size {0:D} {1:D} not supported!", xFieldInfo.FieldType.ToString(), xSize));
            }
        }