Пример #1
0
        public static IList <string> GetAotArguments(Application app, string filename, Abi abi, string outputDir, string outputFile, string llvmOutputFile, string dataFile)
        {
            string fname                = Path.GetFileName(filename);
            var    args                 = new List <string> ();
            bool   enable_llvm          = (abi & Abi.LLVM) != 0;
            bool   enable_thumb         = (abi & Abi.Thumb) != 0;
            bool   enable_debug         = app.EnableDebug;
            bool   enable_debug_symbols = app.PackageManagedDebugSymbols;
            bool   llvm_only            = app.EnableLLVMOnlyBitCode;
            bool   interp               = app.IsInterpreted(Assembly.GetIdentity(filename));
            bool   interp_full          = !interp && app.UseInterpreter;
            bool   is32bit              = (abi & Abi.Arch32Mask) > 0;
            string arch                 = abi.AsArchString();

            args.Add("--debug");

            if (enable_llvm)
            {
                args.Add("--llvm");
            }

            if (!llvm_only && !interp)
            {
                args.Add("-O=gsharedvt");
            }
            if (app.AotOtherArguments != null)
            {
                args.AddRange(app.AotOtherArguments);
            }
            var aot = new StringBuilder();

            aot.Append("--aot=mtriple=");
            aot.Append(enable_thumb ? arch.Replace("arm", "thumb") : arch);
            aot.Append("-ios,");
            aot.Append("data-outfile=").Append(dataFile).Append(",");
            aot.Append(app.AotArguments);
            if (llvm_only)
            {
                aot.Append("llvmonly,");
            }
            else if (interp)
            {
                if (fname != "mscorlib.dll")
                {
                    throw ErrorHelper.CreateError(99, Errors.MX0099, fname);
                }
                aot.Append("interp,");
            }
            else if (interp_full)
            {
                aot.Append("interp,full,");
            }
            else
            {
                aot.Append("full,");
            }

            var aname          = Path.GetFileNameWithoutExtension(fname);
            var sdk_or_product = Profile.IsSdkAssembly(aname) || Profile.IsProductAssembly(aname);

            if (enable_llvm)
            {
                aot.Append("nodebug,");
            }
            else if (!(enable_debug || enable_debug_symbols))
            {
                aot.Append("nodebug,");
            }
            else if (app.DebugAll || app.DebugAssemblies.Contains(fname) || !sdk_or_product)
            {
                aot.Append("soft-debug,");
            }

            aot.Append("dwarfdebug,");

            /* Needed for #4587 */
            if (enable_debug && !enable_llvm)
            {
                aot.Append("no-direct-calls,");
            }

            if (!app.UseDlsym(filename))
            {
                aot.Append("direct-pinvoke,");
            }

            if (app.EnableMSym)
            {
                var msymdir = Path.Combine(outputDir, "Msym");
                aot.Append($"msym-dir={msymdir},");
            }

            if (enable_llvm)
            {
                aot.Append("llvm-path=").Append(GetFrameworkCurrentDirectory(app)).Append("/LLVM/bin/,");
            }

            aot.Append("outfile=").Append(outputFile);
            if (enable_llvm)
            {
                aot.Append(",llvm-outfile=").Append(llvmOutputFile);
            }
            args.Add(aot.ToString());
            args.Add(filename);
            return(args);
        }
Пример #2
0
        bool IsRequiredSymbol(Symbol symbol, Assembly single_assembly = null, Abi?target_abis = null)
        {
            if (symbol.Ignore)
            {
                return(false);
            }

            // If this symbol is only defined for certain abis, verify if there is an abi match
            if (target_abis.HasValue && symbol.ValidAbis.HasValue && (target_abis.Value & symbol.ValidAbis.Value) == 0)
            {
                return(false);
            }

            // Check if this symbol is used in the assembly we're filtering to
            if (single_assembly != null && !symbol.Members.Any((v) => v.Module.Assembly == single_assembly.AssemblyDefinition))
            {
                return(false);                // nope, this symbol is not used in the assembly we're using as filter.
            }
            // If we're code-sharing, the managed linker might have found symbols
            // that are not in any of the assemblies in the current app.
            // This occurs because the managed linker processes all the
            // assemblies for all the apps together, but when linking natively
            // we're only linking with the assemblies that actually go into the app.
            if (App.Platform != ApplePlatform.MacOSX && App.IsCodeShared && symbol.Assemblies.Count > 0)
            {
                // So if this is a symbol related to any assembly, make sure
                // at least one of those assemblies are in the current app.
                if (!symbol.Assemblies.Any((v) => Assemblies.Contains(v)))
                {
                    return(false);
                }
            }

            switch (symbol.Type)
            {
            case SymbolType.Field:
                return(true);

            case SymbolType.Function:
#if MTOUCH
                // functions are not required if they're used in an assembly which isn't using dlsym, and we're AOT-compiling.
                if (App.IsSimulatorBuild)
                {
                    return(true);
                }
                if (App.Platform == ApplePlatform.MacCatalyst)
                {
                    return(true);
                }
                if (single_assembly != null)
                {
                    return(App.UseDlsym(single_assembly.FileName));
                }

                if (symbol.Members?.Any() == true)
                {
                    foreach (var member in symbol.Members)
                    {
                        if (App.UseDlsym(member.Module.FileName))
                        {
                            // If any assembly uses dlsym to reference this symbol, it's a required symbol that must be preserved,
                            // because otherwise stripping the binary will cause the symbol (but not the function itself) to be removed,
                            // preventing any assembly using dlsym to find it.
                            return(true);
                        }
                    }
                    // None of the members use dlsym (and we have at least one member), then we don't need to preserve the symbol.
                    return(false);
                }
#endif
                return(true);

            case SymbolType.ObjectiveCClass:
                // Objective-C classes are not required when we're using the static registrar and we're not compiling to shared libraries,
                // (because the registrar code is linked into the main app, but not each shared library,
                // so the registrar code won't keep symbols in the shared libraries).
                if (single_assembly != null)
                {
                    return(true);
                }
                return(App.Registrar != RegistrarMode.Static);

            default:
                throw ErrorHelper.CreateError(99, Errors.MX0099, $"invalid symbol type {symbol.Type} for symbol {symbol.Name}");
            }
        }
Пример #3
0
        bool IsRequiredSymbol(Symbol symbol, Assembly single_assembly = null)
        {
            if (symbol.Ignore)
            {
                return(false);
            }

            // Check if this symbol is used in the assembly we're filtering to
            if (single_assembly != null && !symbol.Members.Any((v) => v.Module.Assembly == single_assembly.AssemblyDefinition))
            {
                return(false);                // nope, this symbol is not used in the assembly we're using as filter.
            }
#if MTOUCH
            // If we're code-sharing, the managed linker might have found symbols
            // that are not in any of the assemblies in the current app.
            // This occurs because the managed linker processes all the
            // assemblies for all the apps together, but when linking natively
            // we're only linking with the assemblies that actually go into the app.
            if (App.IsCodeShared && symbol.Assemblies.Count > 0)
            {
                // So if this is a symbol related to any assembly, make sure
                // at least one of those assemblies are in the current app.
                if (!symbol.Assemblies.Any((v) => Assemblies.Contains(v)))
                {
                    return(false);
                }
            }
#endif

            switch (symbol.Type)
            {
            case SymbolType.Field:
                return(true);

            case SymbolType.Function:
#if MTOUCH
                // functions are not required if they're used in an assembly which isn't using dlsym, and we're AOT-compiling.
                if (App.IsSimulatorBuild)
                {
                    return(true);
                }
                if (single_assembly != null)
                {
                    return(App.UseDlsym(single_assembly.FileName));
                }

                if (symbol.Members != null)
                {
                    foreach (var member in symbol.Members)
                    {
                        if (!App.UseDlsym(member.Module.FileName))
                        {
                            return(false);
                        }
                    }
                }
#endif
                return(true);

            case SymbolType.ObjectiveCClass:
                // Objective-C classes are not required when we're using the static registrar and we're not compiling to shared libraries,
                // (because the registrar code is linked into the main app, but not each shared library,
                // so the registrar code won't keep symbols in the shared libraries).
                if (single_assembly != null)
                {
                    return(true);
                }
                return(App.Registrar != RegistrarMode.Static);

            default:
                throw ErrorHelper.CreateError(99, $"Internal error: invalid symbol type {symbol.Type} for symbol {symbol.Name}. Please file a bug report with a test case (https://bugzilla.xamarin.com).");
            }
        }