Exemple #1
0
        private TypeDesc FindType(CompilerTypeSystemContext context, string typeName)
        {
            ModuleDesc systemModule = context.SystemModule;

            TypeDesc foundType = systemModule.GetTypeByCustomAttributeTypeName(typeName, false, (typeDefName, module, throwIfNotFound) =>
            {
                return((MetadataType)context.GetCanonType(typeDefName)
                       ?? CustomAttributeTypeNameParser.ResolveCustomAttributeTypeDefinitionName(typeDefName, module, throwIfNotFound));
            });

            if (foundType == null)
            {
                throw new CommandLineException($"Type '{typeName}' not found");
            }

            return(foundType);
        }
Exemple #2
0
        /// <summary>
        /// Given a parsed out module, namespace + type, and method name, try to find a matching MethodDesc
        /// TODO: We have no signature information for the method - what policy should we apply where multiple methods exist with the same name
        /// but different signatures? For now we'll take the first matching and ignore others. Ideally we'll improve the profile data to include this.
        /// </summary>
        /// <returns>MethodDesc if found, null otherwise</returns>
        private MethodDesc ResolveMethodName(CompilerTypeSystemContext context, ModuleDesc module, string namespaceAndTypeName, string methodName)
        {
            TypeDesc resolvedType = module.GetTypeByCustomAttributeTypeName(namespaceAndTypeName, false, (typeDefName, module, throwIfNotFound) =>
            {
                return((MetadataType)context.GetCanonType(typeDefName)
                       ?? CustomAttributeTypeNameParser.ResolveCustomAttributeTypeDefinitionName(typeDefName, module, throwIfNotFound));
            });

            if (resolvedType != null)
            {
                var resolvedMethod = resolvedType.GetMethod(methodName, null);
                if (resolvedMethod != null)
                {
                    return(resolvedMethod);
                }
            }

            return(null);
        }
Exemple #3
0
        private void ProcessType(ModuleDesc assembly)
        {
            if (ShouldProcessElement())
            {
                string typeName = _reader.GetAttribute("fullname");

                if (typeName.Contains('*'))
                {
                    throw new NotSupportedException();
                }

                TypeDesc type = CustomAttributeTypeNameParser.GetTypeByCustomAttributeTypeName(assembly, typeName, throwIfNotFound: false);
                if (type == null)
                {
                    //Context.LogWarning ($"Could not resolve type '{fullname}'", 2008, _xmlDocumentLocation);
                    _reader.Skip();
                    return;
                }

                _reader.Read();

                while (_reader.IsStartElement())
                {
                    if (_reader.Name == "method")
                    {
                        ProcessMethod(type);
                    }
                    else if (_reader.Name == "field")
                    {
                        ProcessField(type);
                    }
                    else if (_reader.Name == "attribute")
                    {
                        ProcessAttribute(type);
                    }

                    _reader.Skip();
                }
            }

            _reader.Skip();
        }
        /// <summary>
        /// Extract preinitialize data as byte[] from a RVA field, and perform necessary validations.
        /// </summary>
        private static PreInitFieldInfo ConstructPreInitFieldInfo(FieldDesc field, FieldDesc dataField)
        {
            if (!dataField.HasRva)
            {
                throw new BadImageFormatException();
            }

            var ecmaDataField = dataField as EcmaField;

            if (ecmaDataField == null)
            {
                throw new NotSupportedException();
            }

            var      rvaData   = ecmaDataField.GetFieldRvaData();
            var      fieldType = field.FieldType;
            int      elementCount;
            int      realDataOffset;
            TypeDesc realDataType = null;

            //
            // Construct fixups
            //
            List <PreInitFixupInfo> fixups = null;

            var typeFixupAttrs = ecmaDataField.GetDecodedCustomAttributes("System.Runtime.CompilerServices", "TypeHandleFixupAttribute");

            foreach (var typeFixupAttr in typeFixupAttrs)
            {
                if (typeFixupAttr.FixedArguments[0].Type != field.Context.GetWellKnownType(WellKnownType.Int32))
                {
                    throw new BadImageFormatException();
                }

                int offset    = (int)typeFixupAttr.FixedArguments[0].Value;
                var typeArg   = typeFixupAttr.FixedArguments[1].Value;
                var fixupType = typeArg as TypeDesc;
                if (fixupType == null)
                {
                    if (typeArg is string fixupTypeName)
                    {
                        fixupType = CustomAttributeTypeNameParser.GetTypeByCustomAttributeTypeName(ecmaDataField.Module, fixupTypeName, throwIfNotFound: true);
                    }
                    else
                    {
                        throw new BadImageFormatException();
                    }
                }

                fixups = fixups ?? new List <PreInitFixupInfo>();

                if (offset == 0 && fieldType.IsSzArray)
                {
                    // For array field, offset 0 is the element type handle followed by the element count
                    realDataType = fixupType;
                }
                else
                {
                    fixups.Add(new PreInitTypeFixupInfo(offset, fixupType));
                }
            }

            var methodFixupAttrs = ecmaDataField.GetDecodedCustomAttributes("System.Runtime.CompilerServices", "MethodAddrFixupAttribute");

            foreach (var methodFixupAttr in methodFixupAttrs)
            {
                if (methodFixupAttr.FixedArguments[0].Type != field.Context.GetWellKnownType(WellKnownType.Int32))
                {
                    throw new BadImageFormatException();
                }

                int      offset    = (int)methodFixupAttr.FixedArguments[0].Value;
                TypeDesc fixupType = methodFixupAttr.FixedArguments[1].Value as TypeDesc;
                if (fixupType == null)
                {
                    throw new BadImageFormatException();
                }

                string methodName = methodFixupAttr.FixedArguments[2].Value as string;
                if (methodName == null)
                {
                    throw new BadImageFormatException();
                }

                var method = fixupType.GetMethod(methodName, signature: null);
                if (method == null)
                {
                    throw new BadImageFormatException();
                }

                fixups = fixups ?? new List <PreInitFixupInfo>();

                fixups.Add(new PreInitMethodFixupInfo(offset, method));
            }

            var fieldFixupAttrs = ecmaDataField.GetDecodedCustomAttributes("System.Runtime.CompilerServices", "FieldAddrFixupAttribute");

            foreach (var fieldFixupAttr in fieldFixupAttrs)
            {
                if (fieldFixupAttr.FixedArguments[0].Type != field.Context.GetWellKnownType(WellKnownType.Int32))
                {
                    throw new BadImageFormatException();
                }

                int      offset    = (int)fieldFixupAttr.FixedArguments[0].Value;
                TypeDesc fixupType = fieldFixupAttr.FixedArguments[1].Value as TypeDesc;
                if (fixupType == null)
                {
                    throw new BadImageFormatException();
                }

                string fieldName = fieldFixupAttr.FixedArguments[2].Value as string;
                if (fieldName == null)
                {
                    throw new BadImageFormatException();
                }

                var fixupField = fixupType.GetField(fieldName);
                if (fixupField == null)
                {
                    throw new BadImageFormatException();
                }

                if (!fixupField.IsStatic)
                {
                    throw new BadImageFormatException();
                }

                fixups = fixups ?? new List <PreInitFixupInfo>();

                fixups.Add(new PreInitFieldFixupInfo(offset, fixupField));
            }

            if (fieldType.IsValueType || fieldType.IsPointer)
            {
                elementCount   = -1;
                realDataOffset = 0;
                realDataType   = fieldType;
            }
            else if (fieldType.IsSzArray)
            {
                // Offset 0 is the element type handle fixup followed by the element count
                if (realDataType == null)
                {
                    throw new BadImageFormatException();
                }

                int ptrSize = fieldType.Context.Target.PointerSize;
                elementCount   = rvaData[ptrSize] | rvaData[ptrSize + 1] << 8 | rvaData[ptrSize + 2] << 16 | rvaData[ptrSize + 3] << 24;
                realDataOffset = ptrSize * 2;
                realDataType   = realDataType.MakeArrayType();
            }
            else
            {
                throw new NotSupportedException();
            }

            return(new PreInitFieldInfo(field, realDataType, rvaData, realDataOffset, elementCount, fixups));
        }