Example #1
0
 public void RegisterAssembly(AssemblyAction action, IIsolate isolate)
 {
     if (_assemblies.Count(x => x.Key == action && x.Value.FullName == isolate.Name.FullName) == 0)             // Check if its already added
     {
         _assemblies.Add(new KeyValuePair <AssemblyAction, AssemblyName>(action, isolate.Name));
     }
 }
Example #2
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());
            }
        }
Example #3
0
        public void DoForEachAssembly(AssemblyAction assemblyAction)
        {
            List <IAppDomainInfo> theDomains = new List <IAppDomainInfo>();

            this.DoForEachAppDomain(
                delegate(IAppDomainInfo adi)
            {
                theDomains.Add(adi);
            }
                );

            _WP.Commands.Debugging_Resolve_Assembly[] reply = m_eng.ResolveAllAssemblies();
            if (reply != null)
            {
                foreach (_WP.Commands.Debugging_Resolve_Assembly resolvedAssm in reply)
                {
                    AssemblyInfoFromResolveAssembly ai = new AssemblyInfoFromResolveAssembly(resolvedAssm);

                    foreach (IAppDomainInfo adi in theDomains)
                    {
                        if (Array.IndexOf <uint>(adi.AssemblyIndicies, ai.Index) != -1)
                        {
                            ai.AddDomain(adi);
                        }
                    }

                    assemblyAction(ai);
                }
            }
        }
        protected override void Process()
        {
            assemblies = Context.Annotations.GetAssemblies().ToArray();
            foreach (var assembly in assemblies)
            {
                ProcessAssemblyAction(assembly);
                if ((Annotations.GetAction(assembly) == AssemblyAction.Copy) &&
                    !Context.KeepTypeForwarderOnlyAssemblies)
                {
                    // Copy assemblies can still contain Type references with
                    // type forwarders from Delete assemblies
                    // thus try to resolve all the type references and see
                    // if some changed the scope. if yes change the action to Save
                    if (ResolveAllTypeReferences(assembly))
                    {
                        Annotations.SetAction(assembly, AssemblyAction.Save);
                    }
                }

                AssemblyAction currentAction = Annotations.GetAction(assembly);

                if ((currentAction == AssemblyAction.Link) || (currentAction == AssemblyAction.Save))
                {
                    // if we save (only or by linking) then unmarked exports (e.g. forwarders) must be cleaned
                    // or they can point to nothing which will break later (e.g. when re-loading for stripping IL)
                    // reference: https://bugzilla.xamarin.com/show_bug.cgi?id=36577
                    if (assembly.MainModule.HasExportedTypes)
                    {
                        SweepCollectionNonAttributable(assembly.MainModule.ExportedTypes);
                    }
                }
            }
        }
Example #5
0
        public void TestAssemblyPaths(ITaskItem[] assemblyPaths)
        {
            var task = new MockTask()
            {
                AssemblyPaths = assemblyPaths
            };

            using (var driver = task.CreateDriver()) {
                var context = driver.Context;

                var expectedReferences = assemblyPaths.Select(p => p.ItemSpec)
                                         .GroupBy(p => Path.GetFileNameWithoutExtension(p))
                                         .Select(g => g.First());
                var actualReferences = driver.GetReferenceAssemblies();
                Assert.Equal(expectedReferences.OrderBy(a => a), actualReferences.OrderBy(a => a));

                foreach (var item in assemblyPaths)
                {
                    var assemblyPath = item.ItemSpec;
                    var trimMode     = item.GetMetadata("TrimMode");
                    if (String.IsNullOrEmpty(trimMode))
                    {
                        continue;
                    }

                    AssemblyAction expectedAction = (AssemblyAction)Enum.Parse(typeof(AssemblyAction), trimMode, ignoreCase: true);
                    AssemblyAction actualAction   = context.Actions[Path.GetFileNameWithoutExtension(assemblyPath)];

                    Assert.Equal(expectedAction, actualAction);
                }
            }
        }
        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());
            }
        }
Example #7
0
        public void SetAction(AssemblyDefinition assembly, AssemblyAction defaultAction)
        {
            if (!_actions.TryGetValue(assembly.Name.Name, out AssemblyAction action))
            {
                action = defaultAction;
            }

            Annotations.SetAction(assembly, action);
        }
        public override bool IsActiveFor(AssemblyDefinition assembly)
        {
            // we're sure "pure" SDK assemblies don't use XamMac.dll (i.e. they are the Product assemblies)
            if (Profile.IsSdkAssembly(assembly))
            {
#if DEBUG
                Console.WriteLine("Assembly {0} : skipped (SDK)", assembly);
#endif
                return(false);
            }

            // process only assemblies where the linker is enabled (e.g. --linksdk, --linkskip)
            AssemblyAction action = Annotations.GetAction(assembly);
            if (action != AssemblyAction.Link)
            {
#if DEBUG
                Console.WriteLine("Assembly {0} : skipped ({1})", assembly, action);
#endif
                return(false);
            }

            // if the assembly does not refer to [CompilerGeneratedAttribute] then there's not much we can do
            HasOptimizableCode = false;
            foreach (TypeReference tr in assembly.MainModule.GetTypeReferences())
            {
                if (tr.Is(Namespaces.ObjCRuntime, "BindingImplAttribute"))
                {
                    HasOptimizableCode = true;
                    break;
                }

                if (!Driver.IsXAMCORE_4_0 && tr.Is("System.Runtime.CompilerServices", "CompilerGeneratedAttribute"))
                {
#if DEBUG
                    Console.WriteLine("Assembly {0} : processing", assembly);
#endif
                    HasOptimizableCode = true;
                    break;
                }
            }
#if DEBUG
            if (!HasOptimizableCode)
            {
                Console.WriteLine("Assembly {0} : no [CompilerGeneratedAttribute] nor [BindingImplAttribute] present (applying basic optimizations)", assembly);
            }
#endif
            // we always apply the step
            return(true);
        }
        protected override void Process()
        {
            base.Process ();

            var assemblies = Context.GetAssemblies ();
            foreach (var assembly in assemblies) {
                CurrentAction = Annotations.GetAction (assembly);
                switch (CurrentAction) {
                case AssemblyAction.Link:
                case AssemblyAction.Save:
                    SweepAssembly (assembly);
                    break;
                }
            }
        }
Example #10
0
        protected void ProcessAssemblyAction(AssemblyDefinition assembly)
        {
            switch (Annotations.GetAction(assembly))
            {
            case AssemblyAction.AddBypassNGenUsed:
                Annotations.SetAction(assembly, AssemblyAction.AddBypassNGen);
                goto case AssemblyAction.AddBypassNGen;

            case AssemblyAction.AddBypassNGen:
                // FIXME: AddBypassNGen is just wrong, it should not be action as we need to
                // turn it to Action.Save here to e.g. correctly update debug symbols
                if (!Context.KeepTypeForwarderOnlyAssemblies || BypassNGenToSave.Contains(assembly))
                {
                    goto case AssemblyAction.Save;
                }

                break;

            case AssemblyAction.CopyUsed:
                AssemblyAction assemblyAction = AssemblyAction.Copy;
                if (!Context.KeepTypeForwarderOnlyAssemblies && SweepTypeForwarders(assembly))
                {
                    // Need to sweep references, in case sweeping type forwarders removed any
                    AssemblyReferencesCorrector.SweepAssemblyReferences(assembly);
                    assemblyAction = AssemblyAction.Save;
                }

                Annotations.SetAction(assembly, assemblyAction);
                break;

            case AssemblyAction.Copy:
                break;

            case AssemblyAction.Link:
                SweepAssembly(assembly);
                break;

            case AssemblyAction.Save:
                if (!Context.KeepTypeForwarderOnlyAssemblies && SweepTypeForwarders(assembly))
                {
                    // Need to sweep references, in case sweeping type forwarders removed any
                    AssemblyReferencesCorrector.SweepAssemblyReferences(assembly);
                }
                break;
            }
        }
Example #11
0
        void SetAction(AssemblyDefinition assembly)
        {
            AssemblyAction action = AssemblyAction.Link;

            AssemblyNameDefinition name = assembly.Name;

            if (_actions.Contains(name.Name))
            {
                action = (AssemblyAction)_actions [name.Name];
            }
            else if (IsCore(name))
            {
                action = _coreAction;
            }

            _annotations.SetAction(assembly, action);
        }
Example #12
0
        protected override void Process()
        {
            base.Process();

            var assemblies = Context.GetAssemblies();

            foreach (var assembly in assemblies)
            {
                CurrentAction = Annotations.GetAction(assembly);
                switch (CurrentAction)
                {
                case AssemblyAction.Link:
                case AssemblyAction.Save:
                    SweepAssembly(assembly);
                    break;
                }
            }
        }
Example #13
0
        public void TestReferenceAssemblyPaths(string[] referenceAssemblyPaths)
        {
            var task = new MockTask()
            {
                ReferenceAssemblyPaths = referenceAssemblyPaths.Select(p => new TaskItem(p)).ToArray()
            };

            using (var driver = task.CreateDriver()) {
                var expectedReferences = referenceAssemblyPaths;
                var actualReferences   = driver.GetReferenceAssemblies();
                Assert.Equal(expectedReferences.OrderBy(a => a), actualReferences.OrderBy(a => a));
                foreach (var reference in expectedReferences)
                {
                    var            ad           = new Mono.Cecil.AssemblyNameDefinition(Path.GetFileNameWithoutExtension(reference), new Version());
                    AssemblyAction actualAction = driver.Context.CalculateAssemblyAction(ad);
                    Assert.Equal(AssemblyAction.Skip, actualAction);
                }
            }
        }
Example #14
0
        public override bool IsActiveFor(AssemblyDefinition assembly)
        {
            if (assembly.Name.Name != (Profile.Current as BaseProfile).ProductAssembly)
            {
                return(false);
            }

            // process only assemblies where the linker is enabled (e.g. --linksdk, --linkskip)
            AssemblyAction action = Annotations.GetAction(assembly);

            if (action != AssemblyAction.Link)
            {
#if DEBUG
                Console.WriteLine("Assembly {0} : skipped ({1})", assembly, action);
#endif
                return(false);
            }

            return(true);
        }
Example #15
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());
            }
        }
        void ProcessSecurityProvider(ISecurityDeclarationProvider provider)
        {
            if (!provider.HasSecurityDeclarations)
            {
                return;
            }

            // for non-linked code we still need to remove the security declarations,
            // if any are present, are save back the assembly. Otherwise it might become
            // impossible to decode what we save #28918.
            switch (Action)
            {
            case AssemblyAction.Link:
            case AssemblyAction.Save:
                break;

            default:
                Annotations.SetAction(Current, AssemblyAction.Save);
                Action = AssemblyAction.Save;
                break;
            }

            provider.SecurityDeclarations.Clear();
        }
Example #17
0
 public void RegisterAssemblyAction(string assemblyName, AssemblyAction action)
 {
     _actions[assemblyName] = action;
 }
Example #18
0
 public void RegisterAssembly(AssemblyAction action, AssemblyName name)
 {
     _assemblies.Add(new KeyValuePair <AssemblyAction, AssemblyName>(action, name));
 }
Example #19
0
 public void SetAction(AssemblyDefinition assembly, AssemblyAction action)
 {
     assembly_actions [assembly] = action;
 }
Example #20
0
        void Run()
        {
            Pipeline       p            = GetStandardPipeline();
            LinkContext    context      = GetDefaultContext(p);
            I18nAssemblies assemblies   = I18nAssemblies.All;
            var            custom_steps = new List <string> ();

            bool resolver = false;

            while (HaveMoreTokens())
            {
                string token = GetParam();
                if (token.Length < 2)
                {
                    Usage("Option is too short");
                }

                if (!(token [0] == '-' || token [1] == '/'))
                {
                    Usage("Expecting an option, got instead: " + token);
                }

                if (token [0] == '-' && token [1] == '-')
                {
                    if (token.Length < 3)
                    {
                        Usage("Option is too short");
                    }

                    switch (token [2])
                    {
                    case 'v':
                        Version();
                        break;

                    case 'a':
                        About();
                        break;

                    default:
                        Usage(null);
                        break;
                    }
                }

                switch (token [1])
                {
                case 'd': {
                    DirectoryInfo info = new DirectoryInfo(GetParam());
                    context.Resolver.AddSearchDirectory(info.FullName);
                    break;
                }

                case 'o':
                    context.OutputDirectory = GetParam();
                    break;

                case 'c':
                    context.CoreAction = ParseAssemblyAction(GetParam());
                    break;

                case 'p':
                    AssemblyAction action = ParseAssemblyAction(GetParam());
                    context.Actions [GetParam()] = action;
                    break;

                case 's':
                    custom_steps.Add(GetParam());
                    break;

                case 't':
                    context.KeepTypeForwarderOnlyAssemblies = true;
                    break;

                case 'x':
                    foreach (string file in GetFiles(GetParam()))
                    {
                        p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file)));
                    }
                    resolver = true;
                    break;

                case 'r':
                case 'a':
                    var rootVisibility = (token[1] == 'r')
                                                        ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                        : ResolveFromAssemblyStep.RootVisibility.Any;
                    foreach (string file in GetFiles(GetParam()))
                    {
                        p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
                    }
                    resolver = true;
                    break;

                case 'i':
                    foreach (string file in GetFiles(GetParam()))
                    {
                        p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
                    }
                    resolver = true;
                    break;

                case 'l':
                    assemblies = ParseI18n(GetParam());
                    break;

                case 'm':
                    context.SetParameter(GetParam(), GetParam());
                    break;

                case 'b':
                    context.LinkSymbols = bool.Parse(GetParam());
                    break;

                case 'g':
                    if (!bool.Parse(GetParam()))
                    {
                        p.RemoveStep(typeof(RegenerateGuidStep));
                    }
                    break;

                case 'v':
                    context.KeepMembersForDebuggerAttributes = bool.Parse(GetParam());
                    break;

                default:
                    Usage("Unknown option: `" + token [1] + "'");
                    break;
                }
            }

            if (!resolver)
            {
                Usage("No resolver was created (use -x, -a or -i)");
            }

            foreach (string custom_step in custom_steps)
            {
                AddCustomStep(p, custom_step);
            }

            p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

            p.Process(context);
        }
Example #21
0
        public void DoForEachAssembly(AssemblyAction assemblyAction)
        {
            List<IAppDomainInfo> theDomains = new List<IAppDomainInfo>();
            
            this.DoForEachAppDomain(
                delegate(IAppDomainInfo adi)
                {
                    theDomains.Add(adi);
                }
            );

            _WP.Commands.Debugging_Resolve_Assembly[] reply = m_eng.ResolveAllAssemblies();
            if ( reply != null )
                foreach (_WP.Commands.Debugging_Resolve_Assembly resolvedAssm in reply)
                {
                    AssemblyInfoFromResolveAssembly ai = new AssemblyInfoFromResolveAssembly(resolvedAssm);
                    
                    foreach (IAppDomainInfo adi in theDomains)
                    {
                        if (Array.IndexOf<uint>(adi.AssemblyIndicies, ai.Index) != -1 )
                        {
                            ai.AddDomain(adi);
                        }
                    }
                    
                    assemblyAction(ai);
                }
        }
Example #22
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;
            }
        }
        static void SetAction(LinkContext context, AssemblyDefinition assembly, AssemblyAction action)
        {
            TryReadSymbols (context, assembly);

            context.Annotations.SetAction (assembly, action);
        }
Example #24
0
        public void Run(ILogger customLogger = null)
        {
            Pipeline p = GetStandardPipeline();

            using (LinkContext context = GetDefaultContext(p)) {
                if (customLogger != null)
                {
                    context.Logger = customLogger;
                }

                I18nAssemblies assemblies             = I18nAssemblies.All;
                var            custom_steps           = new List <string> ();
                var            excluded_features      = new HashSet <string> (StringComparer.Ordinal);
                var            disabled_optimizations = new HashSet <string> (StringComparer.Ordinal);
                bool           dumpDependencies       = false;
                bool           ignoreDescriptors      = false;
                bool           removeCAS = true;

                bool resolver = false;
                while (HaveMoreTokens())
                {
                    string token = GetParam();
                    if (token.Length < 2)
                    {
                        Usage("Option is too short");
                    }

                    if (!(token [0] == '-' || token [1] == '/'))
                    {
                        Usage("Expecting an option, got instead: " + token);
                    }

                    if (token [0] == '-' && token [1] == '-')
                    {
                        if (token.Length < 3)
                        {
                            Usage("Option is too short");
                        }

                        switch (token)
                        {
                        case "--skip-unresolved":
                            bool ignoreUnresolved = bool.Parse(GetParam());
                            context.IgnoreUnresolved          = ignoreUnresolved;
                            context.Resolver.IgnoreUnresolved = ignoreUnresolved;
                            continue;

                        case "--verbose":
                            context.LogMessages = true;
                            continue;

                        case "--dependencies-file":
                            context.Tracer.DependenciesFileName = GetParam();
                            continue;

                        case "--dump-dependencies":
                            dumpDependencies = true;
                            continue;

                        case "--reduced-tracing":
                            context.EnableReducedTracing = bool.Parse(GetParam());
                            continue;

                        case "--used-attrs-only":
                            context.KeepUsedAttributeTypesOnly = bool.Parse(GetParam());
                            continue;

                        case "--strip-security":
                            removeCAS = bool.Parse(GetParam());
                            continue;

                        case "--strip-resources":
                            context.StripResources = bool.Parse(GetParam());
                            continue;

                        case "--exclude-feature":
                            var name = GetParam();
                            foreach (var feature in name.Split(','))
                            {
                                if (!excluded_features.Contains(feature))
                                {
                                    excluded_features.Add(feature);
                                }
                            }
                            continue;

                        case "--custom-step":
                            custom_steps.Add(GetParam());
                            continue;

                        case "--keep-facades":
                            context.KeepTypeForwarderOnlyAssemblies = bool.Parse(GetParam());
                            continue;

                        case "--ignore-descriptors":
                            ignoreDescriptors = bool.Parse(GetParam());
                            continue;

                        case "--disable-opt":
                            var opt = GetParam().ToLower();
                            if (!disabled_optimizations.Contains(opt))
                            {
                                disabled_optimizations.Add(opt);
                            }

                            continue;
                        }

                        switch (token [2])
                        {
                        case 'v':
                            Version();
                            break;

                        case 'a':
                            About();
                            break;

                        default:
                            Usage(null);
                            break;
                        }
                    }

                    switch (token [1])
                    {
                    case 'd':
                        DirectoryInfo info = new DirectoryInfo(GetParam());
                        context.Resolver.AddSearchDirectory(info.FullName);
                        break;

                    case 'o':
                        context.OutputDirectory = GetParam();
                        break;

                    case 'c':
                        context.CoreAction = ParseAssemblyAction(GetParam());
                        break;

                    case 'u':
                        context.UserAction = ParseAssemblyAction(GetParam());
                        break;

                    case 'p':
                        AssemblyAction action = ParseAssemblyAction(GetParam());
                        context.Actions [GetParam()] = action;
                        break;

                    case 't':
                        context.KeepTypeForwarderOnlyAssemblies = true;
                        break;

                    case 'x':
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file)));
                        }
                        resolver = true;
                        break;

                    case 'r':
                    case 'a':
                        var rootVisibility = (token [1] == 'r')
                                                        ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                        : ResolveFromAssemblyStep.RootVisibility.Any;
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
                        }
                        resolver = true;
                        break;

                    case 'i':
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
                        }
                        resolver = true;
                        break;

                    case 'l':
                        assemblies = ParseI18n(GetParam());
                        break;

                    case 'm':
                        context.SetParameter(GetParam(), GetParam());
                        break;

                    case 'b':
                        context.LinkSymbols = bool.Parse(GetParam());
                        break;

                    case 'g':
                        if (!bool.Parse(GetParam()))
                        {
                            p.RemoveStep(typeof(RegenerateGuidStep));
                        }
                        break;

                    case 'z':
                        ignoreDescriptors = !bool.Parse(GetParam());
                        break;

                    case 'v':
                        context.KeepMembersForDebugger = bool.Parse(GetParam());
                        break;

                    default:
                        Usage("Unknown option: `" + token [1] + "'");
                        break;
                    }
                }

                if (!resolver)
                {
                    Usage("No resolver was created (use -x, -a or -i)");
                }

                if (ignoreDescriptors)
                {
                    p.RemoveStep(typeof(BlacklistStep));
                }

                if (dumpDependencies)
                {
                    context.Tracer.Start();
                }

                foreach (string custom_step in custom_steps)
                {
                    AddCustomStep(p, custom_step);
                }

                p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

                if (_needAddBypassNGenStep)
                {
                    p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep());
                }

                if (assemblies != I18nAssemblies.None)
                {
                    p.AddStepAfter(typeof(PreserveDependencyLookupStep), new PreserveCalendarsStep(assemblies));
                }

                if (removeCAS)
                {
                    p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep());
                }

                if (excluded_features.Count > 0)
                {
                    p.AddStepBefore(typeof(MarkStep), new RemoveFeaturesStep()
                    {
                        FeatureCOM           = excluded_features.Contains("com"),
                        FeatureETW           = excluded_features.Contains("etw"),
                        FeatureGlobalization = excluded_features.Contains("globalization")
                    });

                    var excluded = new string [excluded_features.Count];
                    excluded_features.CopyTo(excluded);
                    context.ExcludedFeatures = excluded;
                }

                if (disabled_optimizations.Count > 0)
                {
                    foreach (var item in disabled_optimizations)
                    {
                        switch (item)
                        {
                        case "beforefieldinit":
                            context.DisabledOptimizations |= CodeOptimizations.BeforeFieldInit;
                            break;

                        case "overrideremoval":
                            context.DisabledOptimizations |= CodeOptimizations.OverrideRemoval;
                            break;
                        }
                    }
                }

                PreProcessPipeline(p);

                try {
                    p.Process(context);
                }
                finally {
                    if (dumpDependencies)
                    {
                        context.Tracer.Finish();
                    }
                }
            }
        }
Example #25
0
        public bool Run(ILogger customLogger = null)
        {
            Pipeline p = GetStandardPipeline();

            using (LinkContext context = GetDefaultContext(p)) {
                if (customLogger != null)
                {
                    context.Logger = customLogger;
                }

#if !FEATURE_ILLINK
                I18nAssemblies assemblies = I18nAssemblies.All;
#endif
                var    custom_steps           = new List <string> ();
                var    excluded_features      = new HashSet <string> (StringComparer.Ordinal);
                var    disabled_optimizations = new HashSet <string> (StringComparer.Ordinal);
                var    enabled_optimizations  = new HashSet <string> (StringComparer.Ordinal);
                bool   dumpDependencies       = false;
                string dependenciesFileName   = null;
                bool   ignoreDescriptors      = false;
                bool   removeCAS          = true;
                bool   new_mvid_used      = false;
                bool   deterministic_used = false;

                bool resolver = false;
                while (arguments.Count > 0)
                {
                    string token = arguments.Dequeue();
                    if (token.Length < 2)
                    {
                        ErrorUnrecognizedOption(token);
                        return(false);
                    }

                    //
                    // Handling of --value like options
                    //
                    if (token [0] == '-' && token [1] == '-')
                    {
                        switch (token)
                        {
                        case "--skip-unresolved":
                            if (!GetBoolParam(token, l => context.IgnoreUnresolved = context.Resolver.IgnoreUnresolved = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--verbose":
                            context.LogMessages = true;
                            continue;

                        case "--dependencies-file":
                            if (!GetStringParam(token, l => dependenciesFileName = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--dump-dependencies":
                            dumpDependencies = true;
                            continue;

                        case "--reduced-tracing":
                            if (!GetBoolParam(token, l => context.EnableReducedTracing = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--used-attrs-only":
                            if (!GetBoolParam(token, l => context.KeepUsedAttributeTypesOnly = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--strip-security":
                            if (!GetBoolParam(token, l => removeCAS = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--strip-resources":
                            if (!GetBoolParam(token, l => context.StripResources = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--substitutions":
                            if (arguments.Count < 1)
                            {
                                ErrorMissingArgument(token);
                                return(false);
                            }

                            if (!GetStringParam(token, l => context.AddSubstitutionFile(l)))
                            {
                                return(false);
                            }

                            continue;

                        case "--exclude-feature":
                            if (arguments.Count < 1)
                            {
                                ErrorMissingArgument(token);
                                return(false);
                            }

                            if (!GetStringParam(token, l => {
                                foreach (var feature in l.Split(','))
                                {
                                    if (!excluded_features.Contains(feature))
                                    {
                                        excluded_features.Add(feature);
                                    }
                                }
                            }))
                            {
                                return(false);
                            }

                            continue;

                        case "--explicit-reflection":
                            if (!GetBoolParam(token, l => context.AddReflectionAnnotations = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--custom-step":
                            if (!GetStringParam(token, l => custom_steps.Add(l)))
                            {
                                return(false);
                            }

                            continue;

                        case "--keep-facades":
                            if (!GetBoolParam(token, l => context.KeepTypeForwarderOnlyAssemblies = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--keep-dep-attributes":
                            if (!GetBoolParam(token, l => context.KeepDependencyAttributes = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--ignore-descriptors":
                            if (!GetBoolParam(token, l => ignoreDescriptors = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--disable-opt":
                            if (!GetStringParam(token, l => {
                                var opt = l.ToLowerInvariant();
                                if (!disabled_optimizations.Contains(opt))
                                {
                                    disabled_optimizations.Add(opt);
                                }
                            }))
                            {
                                return(false);
                            }

                            continue;

                        case "--enable-opt":
                            if (!GetStringParam(token, l => {
                                var opt = l.ToLowerInvariant();
                                if (!enabled_optimizations.Contains(opt))
                                {
                                    enabled_optimizations.Add(opt);
                                }
                            }))
                            {
                                return(false);
                            }

                            continue;

                        case "--new-mvid":
                            //
                            // This is not same as --deterministic which calculates MVID
                            // from stable assembly content. This option creates a new random
                            // mvid or uses mvid of the source assembly.
                            //
                            if (!GetBoolParam(token, l => {
                                if (!l)
                                {
                                    p.RemoveStep(typeof(RegenerateGuidStep));
                                }
                            }))
                            {
                                return(false);
                            }

                            new_mvid_used = true;
                            continue;

                        case "--deterministic":
                            if (!GetBoolParam(token, l => context.DeterministicOutput = l))
                            {
                                return(false);
                            }

                            deterministic_used = true;
                            continue;

                        case "--output-assemblylist":
                            if (!GetStringParam(token, l => context.AssemblyListFile = l))
                            {
                                return(false);
                            }

                            continue;

                        case "--version":
                            Version();
                            return(true);

                        case "--about":
                            About();
                            return(true);
                        }
                    }

                    if (token [0] == '-' || token [1] == '/')
                    {
                        switch (token.Substring(1))
                        {
                        case "d":
                            if (!GetStringParam(token, l => {
                                DirectoryInfo info = new DirectoryInfo(l);
                                context.Resolver.AddSearchDirectory(info.FullName);
                            }))
                            {
                                return(false);
                            }

                            continue;

                        case "o":
                        case "out":
                            if (!GetStringParam(token, l => context.OutputDirectory = l))
                            {
                                return(false);
                            }

                            continue;

                        case "c":
                            if (!GetStringParam(token, l => context.CoreAction = ParseAssemblyAction(l)))
                            {
                                return(false);
                            }

                            continue;

                        case "u":
                            if (!GetStringParam(token, l => context.UserAction = ParseAssemblyAction(l)))
                            {
                                return(false);
                            }

                            continue;

                        case "p":
                            if (arguments.Count < 2)
                            {
                                ErrorMissingArgument(token);
                                return(false);
                            }

                            AssemblyAction action = ParseAssemblyAction(arguments.Dequeue());
                            context.Actions [arguments.Dequeue()] = action;
                            continue;

                        case "t":
                            context.KeepTypeForwarderOnlyAssemblies = true;
                            continue;

                        case "x":
                            if (!GetStringParam(token, l => {
                                foreach (string file in GetFiles(l))
                                {
                                    p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file)));
                                }
                            }))
                            {
                                return(false);
                            }

                            resolver = true;
                            continue;

                        case "r":
                        case "a":
                            if (!GetStringParam(token, l => {
                                var rootVisibility = (token [1] == 'r')
                                                                        ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                                        : ResolveFromAssemblyStep.RootVisibility.Any;
                                foreach (string file in GetFiles(l))
                                {
                                    p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
                                }
                            }))
                            {
                                return(false);
                            }

                            resolver = true;
                            continue;

#if !FEATURE_ILLINK
                        case "i":
                            if (!GetStringParam(token, l => {
                                foreach (string file in GetFiles(l))
                                {
                                    p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
                                }
                            }))
                            {
                                return(false);
                            }

                            resolver = true;
                            continue;

                        case "l":
                            if (!GetStringParam(token, l => assemblies = ParseI18n(l)))
                            {
                                return(false);
                            }

                            continue;
#endif
                        case "m":
                            if (arguments.Count < 2)
                            {
                                ErrorMissingArgument(token);
                                return(false);
                            }

                            context.SetParameter(arguments.Dequeue(), arguments.Dequeue());
                            continue;

                        case "b":
                            if (!GetBoolParam(token, l => context.LinkSymbols = l))
                            {
                                return(false);
                            }

                            continue;

                        case "g":
                            if (!GetBoolParam(token, l => context.DeterministicOutput = !l))
                            {
                                return(false);
                            }

                            continue;

                        case "z":
                            if (!GetBoolParam(token, l => ignoreDescriptors = !l))
                            {
                                return(false);
                            }

                            continue;

                        case "v":
                            if (!GetBoolParam(token, l => context.KeepMembersForDebugger = l))
                            {
                                return(false);
                            }

                            continue;

                        case "?":
                        case "help":
                            Usage();
                            return(true);

                        case "reference":
                            if (!GetStringParam(token, l => context.Resolver.AddReferenceAssembly(l)))
                            {
                                return(false);
                            }

                            continue;
                        }
                    }

                    ErrorUnrecognizedOption(token);
                    return(false);
                }

                if (!resolver)
                {
                    Console.WriteLine($"No files to link were specified. Use one of '{resolvers}' options");
                    return(false);
                }

                if (new_mvid_used && deterministic_used)
                {
                    Console.WriteLine($"Options '--new-mvid' and '--deterministic' cannot be used at the same time");
                    return(false);
                }

                if (dumpDependencies)
                {
                    context.Tracer.AddRecorder(new XmlDependencyRecorder(context, dependenciesFileName));
                }

                if (disabled_optimizations.Count > 0)
                {
                    foreach (var item in disabled_optimizations)
                    {
                        switch (item)
                        {
                        case "beforefieldinit":
                            context.DisabledOptimizations |= CodeOptimizations.BeforeFieldInit;
                            break;

                        case "overrideremoval":
                            context.DisabledOptimizations |= CodeOptimizations.OverrideRemoval;
                            break;

                        case "unreachablebodies":
                            context.DisabledOptimizations |= CodeOptimizations.UnreachableBodies;
                            break;

                        case "unusedinterfaces":
                            context.DisabledOptimizations |= CodeOptimizations.UnusedInterfaces;
                            break;

                        case "ipconstprop":
                            context.DisabledOptimizations |= CodeOptimizations.IPConstantPropagation;
                            break;
                        }
                    }
                }

                if (enabled_optimizations.Count > 0)
                {
                    foreach (var item in enabled_optimizations)
                    {
                        switch (item)
                        {
                        case "unreachablebodies":
                            context.DisabledOptimizations &= ~CodeOptimizations.UnreachableBodies;
                            break;

                        case "clearinitlocals":
                            context.DisabledOptimizations &= ~CodeOptimizations.ClearInitLocals;
                            break;

                        case "ipconstprop":
                            context.DisabledOptimizations &= ~CodeOptimizations.IPConstantPropagation;
                            break;
                        }
                    }
                }

                //
                // Modify the default pipeline
                //
                if (ignoreDescriptors)
                {
                    p.RemoveStep(typeof(BlacklistStep));
                }

                if (context.DeterministicOutput)
                {
                    p.RemoveStep(typeof(RegenerateGuidStep));
                }

                if (context.AddReflectionAnnotations)
                {
                    p.AddStepAfter(typeof(MarkStep), new ReflectionBlockedStep());
                }

#if !FEATURE_ILLINK
                p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

                if (assemblies != I18nAssemblies.None)
                {
                    p.AddStepAfter(typeof(PreserveDependencyLookupStep), new PreserveCalendarsStep(assemblies));
                }
#endif

                if (_needAddBypassNGenStep)
                {
                    p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep());
                }

                p.AddStepBefore(typeof(MarkStep), new BodySubstituterStep());

                if (removeCAS)
                {
                    p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep());
                }

                if (excluded_features.Count > 0)
                {
                    p.AddStepBefore(typeof(MarkStep), new RemoveFeaturesStep()
                    {
                        FeatureCOM           = excluded_features.Contains("com"),
                        FeatureETW           = excluded_features.Contains("etw"),
                        FeatureSRE           = excluded_features.Contains("sre"),
                        FeatureGlobalization = excluded_features.Contains("globalization")
                    });

                    var excluded = new string [excluded_features.Count];
                    excluded_features.CopyTo(excluded);
                    context.ExcludedFeatures = excluded;
                }

                p.AddStepBefore(typeof(MarkStep), new RemoveUnreachableBlocksStep());

                if (context.IsOptimizationEnabled(CodeOptimizations.ClearInitLocals))
                {
                    p.AddStepBefore(typeof(OutputStep), new ClearInitLocalsStep());
                }


                //
                // Pipeline setup with all steps enabled
                //
                // LoadReferencesStep
                // BlacklistStep [optional]
                // PreserveDependencyLookupStep
                // TypeMapStep
                // BodySubstituterStep [optional]
                // RemoveSecurityStep [optional]
                // RemoveFeaturesStep [optional]
                // RemoveUnreachableBlocksStep [optional]
                // MarkStep
                // ReflectionBlockedStep [optional]
                // SweepStep
                // AddBypassNGenStep [optional]
                // CodeRewriterStep
                // CleanStep
                // RegenerateGuidStep [optional]
                // ClearInitLocalsStep [optional]
                // OutputStep
                //

                foreach (string custom_step in custom_steps)
                {
                    if (!AddCustomStep(p, custom_step))
                    {
                        return(false);
                    }
                }

                PreProcessPipeline(p);

                try {
                    p.Process(context);
                } finally {
                    context.Tracer.Finish();
                }

                return(true);
            }
        }
Example #26
0
        public void Run(ILogger customLogger = null)
        {
            Pipeline p = GetStandardPipeline();

            using (LinkContext context = GetDefaultContext(p)) {
                if (customLogger != null)
                {
                    context.Logger = customLogger;
                }

                I18nAssemblies assemblies       = I18nAssemblies.All;
                var            custom_steps     = new List <string> ();
                bool           dumpDependencies = false;

                bool resolver = false;
                while (HaveMoreTokens())
                {
                    string token = GetParam();
                    if (token.Length < 2)
                    {
                        Usage("Option is too short");
                    }

                    if (!(token [0] == '-' || token [1] == '/'))
                    {
                        Usage("Expecting an option, got instead: " + token);
                    }

                    if (token [0] == '-' && token [1] == '-')
                    {
                        if (token.Length < 3)
                        {
                            Usage("Option is too short");
                        }

                        if (token == "--skip-unresolved")
                        {
                            bool ignoreUnresolved = bool.Parse(GetParam());
                            context.IgnoreUnresolved          = ignoreUnresolved;
                            context.Resolver.IgnoreUnresolved = ignoreUnresolved;
                            continue;
                        }

                        if (token == "--verbose")
                        {
                            context.LogMessages = true;
                            continue;
                        }

                        if (token == "--dependencies-file")
                        {
                            context.Tracer.DependenciesFileName = GetParam();
                            continue;
                        }

                        if (token == "--dump-dependencies")
                        {
                            dumpDependencies = true;
                            continue;
                        }

                        if (token == "--reduced-tracing")
                        {
                            context.EnableReducedTracing = bool.Parse(GetParam());
                            continue;
                        }

                        if (token == "--used-attrs-only")
                        {
                            context.KeepUsedAttributeTypesOnly = bool.Parse(GetParam());
                            continue;
                        }

                        if (token == "--strip-security")
                        {
                            if (bool.Parse(GetParam()))
                            {
                                p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep());
                            }
                            continue;
                        }

                        if (token == "--strip-resources")
                        {
                            context.StripResources = bool.Parse(GetParam());
                            continue;
                        }

                        switch (token [2])
                        {
                        case 'v':
                            Version();
                            break;

                        case 'a':
                            About();
                            break;

                        default:
                            Usage(null);
                            break;
                        }
                    }

                    switch (token [1])
                    {
                    case 'd': {
                        DirectoryInfo info = new DirectoryInfo(GetParam());
                        context.Resolver.AddSearchDirectory(info.FullName);
                        break;
                    }

                    case 'o':
                        context.OutputDirectory = GetParam();
                        break;

                    case 'c':
                        context.CoreAction = ParseAssemblyAction(GetParam());
                        break;

                    case 'u':
                        context.UserAction = ParseAssemblyAction(GetParam());
                        break;

                    case 'p':
                        AssemblyAction action = ParseAssemblyAction(GetParam());
                        context.Actions [GetParam()] = action;
                        break;

                    case 's':
                        custom_steps.Add(GetParam());
                        break;

                    case 't':
                        context.KeepTypeForwarderOnlyAssemblies = true;
                        break;

                    case 'x':
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromXmlStep(new XPathDocument(file)));
                        }
                        resolver = true;
                        break;

                    case 'r':
                    case 'a':
                        var rootVisibility = (token [1] == 'r')
                                                        ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                        : ResolveFromAssemblyStep.RootVisibility.Any;
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
                        }
                        resolver = true;
                        break;

                    case 'i':
                        foreach (string file in GetFiles(GetParam()))
                        {
                            p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
                        }
                        resolver = true;
                        break;

                    case 'l':
                        assemblies = ParseI18n(GetParam());
                        break;

                    case 'm':
                        context.SetParameter(GetParam(), GetParam());
                        break;

                    case 'b':
                        context.LinkSymbols = bool.Parse(GetParam());
                        break;

                    case 'g':
                        if (!bool.Parse(GetParam()))
                        {
                            p.RemoveStep(typeof(RegenerateGuidStep));
                        }
                        break;

                    case 'z':
                        if (!bool.Parse(GetParam()))
                        {
                            p.RemoveStep(typeof(BlacklistStep));
                        }
                        break;

                    case 'v':
                        context.KeepMembersForDebuggerAttributes = bool.Parse(GetParam());
                        break;

                    default:
                        Usage("Unknown option: `" + token [1] + "'");
                        break;
                    }
                }

                if (!resolver)
                {
                    Usage("No resolver was created (use -x, -a or -i)");
                }

                if (dumpDependencies)
                {
                    context.Tracer.Start();
                }

                foreach (string custom_step in custom_steps)
                {
                    AddCustomStep(p, custom_step);
                }

                p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

                if (_needAddBypassNGenStep)
                {
                    p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep());
                }

                p.Process(context);
            }
        }
Example #27
0
 public static void SetAction(AssemblyDefinition assembly, AssemblyAction action)
 {
     SetAction(AsProvider(assembly), action);
 }
Example #28
0
 public static bool IsFullyPreservedAction(AssemblyAction action)
 {
     return(action == AssemblyAction.Copy || action == AssemblyAction.Save);
 }
 public override void ProcessAssembly(AssemblyDefinition assembly)
 {
     Current = assembly;
     Action  = Annotations.GetAction(assembly);
     ProcessSecurityProvider(assembly);
 }
Example #30
0
 public void SetAction(AssemblyDefinition assembly, AssemblyAction action)
 {
     throw null;
 }
Example #31
0
		public void SetAction (AssemblyDefinition assembly, AssemblyAction action)
		{
			assembly_actions [assembly] = action;
		}
Example #32
0
 public static void SetAction(AssemblyDefinition assembly, AssemblyAction action)
 {
     SetAction (AsProvider (assembly), action);
 }
        static void SetAction(LinkContext context, AssemblyDefinition assembly, AssemblyAction action)
        {
            TryReadSymbols(context, assembly);

            context.Annotations.SetAction(assembly, action);
        }
Example #34
0
        // Perform setup of the LinkContext and parse the arguments.
        // Return values:
        // 0 => successfully set up context with all arguments
        // 1 => argument processing stopped early without errors
        // -1 => error setting up context
        protected int SetupContext(ILogger customLogger = null)
        {
            Pipeline p = GetStandardPipeline();

            context = GetDefaultContext(p);

            if (customLogger != null)
            {
                context.Logger = customLogger;
            }

#if !FEATURE_ILLINK
            I18nAssemblies assemblies              = I18nAssemblies.All;
            var            excluded_features       = new HashSet <string> (StringComparer.Ordinal);
            var            resolve_from_xapi_steps = new Stack <string> ();
#endif
            var    resolve_from_assembly_steps = new Stack <(string, ResolveFromAssemblyStep.RootVisibility)> ();
            var    resolve_from_xml_steps      = new Stack <string> ();
            var    body_substituter_steps      = new Stack <string> ();
            var    custom_steps         = new Stack <string> ();
            var    set_optimizations    = new List <(CodeOptimizations, string, bool)> ();
            bool   dumpDependencies     = false;
            string dependenciesFileName = null;
            bool   removeCAS            = true;
            bool   new_mvid_used        = false;
            bool   deterministic_used   = false;

            bool resolver = false;
            while (arguments.Count > 0)
            {
                string token = arguments.Dequeue();
                if (token.Length < 2)
                {
                    ErrorUnrecognizedOption(token);
                    return(-1);
                }

                //
                // Handling of --value like options
                //
                if (token[0] == '-' && token[1] == '-')
                {
                    switch (token)
                    {
                    case "--skip-unresolved":
                        if (!GetBoolParam(token, l => context.IgnoreUnresolved = context.Resolver.IgnoreUnresolved = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--verbose":
                        context.LogMessages = true;
                        continue;

                    case "--dependencies-file":
                        if (!GetStringParam(token, l => dependenciesFileName = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--dump-dependencies":
                        dumpDependencies = true;
                        continue;

                    case "--reduced-tracing":
                        if (!GetBoolParam(token, l => context.EnableReducedTracing = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--used-attrs-only":
                        if (!GetBoolParam(token, l => context.KeepUsedAttributeTypesOnly = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--strip-security":
                        if (!GetBoolParam(token, l => removeCAS = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--strip-descriptors":
                        if (!GetBoolParam(token, l => context.StripDescriptors = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--strip-substitutions":
                        if (!GetBoolParam(token, l => context.StripSubstitutions = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--substitutions":
                        if (arguments.Count < 1)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        if (!GetStringParam(token, l => body_substituter_steps.Push(l)))
                        {
                            return(-1);
                        }

                        continue;

#if !FEATURE_ILLINK
                    case "--exclude-feature":
                        if (arguments.Count < 1)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        if (!GetStringParam(token, l => {
                            foreach (var feature in l.Split(','))
                            {
                                if (!excluded_features.Contains(feature))
                                {
                                    excluded_features.Add(feature);
                                }
                            }
                        }))
                        {
                            return(-1);
                        }

                        continue;
#endif
                    case "--explicit-reflection":
                        if (!GetBoolParam(token, l => context.AddReflectionAnnotations = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--custom-step":
                        if (!GetStringParam(token, l => custom_steps.Push(l)))
                        {
                            return(-1);
                        }

                        continue;

                    case "--custom-data":
                        if (arguments.Count < 1)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        var      arg    = arguments.Dequeue();
                        string[] values = arg.Split('=');
                        if (values?.Length != 2)
                        {
                            Console.WriteLine($"Value used with '--custom-data' has to be in the KEY=VALUE format");
                            return(-1);
                        }

                        context.SetCustomData(values[0], values[1]);
                        continue;

                    case "--keep-facades":
                        if (!GetBoolParam(token, l => context.KeepTypeForwarderOnlyAssemblies = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--keep-dep-attributes":
                        if (!GetBoolParam(token, l => context.KeepDependencyAttributes = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--ignore-descriptors":
                        if (!GetBoolParam(token, l => context.IgnoreDescriptors = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--ignore-substitutions":
                        if (!GetBoolParam(token, l => context.IgnoreSubstitutions = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--disable-opt": {
                        string optName = null;
                        if (!GetStringParam(token, l => optName = l))
                        {
                            return(-1);
                        }

                        if (!GetOptimizationName(optName, out var opt))
                        {
                            return(-1);
                        }

                        string assemblyName = GetNextStringValue();
                        set_optimizations.Add((opt, assemblyName, false));

                        continue;
                    }

                    case "--enable-opt": {
                        string optName = null;
                        if (!GetStringParam(token, l => optName = l))
                        {
                            return(-1);
                        }

                        if (!GetOptimizationName(optName, out var opt))
                        {
                            return(-1);
                        }

                        string assemblyName = GetNextStringValue();
                        set_optimizations.Add((opt, assemblyName, true));

                        continue;
                    }

                    case "--feature": {
                        string featureName = null;
                        if (!GetStringParam(token, l => featureName = l))
                        {
                            return(-1);
                        }

                        if (!GetBoolParam(token, value => {
                                context.SetFeatureValue(featureName, value);
                            }))
                        {
                            return(-1);
                        }

                        continue;
                    }

                    case "--new-mvid":
                        //
                        // This is not same as --deterministic which calculates MVID
                        // from stable assembly content. This option creates a new random
                        // mvid or uses mvid of the source assembly.
                        //
                        if (!GetBoolParam(token, l => {
                            if (!l)
                            {
                                p.RemoveStep(typeof(RegenerateGuidStep));
                            }
                        }))
                        {
                            return(-1);
                        }

                        new_mvid_used = true;
                        continue;

                    case "--deterministic":
                        if (!GetBoolParam(token, l => context.DeterministicOutput = l))
                        {
                            return(-1);
                        }

                        deterministic_used = true;
                        continue;

                    case "--output-assemblylist":
                        if (!GetStringParam(token, l => context.AssemblyListFile = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--output-pinvokes":
                        if (!GetStringParam(token, l => context.PInvokesListFile = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "--attribute-defs":
                        if (arguments.Count < 1)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        if (!GetStringParam(token, l => context.AddAttributeDefinitionFile(l)))
                        {
                            return(-1);
                        }

                        continue;

                    case "--version":
                        Version();
                        return(1);

                    case "--about":
                        About();
                        return(1);
                    }
                }

                if (token[0] == '-' || token[1] == '/')
                {
                    switch (token.Substring(1))
                    {
                    case "d":
                        if (!GetStringParam(token, l => {
                            DirectoryInfo info = new DirectoryInfo(l);
                            context.Resolver.AddSearchDirectory(info.FullName);
                        }))
                        {
                            return(-1);
                        }

                        continue;

                    case "o":
                    case "out":
                        if (!GetStringParam(token, l => context.OutputDirectory = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "c":
                        if (!GetStringParam(token, l => context.CoreAction = ParseAssemblyAction(l)))
                        {
                            return(-1);
                        }

                        continue;

                    case "u":
                        if (!GetStringParam(token, l => context.UserAction = ParseAssemblyAction(l)))
                        {
                            return(-1);
                        }

                        continue;

                    case "p":
                        if (arguments.Count < 2)
                        {
                            ErrorMissingArgument(token);
                            return(-1);
                        }

                        AssemblyAction action = ParseAssemblyAction(arguments.Dequeue());
                        context.Actions[arguments.Dequeue()] = action;
                        continue;

                    case "t":
                        context.KeepTypeForwarderOnlyAssemblies = true;
                        continue;

                    case "x":
                        if (!GetStringParam(token, l => {
                            foreach (string file in GetFiles(l))
                            {
                                resolve_from_xml_steps.Push(file);
                            }
                        }))
                        {
                            return(-1);
                        }

                        resolver = true;
                        continue;

                    case "r":
                    case "a":
                        if (!GetStringParam(token, l => {
                            var rootVisibility = (token[1] == 'r')
                                                                ? ResolveFromAssemblyStep.RootVisibility.PublicAndFamily
                                                                : ResolveFromAssemblyStep.RootVisibility.Any;
                            foreach (string file in GetFiles(l))
                            {
                                resolve_from_assembly_steps.Push((file, rootVisibility));
                            }
                        }))
                        {
                            return(-1);
                        }

                        resolver = true;
                        continue;

#if !FEATURE_ILLINK
                    case "i":
                        if (!GetStringParam(token, l => {
                            foreach (string file in GetFiles(l))
                            {
                                resolve_from_xapi_steps.Push(file);
                            }
                        }))
                        {
                            return(-1);
                        }

                        resolver = true;
                        continue;

                    case "l":
                        if (!GetStringParam(token, l => assemblies = ParseI18n(l)))
                        {
                            return(-1);
                        }

                        continue;
#endif
                    case "b":
                        if (!GetBoolParam(token, l => context.LinkSymbols = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "g":
                        if (!GetBoolParam(token, l => context.DeterministicOutput = !l))
                        {
                            return(-1);
                        }

                        continue;

                    case "z":
                        if (!GetBoolParam(token, l => context.IgnoreDescriptors = !l))
                        {
                            return(-1);
                        }

                        continue;

                    case "v":
                        if (!GetBoolParam(token, l => context.KeepMembersForDebugger = l))
                        {
                            return(-1);
                        }

                        continue;

                    case "?":
                    case "help":
                        Usage();
                        return(1);

                    case "reference":
                        if (!GetStringParam(token, l => context.Resolver.AddReferenceAssembly(l)))
                        {
                            return(-1);
                        }

                        continue;
                    }
                }

                ErrorUnrecognizedOption(token);
                return(-1);
            }

            if (!resolver)
            {
                Console.WriteLine($"No files to link were specified. Use one of '{resolvers}' options");
                return(-1);
            }

            if (new_mvid_used && deterministic_used)
            {
                Console.WriteLine($"Options '--new-mvid' and '--deterministic' cannot be used at the same time");
                return(-1);
            }

            if (dumpDependencies)
            {
                AddXmlDependencyRecorder(context, dependenciesFileName);
            }

            if (set_optimizations.Count > 0)
            {
                foreach (var(opt, assemblyName, enable) in set_optimizations)
                {
                    if (enable)
                    {
                        context.Optimizations.Enable(opt, assemblyName);
                    }
                    else
                    {
                        context.Optimizations.Disable(opt, assemblyName);
                    }
                }
            }

            //
            // Modify the default pipeline
            //

#if !FEATURE_ILLINK
            foreach (var file in resolve_from_xapi_steps)
            {
                p.PrependStep(new ResolveFromXApiStep(new XPathDocument(file)));
            }
#endif

            foreach (var file in resolve_from_xml_steps)
            {
                AddResolveFromXmlStep(p, file);
            }

            foreach (var(file, rootVisibility) in resolve_from_assembly_steps)
            {
                p.PrependStep(new ResolveFromAssemblyStep(file, rootVisibility));
            }

            foreach (var file in body_substituter_steps)
            {
                AddBodySubstituterStep(p, file);
            }

            if (context.DeterministicOutput)
            {
                p.RemoveStep(typeof(RegenerateGuidStep));
            }

            if (context.AddReflectionAnnotations)
            {
                p.AddStepAfter(typeof(MarkStep), new ReflectionBlockedStep());
            }

#if !FEATURE_ILLINK
            p.AddStepAfter(typeof(LoadReferencesStep), new LoadI18nAssemblies(assemblies));

            if (assemblies != I18nAssemblies.None)
            {
                p.AddStepAfter(typeof(PreserveDependencyLookupStep), new PreserveCalendarsStep(assemblies));
            }
#endif

            if (_needAddBypassNGenStep)
            {
                p.AddStepAfter(typeof(SweepStep), new AddBypassNGenStep());
            }

            if (removeCAS)
            {
                p.AddStepBefore(typeof(MarkStep), new RemoveSecurityStep());
            }

#if !FEATURE_ILLINK
            if (excluded_features.Count > 0)
            {
                p.AddStepBefore(typeof(MarkStep), new RemoveFeaturesStep()
                {
                    FeatureCOM           = excluded_features.Contains("com"),
                    FeatureETW           = excluded_features.Contains("etw"),
                    FeatureSRE           = excluded_features.Contains("sre"),
                    FeatureGlobalization = excluded_features.Contains("globalization")
                });

                var excluded = new string[excluded_features.Count];
                excluded_features.CopyTo(excluded);
                context.ExcludedFeatures = excluded;
            }
#endif

            p.AddStepBefore(typeof(MarkStep), new RemoveUnreachableBlocksStep());
            p.AddStepBefore(typeof(OutputStep), new ClearInitLocalsStep());
            p.AddStepBefore(typeof(OutputStep), new SealerStep());

            //
            // Pipeline setup with all steps enabled
            //
            // ResolveFromAssemblyStep [optional, possibly many]
            // ResolveFromXmlStep [optional, possibly many]
            // [mono only] ResolveFromXApiStep [optional, possibly many]
            // LoadReferencesStep
            // [mono only] LoadI18nAssemblies
            // BlacklistStep
            //   dynamically adds steps:
            //     ResolveFromXmlStep [optional, possibly many]
            //     BodySubstituterStep [optional, possibly many]
            // PreserveDependencyLookupStep
            // [mono only] PreselveCalendarsStep [optional]
            // TypeMapStep
            // BodySubstituterStep [optional]
            // RemoveSecurityStep [optional]
            // [mono only] RemoveFeaturesStep [optional]
            // RemoveUnreachableBlocksStep [optional]
            // MarkStep
            // ReflectionBlockedStep [optional]
            // SweepStep
            // AddBypassNGenStep [optional]
            // CodeRewriterStep
            // CleanStep
            // RegenerateGuidStep [optional]
            // ClearInitLocalsStep
            // SealerStep
            // OutputStep
            //

            foreach (string custom_step in custom_steps)
            {
                if (!AddCustomStep(p, custom_step))
                {
                    return(-1);
                }
            }

            return(0);
        }
Example #35
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;
            }
        }