internal static ImmutableArray <MetadataBlock> GetMetadataBlocks(GetMetadataBytesPtrFunction getMetaDataBytesPtrFunction, ImmutableArray <AssemblyIdentity> missingAssemblyIdentities) { ArrayBuilder <MetadataBlock> builder = null; foreach (AssemblyIdentity missingAssemblyIdentity in missingAssemblyIdentities) { MetadataBlock block; try { uint size; IntPtr ptr; ptr = getMetaDataBytesPtrFunction(missingAssemblyIdentity, out size); Debug.Assert(size > 0); block = GetMetadataBlock(ptr, size); } catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e, missingAssemblyIdentity.GetDisplayName())) { continue; } if (builder == null) { builder = ArrayBuilder <MetadataBlock> .GetInstance(); } builder.Add(block); } return(builder == null ? ImmutableArray <MetadataBlock> .Empty : builder.ToImmutableAndFree()); }
internal static ImmutableArray <AssemblyReaders> MakeAssemblyReaders(this DkmClrInstructionAddress instructionAddress) { var builder = ArrayBuilder <AssemblyReaders> .GetInstance(); foreach (DkmClrModuleInstance module in instructionAddress.RuntimeInstance.GetModulesInAppDomain(instructionAddress.ModuleInstance.AppDomain)) { var symReader = module.GetSymReader(); if (symReader == null) { continue; } MetadataReader reader; unsafe { try { uint size; IntPtr ptr; ptr = module.GetMetaDataBytesPtr(out size); Debug.Assert(size > 0); reader = new MetadataReader((byte *)ptr, (int)size); } catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e, module.FullName)) { continue; } } builder.Add(new AssemblyReaders(reader, symReader)); } return(builder.ToImmutableAndFree()); }
internal unsafe static ImmutableArray <MetadataBlock> GetMetadataBlocks(this DkmClrRuntimeInstance runtime, DkmClrAppDomain appDomain) { var builder = ArrayBuilder <MetadataBlock> .GetInstance(); IntPtr ptr; uint size; foreach (DkmClrModuleInstance module in runtime.GetModulesInAppDomain(appDomain)) { MetadataBlock block; try { ptr = module.GetMetaDataBytesPtr(out size); Debug.Assert(size > 0); block = GetMetadataBlock(ptr, size); } catch (NotImplementedException e) when(module is DkmClrNcModuleInstance) { // DkmClrNcModuleInstance.GetMetaDataBytesPtr not implemented in Dev14. throw new NotImplementedMetadataException(e); } catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e, module.FullName)) { continue; } Debug.Assert(block.ModuleVersionId == module.Mvid); builder.Add(block); } // Include "intrinsic method" assembly. ptr = runtime.GetIntrinsicAssemblyMetaDataBytesPtr(out size); builder.Add(GetMetadataBlock(ptr, size)); return(builder.ToImmutableAndFree()); }
/// <summary> /// Attempt to construct a <see cref="MetadataReader"/> instance for this module. /// </summary> /// <returns>Returns 'false' for modules with "bad" or missing metadata.</returns> private unsafe static bool TryGetMetadataReader(this DkmClrModuleInstance module, out IntPtr ptr, out int size, out MetadataReader reader) { try { uint uSize; ptr = module.GetMetaDataBytesPtr(out uSize); size = (int)uSize; reader = new MetadataReader((byte *)ptr, size); return(true); } catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e, module.FullName)) { ptr = IntPtr.Zero; size = 0; reader = null; return(false); } }
internal sealed override MetadataReader GetModuleMetadata(DkmClrModuleInstance module) { uint length; IntPtr ptr; try { ptr = module.GetMetaDataBytesPtr(out length); } catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e, module.FullName)) { return(null); } Debug.Assert(length > 0); unsafe { return(new MetadataReader((byte *)ptr, (int)length)); } }
/// <summary> /// Attempt to construct a <see cref="MetadataReader"/> instance for this module. /// </summary> /// <returns>Returns 'false' for modules with "bad" or missing metadata.</returns> private unsafe static bool TryGetMetadataReader(GetMetadataBytesPtrFunction getMetaDataBytesPtrFunction, AssemblyIdentity assemblyIdentity, out IntPtr ptr, out int size, out MetadataReader reader) { var assemblyName = assemblyIdentity.GetDisplayName(); try { uint uSize; ptr = getMetaDataBytesPtrFunction(assemblyIdentity, out uSize); size = (int)uSize; reader = new MetadataReader((byte *)ptr, size); return(true); } catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e, assemblyName)) { ptr = IntPtr.Zero; size = 0; reader = null; return(false); } }
private static PortableExecutableReference MakeAssemblyMetadata(ModuleMetadata metadata, Dictionary <string, ModuleMetadata> modulesByName) { Debug.Assert(metadata.Module.IsManifestModule); var builder = ArrayBuilder <ModuleMetadata> .GetInstance(); builder.Add(metadata); // Include any associated netmodules from the manifest. if (modulesByName != null) { try { var reader = metadata.MetadataReader; foreach (var handle in reader.AssemblyFiles) { var assemblyFile = reader.GetAssemblyFile(handle); var name = reader.GetString(assemblyFile.Name); // Find the assembly file in the set of netmodules with that name. // The file may be missing if the file is not a module (say a resource) // or if the module has not been loaded yet. The value will be null // if the name was ambiguous. ModuleMetadata module; if (modulesByName.TryGetValue(name, out module) && (module != null)) { builder.Add(module); } } } catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e)) { // Ignore modules with "bad" or missing metadata. } } var assemblyMetadata = AssemblyMetadata.Create(builder.ToImmutableAndFree()); return(assemblyMetadata.GetReference(embedInteropTypes: false, display: metadata.Name)); }
/// <summary> /// Group module metadata into assemblies. /// </summary> internal static ImmutableArray <MetadataReference> MakeAssemblyReferences(this ImmutableArray <MetadataBlock> metadataBlocks) { // Get metadata for each module. var metadataBuilder = ArrayBuilder <ModuleMetadata> .GetInstance(); // Win8 applications contain a reference to Windows.winmd version >= 1.3 // and perhaps multiple application winmds. At runtime, Windows.winmd // is replaced by multiple Windows.*.winmd version >= 1.3. In the EE, we // need to map compile-time assembly references to the runtime assemblies // supplied by the debugger. To do so, we “merge” all winmds named // Windows.*.winmd into a single fake Windows.winmd at runtime. // All other (application) winmds are left as is. var runtimeWinMdBuilder = ArrayBuilder <ModuleMetadata> .GetInstance(); foreach (var block in metadataBlocks) { var metadata = ModuleMetadata.CreateFromMetadata(block.Pointer, block.Size, includeEmbeddedInteropTypes: true); try { if (IsWindowsComponent(metadata.MetadataReader, metadata.Name)) { runtimeWinMdBuilder.Add(metadata); } else { metadataBuilder.Add(metadata); } } catch (Exception e) when(MetadataUtilities.IsBadOrMissingMetadataException(e)) { // Ignore modules with "bad" or missing metadata. } } // Index non-primary netmodules by name. Multiple modules may // have the same name but we do not have a way to differentiate // netmodules other than by name so if there are duplicates, the // dictionary value is set to null and references are dropped when // generating the containing assembly metadata. Dictionary <string, ModuleMetadata> modulesByName = null; foreach (var metadata in metadataBuilder) { if (IsPrimaryModule(metadata)) { // Primary module. No need to add to dictionary. continue; } if (modulesByName == null) { modulesByName = new Dictionary <string, ModuleMetadata>(); // Requires case-insensitive comparison? } var name = metadata.Name; modulesByName[name] = modulesByName.ContainsKey(name) ? null : metadata; } // Build assembly references from modules in primary module // manifests. There will be duplicate assemblies if the process has // multiple app domains and those duplicates need to be dropped. var referencesBuilder = ArrayBuilder <MetadataReference> .GetInstance(); var moduleIds = PooledHashSet <Guid> .GetInstance(); foreach (var metadata in metadataBuilder) { if (!IsPrimaryModule(metadata)) { continue; } var mvid = metadata.GetModuleVersionId(); if (moduleIds.Contains(mvid)) { continue; } moduleIds.Add(mvid); referencesBuilder.Add(MakeAssemblyMetadata(metadata, modulesByName)); } moduleIds.Free(); // Any runtime winmd modules were separated out initially. Now add // those to a placeholder for the missing compile time module since // each of the runtime winmds refer to the compile time module. if (runtimeWinMdBuilder.Any()) { referencesBuilder.Add(MakeCompileTimeWinMdAssemblyMetadata(runtimeWinMdBuilder)); } runtimeWinMdBuilder.Free(); metadataBuilder.Free(); return(referencesBuilder.ToImmutableAndFree()); }