示例#1
0
        // Stores custom attributes in the link context, so that the attribute can be retrieved and
        // inspected even if it's linked away.
        public void StoreCustomAttribute(ICustomAttributeProvider provider, CustomAttribute attribute, string storage_name)
        {
            var dict = Annotations.GetCustomAnnotations(storage_name);
            List <ICustomAttribute> attribs;
            object attribObjects;

            if (!dict.TryGetValue(provider, out attribObjects))
            {
                attribs         = new List <ICustomAttribute> ();
                dict [provider] = attribs;
            }
            else
            {
                attribs = (List <ICustomAttribute>)attribObjects;
            }
            // Make sure the attribute is resolved, since after removing the attribute
            // it won't be able to do it. The 'CustomAttribute.Resolve' method is private, but fetching
            // any property will cause it to be called.
            // We also need to store the constructor's DeclaringType separately, because it may
            // be nulled out from the constructor by the linker if the attribute type itself is linked away.
            var dummy = attribute.HasConstructorArguments;

            attribs.Add(new AttributeStorage {
                Attribute = attribute, AttributeType = attribute.Constructor.DeclaringType
            });
        }
示例#2
0
 public override void Initialize(LinkContext context)
 {
     base.Initialize(context);
     // is some user code depending (or not) on reflection to get method's parameters names ?
     // note: member references will still exists (even if not marked) until the assembly is saved
     // so we need this to be pre-computed at the marking stage
     ReflectedParameterNames = Annotations.GetCustomAnnotations("ParameterInfo").Count > 0;
 }
示例#3
0
        void ProcessMethod(MethodDefinition method)
        {
            if (method.IsPInvokeImpl && method.HasPInvokeInfo && method.PInvokeInfo != null)
            {
                var pinfo = method.PInvokeInfo;

                if (state != null)
                {
                    switch (pinfo.EntryPoint)
                    {
                    case "objc_msgSend":
                    case "objc_msgSendSuper":
                    case "objc_msgSend_stret":
                    case "objc_msgSendSuper_stret":
                    case "objc_msgSend_fpret":
                        state.ProcessMethod(method);
                        break;

                    default:
                        break;
                    }
                }

                switch (pinfo.Module.Name)
                {
                case "__Internal":
                    DerivedLinkContext.RequiredSymbols.AddFunction(pinfo.EntryPoint).AddMember(method);
                    break;

                case "System.Net.Security.Native":
#if NET
                    if (DerivedLinkContext.App.Platform == ApplePlatform.TVOS)
                    {
                        break;                         // tvOS does not ship with System.Net.Security.Native due to https://github.com/dotnet/runtime/issues/45535
                    }
                    goto case "System.Native";
#endif
                case "System.Native":
                case "System.Security.Cryptography.Native.Apple":
                    DerivedLinkContext.RequireMonoNative = true;
                    DerivedLinkContext.RequiredSymbols.AddFunction(pinfo.EntryPoint).AddMember(method);
                    break;
                }
            }

            if (method.IsPropertyMethod())
            {
                var    property = method.GetProperty();
                object symbol;
                // The Field attribute may have been linked away, but we've stored it in an annotation.
                if (property != null && Annotations.GetCustomAnnotations("ExportedFields").TryGetValue(property, out symbol))
                {
                    DerivedLinkContext.RequiredSymbols.AddField((string)symbol).AddMember(property);
                }
            }
        }
示例#4
0
        public void StoreProtocolMethods(TypeDefinition type)
        {
            var    attribs = Annotations.GetCustomAnnotations("ProtocolMethods");
            object value;

            if (!attribs.TryGetValue(type, out value))
            {
                attribs [type] = type.Methods.ToArray();                  // Make a copy of the collection, since the linker may remove methods from it.
            }
        }
示例#5
0
        public IList <MethodDefinition> GetProtocolMethods(TypeDefinition type)
        {
            var    attribs = Annotations.GetCustomAnnotations("ProtocolMethods");
            object value;

            if (attribs.TryGetValue(type, out value))
            {
                return((MethodDefinition [])value);
            }
            return(null);
        }
示例#6
0
        public List <ICustomAttribute> GetCustomAttributes(ICustomAttributeProvider provider, string storage_name)
        {
            var    annotations = Annotations?.GetCustomAnnotations(storage_name);
            object storage     = null;

            if (annotations?.TryGetValue(provider, out storage) != true)
            {
                return(null);
            }
            return((List <ICustomAttribute>)storage);
        }
示例#7
0
        void ProcessProperty(PropertyDefinition property)
        {
            if (!property.HasCustomAttributes)
            {
                return;
            }

            var symbol = GetFieldSymbol(property);

            if (symbol == null)
            {
                return;
            }

            Annotations.GetCustomAnnotations("ExportedFields").Add(property, symbol);
        }
示例#8
0
        protected override MethodDefinition MarkMethod(MethodReference reference)
        {
            var method = base.MarkMethod(reference);

            if (method == null)
            {
                return(null);
            }

            // we need to track who's calling ParameterInfo.Name property getter, if it comes from
            // user code then it's not possible to remove the parameters from the assemblies metadata
            if (!parameter_info && (method.Name == "get_Name") && method.DeclaringType.Is("System.Reflection", "ParameterInfo"))
            {
                if (current_method == null)
                {
                    // This can happen if ParameterInfo.get_Name is preserved in an xml file
                    Annotations.GetCustomAnnotations("ParameterInfo").Add(method, null);
                }
                else
                {
                    var a = current_method.DeclaringType.Module.Assembly;
                    if (!Profile.IsSdkAssembly(a) && !Profile.IsProductAssembly(a))
                    {
                        // see MetadataReducerSubStep for the consumer part of the data
                        Annotations.GetCustomAnnotations("ParameterInfo").Add(method, current_method);
                        parameter_info = true;
                    }
                }
            }

            // if the application creates instances of SerializationInfo then we assume serialization is likely
            // and include all the .ctor(SerializationInfo,StreamingContext) inside the application
            if (!serialization_required && method.IsConstructor && !method.IsStatic &&
                method.DeclaringType.Is("System.Runtime.Serialization", "SerializationInfo"))
            {
                serialization_required = true;
                // stop procrastinaing and mark them all
                foreach (var m in pending_serialization_constructors)
                {
                    MarkMethod(m);
                }
                pending_serialization_constructors.Clear();
            }

            return(method);
        }
        protected override MethodDefinition MarkMethod(MethodReference reference)
        {
            var method = base.MarkMethod(reference);

            if (method == null)
            {
                return(null);
            }

            // we need to track who's calling ParameterInfo.Name property getter, if it comes from
            // user code then it's not possible to remove the parameters from the assemblies metadata
            if (!parameter_info && (method.Name == "get_Name") && method.DeclaringType.Is("System.Reflection", "ParameterInfo"))
            {
                if (current_method == null)
                {
                    // This can happen if ParameterInfo.get_Name is preserved in an xml file
                    Annotations.GetCustomAnnotations("ParameterInfo").Add(method, null);
                }
                else
                {
                    var a = current_method.DeclaringType.Module.Assembly;
                    if (!Profile.IsSdkAssembly(a) && !Profile.IsProductAssembly(a))
                    {
                        // see MetadataReducerSubStep for the consumer part of the data
                        Annotations.GetCustomAnnotations("ParameterInfo").Add(method, current_method);
                        parameter_info = true;
                    }
                }
            }

            // if the application creates instances of SerializationInfo then we assume serialization is likely
            // and include all the .ctor(SerializationInfo,StreamingContext) inside the application
            if (!serialization_required && method.IsConstructor && !method.IsStatic &&
                method.DeclaringType.Is("System.Runtime.Serialization", "SerializationInfo"))
            {
                serialization_required = true;
                // stop procrastinaing and mark them all
                foreach (var m in pending_serialization_constructors)
                {
                    MarkMethod(m);
                }
                pending_serialization_constructors.Clear();
            }

            // we want to avoid separate mscorlib.dll for 32/64 bits so the arch specific code for n[u]int and nfloat must be preserved in both cases
            // a single, slightly larger, assembly is much smaller thn two (slightly smaller) ones
            if (LinkContext.App.IsDualBuild)
            {
                switch (method.Name)
                {
                case "TryParse":
                    switch (method.DeclaringType.Name)
                    {
                    case "nfloat":
                        MarkNamedMethod(GetType("mscorlib", "System.Double"), "TryParse");
                        MarkNamedMethod(GetType("mscorlib", "System.Single"), "TryParse");
                        break;
                    }
                    break;

                case "Create":
                    // ARCH_32 optimization
                    if (!method.DeclaringType.Is(Namespaces.Foundation, "NSIndexPath"))
                    {
                        break;
                    }
                    MarkNamedMethod(GetType("mscorlib", "System.Array"), "ConvertAll");
                    break;
                }
            }

            return(method);
        }
示例#10
0
 public Dictionary <IMetadataTokenProvider, object> GetAllCustomAttributes(string storage_name)
 {
     return(Annotations?.GetCustomAnnotations(storage_name));
 }
示例#11
0
        void ProcessMethod(MethodDefinition method)
        {
            if (method.IsPInvokeImpl && method.HasPInvokeInfo && method.PInvokeInfo != null)
            {
                var  pinfo            = method.PInvokeInfo;
                bool addPInvokeSymbol = false;

                if (state != null)
                {
                    switch (pinfo.EntryPoint)
                    {
                    case "objc_msgSend":
                    case "objc_msgSendSuper":
                    case "objc_msgSend_stret":
                    case "objc_msgSendSuper_stret":
                    case "objc_msgSend_fpret":
                        state.ProcessMethod(method);
                        break;

                    default:
                        break;
                    }
                }

#if NET
                // Create a list of all the libraries from Mono that we'll link with
                // We add 4 different variations for each library:
                // * with and without a "lib" prefix
                // * with and without the ".dylib" extension
                var app = LinkerConfiguration.GetInstance(Context).Application;
                var monoLibraryVariations = app.MonoLibraries.
                                            Where(v => v.EndsWith(".dylib", StringComparison.OrdinalIgnoreCase) || v.EndsWith(".a", StringComparison.OrdinalIgnoreCase)).
                                            Select(v => Path.GetFileNameWithoutExtension(v)).
                                            Select(v => v.StartsWith("lib", StringComparison.OrdinalIgnoreCase) ? v.Substring(3) : v).ToHashSet();
                monoLibraryVariations.UnionWith(monoLibraryVariations.Select(v => "lib" + v).ToArray());
                monoLibraryVariations.UnionWith(monoLibraryVariations.Select(v => v + ".dylib").ToArray());
                // If the P/Invoke points to any of those libraries, then we add it as a P/Invoke symbol.
                if (monoLibraryVariations.Contains(pinfo.Module.Name))
                {
                    addPInvokeSymbol = true;
                }
#endif

                switch (pinfo.Module.Name)
                {
                case "__Internal":
                    Driver.Log(4, "Adding native reference to {0} in {1} because it's referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    DerivedLinkContext.RequiredSymbols.AddFunction(pinfo.EntryPoint).AddMember(method);
                    break;

#if !NET
                case "System.Net.Security.Native":
                case "System.Security.Cryptography.Native.Apple":
                case "System.Native":
                    addPInvokeSymbol = true;
                    break;
#endif

                default:
                    if (!addPInvokeSymbol)
                    {
                        Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    }
                    break;
                }

                if (addPInvokeSymbol)
                {
                    Driver.Log(4, "Adding native reference to {0} in {1} because it's referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    DerivedLinkContext.RequireMonoNative = true;
                    if (DerivedLinkContext.App.Platform != ApplePlatform.MacOSX &&
                        DerivedLinkContext.App.LibMonoNativeLinkMode == AssemblyBuildTarget.StaticObject)
                    {
                        DerivedLinkContext.RequiredSymbols.AddFunction(pinfo.EntryPoint).AddMember(method);
                    }
                }
            }

            if (method.IsPropertyMethod())
            {
                var    property = method.GetProperty();
                object symbol;
                // The Field attribute may have been linked away, but we've stored it in an annotation.
                if (property != null && Annotations.GetCustomAnnotations("ExportedFields").TryGetValue(property, out symbol))
                {
                    DerivedLinkContext.RequiredSymbols.AddField((string)symbol).AddMember(property);
                }
            }
        }
示例#12
0
        void ProcessMethod(MethodDefinition method)
        {
            if (method.IsPInvokeImpl && method.HasPInvokeInfo && method.PInvokeInfo != null)
            {
                var  pinfo            = method.PInvokeInfo;
                bool addPInvokeSymbol = false;

                if (state != null)
                {
                    switch (pinfo.EntryPoint)
                    {
                    case "objc_msgSend":
                    case "objc_msgSendSuper":
                    case "objc_msgSend_stret":
                    case "objc_msgSendSuper_stret":
                    case "objc_msgSend_fpret":
                        state.ProcessMethod(method);
                        break;

                    default:
                        break;
                    }
                }

                switch (pinfo.Module.Name)
                {
                case "__Internal":
                    Driver.Log(4, "Adding native reference to {0} in {1} because it's referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    DerivedLinkContext.RequiredSymbols.AddFunction(pinfo.EntryPoint).AddMember(method);
                    break;

                case "libSystem.Net.Security.Native":
                case "System.Net.Security.Native":
#if NET
                    // tvOS does not ship with System.Net.Security.Native due to https://github.com/dotnet/runtime/issues/45535
                    if (DerivedLinkContext.App.Platform == ApplePlatform.TVOS)
                    {
                        Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                        break;
                    }
#endif
                    addPInvokeSymbol = true;
                    break;

                case "libSystem.Security.Cryptography.Native.Apple":
                case "System.Security.Cryptography.Native.Apple":
#if NET
                    // https://github.com/dotnet/runtime/issues/47533
                    if (DerivedLinkContext.App.Platform != ApplePlatform.MacOSX)
                    {
                        Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                        break;
                    }
#endif
                    addPInvokeSymbol = true;
                    break;

                case "libSystem.Native":
                case "System.Native":
#if NET
                    // https://github.com/dotnet/runtime/issues/47533
                    if (DerivedLinkContext.App.Platform != ApplePlatform.MacOSX && pinfo.EntryPoint == "SystemNative_ConfigureTerminalForChildProcess")
                    {
                        Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                        break;
                    }
#endif
                    addPInvokeSymbol = true;
                    break;

                case "libSystem.Globalization.Native":
                case "System.Globalization.Native":
#if NET
                    // https://github.com/xamarin/xamarin-macios/issues/11392
                    if (DerivedLinkContext.App.Platform == ApplePlatform.MacCatalyst)
                    {
                        Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                        break;
                    }
#endif
                    addPInvokeSymbol = true;
                    break;

                default:
                    Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    break;
                }

                if (addPInvokeSymbol)
                {
                    Driver.Log(4, "Adding native reference to {0} in {1} because it's referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    DerivedLinkContext.RequireMonoNative = true;
                    if (DerivedLinkContext.App.Platform != ApplePlatform.MacOSX &&
                        DerivedLinkContext.App.LibMonoNativeLinkMode == AssemblyBuildTarget.StaticObject)
                    {
                        DerivedLinkContext.RequiredSymbols.AddFunction(pinfo.EntryPoint).AddMember(method);
                    }
                }
            }

            if (method.IsPropertyMethod())
            {
                var    property = method.GetProperty();
                object symbol;
                // The Field attribute may have been linked away, but we've stored it in an annotation.
                if (property != null && Annotations.GetCustomAnnotations("ExportedFields").TryGetValue(property, out symbol))
                {
                    DerivedLinkContext.RequiredSymbols.AddField((string)symbol).AddMember(property);
                }
            }
        }
示例#13
0
        void ProcessMethod(MethodDefinition method)
        {
            if (method.IsPInvokeImpl && method.HasPInvokeInfo && method.PInvokeInfo != null)
            {
                var pinfo = method.PInvokeInfo;

                if (state != null)
                {
                    switch (pinfo.EntryPoint)
                    {
                    case "objc_msgSend":
                    case "objc_msgSendSuper":
                    case "objc_msgSend_stret":
                    case "objc_msgSendSuper_stret":
                    case "objc_msgSend_fpret":
                        state.ProcessMethod(method);
                        break;

                    default:
                        break;
                    }
                }

                switch (pinfo.Module.Name)
                {
                case "__Internal":
                    Driver.Log(4, "Adding native reference to {0} in {1} because it's referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    DerivedLinkContext.RequiredSymbols.AddFunction(pinfo.EntryPoint).AddMember(method);
                    break;

                case "System.Net.Security.Native":
#if NET
                    if (DerivedLinkContext.App.Platform == ApplePlatform.TVOS)
                    {
                        Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                        break;                         // tvOS does not ship with System.Net.Security.Native due to https://github.com/dotnet/runtime/issues/45535
                    }

                    if (DerivedLinkContext.App.Platform == ApplePlatform.MacOSX)
                    {
                        Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                        break;                         // The macOS version of the BCL has several references to native methods supposedly in libSystem.Net.Security.Native that aren't there, so skip it.
                    }

                    goto case "System.Native";
#endif
                case "System.Native":
#if NET
                    if (DerivedLinkContext.App.Platform == ApplePlatform.MacOSX)
                    {
                        Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                        break;                         // The macOS version of the BCL has several references to native methods supposedly in libSystem.Native that aren't there, so skip it.
                    }
                    goto case "System.Security.Cryptography.Native.Apple";
#endif
                case "System.Security.Cryptography.Native.Apple":
                    Driver.Log(4, "Adding native reference to {0} in {1} because it's referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    DerivedLinkContext.RequireMonoNative = true;
                    DerivedLinkContext.RequiredSymbols.AddFunction(pinfo.EntryPoint).AddMember(method);
                    break;

                default:
                    Driver.Log(4, "Did not add native reference to {0} in {1} referenced by {2} in {3}.", pinfo.EntryPoint, pinfo.Module.Name, method.FullName, method.Module.Name);
                    break;
                }
            }

            if (method.IsPropertyMethod())
            {
                var    property = method.GetProperty();
                object symbol;
                // The Field attribute may have been linked away, but we've stored it in an annotation.
                if (property != null && Annotations.GetCustomAnnotations("ExportedFields").TryGetValue(property, out symbol))
                {
                    DerivedLinkContext.RequiredSymbols.AddField((string)symbol).AddMember(property);
                }
            }
        }