Beispiel #1
0
        /// <summary>
        /// Preprocesses the given ASM block.
        /// </summary>
        /// <param name="theBlock">The block to preprocess.</param>
        private static void Preprocess(ASMBlock theBlock)
        {
            // Due to "insert 0", asm ops are constructed in reverse order here

            string currMethodLabel = theBlock.GenerateMethodLabel();

            if (currMethodLabel != null)
            {
                ASM.ASMOp newLabelOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.Label, true);
                theBlock.ASMOps.Insert(0, newLabelOp);
            }
            if (currMethodLabel != null)
            {
                ASM.ASMOp newGlobalLabelOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.GlobalLabel, currMethodLabel);
                theBlock.ASMOps.Insert(0, newGlobalLabelOp);
            }

            foreach (string anExternalLabel in theBlock.ExternalLabels.Distinct())
            {
                if (anExternalLabel != currMethodLabel)
                {
                    ASM.ASMOp newExternalLabelOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.ExternalLabel, anExternalLabel);
                    theBlock.ASMOps.Insert(0, newExternalLabelOp);
                }
            }
            ASM.ASMOp newHeaderOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.Header);
            theBlock.ASMOps.Insert(0, newHeaderOp);
        }
Beispiel #2
0
        /// <summary>
        /// Scans the specified type's non-static fields.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="TheTypeInfo">The type to scan the non-static fields of.</param>
        /// <param name="FieldTablesBlock">The ASM block for the fields table for the library currently being compiled.</param>
        private static void ScanFields(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock FieldTablesBlock)
        {
            string currentTypeId   = TheTypeInfo.ID;
            string currentTypeName = TheTypeInfo.UnderlyingType.FullName;
            List <Tuple <string, string, string> > AllFieldInfo = new List <Tuple <string, string, string> >();

            if (TheTypeInfo.UnderlyingType.BaseType == null || (TheTypeInfo.UnderlyingType.BaseType.FullName != "System.Array" &&
                                                                TheTypeInfo.UnderlyingType.BaseType.FullName != "System.MulticastDelegate"))
            {
                foreach (Types.FieldInfo anOwnField in TheTypeInfo.FieldInfos)
                {
                    if (!anOwnField.IsStatic)
                    {
                        Types.TypeInfo FieldTypeInfo = TheLibrary.GetTypeInfo(anOwnField.FieldType);

                        string fieldOffsetVal = anOwnField.OffsetInBytes.ToString();
                        string fieldSizeVal   = (FieldTypeInfo.IsValueType ? FieldTypeInfo.SizeOnHeapInBytes : FieldTypeInfo.SizeOnStackInBytes).ToString();
                        string fieldTypeIdVal = FieldTypeInfo.ID;

                        FieldTablesBlock.AddExternalLabel(fieldTypeIdVal);
                        AllFieldInfo.Add(new Tuple <string, string, string>(fieldOffsetVal, fieldSizeVal, fieldTypeIdVal));
                    }
                }
            }

            string parentTypeFieldTablePtr = "0";
            bool   parentPtrIsExternal     = false;

            if (TheTypeInfo.UnderlyingType.BaseType != null)
            {
                if (!TheTypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib"))
                {
                    Types.TypeInfo baseTypeInfo = TheLibrary.GetTypeInfo(TheTypeInfo.UnderlyingType.BaseType);
                    parentPtrIsExternal = (ScannedTypes.ContainsKey(baseTypeInfo.ID) &&
                                           ScannedTypes[baseTypeInfo.ID] != TheLibrary) || !TheLibrary.TypeInfos.Contains(baseTypeInfo);
                    parentTypeFieldTablePtr = baseTypeInfo.ID + "_FieldTable";
                }
            }
            {
                string fieldOffsetVal = "0";
                string fieldSizeVal   = "0";
                string fieldTypeIdVal = parentTypeFieldTablePtr;

                if (parentPtrIsExternal)
                {
                    FieldTablesBlock.AddExternalLabel(fieldTypeIdVal);
                }

                AllFieldInfo.Add(new Tuple <string, string, string>(fieldOffsetVal, fieldSizeVal, fieldTypeIdVal));
            }

            List <Tuple <string, int> > TableEntryFieldInfos = GetSpecialClassFieldInfo(TheLibrary, typeof(Attributes.FieldInfoStructAttribute));

            ASM.ASMOp newFieldTableOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.FieldTable,
                                                                       currentTypeId, currentTypeName, AllFieldInfo, TableEntryFieldInfos);
            FieldTablesBlock.Append(newFieldTableOp);
        }
Beispiel #3
0
        /// <summary>
        /// Scans the specified type's methods.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="TheTypeInfo">The type to scan the methods of.</param>
        /// <param name="MethodTablesBlock">The ASM block for the methods table for the library currently being compiled.</param>
        private static void ScanMethods(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock MethodTablesBlock)
        {
            string currentTypeId   = TheTypeInfo.ID;
            string currentTypeName = TheTypeInfo.UnderlyingType.FullName;

            List <Tuple <string, string> > AllMethodInfo = new List <Tuple <string, string> >();

            if (TheTypeInfo.UnderlyingType.BaseType == null || TheTypeInfo.UnderlyingType.BaseType.FullName != "System.Array")
            {
                foreach (Types.MethodInfo aMethodInfo in TheTypeInfo.MethodInfos)
                {
                    if (!aMethodInfo.IsStatic && !aMethodInfo.UnderlyingInfo.IsAbstract)
                    {
                        string methodID      = aMethodInfo.ID;
                        string methodIDValue = aMethodInfo.IDValue.ToString();

                        MethodTablesBlock.AddExternalLabel(methodID);

                        AllMethodInfo.Add(new Tuple <string, string>(methodID, methodIDValue));
                    }
                }
            }

            string parentTypeMethodTablePtr = "0";
            bool   parentPtrIsExternal      = false;

            if (TheTypeInfo.UnderlyingType.BaseType != null)
            {
                if (!TheTypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib"))
                {
                    Types.TypeInfo baseTypeInfo = TheLibrary.GetTypeInfo(TheTypeInfo.UnderlyingType.BaseType);
                    parentPtrIsExternal = (ScannedTypes.ContainsKey(baseTypeInfo.ID) && ScannedTypes[baseTypeInfo.ID] != TheLibrary) ||
                                          !TheLibrary.TypeInfos.Contains(baseTypeInfo);
                    parentTypeMethodTablePtr = baseTypeInfo.ID + "_MethodTable";
                }
            }
            {
                string methodID      = parentTypeMethodTablePtr;
                string methodIDValue = "0";

                if (parentPtrIsExternal)
                {
                    MethodTablesBlock.AddExternalLabel(methodID);
                }

                AllMethodInfo.Add(new Tuple <string, string>(methodID, methodIDValue));
            }

            List <Tuple <string, int> > TableEntryFieldInfos = GetSpecialClassFieldInfo(TheLibrary, typeof(Attributes.MethodInfoStructAttribute));

            ASM.ASMOp newMethodTableOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.MethodTable,
                                                                        currentTypeId, currentTypeName, AllMethodInfo, TableEntryFieldInfos);
            MethodTablesBlock.Append(newMethodTableOp);
        }
Beispiel #4
0
        /// <summary>
        /// Scans the specified type (excludes fields and methods).
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="TheTypeInfo">The type to scan.</param>
        /// <param name="TypesTableBlock">The ASM block for the types table for the library currently being compiled.</param>
        private static void ScanType(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock TypesTableBlock)
        {
            string TypeId             = TheTypeInfo.ID;
            string SizeVal            = TheTypeInfo.SizeOnHeapInBytes.ToString();
            string IdVal              = (TypesScanned++).ToString();
            string StackSizeVal       = TheTypeInfo.SizeOnStackInBytes.ToString();
            string IsValueTypeVal     = (TheTypeInfo.IsValueType ? "1" : "0");
            string MethodTablePointer = TypeId + "_MethodTable";
            string IsPointerTypeVal   = (TheTypeInfo.IsPointer ? "1" : "0");
            string BaseTypeIdVal      = "0";

            if (TheTypeInfo.UnderlyingType.BaseType != null)
            {
                if (!TheTypeInfo.UnderlyingType.BaseType.AssemblyQualifiedName.Contains("mscorlib"))
                {
                    Types.TypeInfo baseTypeInfo = TheLibrary.GetTypeInfo(TheTypeInfo.UnderlyingType.BaseType);
                    BaseTypeIdVal = baseTypeInfo.ID;
                    //Declared external to this library, so won't appear in this library's type tables
                    if ((ScannedTypes.ContainsKey(baseTypeInfo.ID) &&
                         ScannedTypes[baseTypeInfo.ID] != TheLibrary) ||
                        !TheLibrary.TypeInfos.Contains(baseTypeInfo))
                    {
                        TypesTableBlock.AddExternalLabel(BaseTypeIdVal);
                    }
                }
            }
            string FieldTablePointer         = TypeId + "_FieldTable";
            string TypeSignatureLiteralLabel = TheLibrary.AddStringLiteral(TheTypeInfo.UnderlyingType.FullName); // Legacy
            string TypeIdLiteralLabel        = TheLibrary.AddStringLiteral(TheTypeInfo.ID);

            Types.TypeInfo         typeTypeInfo  = ILLibrary.SpecialClasses[typeof(Attributes.TypeClassAttribute)].First();
            List <Types.FieldInfo> OrderedFields = typeTypeInfo.FieldInfos.Where(x => !x.IsStatic).OrderBy(x => x.OffsetInBytes).ToList();
            List <Tuple <string, Types.TypeInfo> > FieldInformation = new List <Tuple <string, Types.TypeInfo> >();

            foreach (Types.FieldInfo aTypeField in OrderedFields)
            {
                Types.TypeInfo FieldTypeInfo = TheLibrary.GetTypeInfo(aTypeField.FieldType);
                FieldInformation.Add(new Tuple <string, Types.TypeInfo>(aTypeField.Name, FieldTypeInfo));
            }

            ASM.ASMOp newTypeTableOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.TypeTable,
                                                                      TypeId, SizeVal, IdVal, StackSizeVal, IsValueTypeVal, MethodTablePointer, IsPointerTypeVal,
                                                                      BaseTypeIdVal, FieldTablePointer, TypeSignatureLiteralLabel, TypeIdLiteralLabel, FieldInformation);
            TypesTableBlock.Append(newTypeTableOp);

            TypesTableBlock.AddExternalLabel(MethodTablePointer);
            TypesTableBlock.AddExternalLabel(FieldTablePointer);
            TypesTableBlock.AddExternalLabel(TypeSignatureLiteralLabel);
            TypesTableBlock.AddExternalLabel(TypeIdLiteralLabel);
        }
Beispiel #5
0
        /// <summary>
        /// Scans the specified type's static fields.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="TheTypeInfo">The type to scan the static fields of.</param>
        /// <param name="StaticFieldsBlock">The ASM block for the static fields for the library currently being compiled.</param>
        private static void ScanStaticFields(ILLibrary TheLibrary, Types.TypeInfo TheTypeInfo, ASM.ASMBlock StaticFieldsBlock)
        {
            foreach (Types.FieldInfo aFieldInfo in TheTypeInfo.FieldInfos)
            {
                if (aFieldInfo.IsStatic)
                {
                    Types.TypeInfo fieldTypeInfo = TheLibrary.GetTypeInfo(aFieldInfo.FieldType);

                    string FieldID = aFieldInfo.ID;
                    string Size    = fieldTypeInfo.SizeOnStackInBytes.ToString();

                    ASM.ASMOp newStaticFieldOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.StaticField, FieldID, Size);
                    StaticFieldsBlock.Append(newStaticFieldOp);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Processes the given ASM block.
        /// </summary>
        /// <param name="TheBlock">The ASM block to process.</param>
        private static void ProcessBlock(ASMBlock TheBlock)
        {
            string ASMText = "";
            
            if (TheBlock.Plugged)
            {
                string ASMPlugPath = Path.Combine(Options.OutputPath, TheBlock.PlugPath);
                // Legacy file name support
                if (Options.TargetArchitecture == "x86" &&
                    !File.Exists(ASMPlugPath + "." + Options.TargetArchitecture + ".asm"))
                {
                    if (!File.Exists(ASMPlugPath + ".x86_32.asm"))
                    {
                        throw new FileNotFoundException("Plug file not found! File name: " + ASMPlugPath + "." + Options.TargetArchitecture + ".asm", ASMPlugPath + "." + Options.TargetArchitecture + ".asm");
                    }
                    else
                    {
                        ASMPlugPath += ".x86_32.asm";
                    }
                }
                else
                {
                    ASMPlugPath += "." + Options.TargetArchitecture + ".asm";
                }

                if (!File.Exists(ASMPlugPath))
                {
                    throw new FileNotFoundException("Plug file not found! File name: " + ASMPlugPath, ASMPlugPath);
                }

                ASMText = File.ReadAllText(ASMPlugPath);

                ASMText = ASMText.Replace("%KERNEL_CALL_STATIC_CONSTRUCTORS_METHOD%", IL.ILLibrary.SpecialMethods[typeof(Attributes.CallStaticConstructorsMethodAttribute)].First().ID);
                if (IL.ILLibrary.SpecialMethods.ContainsKey(typeof(Attributes.MainMethodAttribute)))
                {
                    ASMText = ASMText.Replace("%KERNEL_MAIN_METHOD%", IL.ILLibrary.SpecialMethods[typeof(Attributes.MainMethodAttribute)].First().ID);
                }
            }
            else
            {
                foreach (ASMOp anASMOp in TheBlock.ASMOps)
                {
                    if (anASMOp.RequiresILLabel)
                    {
                        ASMText += ((ASMLabel)TargetArchitecture.CreateASMOp(OpCodes.Label, anASMOp.ILLabelPosition, "")).Convert(TheBlock) + "\r\n";
                    }

                    if (anASMOp is ASM.ASMOps.ASMLabel)
                    {
                        ASMLabel labelOp = (ASM.ASMOps.ASMLabel)anASMOp;
                        if (labelOp.IsDebugOp)
                        {
                            DebugDataWriter.AddDebugOp(TheBlock.OriginMethodInfo.ID, TheBlock.GenerateILOpLabel(labelOp.ILPosition, labelOp.Extension));
                        }
                    }

                    ASMText += anASMOp.Convert(TheBlock) + "\r\n";
                }
            }

            TargetArchitecture.TargetFunctions.CleanUpAssemblyCode(TheBlock, ref ASMText);

            if (!string.IsNullOrWhiteSpace(ASMText))
            {
                string FileName = Utilities.CleanFileName(Guid.NewGuid().ToString() + "." + Options.TargetArchitecture) + ".s";
                string OutputPath = GetASMOutputPath();
                FileName = Path.Combine(OutputPath, FileName);
                TheBlock.ASMOutputFilePath = FileName;
                File.WriteAllText(FileName, ASMText);
            }
            else
            {
                TheBlock.ASMOutputFilePath = null;
            }
        }
Beispiel #7
0
        /// <summary>
        /// Scans the specified library and any dependencies.
        /// </summary>
        /// <param name="TheLibrary">The library to scan.</param>
        /// <returns>
        /// CompileResult.OK if completed successfully.
        /// Otherwise CompileResult.PartialFail or CompileResult.Error depending on
        /// the extent of the problem.
        /// </returns>
        public static CompileResult Scan(ILLibrary TheLibrary)
        {
            CompileResult result = CompileResult.OK;

            if (TheLibrary.ILScanned)
            {
                return(result);
            }
            TheLibrary.ILScanned = true;

            foreach (ILLibrary depLib in TheLibrary.Dependencies)
            {
                Scan(depLib);
            }

            // Create / Add Static Fields ASM Block
            ASM.ASMBlock StaticFieldsBlock = new ASM.ASMBlock()
            {
                Priority = (long.MinValue / 2) - 9
            };
            TheLibrary.TheASMLibrary.ASMBlocks.Add(StaticFieldsBlock);

            // Create / Add Types Table ASM Block
            ASM.ASMBlock TypesTableBlock = new ASM.ASMBlock()
            {
                Priority = (long.MinValue / 2) - 8
            };
            TheLibrary.TheASMLibrary.ASMBlocks.Add(TypesTableBlock);

            // Create / Add Method Tables ASM Block
            ASM.ASMBlock MethodTablesBlock = new ASM.ASMBlock()
            {
                Priority = (long.MinValue / 2) + 0
            };
            TheLibrary.TheASMLibrary.ASMBlocks.Add(MethodTablesBlock);

            // Create / Add Field Tables ASM Block
            ASM.ASMBlock FieldTablesBlock = new ASM.ASMBlock()
            {
                Priority = (long.MinValue / 2) + 1
            };
            TheLibrary.TheASMLibrary.ASMBlocks.Add(FieldTablesBlock);

            // Don't use foreach or you get collection modified exceptions
            for (int i = 0; i < TheLibrary.TypeInfos.Count; i++)
            {
                Types.TypeInfo aTypeInfo = TheLibrary.TypeInfos[i];
                if (!ScannedTypes.ContainsKey(aTypeInfo.ID))
                {
                    ScannedTypes.Add(aTypeInfo.ID, TheLibrary);
                    ScanStaticFields(TheLibrary, aTypeInfo, StaticFieldsBlock);
                    ScanType(TheLibrary, aTypeInfo, TypesTableBlock);
                    ScanMethods(TheLibrary, aTypeInfo, MethodTablesBlock);
                    ScanFields(TheLibrary, aTypeInfo, FieldTablesBlock);
                }
            }

            foreach (Types.MethodInfo aMethodInfo in TheLibrary.ILBlocks.Keys)
            {
                ILBlock       anILBlock    = TheLibrary.ILBlocks[aMethodInfo];
                CompileResult singleResult = CompileResult.OK;

                if (anILBlock.Plugged)
                {
                    singleResult = ScanPluggedILBlock(TheLibrary, aMethodInfo, anILBlock);
                }
                else
                {
                    singleResult = ScanNonpluggedILBlock(TheLibrary, aMethodInfo, anILBlock);
                }

                if (result != CompileResult.OK)
                {
                    result = singleResult;
                }
            }

            // Create / Add String Literals ASM Block
            #region String Literals Block

            ASM.ASMBlock StringLiteralsBlock = new ASM.ASMBlock()
            {
                Priority = (long.MinValue / 2) - 10
            };
            TheLibrary.TheASMLibrary.ASMBlocks.Add(StringLiteralsBlock);

            string StringTypeId = ILLibrary.SpecialClasses[typeof(Attributes.StringClassAttribute)].First().ID;
            StringLiteralsBlock.AddExternalLabel(StringTypeId);
            foreach (KeyValuePair <string, string> aStringLiteral in TheLibrary.StringLiterals)
            {
                string value       = aStringLiteral.Value;
                byte[] lengthBytes = BitConverter.GetBytes(value.Length);

                ASM.ASMOp newLiteralOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.StringLiteral,
                                                                        aStringLiteral.Key, StringTypeId, lengthBytes, value.ToCharArray());

                StringLiteralsBlock.Append(newLiteralOp);
            }

            #endregion

            return(result);
        }
Beispiel #8
0
        /// <summary>
        /// Scans the specified non-plugged IL block.
        /// </summary>
        /// <param name="TheLibrary">The library currently being compiled.</param>
        /// <param name="theMethodInfo">The method which generated the IL block.</param>
        /// <param name="theILBlock">The IL block to scan.</param>
        /// <returns>CompileResult.OK.</returns>
        private static CompileResult ScanNonpluggedILBlock(ILLibrary TheLibrary, Types.MethodInfo theMethodInfo, ILBlock theILBlock)
        {
            CompileResult result = CompileResult.OK;

            ASM.ASMBlock TheASMBlock = new ASM.ASMBlock()
            {
                OriginMethodInfo = theMethodInfo,
                Priority         = theMethodInfo.Priority
            };

            ILConversionState convState = new ILConversionState()
            {
                TheILLibrary      = TheLibrary,
                CurrentStackFrame = new StackFrame(),
                Input             = theILBlock,
                Result            = TheASMBlock
            };

            foreach (ILOp anOp in theILBlock.ILOps)
            {
                try
                {
                    string commentText = TheASMBlock.GenerateILOpLabel(convState.PositionOf(anOp), "") + "  --  " + anOp.opCode.ToString() + " -- Offset: " + anOp.Offset.ToString("X2");

                    ASM.ASMOp newCommentOp = TargetArchitecture.CreateASMOp(ASM.OpCodes.Comment, commentText);
                    TheASMBlock.ASMOps.Add(newCommentOp);

                    int currCount = TheASMBlock.ASMOps.Count;
                    if (anOp is ILOps.MethodStart)
                    {
                        TargetArchitecture.MethodStartOp.Convert(convState, anOp);
                    }
                    else if (anOp is ILOps.MethodEnd)
                    {
                        TargetArchitecture.MethodEndOp.Convert(convState, anOp);
                    }
                    else if (anOp is ILOps.StackSwitch)
                    {
                        TargetArchitecture.StackSwitchOp.Convert(convState, anOp);
                    }
                    else
                    {
                        ILOp ConverterOp = TargetArchitecture.TargetILOps[(ILOp.OpCodes)anOp.opCode.Value];
                        ConverterOp.Convert(convState, anOp);
                    }

                    if (anOp.LabelRequired)
                    {
                        if (currCount < TheASMBlock.ASMOps.Count)
                        {
                            TheASMBlock.ASMOps[currCount].ILLabelPosition = convState.PositionOf(anOp);
                            TheASMBlock.ASMOps[currCount].RequiresILLabel = true;
                        }
                    }
                }
                catch (KeyNotFoundException)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                                    string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], "Conversion IL op not found: " + Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value) + "."));
                }
                catch (InvalidOperationException)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                                    string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value)));
                }
                catch (NotSupportedException ex)
                {
                    result = CompileResult.PartialFailure;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                                    string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], "An IL op reported something as not supported. " + Enum.GetName(typeof(ILOp.OpCodes), anOp.opCode.Value) + ". " + ex.Message));
                }
                catch (Exception ex)
                {
                    result = CompileResult.Fail;

                    Logger.LogError(Errors.ILCompiler_ScanILOpFailure_ErrorCode, theMethodInfo.ToString(), anOp.Offset,
                                    string.Format(Errors.ErrorMessages[Errors.ILCompiler_ScanILOpFailure_ErrorCode], ex.Message));
                }
            }

            TheLibrary.TheASMLibrary.ASMBlocks.Add(TheASMBlock);

            return(result);
        }