// 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 }); }
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; }
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); } } }
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. } }
public IList <MethodDefinition> GetProtocolMethods(TypeDefinition type) { var attribs = Annotations.GetCustomAnnotations("ProtocolMethods"); object value; if (attribs.TryGetValue(type, out value)) { return((MethodDefinition [])value); } return(null); }
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); }
void ProcessProperty(PropertyDefinition property) { if (!property.HasCustomAttributes) { return; } var symbol = GetFieldSymbol(property); if (symbol == null) { return; } Annotations.GetCustomAnnotations("ExportedFields").Add(property, symbol); }
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); }
public Dictionary <IMetadataTokenProvider, object> GetAllCustomAttributes(string storage_name) { return(Annotations?.GetCustomAnnotations(storage_name)); }
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); } } }
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); } } }
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); } } }