private void CreateAssemblyManager(IEnumerable <ModuleData> compilationDependencies, ModuleData mainModule)
        {
            var allModules = compilationDependencies;

            if (_additionalDependencies != null)
            {
                allModules = allModules.Concat(_additionalDependencies);
            }

            // We need to add the main module so that it gets checked against already loaded assembly names.
            // If an assembly is loaded directly via PEVerify(image) another assembly of the same full name
            // can't be loaded as a dependency (via Assembly.ReflectionOnlyLoad) in the same domain.
            if (mainModule != null)
            {
                allModules = allModules.Concat(new[] { mainModule });
            }

            allModules = allModules.ToArray();

            string conflict = DetectNameCollision(allModules);

            if (conflict != null && !CLRHelpers.IsRunningOnMono())
            {
                Type     appDomainProxyType = typeof(RuntimeAssemblyManager);
                Assembly thisAssembly       = appDomainProxyType.Assembly;

                AppDomain appDomain = null;
                RuntimeAssemblyManager manager;
                try
                {
                    appDomain = AppDomain.CreateDomain("HostedRuntimeEnvironment", null, AppDomain.CurrentDomain.BaseDirectory, null, false);
                    manager   = (RuntimeAssemblyManager)appDomain.CreateInstanceAndUnwrap(thisAssembly.FullName, appDomainProxyType.FullName);
                }
                catch
                {
                    if (appDomain != null)
                    {
                        AppDomain.Unload(appDomain);
                    }
                    throw;
                }

                _domain          = appDomain;
                _assemblyManager = manager;
            }
            else
            {
                _assemblyManager = new RuntimeAssemblyManager();
            }

            _assemblyManager.AddModuleData(allModules);

            if (mainModule != null)
            {
                _assemblyManager.AddMainModuleMvid(mainModule.Mvid);
            }
        }
        private void AssemblyLoad(object sender, AssemblyLoadEventArgs args)
        {
            var assembly = args.LoadedAssembly;

            // ModuleResolve needs to be hooked up for the main assembly once its loaded.
            // We won't get an AssemblyResolve event for the main assembly so we need to do it here.
            if (_mainMvids.Contains(assembly.ManifestModule.ModuleVersionId) && _loadedAssemblies.Add(assembly))
            {
                if (!CLRHelpers.IsRunningOnMono())
                {
                    assembly.ModuleResolve += ModuleResolve;
                }
            }
        }
        internal static bool EmitCompilation(
            Compilation compilation,
            IEnumerable <ResourceDescription> manifestResources,
            List <ModuleData> dependencies,
            DiagnosticBag diagnostics,
            CompilationTestData testData,
            out ImmutableArray <byte> assembly,
            out ImmutableArray <byte> pdb
            )
        {
            assembly = default(ImmutableArray <byte>);
            pdb      = default(ImmutableArray <byte>);

            EmitReferences(compilation, dependencies, diagnostics);

            using (var executableStream = new MemoryStream())
            {
                MemoryStream pdbStream = CLRHelpers.IsRunningOnMono()
                    ? null
                    : new MemoryStream();

                EmitResult result;
                try
                {
                    result = compilation.Emit(
                        executableStream,
                        pdbStream: pdbStream,
                        xmlDocumentationStream: null,
                        win32Resources: null,
                        manifestResources: manifestResources,
                        options: EmitOptions.Default,
                        testData: testData,
                        getHostDiagnostics: null,
                        cancellationToken: default(CancellationToken));
                }
                finally
                {
                    if (pdbStream != null)
                    {
                        pdb = pdbStream.ToImmutable();
                        pdbStream.Dispose();
                    }
                }

                diagnostics.AddRange(result.Diagnostics);
                assembly = executableStream.ToImmutable();

                return(result.Success);
            }
        }
        public string[] PeVerifyModules(string[] modulesToVerify, bool throwOnError = true)
        {
            // For Windows RT (ARM) THE CLRHelper.Peverify appears to not work and will exclude this
            // for ARM testing at present.
            StringBuilder errors    = new StringBuilder();
            List <string> allOutput = new List <string>();

            foreach (var name in modulesToVerify)
            {
                var assemblyData = _fullNameToAssemblyDataMap[name];
                if (assemblyData.Kind != Kind.ModuleData)
                {
                    continue;
                }

                var      module = assemblyData.ModuleData;
                string[] output = CLRHelpers.PeVerify(module.Image);
                if (output.Length > 0)
                {
                    if (modulesToVerify.Length > 1)
                    {
                        errors.AppendLine();
                        errors.AppendLine("<<" + name + ">>");
                        errors.AppendLine();
                    }

                    foreach (var error in output)
                    {
                        errors.AppendLine(error);
                    }
                }

                if (!throwOnError)
                {
                    allOutput.AddRange(output);
                }
            }

            if (throwOnError && errors.Length > 0)
            {
                string dumpDir;
                RuntimeUtilities.DumpAssemblyData(ModuleDatas, out dumpDir);
                throw new PeVerifyException(errors.ToString(), dumpDir);
            }
            return(allOutput.ToArray());
        }
        public string[] PeVerifyModules(string[] modulesToVerify, bool throwOnError = true)
        {
            // For Windows RT (ARM) THE CLRHelper.Peverify appears to not work and will exclude this
            // for ARM testing at present.
            StringBuilder errors    = new StringBuilder();
            List <string> allOutput = new List <string>();

// Disable all PEVerification due to https://github.com/dotnet/roslyn/issues/6190
#if false
            foreach (var name in modulesToVerify)
            {
                var      module = _modules[name];
                string[] output = CLRHelpers.PeVerify(module.Image);
                if (output.Length > 0)
                {
                    if (modulesToVerify.Length > 1)
                    {
                        errors.AppendLine();
                        errors.AppendLine("<<" + name + ">>");
                        errors.AppendLine();
                    }

                    foreach (var error in output)
                    {
                        errors.AppendLine(error);
                    }
                }

                if (!throwOnError)
                {
                    allOutput.AddRange(output);
                }
            }

            if (throwOnError && errors.Length > 0)
            {
                string dumpDir;
                DumpAssemblyData(_modules.Values, out dumpDir);
                throw new PeVerifyException(errors.ToString(), dumpDir);
            }
#endif
            return(allOutput.ToArray());
        }
        internal Assembly GetAssembly(string fullName, bool reflectionOnly)
        {
            ModuleData data;

            if (!_modules.TryGetValue(fullName, out data))
            {
                return(null);
            }

            ConcurrentDictionary <Guid, Assembly> cache = reflectionOnly ? s_domainReflectionOnlyAssemblyCache : s_domainAssemblyCache;

            var assembly = cache.GetOrAdd(data.Mvid, _ => LoadAsAssembly(data.Image, reflectionOnly));

            if (!CLRHelpers.IsRunningOnMono())
            {
                assembly.ModuleResolve += ModuleResolve;
            }

            _loadedAssemblies.Add(assembly);
            return(assembly);
        }
        internal static ImmutableArray <byte> EmitToArray(
            this Compilation compilation,
            EmitOptions options                      = null,
            CompilationTestData testData             = null,
            DiagnosticDescription[] expectedWarnings = null,
            Stream pdbStream = null)
        {
            var stream = new MemoryStream();

            if (pdbStream == null && compilation.Options.OptimizationLevel == OptimizationLevel.Debug)
            {
                if (CLRHelpers.IsRunningOnMono())
                {
                    options = (options ?? EmitOptions.Default).WithDebugInformationFormat(DebugInformationFormat.PortablePdb);
                }

                pdbStream = new MemoryStream();
            }

            var emitResult = compilation.Emit(
                peStream: stream,
                pdbStream: pdbStream,
                xmlDocumentationStream: null,
                win32Resources: null,
                manifestResources: null,
                options: options,
                testData: testData,
                getHostDiagnostics: null,
                cancellationToken: default(CancellationToken));

            Assert.True(emitResult.Success, "Diagnostics:\r\n" + string.Join("\r\n", emitResult.Diagnostics.Select(d => d.ToString())));

            if (expectedWarnings != null)
            {
                emitResult.Diagnostics.Verify(expectedWarnings);
            }

            return(stream.ToImmutable());
        }
        public void Dispose()
        {
            // clean up our handlers, so that they don't accumulate

            AppDomain.CurrentDomain.AssemblyResolve  -= AssemblyResolve;
            AppDomain.CurrentDomain.AssemblyLoad     -= AssemblyLoad;
            CLRHelpers.ReflectionOnlyAssemblyResolve -= ReflectionOnlyAssemblyResolve;

            foreach (var assembly in _loadedAssemblies)
            {
                if (!CLRHelpers.IsRunningOnMono())
                {
                    assembly.ModuleResolve -= ModuleResolve;
                }
            }

            //EDMAURER Some RuntimeAssemblyManagers are created via reflection in an AppDomain of our creation.
            //Sometimes those AppDomains are not released. I don't fully understand how that appdomain roots
            //a RuntimeAssemblyManager, but according to heap dumps, it does. Even though the appdomain is not
            //unloaded, its RuntimeAssemblyManager is explicitly disposed. So make sure that it cleans up this
            //memory hog - the modules dictionary.
            _modules.Clear();
        }
Exemple #9
0
        public static void IlasmTempAssembly(string declarations, bool appendDefaultHeader, bool includePdb, out string assemblyPath, out string pdbPath)
        {
            if (declarations == null)
            {
                throw new ArgumentNullException(nameof(declarations));
            }

            using (var sourceFile = new DisposableFile(extension: ".il"))
            {
                string sourceFileName = Path.GetFileNameWithoutExtension(sourceFile.Path);

                assemblyPath = Path.Combine(
                    TempRoot.Root,
                    Path.ChangeExtension(Path.GetFileName(sourceFile.Path), "dll"));

                string completeIL;
                if (appendDefaultHeader)
                {
                    completeIL = string.Format(
                        @".assembly '{0}' {{}} 

.assembly extern mscorlib 
{{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
  .ver 4:0:0:0
}} 

{1}",
                        sourceFileName,
                        declarations);
                }
                else
                {
                    completeIL = declarations.Replace("<<GeneratedFileName>>", sourceFileName);
                }

                sourceFile.WriteAllText(completeIL);

                var ilasmPath = Path.Combine(
                    Path.GetDirectoryName(typeof(object).Assembly.Location),
                    "ilasm.exe");

                var arguments = string.Format(
                    "\"{0}\" /DLL /OUT=\"{1}\"",
                    sourceFile.Path,
                    assemblyPath);

                if (includePdb && !CLRHelpers.IsRunningOnMono())
                {
                    pdbPath    = Path.ChangeExtension(assemblyPath, "pdb");
                    arguments += string.Format(" /PDB=\"{0}\"", pdbPath);
                }
                else
                {
                    pdbPath = null;
                }

                var program = ilasmPath;
                if (CLRHelpers.IsRunningOnMono())
                {
                    arguments = string.Format("{0} {1}", ilasmPath, arguments);
                    arguments = arguments.Replace("\"", "");
                    arguments = arguments.Replace("=", ":");
                    program   = "mono";
                }

                var result = ProcessLauncher.Run(program, arguments);

                if (result.ContainsErrors)
                {
                    throw new ArgumentException(
                              "The provided IL cannot be compiled." + Environment.NewLine +
                              program + " " + arguments + Environment.NewLine +
                              result,
                              "declarations");
                }
            }
        }