Esempio n. 1
0
        /// <summary>
        /// See base class documentation.
        /// <para>To Do's:</para>
        /// <list type="bullet">
        /// <item>
        /// <term>To do</term>
        /// <description>Implement storing of float arguments.</description>
        /// </item>
        /// </list>
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotImplementedException">
        /// Thrown when storing a float argument is required as it currently hasn't been
        /// implemented.
        /// </exception>
        /// <exception cref="System.ArgumentException">
        /// Thrown when an invalid number of bytes is specified for the argument to store.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Get the index of the argument to load
            Int16 index = 0;

            switch ((OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Starg:
                index = Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Starg_S:
                index = (Int16)theOp.ValueBytes[0];
                break;
            }

            Types.VariableInfo argInfo = conversionState.Input.TheMethodInfo.ArgumentInfos[index];
            //Used to store the number of bytes to add to EBP to get to the arg
            int BytesOffsetFromEBP = argInfo.Offset;

            //Pop the argument value from the stack
            int bytesForArg = argInfo.TheTypeInfo.SizeOnStackInBytes;

            for (int i = 0; i < bytesForArg; i += 4)
            {
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Dword, Dest = "[EBP+" + (BytesOffsetFromEBP + i) + "]"
                });
            }

            //Pop the arg value from our stack
            conversionState.CurrentStackFrame.Stack.Pop();
        }
Esempio n. 2
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when the metadata token is not for method metadata.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load token i.e. typeref
            //It should also support methodref and fieldrefs

            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);

            try
            {
                Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);
                if (theType == null)
                {
                    throw new NullReferenceException();
                }
                string typeTableId = conversionState.TheILLibrary.GetTypeInfo(theType).ID;
                conversionState.AddExternalLabel(typeTableId);

                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = typeTableId
                });

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false
                });
            }
            catch
            {
                throw new NotSupportedException("The metadata token specifies a fieldref or methodref which isn't supported yet!");
            }
        }
Esempio n. 3
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if divide operands are floating point numbers or if attempting to divide 64-bit numbers.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// Thrown if either operand is &lt; 4 bytes long.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            StackItem testItem = conversionState.CurrentStackFrame.Stack.Pop();

            if (testItem.isFloat)
            {
                //TODO - Support floats
                throw new NotSupportedException("Switch for floats no supported!");
            }
            else if (testItem.sizeOnStackInBytes != 4)
            {
                //TODO - Support other sizes
                throw new NotSupportedException("Switch for non-int32s not supported!");
            }

            conversionState.Append(new ASMOps.Pop()
            {
                Size = ASMOps.OperandSize.Word, Dest = "$t0"
            });
            for (int i = 0; i < theOp.ValueBytes.Length / 4; i++)
            {
                int  branchOffset = theOp.NextOffset + Utilities.ReadInt32(theOp.ValueBytes, i * 4);
                ILOp opToGoTo     = conversionState.Input.At(branchOffset);
                int  branchPos    = conversionState.PositionOf(opToGoTo);

                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchEqual, Src2 = i.ToString(), Src1 = "$t0", DestILPosition = branchPos
                });
            }
        }
Esempio n. 4
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load a string literal (- fixed string i.e. one programmed as "a string in code")

            //Get the string metadata token used to get the string from the assembly
            int StringMetadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the value of the string to load
            string theString = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveString(StringMetadataToken);
            //Add the string literal and get its ID
            string theStringID = conversionState.TheILLibrary.AddStringLiteral(theString);

            conversionState.AddExternalLabel(theStringID);

            //Push the address of the string (i.e. address of ID - ASM label)
            conversionState.Append(new ASMOps.La()
            {
                Dest = "$t4", Label = theStringID
            });
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Word, Src = "$t4"
            });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                sizeOnStackInBytes = 4,
                isFloat            = false,
                isGCManaged        = true,
                isValue            = false
            });
        }
Esempio n. 5
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if the value to store is floating point.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            UInt16 localIndex = 0;

            switch ((ILOp.OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Stloc:
                localIndex = (UInt16)Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Stloc_0:
                localIndex = 0;
                break;

            case OpCodes.Stloc_1:
                localIndex = 1;
                break;

            case OpCodes.Stloc_2:
                localIndex = 2;
                break;

            case OpCodes.Stloc_3:
                localIndex = 3;
                break;

            case OpCodes.Stloc_S:
                localIndex = (UInt16)theOp.ValueBytes[0];
                break;
            }

            Types.VariableInfo localInfo = conversionState.Input.TheMethodInfo.LocalInfos[localIndex];

            StackItem theItem = conversionState.CurrentStackFrame.Stack.Pop();

            if (theItem.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Float locals not supported yet!");
            }

            int locSize = localInfo.TheTypeInfo.SizeOnStackInBytes;

            if (locSize == 0)
            {
                conversionState.Append(new ASMOps.Comment("0 pop size (?!)"));
            }
            else
            {
                for (int i = 0; i < locSize; i += 4)
                {
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "[EBP-" + Math.Abs(localInfo.Offset + i).ToString() + "]"
                    });
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if the value to store is floating point or
        /// if the value is not 4 or 8 bytes in size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int       metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            FieldInfo theField      = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);

            Types.TypeInfo  objTypeInfo   = conversionState.TheILLibrary.GetTypeInfo(theField.DeclaringType);
            Types.TypeInfo  fieldTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.FieldType);
            Types.FieldInfo theFieldInfo  = conversionState.TheILLibrary.GetFieldInfo(objTypeInfo, theField.Name);


            int offset = theFieldInfo.OffsetInBytes;

            int stackSize = fieldTypeInfo.SizeOnStackInBytes;
            int memSize   = fieldTypeInfo.IsValueType ? fieldTypeInfo.SizeOnHeapInBytes : stackSize;

            StackItem value      = conversionState.CurrentStackFrame.Stack.Pop();
            StackItem objPointer = conversionState.CurrentStackFrame.Stack.Pop();

            if (value.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Storing fields of type float not supported yet!");
            }

            //Get object pointer
            conversionState.Append(new ASMOps.Mov()
            {
                Size = ASMOps.OperandSize.Word, Src = stackSize.ToString() + "($sp)", Dest = "$t2", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg
            });
            //Pop and mov value
            for (int i = 0; i < memSize; i += 2)
            {
                if (memSize - i == 1)
                {
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Halfword, Dest = "$t0"
                    });
                    //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = "$t0", Dest = (offset + i).ToString() + "($t2)" });
                    GlobalMethods.StoreData(conversionState, theOp, "$t2", "$t0", (offset + i), 1);
                }
                else
                {
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Halfword, Dest = "$t0"
                    });
                    //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = (offset + i).ToString() + "($t2)" });
                    GlobalMethods.StoreData(conversionState, theOp, "$t2", "$t0", (offset + i), 2);
                }
            }
            //                                                           Rounds down             || Pop object pointer
            conversionState.Append(new ASMOps.Add()
            {
                Src1 = "$sp", Src2 = ((((stackSize - memSize) / 2) * 2) + 4).ToString(), Dest = "$sp"
            });
        }
Esempio n. 7
0
 /// <summary>
 /// See base class documentation.
 /// </summary>
 /// <param name="theOp">See base class documentation.</param>
 /// <param name="conversionState">See base class documentation.</param>
 /// <returns>See base class documentation.</returns>
 public override void Convert(ILConversionState conversionState, ILOp theOp)
 {
     //Ignore for now
     //TODO: Do we need to do any proper initialisation?
     conversionState.Append(new ASMOps.Add()
     {
         Src1 = "$sp", Src2 = "4", Dest = "$sp", Unsigned = false
     });
 }
Esempio n. 8
0
 /// <summary>
 /// See base class documentation.
 /// </summary>
 /// <param name="theOp">See base class documentation.</param>
 /// <param name="conversionState">See base class documentation.</param>
 /// <returns>See base class documentation.</returns>
 public override void Convert(ILConversionState conversionState, ILOp theOp)
 {
     //Ignore for now
     //TODO: Do we need to do any proper initialisation?
     conversionState.Append(new ASMOps.Add()
     {
         Src = "4", Dest = "ESP"
     });
 }
Esempio n. 9
0
 /// <summary>
 /// See base class documentation.
 /// </summary>
 /// <param name="theOp">See base class documentation.</param>
 /// <param name="conversionState">See base class documentation.</param>
 /// <returns>See base class documentation.</returns>
 public override void Convert(ILConversionState conversionState, ILOp theOp)
 {
     //Ignore for now
     //TODO: Initialise the structure to 0
     conversionState.Append(new ASMOps.Add()
     {
         Src = "4", Dest = "ESP"
     });
 }
Esempio n. 10
0
 /// <summary>
 /// See base class documentation.
 /// </summary>
 /// <param name="theOp">See base class documentation.</param>
 /// <param name="conversionState">See base class documentation.</param>
 /// <returns>See base class documentation.</returns>
 public override void Convert(ILConversionState conversionState, ILOp theOp)
 {
     //Ignore for now
     //TODO: Initialise the structure to 0
     conversionState.Append(new ASMOps.Add()
     {
         Src1 = "$sp", Src2 = "4", Dest = "$sp", Unsigned = false
     });
 }
Esempio n. 11
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if either or both values to not are floating point values or
        /// if the values are 8 bytes in size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            StackItem theItem = conversionState.CurrentStackFrame.Stack.Peek();

            if (theItem.isFloat)
            {
                //SUPPORT - Not op for floats
                throw new NotSupportedException("Not op not supported for float operands!");
            }

            if (theItem.sizeOnStackInBytes == 4)
            {
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Dword, Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Not()
                {
                    Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });
            }
            else if (theItem.sizeOnStackInBytes == 8)
            {
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Dword, Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Pop()
                {
                    Size = ASMOps.OperandSize.Dword, Dest = "EBX"
                });
                conversionState.Append(new ASMOps.Not()
                {
                    Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Not()
                {
                    Dest = "EBX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EBX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });
            }
            else
            {
                throw new NotSupportedException("Not op not supported for operand size!");
            }
        }
Esempio n. 12
0
 public static void InsertPageFaultDetection(ILConversionState conversionState, string reg, int offset, ILOp.OpCodes opCode)
 {
     if (PageFaultDetectionEnabled)
     {
         conversionState.Append(new ASMOps.Call()
         {
             Target = PageFaultDetectionMethod
         });
     }
 }
Esempio n. 13
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Get the ID (i.e. ASM label) of the method to load a pointer to
            Types.MethodInfo methodInfo       = conversionState.TheILLibrary.GetMethodInfo(theOp.MethodToCall);
            string           methodID         = methodInfo.ID;
            bool             addExternalLabel = methodID != conversionState.Input.TheMethodInfo.ID;

            //If we want to load the pointer at a specified IL op number:
            if (theOp.LoadAtILOpAfterOp != null)
            {
                ILBlock anILBlock = conversionState.TheILLibrary.GetILBlock(methodInfo);
                int     index     = anILBlock.ILOps.IndexOf(theOp.LoadAtILOpAfterOp);
                if (index == -1)
                {
                    throw new NullReferenceException("LoadAtILOpAfterOp not found in IL block!");
                }

                index++;
                methodID = ASM.ASMBlock.GenerateLabel(methodID, anILBlock.PositionOf(anILBlock.ILOps[index]));
            }
            else if (theOp.LoadAtILOffset != int.MaxValue)
            {
                //Append the IL sub-label to the ID
                ILBlock anILBlock = conversionState.TheILLibrary.GetILBlock(methodInfo);
                methodID = ASM.ASMBlock.GenerateLabel(methodID, anILBlock.PositionOf(anILBlock.At(theOp.LoadAtILOffset)));

                //Note: This is used by try/catch/finally blocks for pushing pointers
                //      to catch/finally handlers and filters
            }

            if (addExternalLabel)
            {
                conversionState.AddExternalLabel(methodID);
            }

            //Push the pointer to the function
            conversionState.Append(new ASMOps.La()
            {
                Dest = "$t4", Label = methodID
            });
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Word, Src = "$t4"
            });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat            = false,
                sizeOnStackInBytes = 4,
                isGCManaged        = false
            });
        }
Esempio n. 14
0
        public static void LoadData(ILConversionState conversionState, ILOp theOp,
            string addressReg, string valueReg, int offset, int size, bool SignExtend = false)
        {
            if (size == 1)
            {
                conversionState.Append(new ASMOps.Mov() { Src = offset + "(" + addressReg + ")", Dest = "$t6", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg, Size = ASMOps.OperandSize.Byte, SignExtend = SignExtend });
            }
            else
            {
                conversionState.Append(new ASMOps.Xor() { Src1 = "$t6", Src2 = "$t6", Dest = "$t6" });
                int shiftBits = 0;
                if (offset % 2 == 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Src = offset + "(" + addressReg + ")", Dest = "$t7", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg, Size = ASMOps.OperandSize.Byte });
                    conversionState.Append(new ASMOps.Or() { Src1 = "$t7", Src2 = "$t6", Dest = "$t6" });

                    size -= 1;
                    offset += 1;
                    shiftBits += 8;
                }

                while (size > 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Src = offset + "(" + addressReg + ")", Dest = "$t7", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg, Size = ASMOps.OperandSize.Halfword, SignExtend = (SignExtend && size == 2) });
                    if (shiftBits > 0)
                    {
                        conversionState.Append(new ASMOps.Sll() { Src = "$t7", Dest = "$t7", Bits = shiftBits });
                    }
                    conversionState.Append(new ASMOps.Or() { Src1 = "$t7", Src2 = "$t6", Dest = "$t6" });

                    size -= 2;
                    offset += 2;
                    shiftBits += 16;
                }

                if (size == 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Src = offset + "(" + addressReg + ")", Dest = "$t7", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg, Size = ASMOps.OperandSize.Byte, SignExtend = SignExtend });
                    if (shiftBits > 0)
                    {
                        conversionState.Append(new ASMOps.Sll() { Src = "$t7", Dest = "$t7", Bits = shiftBits });
                    }
                    conversionState.Append(new ASMOps.Or() { Src1 = "$t7", Src2 = "$t6", Dest = "$t6" });

                    size -= 1;
                    offset += 1;
                    shiftBits += 8;
                }
            }

            conversionState.Append(new ASMOps.Mov() { Src = "$t6", Dest = valueReg, Size = ASMOps.OperandSize.Word, MoveType = ASMOps.Mov.MoveTypes.RegToReg });
        }
Esempio n. 15
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when loading a static float field.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load static field

            //Load the metadata token used to get the type info
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the type info for the object to load
            Type theType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);

            Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);

            //Get the object size information
            int size = theTypeInfo.SizeOnStackInBytes;

            //Load the object onto the stack
            conversionState.Append(new ASMOps.Pop()
            {
                Size = ASMOps.OperandSize.Dword, Dest = "ECX"
            });
            for (int i = size - 4; i >= 0; i -= 4)
            {
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "[ECX+" + i.ToString() + "]", Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });
            }
            int extra = size % 4;

            for (int i = extra - 1; i >= 0; i--)
            {
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "[ECX+" + i.ToString() + "]", Dest = "AL"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Byte, Src = "AL"
                });
            }

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat            = false,
                sizeOnStackInBytes = size,
                isGCManaged        = false
            });
        }
Esempio n. 16
0
 /// <summary>
 /// See base class documentation.
 /// </summary>
 /// <param name="theOp">See base class documentation.</param>
 /// <param name="conversionState">See base class documentation.</param>
 /// <returns>See base class documentation.</returns>
 public override void Convert(ILConversionState conversionState, ILOp theOp)
 {
     //Load null (i.e. 0 as word)
     conversionState.CurrentStackFrame.Stack.Push(new StackItem()
     {
         isFloat            = false,
         sizeOnStackInBytes = 4,
         isGCManaged        = false
     });
     conversionState.Append(new ASMOps.Push()
     {
         Size = ASMOps.OperandSize.Word, Src = "$zero"
     });
 }
Esempio n. 17
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int dwordsToRotate = theOp.ValueBytes == null ? 2 : BitConverter.ToInt32(theOp.ValueBytes, 0);

            int bytesShift = 0;

            for (int i = 0; i < dwordsToRotate; i++)
            {
                if (i == 0)
                {
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + bytesShift.ToString() + "]", Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + (bytesShift + 4).ToString() + "]", Dest = "EBX"
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EBX", Dest = "[ESP+" + bytesShift.ToString() + "]"
                    });
                }
                else if (i == dwordsToRotate - 1)
                {
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EAX", Dest = "[ESP+" + bytesShift.ToString() + "]"
                    });
                }
                else
                {
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "[ESP+" + (bytesShift + 4).ToString() + "]", Dest = "EBX"
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EBX", Dest = "[ESP+" + bytesShift.ToString() + "]"
                    });
                }
                bytesShift += 4;
            }

            rotateStackItems(conversionState, theOp.StackSwitch_Items, 1);
        }
Esempio n. 18
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int dwordsToRotate = theOp.ValueBytes == null ? 2 : BitConverter.ToInt32(theOp.ValueBytes, 0);

            int bytesShift = 0;

            for (int i = 0; i < dwordsToRotate; i++)
            {
                if (i == 0)
                {
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Word, Src = bytesShift.ToString() + "($sp)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Word, Src = (bytesShift + 4).ToString() + "($sp)", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Word, Src = "$t1", Dest = bytesShift.ToString() + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                    });
                }
                else if (i == dwordsToRotate - 1)
                {
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = bytesShift + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                    });
                }
                else
                {
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Word, Src = (bytesShift + 4).ToString() + "($sp)", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Word, Src = "$t1", Dest = bytesShift.ToString() + "($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                    });
                }
                bytesShift += 4;
            }

            rotateStackItems(conversionState, theOp.StackSwitch_Items, 1);
        }
Esempio n. 19
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            if (theOp.IsDebugOp)
            {
                int currOpPosition = conversionState.PositionOf(theOp);

                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "Debug", IsDebugOp = true
                });
                conversionState.Append(new ASMOps.Nop());
                //conversionState.Append(new ASMOps.Int() { IntNum = "3" });
            }
            else
            {
                conversionState.Append(new ASMOps.Nop());
            }
        }
Esempio n. 20
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            int  metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            Type theType       = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);

            Types.TypeInfo theTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theType);
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Dword,
                Src  = (theTypeInfo.IsValueType ? theTypeInfo.SizeOnHeapInBytes : theTypeInfo.SizeOnStackInBytes).ToString()
            });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat            = false,
                sizeOnStackInBytes = 4,
                isGCManaged        = false
            });
        }
Esempio n. 21
0
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Save return address
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Word, Src = "$ra"
            });
            //Push the previous method's fp
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Word, Src = "$fp"
            });
            //Set fp for this method
            conversionState.Append(new ASMOps.Mov()
            {
                Size = ASMOps.OperandSize.Word, Src = "$sp", Dest = "$fp", MoveType = ASMOps.Mov.MoveTypes.RegToReg
            });

            //Allocate stack space for locals
            //Only bother if there are any locals
            if (conversionState.Input.TheMethodInfo.LocalInfos.Count > 0)
            {
                int totalBytes = 0;
                foreach (Types.VariableInfo aLocal in conversionState.Input.TheMethodInfo.LocalInfos)
                {
                    totalBytes += aLocal.TheTypeInfo.SizeOnStackInBytes;
                }
                //We do not use "sub esp, X" (see below) because that leaves
                //junk memory - we need memory to be "initialised" to 0
                //so that local variables are null unless properly initialised.
                //This prevents errors in the GC.
                for (int i = 0; i < totalBytes / 4; i++)
                {
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Word, Src = "$zero"
                    });
                }
                //result.AppendLine(string.Format("sub esp, {0}", totalBytes));
            }
        }
Esempio n. 22
0
        private static void rotateStackItems(ILConversionState state, int items, int distance)
        {
            if (distance >= items)
            {
                throw new IndexOutOfRangeException("IlPreprocessor.rotateStackItems: distance >= items invalid!");
            }
            List <StackItem> poppedItems = new List <StackItem>();

            for (int i = 0; i < items; i++)
            {
                poppedItems.Add(state.CurrentStackFrame.Stack.Pop());
            }
            for (int i = distance; i > -1; i--)
            {
                state.CurrentStackFrame.Stack.Push(poppedItems[i]);
            }
            for (int i = items - 1; i > distance; i--)
            {
                state.CurrentStackFrame.Stack.Push(poppedItems[i]);
            }
        }
Esempio n. 23
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Push the previous method's ebp
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Dword, Src = "EBP"
            });
            //Set ebp for this method
            //See calling convention spec - this allows easy access of
            //args and locals within the method without having to track
            //temporary values (which would be a nightmare with the
            //exception handling implementation that the kernel uses!)
            conversionState.Append(new ASMOps.Mov()
            {
                Size = ASMOps.OperandSize.Dword, Src = "ESP", Dest = "EBP"
            });

            //Allocate stack space for locals
            //Only bother if there are any locals
            if (conversionState.Input.TheMethodInfo.LocalInfos.Count > 0)
            {
                int totalBytes = 0;
                foreach (Types.VariableInfo aLocal in conversionState.Input.TheMethodInfo.LocalInfos)
                {
                    totalBytes += aLocal.TheTypeInfo.SizeOnStackInBytes;
                }
                //We do not use "sub esp, X" (see below) because that leaves
                //junk memory - we need memory to be "initialised" to 0
                //so that local variables are null unless properly initialised.
                //This prevents errors in the GC.
                for (int i = 0; i < totalBytes / 4; i++)
                {
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "0"
                    });
                }
                //result.AppendLine(string.Format("sub esp, {0}", totalBytes));
            }
        }
Esempio n. 24
0
        public static void StoreData(ILConversionState conversionState, ILOp theOp,
            string addressReg, string valueReg, int offset, int size)
        {
            if (size == 1)
            {
                conversionState.Append(new ASMOps.Mov() { Src = valueReg, Dest = offset + "(" + addressReg + ")", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory, Size = ASMOps.OperandSize.Byte });
            }
            else
            {
                conversionState.Append(new ASMOps.Mov() { Dest = "$t6", Src = valueReg, Size = ASMOps.OperandSize.Word, MoveType = ASMOps.Mov.MoveTypes.RegToReg });
                
                if (offset % 2 == 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Dest = offset + "(" + addressReg + ")", Src = "$t6", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory, Size = ASMOps.OperandSize.Byte });
                    conversionState.Append(new ASMOps.Srl() { Src = "$t6", Dest = "$t6", Bits = 8 });

                    size -= 1;
                    offset += 1;
                }

                while (size > 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Dest = offset + "(" + addressReg + ")", Src = "$t6", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory, Size = ASMOps.OperandSize.Halfword });
                    conversionState.Append(new ASMOps.Srl() { Src = "$t6", Dest = "$t6", Bits = 16 });
                    
                    size -= 2;
                    offset += 2;
                }

                if(size == 1)
                {
                    conversionState.Append(new ASMOps.Mov() { Dest = offset + "(" + addressReg + ")", Src = "$t6", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory, Size = ASMOps.OperandSize.Byte });
                    conversionState.Append(new ASMOps.Srl() { Src = "$t6", Dest = "$t6", Bits = 8 });

                    size -= 1;
                    offset += 1;
                }
            }
        }
Esempio n. 25
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            StackItem theItem = conversionState.CurrentStackFrame.Stack.Pop();

            if (theItem.isNewGCObject)
            {
                //Decrement ref count

                //Get the ID of method to call as it will be labeled in the output ASM.
                Types.MethodInfo anInfo   = conversionState.GetDecrementRefCountMethodInfo();
                string           methodID = anInfo.ID;
                conversionState.AddExternalLabel(anInfo.ID);
                //Append the actual call
                conversionState.Append(new ASMOps.Call()
                {
                    Target = methodID
                });
            }

            conversionState.Append(new ASMOps.Add()
            {
                Src = theItem.sizeOnStackInBytes.ToString(), Dest = "ESP"
            });
        }
Esempio n. 26
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if field to load is a floating value or the field to load
        /// is not of size 4 or 8 bytes.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Get the field's token that is used to get FieldInfo from the assembly
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the field info from the referencing assembly
            FieldInfo theField = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveField(metadataToken);

            //Get the database type information about the object that contains the field
            Types.TypeInfo objTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.DeclaringType);
            int            offset      = conversionState.TheILLibrary.GetFieldInfo(objTypeInfo, theField.Name).OffsetInBytes;

            //Is the value to load a floating pointer number?
            bool valueisFloat = Utilities.IsFloat(theField.FieldType);

            //Get the size of the value to load (in bytes, as it will appear on the stack)
            Types.TypeInfo fieldTypeInfo = conversionState.TheILLibrary.GetTypeInfo(theField.FieldType);
            int            stackSize     = fieldTypeInfo.SizeOnStackInBytes;
            int            memSize       = theField.FieldType.IsValueType ? fieldTypeInfo.SizeOnHeapInBytes : stackSize;

            //Pop the object pointer from our stack
            StackItem objPointer = conversionState.CurrentStackFrame.Stack.Pop();

            //If the value to load is a float, erm...abort...
            if (valueisFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Loading fields of type float not supported yet!");
            }

            //Pop object pointer
            conversionState.Append(new ASMOps.Pop()
            {
                Size = ASMOps.OperandSize.Word, Dest = "$t2"
            });
            if ((OpCodes)theOp.opCode.Value == OpCodes.Ldflda)
            {
                conversionState.Append(new ASMOps.Add()
                {
                    Src1 = "$t2", Src2 = offset.ToString(), Dest = "$t2"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t2"
                });

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false
                });
            }
            else
            {
                //Push value at pointer+offset
                int sizeNotInMem = stackSize - memSize;
                int sizeToSub    = (sizeNotInMem / 2) * 2; //Rounds down
                for (int i = 0; i < sizeToSub; i += 2)
                {
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Halfword, Src = "$zero"
                    });
                }
                for (int i = memSize + (memSize % 2); i > 0; i -= 2)
                {
                    if (sizeToSub != sizeNotInMem)
                    {
                        conversionState.Append(new ASMOps.Mov()
                        {
                            Size = ASMOps.OperandSize.Halfword, Src = "0", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg
                        });
                        //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Byte, Src = (offset + i - 2).ToString() + "($t2)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
                        GlobalMethods.LoadData(conversionState, theOp, "$t2", "$t0", (offset + i - 2), 1);
                        conversionState.Append(new ASMOps.Push()
                        {
                            Size = ASMOps.OperandSize.Halfword, Src = "$t0"
                        });
                    }
                    else
                    {
                        //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Halfword, Src = (offset + i - 2).ToString() + "($t2)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg });
                        GlobalMethods.LoadData(conversionState, theOp, "$t2", "$t0", (offset + i - 2), 2);
                        conversionState.Append(new ASMOps.Push()
                        {
                            Size = ASMOps.OperandSize.Halfword, Src = "$t0"
                        });
                    }
                }

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = valueisFloat,
                    sizeOnStackInBytes = stackSize,
                    isGCManaged        = fieldTypeInfo.IsGCManaged
                });
            }
        }
Esempio n. 27
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown when loading a float local is required as it currently hasn't been
        /// implemented.
        /// Also thrown if arguments are not of size 4 or 8 bytes.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load local

            bool loadAddr = (ILOp.OpCodes)theOp.opCode.Value == OpCodes.Ldloca ||
                            (ILOp.OpCodes)theOp.opCode.Value == OpCodes.Ldloca_S;
            UInt16 localIndex = 0;

            switch ((ILOp.OpCodes)theOp.opCode.Value)
            {
            case OpCodes.Ldloc:
            case OpCodes.Ldloca:
                localIndex = (UInt16)Utilities.ReadInt16(theOp.ValueBytes, 0);
                break;

            case OpCodes.Ldloc_0:
                localIndex = 0;
                break;

            case OpCodes.Ldloc_1:
                localIndex = 1;
                break;

            case OpCodes.Ldloc_2:
                localIndex = 2;
                break;

            case OpCodes.Ldloc_3:
                localIndex = 3;
                break;

            case OpCodes.Ldloc_S:
            case OpCodes.Ldloca_S:
                localIndex = (UInt16)theOp.ValueBytes[0];
                break;
            }

            Types.VariableInfo theLoc = conversionState.Input.TheMethodInfo.LocalInfos[localIndex];
            if (Utilities.IsFloat(theLoc.UnderlyingType))
            {
                //SUPPORT - floats
                throw new NotSupportedException("Float locals not supported yet!");
            }

            if (loadAddr)
            {
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EBP", Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Sub()
                {
                    Src = (-theLoc.Offset).ToString(), Dest = "EAX"
                });
                conversionState.Append(new ASMOps.Push()
                {
                    Size = ASMOps.OperandSize.Dword, Src = "EAX"
                });

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = false,
                    sizeOnStackInBytes = 4,
                    isGCManaged        = false,
                    isValue            = false
                });
            }
            else
            {
                int localSizeOnStack = theLoc.TheTypeInfo.SizeOnStackInBytes;

                if ((localSizeOnStack % 4) != 0)
                {
                    throw new NotSupportedException("Invalid local bytes size!");
                }
                else
                {
                    for (int i = theLoc.Offset + (localSizeOnStack - 4); i >= theLoc.Offset; i -= 4)
                    {
                        conversionState.Append(new ASMOps.Push()
                        {
                            Size = ASMOps.OperandSize.Dword, Src = "[EBP-" + Math.Abs(i).ToString() + "]"
                        });
                    }
                }

                conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                {
                    isFloat            = Utilities.IsFloat(theLoc.UnderlyingType),
                    sizeOnStackInBytes = localSizeOnStack,
                    isGCManaged        = theLoc.TheTypeInfo.IsGCManaged,
                    isValue            = theLoc.TheTypeInfo.IsValueType
                });
            }
        }
Esempio n. 28
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Load the metadata token used to get the type info
            int metadataToken = Utilities.ReadInt32(theOp.ValueBytes, 0);
            //Get the type info for the element type
            Type elementType = conversionState.Input.TheMethodInfo.UnderlyingInfo.Module.ResolveType(metadataToken);

            conversionState.AddExternalLabel(conversionState.GetThrowNullReferenceExceptionMethodInfo().ID);
            conversionState.AddExternalLabel(conversionState.GetNewArrMethodInfo().ID);

            //New array must:
            // - Allocate memory on the heap for the object
            //          - If no memory is left, throw a panic attack because we're out of memory...
            // - Call the specified constructor

            int currOpPosition = conversionState.PositionOf(theOp);

            //Attempt to allocate memory on the heap for the new array
            //This involves:
            // - (Number of elements is already on the stack)
            // - Pushing the element type reference onto the stack
            // - Calling GC NewArr method
            // - Check the pointer == 0, if so, out of memory

            //Push type reference
            string typeIdStr = conversionState.TheILLibrary.GetTypeInfo(elementType).ID;

            conversionState.AddExternalLabel(typeIdStr);
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Dword, Src = typeIdStr
            });
            //Push a dword for return value (i.e. new array pointer)
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Dword, Src = "0"
            });
            //Get the GC.NewArr method ID (i.e. ASM label)
            string methodLabel = conversionState.GetNewArrMethodInfo().ID;

            //Call GC.NewArr
            conversionState.Append(new ASMOps.Call()
            {
                Target = methodLabel
            });
            //Pop the return value (i.e. new array pointer)
            conversionState.Append(new ASMOps.Pop()
            {
                Size = ASMOps.OperandSize.Dword, Dest = "EAX"
            });
            //Remove args from stack
            conversionState.Append(new ASMOps.Add()
            {
                Src = "8", Dest = "ESP"
            });
            //Check if pointer == 0?
            conversionState.Append(new ASMOps.Cmp()
            {
                Arg1 = "EAX", Arg2 = "0"
            });
            //If it isn't 0, not out of memory so continue execution
            conversionState.Append(new ASMOps.Jmp()
            {
                JumpType = ASMOps.JmpOp.JumpNotZero, DestILPosition = currOpPosition, Extension = "NotNullMem"
            });
            //If we are out of memory, we have a massive problem
            //Because it means we don't have space to create a new exception object
            //So ultimately we just have to throw a kernel panic
            //Throw a panic attack... ( :/ ) by calling kernel Halt(uint lastAddress)

            //result.AppendLine("call GetEIP");
            //result.AppendLine("push dword esp");
            //result.AppendLine("push dword ebp");
            //result.AppendLine("pushad");
            //result.AppendLine("mov dword eax, 0xDEADBEEF");
            //result.AppendLine("mov dword ebx, 0x2");
            //result.AppendLine("mov dword ecx, 1");
            //result.AppendLine("mov dword [staticfield_System_Boolean_Kernel_FOS_System_GC_Enabled], 1");
            //result.AppendLine("mov dword [staticfield_System_Boolean_Kernel_FOS_System_Heap_PreventAllocation], 0");
            //result.AppendLine("jmp method_System_Void_RETEND_Kernel_PreReqs_DECLEND_PageFaultDetection_NAMEEND___Fail");

            conversionState.Append(new ASMOps.Call()
            {
                Target = "GetEIP"
            });
            conversionState.AddExternalLabel("GetEIP");
            conversionState.Append(new ASMOps.Call()
            {
                Target = conversionState.GetThrowNullReferenceExceptionMethodInfo().ID
            });
            //Insert the not null label
            conversionState.Append(new ASMOps.Label()
            {
                ILPosition = currOpPosition, Extension = "NotNullMem"
            });

            //Push new array pointer
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Dword, Src = "EAX"
            });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat            = false,
                sizeOnStackInBytes = 4,
                isNewGCObject      = true,
                isGCManaged        = true,
                isValue            = false
            });
        }
Esempio n. 29
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            MethodBase constructorMethod = theOp.MethodToCall;
            Type       objectType        = constructorMethod.DeclaringType;

            //New obj must:
            // - Ignore for creation of Delegates
            // - Allocate memory on the heap for the object
            //          - If no memory is left, throw a panic attack because we're out of memory...
            // - Call the specified constructor

            if (typeof(Delegate).IsAssignableFrom(objectType))
            {
                conversionState.Append(new ASMOps.Comment("Ignore newobj calls for Delegates"));
                //Still need to:
                // - Remove the "object" param but preserve the "function pointer"
                StackItem funcPtrItem = conversionState.CurrentStackFrame.Stack.Pop();;
                conversionState.CurrentStackFrame.Stack.Pop();
                conversionState.CurrentStackFrame.Stack.Push(funcPtrItem);

                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Src = "0($sp)", Dest = "$t0", MoveType = ASMOps.Mov.MoveTypes.SrcMemoryToDestReg
                });
                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "4($sp)", MoveType = ASMOps.Mov.MoveTypes.SrcRegToDestMemory
                });
                conversionState.Append(new ASMOps.Add()
                {
                    Src1 = "$sp", Src2 = "4", Dest = "$sp"
                });
                return;
            }

            Types.MethodInfo constructorMethodInfo = conversionState.TheILLibrary.GetMethodInfo(constructorMethod);

            conversionState.AddExternalLabel(conversionState.GetNewObjMethodInfo().ID);
            conversionState.AddExternalLabel(conversionState.GetThrowNullReferenceExceptionMethodInfo().ID);
            conversionState.AddExternalLabel(constructorMethodInfo.ID);

            int currOpPosition = conversionState.PositionOf(theOp);

            //Attempt to allocate memory on the heap for the new object
            //This involves:
            // - Pushing the type reference onto the stack
            // - Calling GC NewObj method
            // - Check the pointer == 0, if so, out of memory

            //Push type reference
            string typeIdStr = conversionState.TheILLibrary.GetTypeInfo(objectType).ID;

            conversionState.AddExternalLabel(typeIdStr);
            conversionState.Append(new ASMOps.La()
            {
                Dest = "$t4", Label = typeIdStr
            });
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Word, Src = "$t4"
            });
            //Push a word for return value (i.e. new object pointer)
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Word, Src = "$zero"
            });
            //Get the GC.NewObj method ID (i.e. ASM label)
            string methodLabel = conversionState.GetNewObjMethodInfo().ID;

            //Call GC.NewObj
            conversionState.Append(new ASMOps.Call()
            {
                Target = methodLabel
            });
            //Pop the return value (i.e. new object pointer)
            conversionState.Append(new ASMOps.Pop()
            {
                Size = ASMOps.OperandSize.Word, Dest = "$t0"
            });
            //Remove arg 0 from stack
            conversionState.Append(new ASMOps.Add()
            {
                Src1 = "$sp", Src2 = "4", Dest = "$sp"
            });
            //Check if pointer == 0?
            //If it isn't 0, not out of memory so continue execution
            conversionState.Append(new ASMOps.Branch()
            {
                BranchType = ASMOps.BranchOp.BranchNotZero, Src1 = "$t0", DestILPosition = currOpPosition, Extension = "NotNullMem"
            });
            //If we are out of memory, we have a massive problem
            //Because it means we don't have space to create a new exception object
            //So ultimately we just have to throw a kernel panic
            //Throw a panic attack... ( :/ ) by calling kernel Halt(uint lastAddress)

            //result.AppendLine("call GetEIP");
            //result.AppendLine("push dword esp");
            //result.AppendLine("push dword ebp");
            //result.AppendLine("pushad");
            //result.AppendLine("mov dword eax, 0xDEADBEEF");
            //result.AppendLine("mov dword ebx, 0x1");
            //result.AppendLine("mov dword ecx, 1");
            //result.AppendLine("mov dword [staticfield_System_Boolean_Kernel_FOS_System_GC_Enabled], 1");
            //result.AppendLine("mov dword [staticfield_System_Boolean_Kernel_FOS_System_Heap_PreventAllocation], 0");
            //result.AppendLine("jmp method_System_Void_RETEND_Kernel_PreReqs_DECLEND_PageFaultDetection_NAMEEND___Fail");

            conversionState.Append(new ASMOps.Call()
            {
                Target = "GetEIP"
            });
            conversionState.AddExternalLabel("GetEIP");
            conversionState.Append(new ASMOps.Call()
            {
                Target = conversionState.GetThrowNullReferenceExceptionMethodInfo().ID
            });
            //Insert the not null label
            conversionState.Append(new ASMOps.Label()
            {
                ILPosition = currOpPosition, Extension = "NotNullMem"
            });

            //Call the specified constructor
            //This involves:
            // - Push empty dword onto stack
            // - Move all args down by one dword
            // - Move object reference into dword as first arg
            // - Call constructor
            conversionState.Append(new ASMOps.Push()
            {
                Size = ASMOps.OperandSize.Word, Src = "$zero"
            });
            int sizeOfArgs = 0;

            ParameterInfo[] allParams = constructorMethod.GetParameters();
            foreach (ParameterInfo aParam in allParams)
            {
                sizeOfArgs += conversionState.TheILLibrary.GetTypeInfo(aParam.ParameterType).SizeOnStackInBytes;
                conversionState.CurrentStackFrame.Stack.Pop();
            }
            conversionState.Append(new ASMOps.Mov()
            {
                Size = ASMOps.OperandSize.Word, Src = "$sp", Dest = "$t1", MoveType = ASMOps.Mov.MoveTypes.RegToReg
            });
            if (sizeOfArgs > 0)
            {
                if (sizeOfArgs % 4 != 0)
                {
                    throw new InvalidOperationException("sizeOfArgs not exact multiple of 4!");
                }

                conversionState.Append(new ASMOps.Mov()
                {
                    Size = ASMOps.OperandSize.Word, Src = (sizeOfArgs / 4).ToString(), Dest = "$t2", MoveType = ASMOps.Mov.MoveTypes.ImmediateToReg
                });
                conversionState.Append(new ASMOps.Label()
                {
                    ILPosition = currOpPosition, Extension = "ShiftArgsLoop"
                });
                //Decrement counter ($t2)
                conversionState.Append(new ASMOps.Sub()
                {
                    Src1 = "$t2", Src2 = "1", Dest = "$t2"
                });
                //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "4($t1)", Dest = "$t3" });
                GlobalMethods.LoadData(conversionState, theOp, "$t1", "$t3", 4, 4);
                //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t3", Dest = "0($t1)" });
                GlobalMethods.StoreData(conversionState, theOp, "$t1", "$t3", 0, 4);
                conversionState.Append(new ASMOps.Add()
                {
                    Src1 = "$t1", Src2 = "4", Dest = "$t1"
                });
                conversionState.Append(new ASMOps.Branch()
                {
                    BranchType = ASMOps.BranchOp.BranchNotZero, Src1 = "$t2", DestILPosition = currOpPosition, Extension = "ShiftArgsLoop"
                });
            }
            //conversionState.Append(new ASMOps.Mov() { Size = ASMOps.OperandSize.Word, Src = "$t0", Dest = "0($t1)" });
            GlobalMethods.StoreData(conversionState, theOp, "$t1", "$t0", 0, 4);
            conversionState.Append(new ASMOps.Call()
            {
                Target = constructorMethodInfo.ID
            });
            //Only remove args from stack - we want the object pointer to remain on the stack
            conversionState.Append(new ASMOps.Add()
            {
                Src1 = "$sp", Src2 = sizeOfArgs.ToString(), Dest = "$sp"
            });

            conversionState.CurrentStackFrame.Stack.Push(new StackItem()
            {
                isFloat            = false,
                sizeOnStackInBytes = 4,
                isNewGCObject      = true,
                isGCManaged        = true
            });
        }
Esempio n. 30
0
        /// <summary>
        /// See base class documentation.
        /// </summary>
        /// <param name="theOp">See base class documentation.</param>
        /// <param name="conversionState">See base class documentation.</param>
        /// <returns>See base class documentation.</returns>
        /// <exception cref="System.NotSupportedException">
        /// Thrown if either or both values to shift left are floating point values or
        /// if the values are 8 bytes in size.
        /// </exception>
        /// <exception cref="System.InvalidOperationException">
        /// Thrown if either or both values to multiply are not 4 or 8 bytes
        /// in size or if the values are of different size.
        /// </exception>
        public override void Convert(ILConversionState conversionState, ILOp theOp)
        {
            //Pop in reverse order to push
            StackItem itemB = conversionState.CurrentStackFrame.Stack.Pop();
            StackItem itemA = conversionState.CurrentStackFrame.Stack.Pop();

            int currOpPosition = conversionState.PositionOf(theOp);

            if (itemB.sizeOnStackInBytes < 4 ||
                itemA.sizeOnStackInBytes < 4)
            {
                throw new InvalidOperationException("Invalid stack operand sizes!");
            }
            else if (itemB.isFloat || itemA.isFloat)
            {
                //SUPPORT - floats
                throw new NotSupportedException("Shift left on floats is unsupported!");
            }
            else
            {
                if (itemA.sizeOnStackInBytes == 4 &&
                    itemB.sizeOnStackInBytes == 4)
                {
                    //Pop item B
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "ECX"
                    });
                    //Pop item A
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Shl()
                    {
                        Src = "CL", Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EAX"
                    });

                    conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                    {
                        isFloat            = false,
                        sizeOnStackInBytes = 4,
                        isGCManaged        = false
                    });
                }
                else if ((itemA.sizeOnStackInBytes == 4 &&
                          itemB.sizeOnStackInBytes == 8))
                {
                    throw new InvalidOperationException("Invalid stack operand sizes! 4,8 not supported.");
                }
                else if ((itemA.sizeOnStackInBytes == 8 &&
                          itemB.sizeOnStackInBytes == 4))
                {
                    //Pop item B
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "ECX"
                    });
                    //Pop item A (8 bytes)
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "EDX"
                    });

                    //Check shift size
                    conversionState.Append(new ASMOps.Cmp()
                    {
                        Arg1 = "ECX", Arg2 = "32"
                    });
                    conversionState.Append(new ASMOps.Jmp()
                    {
                        JumpType = ASMOps.JmpOp.JumpGreaterThanEqual, DestILPosition = currOpPosition, Extension = "ShiftMoreThan32", UnsignedTest = true
                    });

                    //Shld (< 32)
                    conversionState.Append(new ASMOps.Shl()
                    {
                        Src = "EAX", Dest = "EDX", Count = "CL"
                    });
                    conversionState.Append(new ASMOps.Shl()
                    {
                        Src = "CL", Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Jmp()
                    {
                        JumpType = ASMOps.JmpOp.Jump, DestILPosition = currOpPosition, Extension = "End"
                    });

                    //Shld (>= 32)
                    conversionState.Append(new ASMOps.Label()
                    {
                        ILPosition = currOpPosition, Extension = "ShiftMoreThan32"
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EAX", Dest = "EDX"
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "0", Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Sub()
                    {
                        Src = "32", Dest = "ECX"
                    });
                    conversionState.Append(new ASMOps.Shl()
                    {
                        Src = "CL", Dest = "EDX"
                    });

                    //Push result
                    conversionState.Append(new ASMOps.Label()
                    {
                        ILPosition = currOpPosition, Extension = "End"
                    });
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EDX"
                    });
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EAX"
                    });

                    conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                    {
                        isFloat            = false,
                        sizeOnStackInBytes = 8,
                        isGCManaged        = false
                    });
                }
                else if (itemA.sizeOnStackInBytes == 8 &&
                         itemB.sizeOnStackInBytes == 8)
                {
                    //Note: Shifting by more than 64 bits is pointless since the value will be annihilated entirely.
                    //          "64" fits well within the low 32-bits
                    //      So for this op, we do the same as the 8-4 byte version but discard the top four bytes
                    //          of the second operand
                    //      Except we must check the high bytes for non-zero value. If they are non-zero, we simply
                    //          push a result of zero.

                    //Pop item B
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "ECX"
                    });
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "EBX"
                    });
                    //Pop item A (8 bytes)
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Pop()
                    {
                        Size = ASMOps.OperandSize.Dword, Dest = "EDX"
                    });
                    //Check high 4 bytes of second param
                    conversionState.Append(new ASMOps.Cmp()
                    {
                        Arg1 = "EBX", Arg2 = "0"
                    });
                    conversionState.Append(new ASMOps.Jmp()
                    {
                        JumpType = ASMOps.JmpOp.JumpZero, DestILPosition = currOpPosition, Extension = "Zero"
                    });
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "0"
                    });
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "0"
                    });
                    conversionState.Append(new ASMOps.Jmp()
                    {
                        JumpType = ASMOps.JmpOp.Jump, DestILPosition = currOpPosition, Extension = "End2"
                    });
                    conversionState.Append(new ASMOps.Label()
                    {
                        ILPosition = currOpPosition, Extension = "Zero"
                    });

                    conversionState.Append(new ASMOps.Cmp()
                    {
                        Arg1 = "ECX", Arg2 = "32"
                    });
                    conversionState.Append(new ASMOps.Jmp()
                    {
                        JumpType = ASMOps.JmpOp.JumpGreaterThanEqual, DestILPosition = currOpPosition, Extension = "ShiftMoreThan32", UnsignedTest = true
                    });

                    //Shld (< 32)
                    conversionState.Append(new ASMOps.Shl()
                    {
                        Src = "EAX", Dest = "EDX", Count = "CL"
                    });
                    conversionState.Append(new ASMOps.Shl()
                    {
                        Src = "CL", Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Jmp()
                    {
                        JumpType = ASMOps.JmpOp.Jump, DestILPosition = currOpPosition, Extension = "End1"
                    });

                    //Shl (>= 32)
                    conversionState.Append(new ASMOps.Label()
                    {
                        ILPosition = currOpPosition, Extension = "ShiftMoreThan32"
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EAX", Dest = "EDX"
                    });
                    conversionState.Append(new ASMOps.Mov()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "0", Dest = "EAX"
                    });
                    conversionState.Append(new ASMOps.Sub()
                    {
                        Src = "32", Dest = "ECX"
                    });
                    conversionState.Append(new ASMOps.Shl()
                    {
                        Src = "CL", Dest = "EDX"
                    });

                    //Push result
                    conversionState.Append(new ASMOps.Label()
                    {
                        ILPosition = currOpPosition, Extension = "End1"
                    });
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EDX"
                    });
                    conversionState.Append(new ASMOps.Push()
                    {
                        Size = ASMOps.OperandSize.Dword, Src = "EAX"
                    });
                    conversionState.Append(new ASMOps.Label()
                    {
                        ILPosition = currOpPosition, Extension = "End2"
                    });

                    conversionState.CurrentStackFrame.Stack.Push(new StackItem()
                    {
                        isFloat            = false,
                        sizeOnStackInBytes = 8,
                        isGCManaged        = false
                    });
                }
            }
        }