示例#1
0
        protected override void ProcessAssembly(AssemblyDefinition assembly)
        {
            if (!Annotations.HasAction(assembly))
            {
                Annotations.SetAction(assembly, AssemblyAction.Skip);
            }

            if (Profile.IsSdkAssembly(assembly) || Profile.IsProductAssembly(assembly))
            {
                return;
            }

            bool changed = false;

            foreach (var type in assembly.MainModule.Types)
            {
                if (MightNeedFix(type))
                {
                    changed |= FixAbstractMethods(type);
                }
            }

            if (changed)
            {
                AssemblyAction action = Annotations.HasAction(assembly) ? Annotations.GetAction(assembly) : AssemblyAction.Skip;
                if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete)
                {
                    Annotations.SetAction(assembly, AssemblyAction.Save);
                }
                var td = AbstractMethodErrorConstructor.DeclaringType.Resolve();
                Annotations.Mark(td);
                Annotations.SetPreserve(td, TypePreserve.Nothing);
                Annotations.AddPreservedMethod(td, AbstractMethodErrorConstructor.Resolve());
            }
        }
示例#2
0
        void ProcessType(TypeDefinition type)
        {
            if (!IsActiveFor(type.Module.Assembly))
            {
                return;
            }

            // If we are preserving a Mono.Android interface,
            // preserve all members on the interface.
            if (!type.IsInterface)
            {
                return;
            }

            // Mono.Android interfaces will always inherit IJavaObject
            if (!type.ImplementsIJavaObject())
            {
                return;
            }

            foreach (MethodReference method in type.Methods)
            {
                Annotations.AddPreservedMethod(type, method.Resolve());
            }
        }
示例#3
0
        void MapInterfaceMethodsInTypeHierarchy(TypeDefinition type)
        {
            if (!type.HasInterfaces)
            {
                return;
            }

            foreach (TypeReference @interface in type.Interfaces)
            {
                var iface = @interface.Resolve();
                if (iface == null || !iface.HasMethods)
                {
                    continue;
                }

                foreach (MethodDefinition method in iface.Methods)
                {
                    if (TryMatchMethod(type, method) != null)
                    {
                        continue;
                    }

                    var @base = GetBaseMethodInTypeHierarchy(type, method);
                    if (@base == null)
                    {
                        continue;
                    }

                    Annotations.AddPreservedMethod(type, @base);
                }
            }
        }
        protected override void ProcessAssembly(AssemblyDefinition assembly)
        {
            if (!Annotations.HasAction(assembly))
            {
                Annotations.SetAction(assembly, AssemblyAction.Skip);
            }


            if (IsProductOrSdkAssembly(assembly))
            {
                return;
            }

            CheckAppDomainUsageUnconditional(assembly, (string msg) => Context.Logger.LogMessage(MessageImportance.High, msg));

            if (FixAbstractMethodsUnconditional(assembly))
            {
                Context.SafeReadSymbols(assembly);
                AssemblyAction action = Annotations.HasAction(assembly) ? Annotations.GetAction(assembly) : AssemblyAction.Skip;
                if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete)
                {
                    Annotations.SetAction(assembly, AssemblyAction.Save);
                }
                var td = AbstractMethodErrorConstructor.DeclaringType.Resolve();
                Annotations.Mark(td);
                Annotations.SetPreserve(td, TypePreserve.Nothing);
                Annotations.AddPreservedMethod(td, AbstractMethodErrorConstructor.Resolve());
            }
        }
 void AddPreservedMethod(MethodDefinition target, string methodName)
 {
     foreach (MethodDefinition method in target.DeclaringType.Methods)
     {
         if (method.Name == methodName)
         {
             Annotations.AddPreservedMethod(target, method);
         }
     }
 }
        void PreserveConditional(IMetadataTokenProvider provider)
        {
            var method = provider as MethodDefinition;

            if (method == null)
            {
                return;
            }

            Annotations.AddPreservedMethod(method.DeclaringType, method);
        }
		void MarkDefautConstructor (TypeDefinition type)
		{
			if ((type == null) || !type.HasMethods)
				return;
			
			foreach (MethodDefinition ctor in type.Methods) {
				if (!ctor.IsConstructor || ctor.IsStatic || ctor.HasParameters)
					continue;

				Annotations.AddPreservedMethod (type, ctor);
			}
		}
        void PreserveConditional(IMetadataTokenProvider provider)
        {
            var method = provider as MethodDefinition;

            if (method == null)
            {
                // workaround to support (uncommon but valid) conditional fields form [Preserve]
                PreserveUnconditional(provider);
                return;
            }

            Annotations.AddPreservedMethod(method.DeclaringType, method);
        }
		public override void ProcessType (TypeDefinition type)
		{
			// If we are preserving a Mono.Android interface,
			// preserve all members on the interface.
			if (!type.IsInterface)
				return;

			// Mono.Android interfaces will always inherit IJavaObject
			if (!type.ImplementsIJavaObject ())
				return;

			foreach (MethodReference method in type.Methods)
				Annotations.AddPreservedMethod (type, method.Resolve ());
		}
        void MarkAbstractMethodErrorType()
        {
            if (markedAbstractMethodErrorType)
            {
                return;
            }
            markedAbstractMethodErrorType = true;


            var td = AbstractMethodErrorConstructor.DeclaringType;

            Annotations.Mark(td);
            Annotations.SetPreserve(td, TypePreserve.Nothing);
            Annotations.AddPreservedMethod(td, AbstractMethodErrorConstructor);
        }
示例#11
0
    public void ProcessMethod(MethodDefinition method)
    {
        if (method.Name == "MarkedMethod")
        {
            Annotations.Mark(method);
        }

        foreach (var m in method.DeclaringType.Methods)
        {
            if (m.Name == $"PreservedForMethod_{method.Name}")
            {
                Annotations.AddPreservedMethod(method, m);
            }
        }
    }
示例#12
0
        protected override void ProcessMethod(TypeDefinition type, MethodDefinition method, XPathNavigator nav, object customData)
        {
            if (Annotations.IsMarked(method))
            {
                Context.LogWarning($"Duplicate preserve of '{method.GetDisplayName ()}' in '{_xmlDocumentLocation}'", 2025, _xmlDocumentLocation);
            }

            Annotations.Mark(method, new DependencyInfo(DependencyKind.XmlDescriptor, _xmlDocumentLocation));
            Annotations.MarkIndirectlyCalledMethod(method);
            Annotations.SetAction(method, MethodAction.Parse);

            if (!(bool)customData)
            {
                Annotations.AddPreservedMethod(type, method);
            }
        }
示例#13
0
        void MarkMethod(TypeDefinition type, MethodDefinition method, bool required)
        {
            if (Annotations.IsMarked(method))
            {
                Context.LogMessage(MessageContainer.CreateWarningMessage($"Duplicate preserve of '{method.FullName}' in '{_xmlDocumentLocation}'", 2025));
            }

            Annotations.Mark(method, new DependencyInfo(DependencyKind.XmlDescriptor, _xmlDocumentLocation));
            Annotations.MarkIndirectlyCalledMethod(method);
            Annotations.SetAction(method, MethodAction.Parse);

            if (!required)
            {
                Annotations.AddPreservedMethod(type, method);
            }
        }
示例#14
0
        void PreserveIntPtrConstructor(TypeDefinition type)
        {
            foreach (MethodDefinition constructor in type.GetConstructors())
            {
                if (!constructor.HasParameters)
                {
                    continue;
                }

                if (constructor.Parameters.Count != 1 || !constructor.Parameters [0].ParameterType.Is("System", "IntPtr"))
                {
                    continue;
                }

                Annotations.AddPreservedMethod(type, constructor);
                break;                 // only one .ctor can match this
            }
        }
示例#15
0
        void PreserveTypeConverter(TypeDefinition type)
        {
            if (!type.HasMethods)
            {
                return;
            }

            foreach (var ctor in type.Methods.Where(m => m.IsConstructor))
            {
                // We only care about ctors with 0 or 1 params.
                if (ctor.HasParameters && ctor.Parameters.Count > 1)
                {
                    continue;
                }

                Annotations.AddPreservedMethod(type, ctor);
            }
        }
示例#16
0
        void PreserveExportedMethods(TypeDefinition type)
        {
            foreach (var method in type.Methods)
            {
                if (!IsExportedMethod(method))
                {
                    continue;
                }

                // not optimal if "Link all" is used as the override might be removed later
                if (!IsOverridenInUserCode(method))
                {
                    continue;
                }

                Annotations.AddPreservedMethod(type, method);
            }
        }
        void PreserveJSInvokable(MethodDefinition method)
        {
            Context.LogDebug($"Preserving `[{js_invokable_attribute_type}]': `{method}' in `{method.DeclaringType.Module.FileName}'.");

            PreserveType(method.DeclaringType);
            Annotations.AddPreservedMethod(method.DeclaringType, method);

            if (method.HasParameters)
            {
                foreach (var pd in method.Parameters)
                {
                    var ptype = BasicBlocks.CecilHelper.Resolve(pd.ParameterType);
                    if (ptype != null)
                    {
                        PreserveType(ptype);
                        Annotations.SetPreserve(ptype, TypePreserve.All);
                    }
                }
            }
        }
示例#18
0
            void PreserveTypeIfRequested(TypeDefinition type)
            {
                var typePreserved = IsTypePreserved(type);

                if (IsTypePreserved(type))
                {
                    MarkAndPreserveAll(type);
                }
                else
                {
                    foreach (var m in type.Methods.Where(IsMethodPreserved))
                    {
                        Annotations.AddPreservedMethod(type, m);
                    }
                    foreach (var t in type.NestedTypes)
                    {
                        PreserveTypeIfRequested(t);
                    }
                }
            }
示例#19
0
    void ProcessType(TypeDefinition type)
    {
        if (type.HasNestedTypes)
        {
            foreach (var nested in type.NestedTypes)
            {
                ProcessType(nested);
            }
        }


        foreach (var method in type.Methods)
        {
            if (method.Name == "PreservedForType")
            {
                Annotations.AddPreservedMethod(type, method);
            }

            ProcessMethod(method);
        }
    }
示例#20
0
        protected override void ProcessAssembly(AssemblyDefinition assembly)
        {
            if (!Annotations.HasAction(assembly))
            {
                Annotations.SetAction(assembly, AssemblyAction.Skip);
            }

            bool changed = FixAbstractMethods(assembly);

            if (changed)
            {
                Context.SafeReadSymbols(assembly);
                AssemblyAction action = Annotations.HasAction(assembly) ? Annotations.GetAction(assembly) : AssemblyAction.Skip;
                if (action == AssemblyAction.Skip || action == AssemblyAction.Copy || action == AssemblyAction.Delete)
                {
                    Annotations.SetAction(assembly, AssemblyAction.Save);
                }
                var td = AbstractMethodErrorConstructor.DeclaringType.Resolve();
                Annotations.Mark(td);
                Annotations.SetPreserve(td, TypePreserve.Nothing);
                Annotations.AddPreservedMethod(td, AbstractMethodErrorConstructor.Resolve());
            }
        }
示例#21
0
 void PreserveMethod(TypeDefinition type, MethodDefinition method)
 {
     Annotations.AddPreservedMethod(type, method);
 }
示例#22
0
 void AddPreservedMethod(MethodDefinition key, MethodDefinition method)
 {
     Annotations.AddPreservedMethod(key, method);
 }
示例#23
0
        protected override void Process()
        {
            AssemblyDefinition?assembly = LoadAssemblyFile();

            if (assembly == null)
            {
                return;
            }

            var di     = new DependencyInfo(DependencyKind.RootAssembly, assembly);
            var origin = new MessageOrigin(assembly);

            AssemblyAction action = Context.Annotations.GetAction(assembly);

            switch (action)
            {
            case AssemblyAction.Copy:
                Annotations.Mark(assembly.MainModule, di, origin);
                // Mark Step will take care of marking whole assembly
                return;

            case AssemblyAction.CopyUsed:
            case AssemblyAction.Link:
                break;

            default:
                Context.LogError(null, DiagnosticId.RootAssemblyCannotUseAction, assembly.Name.ToString(), action.ToString());
                return;
            }

            switch (rootMode)
            {
            case AssemblyRootMode.Default:
                if (assembly.MainModule.Kind == ModuleKind.Dll)
                {
                    goto case AssemblyRootMode.AllMembers;
                }
                else
                {
                    goto case AssemblyRootMode.EntryPoint;
                }

            case AssemblyRootMode.EntryPoint:
                var ep = assembly.MainModule.EntryPoint;
                if (ep == null)
                {
                    Context.LogError(null, DiagnosticId.RootAssemblyDoesNotHaveEntryPoint, assembly.Name.ToString());
                    return;
                }

                Annotations.Mark(ep.DeclaringType, di, origin);
                Annotations.AddPreservedMethod(ep.DeclaringType, ep);
                break;

            case AssemblyRootMode.VisibleMembers:
                var preserve_visible = TypePreserveMembers.Visible;
                if (MarkInternalsVisibleTo(assembly))
                {
                    preserve_visible |= TypePreserveMembers.Internal;
                }

                MarkAndPreserve(assembly, preserve_visible);
                break;

            case AssemblyRootMode.Library:
                var preserve_library = TypePreserveMembers.Visible | TypePreserveMembers.Library;
                if (MarkInternalsVisibleTo(assembly))
                {
                    preserve_library |= TypePreserveMembers.Internal;
                }

                MarkAndPreserve(assembly, preserve_library);

                // Assembly root mode wins over any enabled optimization which
                // could conflict with library rooting behaviour
                Context.Optimizations.Disable(
                    CodeOptimizations.Sealer |
                    CodeOptimizations.UnusedTypeChecks |
                    CodeOptimizations.UnreachableBodies |
                    CodeOptimizations.UnusedInterfaces |
                    CodeOptimizations.RemoveDescriptors |
                    CodeOptimizations.RemoveLinkAttributes |
                    CodeOptimizations.RemoveSubstitutions |
                    CodeOptimizations.RemoveDynamicDependencyAttribute |
                    CodeOptimizations.OptimizeTypeHierarchyAnnotations, assembly.Name.Name);

                // Enable EventSource special handling
                Context.DisableEventSourceSpecialHandling = false;

                // No metadata trimming
                Context.MetadataTrimming = MetadataTrimming.None;
                break;

            case AssemblyRootMode.AllMembers:
                Context.Annotations.SetAction(assembly, AssemblyAction.Copy);
                return;
            }
        }
示例#24
0
        protected override void Process()
        {
            AssemblyDefinition assembly = LoadAssemblyFile();

            if (assembly == null)
            {
                return;
            }

            var di = new DependencyInfo(DependencyKind.RootAssembly, assembly);

            AssemblyAction action = Context.Annotations.GetAction(assembly);

            switch (action)
            {
            case AssemblyAction.Copy:
                Annotations.Mark(assembly.MainModule, di);
                // Mark Step will take care of marking whole assembly
                return;

            case AssemblyAction.CopyUsed:
            case AssemblyAction.Link:
                break;

            default:
                Context.LogError($"Root assembly '{assembly.Name}' cannot use action '{action}'", 1035);
                return;
            }

            switch (rootMode)
            {
            case AssemblyRootMode.Default:
                if (assembly.MainModule.Kind == ModuleKind.Dll)
                {
                    goto case AssemblyRootMode.AllMembers;
                }
                else
                {
                    goto case AssemblyRootMode.EntryPoint;
                }

            case AssemblyRootMode.EntryPoint:
                var ep = assembly.MainModule.EntryPoint;
                if (ep == null)
                {
                    Context.LogError($"Root assembly '{assembly.Name}' does not have entry point", 1034);
                    return;
                }

                Annotations.Mark(ep.DeclaringType, di);
                Annotations.AddPreservedMethod(ep.DeclaringType, ep);
                break;

            case AssemblyRootMode.VisibleMembers:
                var preserve_visible = TypePreserveMembers.Visible;
                if (MarkInternalsVisibleTo(assembly))
                {
                    preserve_visible |= TypePreserveMembers.Internal;
                }

                MarkAndPreserve(assembly, preserve_visible);
                break;

            case AssemblyRootMode.Library:
                var preserve_library = TypePreserveMembers.Visible | TypePreserveMembers.Library;
                if (MarkInternalsVisibleTo(assembly))
                {
                    preserve_library |= TypePreserveMembers.Internal;
                }

                MarkAndPreserve(assembly, preserve_library);

                // Assembly root mode wins over any enabled optimization which
                // could conflict with library rooting behaviour
                Context.Optimizations.Disable(
                    CodeOptimizations.Sealer |
                    CodeOptimizations.UnusedTypeChecks |
                    CodeOptimizations.UnreachableBodies |
                    CodeOptimizations.UnusedInterfaces |
                    CodeOptimizations.RemoveDescriptors |
                    CodeOptimizations.RemoveLinkAttributes |
                    CodeOptimizations.RemoveSubstitutions |
                    CodeOptimizations.RemoveDynamicDependencyAttribute, assembly.Name.Name);

                // No metadata trimming
                Context.MetadataTrimming = MetadataTrimming.None;
                break;

            case AssemblyRootMode.AllMembers:
                Context.Annotations.SetAction(assembly, AssemblyAction.Copy);
                return;
            }
        }
示例#25
0
        void PreserveBlockField(FieldDefinition field)
        {
            /* For the following class:
             *
             * static internal class SDInnerBlock {
             *      // this field is not preserved by other means, but it must not be linked away
             *      static internal readonly DInnerBlock Handler = Invoke;
             *
             *      [MonoPInvokeCallback (typeof (DInnerBlock))]
             *      static internal void Invoke (IntPtr block, int magic_number)
             *      {
             *      }
             * }
             *
             * We need to make sure the linker doesn't remove the Handler field
             * and the Invoke method. Unfortunately there's no programmatic way
             * to preserve a field dependent upon the preservation of the
             * containing type, so we have to inject a DynamicDependency
             * attribute. And since we can't add a DynamicDependency attribute on
             * the type itself, we add it to the Invoke method. We also need to
             * preserve the Invoke method (which is done programmatically). Our
             * generator generates the required attributes, but since we have to
             * work with existing assemblies, we detect the scenario here as well
             * and inject the attributes manually if they're not already there.
             *
             */

            // First make sure we got the right field
            // The containing type for the field we're looking for is abstract, sealed and nested and contains exactly 1 field.
            var td = field.DeclaringType;

            if (!td.IsAbstract || !td.IsSealed || !td.IsNested)
            {
                return;
            }
            if (td.Fields.Count != 1)
            {
                return;
            }

            // The containing type is also nested inside ObjCRuntime.Trampolines class)
            var nestingType = td.DeclaringType;

            if (!nestingType.Is("ObjCRuntime", "Trampolines"))
            {
                return;
            }

            // The field itself is a readonly field named 'Handler'
            if (!field.IsInitOnly)
            {
                return;
            }
            if (field.Name != "Handler")
            {
                return;
            }

            // One problem is that we can't add the DynamicDependency attribute to the type, nor the field itself,
            // so we add it to the Invoke method in the same type.
            if (!td.HasMethods)
            {
                return;
            }

            var method = td.Methods.SingleOrDefault(v => {
                if (v.Name != "Invoke")
                {
                    return(false);
                }
                if (v.Parameters.Count == 0)
                {
                    return(false);
                }
                if (!v.HasCustomAttributes)
                {
                    return(false);
                }
                if (!v.CustomAttributes.Any(v => v.AttributeType.Name == "MonoPInvokeCallbackAttribute"))
                {
                    return(false);
                }
                return(true);
            });

            if (method == null)
            {
                return;
            }

            // We need to preserve the method, if the type is used (unless it's already preserved)
            if (!method.CustomAttributes.Any(v => v.AttributeType.Name == "PreserveAttribute"))
            {
                Annotations.AddPreservedMethod(method.DeclaringType, method);
            }

            // Does the method already have a DynamicDependency attribute? If so, no need to add another one
            if (method.CustomAttributes.Any(v => v.AttributeType.Is("System.Diagnostics.CodeAnalysis", "DynamicDependencyAttribute")))
            {
                return;
            }

            // Create and add the DynamicDependency attribute to the method
            var ctor   = GetConstructorReference(field.DeclaringType.Module.Assembly);
            var attrib = new CustomAttribute(ctor);

            attrib.ConstructorArguments.Add(new CustomAttributeArgument(ctor.Parameters [0].ParameterType, "Handler"));
            method.CustomAttributes.Add(attrib);
        }