/*^ #pragma warning disable 2666, 2669, 2677, 2674 ^*/ internal PEFileToObjectModel( PeReader peReader, PEFileReader peFileReader, ModuleIdentity moduleIdentity, Assembly/*?*/ containingAssembly, byte pointerSize ) //^ requires peFileReader.IsAssembly ==> moduleIdentity.ContainingAssembly != null; //^ requires peFileReader.IsAssembly ==> containingAssembly == null; //^ requires !(moduleIdentity.Location != null && moduleIdentity.Location.Length != 0); { this.pointerSize = pointerSize; this.document = new MetadataObjectDocument(this); this.ModuleReader = peReader; this.PEFileReader = peFileReader; this.NameTable = peReader.metadataReaderHost.NameTable; this.InternFactory = peReader.metadataReaderHost.InternFactory; this.StringIndexToNameTable = new Hashtable<IName>(); this.StringIndexToUnmangledNameTable = new Hashtable<IName>(); this.typeCache = new TypeCache(this); uint moduleNameOffset = peFileReader.ModuleTable.GetName(1); IName moduleName = this.GetNameFromOffset(moduleNameOffset); AssemblyIdentity/*?*/ assemblyIdentity = moduleIdentity as AssemblyIdentity; if (peFileReader.IsAssembly) { //^ assert assemblyIdentity != null; AssemblyRow assemblyRow = peFileReader.AssemblyTable[1]; IName assemblyName = this.GetNameFromOffset(assemblyRow.Name); byte[] publicKeyArray = TypeCache.EmptyByteArray; if (assemblyRow.PublicKey != 0) { publicKeyArray = peFileReader.BlobStream[assemblyRow.PublicKey]; } uint internedModuleId = (uint)peReader.metadataReaderHost.InternFactory.GetAssemblyInternedKey(assemblyIdentity); Assembly assem = new Assembly(this, moduleName, peFileReader.COR20Header.COR20Flags, internedModuleId, assemblyIdentity, assemblyName, assemblyRow.Flags, publicKeyArray); this.ContainingAssembly = assem; this.Module = assem; } else { uint internedModuleId = (uint)peReader.metadataReaderHost.InternFactory.GetModuleInternedKey(moduleIdentity); this.ContainingAssembly = containingAssembly; this.Module = new Module(this, moduleName, peFileReader.COR20Header.COR20Flags, internedModuleId, moduleIdentity); } this.LoadAssemblyReferences(); this.LoadModuleReferences(); this.RootModuleNamespace = new RootNamespace(this); this.NamespaceINameHashtable = new Hashtable<Namespace>(); this.LoadNamespaces(); this.NamespaceReferenceINameHashtable = new DoubleHashtable<NamespaceReference>(); this.NamespaceTypeTokenTable = new DoubleHashtable(peFileReader.TypeDefTable.NumberOfRows + peFileReader.ExportedTypeTable.NumberOfRows); this.NestedTypeTokenTable = new DoubleHashtable(peFileReader.NestedClassTable.NumberOfRows + peFileReader.ExportedTypeTable.NumberOfRows); this.PreLoadTypeDefTableLookup(); this.ModuleTypeDefArray = new TypeBase/*?*/[peFileReader.TypeDefTable.NumberOfRows + 1]; this.ModuleTypeDefLoadState = new LoadState[peFileReader.TypeDefTable.NumberOfRows + 1]; this.RedirectedTypeDefArray = new INamedTypeReference/*?*/[peFileReader.TypeDefTable.NumberOfRows + 1]; this.ModuleTypeDefLoadState[0] = LoadState.Loaded; this.ExportedTypeArray = new ExportedTypeAliasBase/*?*/[peFileReader.ExportedTypeTable.NumberOfRows + 1]; this.ExportedTypeLoadState = new LoadState[peFileReader.ExportedTypeTable.NumberOfRows + 1]; this.ExportedTypeLoadState[0] = LoadState.Loaded; this.ModuleGenericParamArray = new GenericParameter[peFileReader.GenericParamTable.NumberOfRows + 1]; if (peFileReader.MethodSpecTable.NumberOfRows > 0) { this.ModuleMethodSpecHashtable = new DoubleHashtable<IGenericMethodInstanceReference>(peFileReader.MethodSpecTable.NumberOfRows + 1); } this.ModuleTypeRefReferenceArray = new INamedTypeReference[peFileReader.TypeRefTable.NumberOfRows + 1]; this.ModuleTypeRefReferenceLoadState = new LoadState[peFileReader.TypeRefTable.NumberOfRows + 1]; this.ModuleTypeRefReferenceLoadState[0] = LoadState.Loaded; if (peFileReader.TypeSpecTable.NumberOfRows > 0) { this.ModuleTypeSpecHashtable = new DoubleHashtable<TypeSpecReference>(peFileReader.TypeSpecTable.NumberOfRows + 1); } this.ModuleFieldArray = new FieldDefinition[peFileReader.FieldTable.NumberOfRows + 1]; this.ModuleMethodArray = new IMethodDefinition[peFileReader.MethodTable.NumberOfRows + 1]; this.ModuleEventArray = new EventDefinition[peFileReader.EventTable.NumberOfRows + 1]; this.ModulePropertyArray = new PropertyDefinition[peFileReader.PropertyTable.NumberOfRows + 1]; this.ModuleMemberReferenceArray = new MemberReference/*?*/[peFileReader.MemberRefTable.NumberOfRows + 1]; this.UnspecializedMemberReferenceArray = new MemberReference/*?*/[peFileReader.MemberRefTable.NumberOfRows + 1]; this.SpecializedFieldHashtable = new DoubleHashtable<ISpecializedFieldReference>(); this.SpecializedMethodHashtable = new DoubleHashtable<ISpecializedMethodReference>(); this.CustomAttributeArray = new ICustomAttribute/*?*/[peFileReader.CustomAttributeTable.NumberOfRows + 1]; this.DeclSecurityArray = new ISecurityAttribute/*?*/[peFileReader.DeclSecurityTable.NumberOfRows + 1]; this._Module_ = this.Create_Module_Type(); }
/// <summary> /// Computes the AssemblyIdentifier of the PE File. This requires that peFile is an assembly. /// </summary> /// <param name="peFileReader"></param> /// <returns></returns> internal AssemblyIdentity GetAssemblyIdentifier(PEFileReader peFileReader) //^ requires peFileReader.ReaderState >= ReaderState.Metadata && peFileReader.IsAssembly; //^ ensures (result.Location != null && result.Location.Length != 0); { AssemblyRow assemblyRow = peFileReader.AssemblyTable[1]; IName assemblyName = this.metadataReaderHost.NameTable.GetNameFor(peFileReader.StringStream[assemblyRow.Name]); string cultureName = peFileReader.StringStream[assemblyRow.Culture]; Version version = new Version(assemblyRow.MajorVersion, assemblyRow.MinorVersion, assemblyRow.BuildNumber, assemblyRow.RevisionNumber); byte[] publicKeyArray = TypeCache.EmptyByteArray; byte[] publicKeyTokenArray = TypeCache.EmptyByteArray; if (assemblyRow.PublicKey != 0) { publicKeyArray = peFileReader.BlobStream[assemblyRow.PublicKey]; if (publicKeyArray.Length > 0) { publicKeyTokenArray = UnitHelper.ComputePublicKeyToken(publicKeyArray); } } return new AssemblyIdentity(assemblyName, cultureName, version, publicKeyTokenArray, peFileReader.BinaryDocumentMemoryBlock.BinaryDocument.Location); }
/// <summary> /// Computes the ModuleIdentifier of the PE File as if the module belong to given assembly. /// </summary> /// <param name="peFileReader"></param> /// <param name="containingAssemblyIdentity"></param> /// <returns></returns> internal ModuleIdentity GetModuleIdentifier(PEFileReader peFileReader, AssemblyIdentity containingAssemblyIdentity) //^ requires peFileReader.ReaderState >= ReaderState.Metadata; //^ ensures (result.Location != null && result.Location.Length != 0); { ModuleRow moduleRow = peFileReader.ModuleTable[1]; IName moduleName = this.metadataReaderHost.NameTable.GetNameFor(peFileReader.StringStream[moduleRow.Name]); return new ModuleIdentity(moduleName, peFileReader.BinaryDocumentMemoryBlock.BinaryDocument.Location, containingAssemblyIdentity); }
/// <summary> /// Method to open the module in the MetadataReader. This method loads the module and returns the object corresponding to the opened module. /// Also returns the ModuleIDentifier corresponding to the module as the out parameter. Modules are opened as if they are not contained in any assembly. /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an module.</param> /// <param name="moduleIdentity">Contains the module identity of the binary document in case it is an module.</param> /// <returns>Module that is loaded or Dummy.Module in case module could not be loaded.</returns> public IModule OpenModule( IBinaryDocument binaryDocument, out ModuleIdentity/*?*/ moduleIdentity ) { moduleIdentity = null; lock (GlobalLock.LockingObject) { IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) { // Error... return Dummy.Module; } PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... return Dummy.Module; } //^ assert peFileReader.ReaderState >= ReaderState.Metadata; if (peFileReader.IsAssembly) { AssemblyIdentity assemblyIdentity = this.GetAssemblyIdentifier(peFileReader); moduleIdentity = assemblyIdentity; Assembly/*?*/ lookupAssembly = this.LookupAssembly(null, assemblyIdentity); if (lookupAssembly != null) { return lookupAssembly; } } else { moduleIdentity = this.GetModuleIdentifier(peFileReader); Module/*?*/ lookupModule = this.LookupModule(null, moduleIdentity); if (lookupModule != null) { return lookupModule; } } try { PEFileToObjectModel peFileToObjectModel = new PEFileToObjectModel(this, peFileReader, moduleIdentity, null, this.metadataReaderHost.PointerSize); this.LoadedModule(peFileToObjectModel.Module); Assembly/*?*/ assembly = peFileToObjectModel.Module as Assembly; if (assembly != null) { this.OpenMemberModules(binaryDocument, assembly); } return peFileToObjectModel.Module; } catch (MetadataReaderException) { // Error... } } return Dummy.Module; }
/// <summary> /// If the given binary document contains a CLR assembly, return the identity of the assembly. Otherwise, return null. /// </summary> public AssemblyIdentity/*?*/ GetAssemblyIdentifier(IBinaryDocument binaryDocument) { IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) return null; PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) return null; if (!peFileReader.IsAssembly) return null; return this.GetAssemblyIdentifier(peFileReader); }
/// <summary> /// Method to open the assembly in MetadataReader. This method loads the assembly and returns the object corresponding to the /// opened assembly. Also returns the AssemblyIdentifier corresponding to the assembly as the out parameter. /// Only assemblies that unify to themselves can be opened i.e. if the unification policy of the compilation host says that mscorlib 1.0 unifies to mscorlib 2.0 /// then only mscorlib 2.0 can be loaded. /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an assembly.</param> /// <param name="assemblyIdentity">Contains the assembly identifier of the binary document in case it is an assembly.</param> /// <returns>Assembly that is loaded or Dummy.Assembly in case assembly could not be loaded.</returns> public IAssembly OpenAssembly( IBinaryDocument binaryDocument, out AssemblyIdentity/*?*/ assemblyIdentity ) { assemblyIdentity = null; lock (GlobalLock.LockingObject) { IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) { // Error... return Dummy.Assembly; } PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... return Dummy.Assembly; } //^ assert peFileReader.ReaderState >= ReaderState.Metadata; if (!peFileReader.IsAssembly) { // Error... return Dummy.Assembly; } assemblyIdentity = this.GetAssemblyIdentifier(peFileReader); Assembly/*?*/ lookupAssembly = this.LookupAssembly(null, assemblyIdentity); if (lookupAssembly != null) { return lookupAssembly; } try { PEFileToObjectModel peFileToObjectModel = new PEFileToObjectModel(this, peFileReader, assemblyIdentity, null, this.metadataReaderHost.PointerSize); Assembly/*?*/ assembly = peFileToObjectModel.Module as Assembly; //^ assert assembly != null; this.LoadedModule(assembly); this.OpenMemberModules(binaryDocument, assembly); return assembly; } catch (MetadataReaderException) { return Dummy.Assembly; } } }
/// <summary> /// This method is called when an assembly is loaded. This makes sure that all the member modules of the assembly are loaded. /// </summary> /// <param name="binaryDocument"></param> /// <param name="assembly"></param> void OpenMemberModules(IBinaryDocument binaryDocument, Assembly assembly) { List<Module> memberModuleList = new List<Module>(); AssemblyIdentity assemblyIdentity = assembly.AssemblyIdentity; foreach (IFileReference fileRef in assembly.PEFileToObjectModel.GetFiles()) { if (!fileRef.HasMetadata) continue; IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument, fileRef.FileName.Value); if (binaryDocumentMemoryBlock == null) { // Error... continue; } try { PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock); if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... continue; } if (peFileReader.IsAssembly) { // Error... continue; } ModuleIdentity moduleIdentity = this.GetModuleIdentifier(peFileReader, assemblyIdentity); PEFileToObjectModel peFileToObjectModel = new PEFileToObjectModel(this, peFileReader, moduleIdentity, assembly, this.metadataReaderHost.PointerSize); memberModuleList.Add(peFileToObjectModel.Module); } catch (MetadataReaderException) { continue; } } if (memberModuleList.Count == 0) return; assembly.SetMemberModules(new EnumerableArrayWrapper<Module, IModule>(memberModuleList.ToArray(), Dummy.Module)); }
//^ requires peFileReader.ReaderState >= ReaderState.Metadata; //^ ensures (result.Location != null && result.Location.Length != 0); /// <summary> /// Computes the ModuleIdentifier of the PE File as if the module belong to given assembly. /// </summary> /// <param name="peFileReader"></param> /// <param name="containingAssemblyIdentity"></param> /// <returns></returns> internal ModuleIdentity GetModuleIdentifier(PEFileReader peFileReader, AssemblyIdentity containingAssemblyIdentity) { ModuleRow moduleRow = peFileReader.ModuleTable[1]; IName moduleName = this.metadataReaderHost.NameTable.GetNameFor(peFileReader.StringStream[moduleRow.Name]); return new ModuleIdentity(moduleName, peFileReader.BinaryDocumentMemoryBlock.BinaryDocument.Location, containingAssemblyIdentity); }
/// <summary> /// This method loads a module from a file containing only the metadata section of a PE file. (No headers and no IL.) /// </summary> /// <param name="binaryDocument">The binary document that needes to be opened as an module.</param> /// <returns>Module that is loaded or Dummy.Module in case module could not be loaded.</returns> public IModule OpenSnapshot(IBinaryDocument binaryDocument) { ModuleIdentity moduleIdentity; lock (GlobalLock.LockingObject) { IBinaryDocumentMemoryBlock/*?*/ binaryDocumentMemoryBlock = this.metadataReaderHost.OpenBinaryDocument(binaryDocument); if (binaryDocumentMemoryBlock == null) { // Error... return Dummy.Module; } PEFileReader peFileReader = new PEFileReader(this, binaryDocumentMemoryBlock, snapshot: true); if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... return Dummy.Module; } if (peFileReader.IsAssembly) { AssemblyIdentity assemblyIdentity = this.GetAssemblyIdentifier(peFileReader); moduleIdentity = assemblyIdentity; Assembly/*?*/ lookupAssembly = this.LookupAssembly(null, assemblyIdentity); if (lookupAssembly != null) { return lookupAssembly; } } else { moduleIdentity = this.GetModuleIdentifier(peFileReader); Module/*?*/ lookupModule = this.LookupModule(null, moduleIdentity); if (lookupModule != null) { return lookupModule; } } if (peFileReader.ReaderState < ReaderState.Metadata) { // Error... return Dummy.Module; } try { PEFileToObjectModel peFileToObjectModel = new PEFileToObjectModel(this, peFileReader, moduleIdentity, null, this.metadataReaderHost.PointerSize); this.LoadedModule(peFileToObjectModel.Module); CciEventSource.Log.ModuleOpened(peFileToObjectModel.Module, moduleIdentity, binaryDocument.Length); return peFileToObjectModel.Module; } catch (MetadataReaderException) { // Error... } } return Dummy.Module; }
//^ requires peFileReader.IsAssembly ==> moduleIdentity.ContainingAssembly != null; //^ requires peFileReader.IsAssembly ==> containingAssembly == null; //^ requires !(moduleIdentity.Location != null && moduleIdentity.Location.Length != 0); /*^ #pragma warning disable 2666, 2669, 2677, 2674 ^*/ internal PEFileToObjectModel( PeReader peReader, PEFileReader peFileReader, ModuleIdentity moduleIdentity, Assembly/*?*/ containingAssembly, byte pointerSize ) { this.pointerSize = pointerSize; this.ModuleReader = peReader; this.PEFileReader = peFileReader; this.NameTable = peReader.metadataReaderHost.NameTable; this.StringIndexToNameTable = new Hashtable<IName>(); this.StringIndexToUnmangledNameTable = new Hashtable<IName>(); this.typeCache = new TypeCache(this); uint moduleNameOffset = peFileReader.ModuleTable.GetName(1); IName moduleName = this.GetNameFromOffset(moduleNameOffset); AssemblyIdentity/*?*/ assemblyIdentity = moduleIdentity as AssemblyIdentity; if (peFileReader.IsAssembly) { //^ assert assemblyIdentity != null; AssemblyRow assemblyRow = peFileReader.AssemblyTable[1]; IName assemblyName = this.GetNameFromOffset(assemblyRow.Name); byte[] publicKeyArray = TypeCache.EmptyByteArray; if (assemblyRow.PublicKey != 0) { publicKeyArray = peFileReader.BlobStream[assemblyRow.PublicKey]; } uint internedModuleId = (uint)peReader.metadataReaderHost.InternFactory.GetAssemblyInternedKey(assemblyIdentity); Assembly assem = new Assembly(this, moduleName, peFileReader.COR20Header.COR20Flags, internedModuleId, assemblyIdentity, assemblyName, assemblyRow.Flags, publicKeyArray); this.ContainingAssembly = assem; this.Module = assem; } else { uint internedModuleId = (uint)peReader.metadataReaderHost.InternFactory.GetModuleInternedKey(moduleIdentity); this.ContainingAssembly = containingAssembly; this.Module = new Module(this, moduleName, peFileReader.COR20Header.COR20Flags, internedModuleId, moduleIdentity); } this.LoadAssemblyReferences(); this.LoadModuleReferences(); this.RootModuleNamespace = new RootNamespace(this); this.NamespaceINameHashtable = new Hashtable<Namespace>(); this.LoadNamespaces(); this.NamespaceReferenceINameHashtable = new DoubleHashtable<NamespaceReference>(); this.NamespaceTypeTokenTable = new DoubleHashtable(peFileReader.TypeDefTable.NumberOfRows + peFileReader.ExportedTypeTable.NumberOfRows); this.NestedTypeTokenTable = new DoubleHashtable(peFileReader.NestedClassTable.NumberOfRows + peFileReader.ExportedTypeTable.NumberOfRows); this.PreLoadTypeDefTableLookup(); this.ModuleTypeDefArray = new TypeBase/*?*/[peFileReader.TypeDefTable.NumberOfRows + 1]; this.ModuleTypeDefLoadState = new LoadState[peFileReader.TypeDefTable.NumberOfRows + 1]; this.ModuleTypeDefLoadState[0] = LoadState.Loaded; this.ExportedTypeArray = new ExportedTypeAliasBase/*?*/[peFileReader.ExportedTypeTable.NumberOfRows + 1]; this.ExportedTypeLoadState = new LoadState[peFileReader.ExportedTypeTable.NumberOfRows + 1]; this.ExportedTypeLoadState[0] = LoadState.Loaded; this.ModuleGenericParamArray = new GenericParameter[peFileReader.GenericParamTable.NumberOfRows + 1]; if (peFileReader.MethodSpecTable.NumberOfRows > 0) { this.ModuleMethodSpecHashtable = new DoubleHashtable<GenericMethodInstanceReference>(peFileReader.MethodSpecTable.NumberOfRows + 1); } this.ModuleTypeRefReferenceArray = new TypeRefReference[peFileReader.TypeRefTable.NumberOfRows + 1]; this.ModuleTypeRefReferenceLoadState = new LoadState[peFileReader.TypeRefTable.NumberOfRows + 1]; this.ModuleTypeRefReferenceLoadState[0] = LoadState.Loaded; if (peFileReader.TypeSpecTable.NumberOfRows > 0) { this.ModuleTypeSpecHashtable = new DoubleHashtable<TypeSpecReference>(peFileReader.TypeSpecTable.NumberOfRows + 1); } this.ModuleFieldArray = new FieldDefinition[peFileReader.FieldTable.NumberOfRows + 1]; this.ModuleMethodArray = new MethodDefinition[peFileReader.MethodTable.NumberOfRows + 1]; this.ModuleEventArray = new EventDefinition[peFileReader.EventTable.NumberOfRows + 1]; this.ModulePropertyArray = new PropertyDefinition[peFileReader.PropertyTable.NumberOfRows + 1]; this.ModuleMemberReferenceArray = new MemberReference/*?*/[peFileReader.MemberRefTable.NumberOfRows + 1]; this.CustomAttributeArray = new ICustomAttribute/*?*/[peFileReader.CustomAttributeTable.NumberOfRows + 1]; this.DeclSecurityArray = new ISecurityAttribute/*?*/[peFileReader.DeclSecurityTable.NumberOfRows + 1]; uint moduleClassTypeDefToken = this.NamespaceTypeTokenTable.Find((uint)this.NameTable.EmptyName.UniqueKey, (uint)peReader._Module_.UniqueKey); _Module_Type/*?*/ _module_ = null; if (moduleClassTypeDefToken != 0 && ((TokenTypeIds.TokenTypeMask & moduleClassTypeDefToken) == TokenTypeIds.TypeDef)) { _module_ = this.Create_Module_Type(moduleClassTypeDefToken & TokenTypeIds.RIDMask); } if (_module_ == null) { // Error throw new MetadataReaderException("<Module> Type not present"); } this._Module_ = _module_; //^ NonNullType.AssertInitialized(this.ModuleGenericParamArray); //^ NonNullType.AssertInitialized(this.ModuleTypeRefReferenceArray); //^ NonNullType.AssertInitialized(this.ModuleFieldArray); //^ NonNullType.AssertInitialized(this.ModuleMethodArray); //^ NonNullType.AssertInitialized(this.ModuleEventArray); //^ NonNullType.AssertInitialized(this.ModulePropertyArray); }