// Resolve all the custom attributes found in the assemblies registered // in 'resolver', using all the type information found in 'resolver' and // 'resolvers'. internal void resolveReferences(MetaDataResolver resolver, MetaDataResolver[] resolvers) { if (this.buffer[0] != 0x01 || this.buffer[1] != 0x00) { throw new MetaDataLoader.IllegalMetaDataFormatException("Custom Attribute doesn't start with 0x0001!"); } SignatureMethod signature; if (this.type is MetaDataMethod) { MetaDataMethod method = (MetaDataMethod)this.type; signature = (SignatureMethod)method.Signature; if (!method.Name.Equals(".ctor")) { throw new MetaDataLoader.IllegalMetaDataFormatException("Custom attribute with unexpected method name: " + method.Name); } this.typeDefOrRef = method.Parent; this.name = method.Parent.FullName; } else if (this.type is MetaDataMemberRef) { MetaDataMemberRef memberRef = (MetaDataMemberRef)this.type; signature = (SignatureMethod)memberRef.Signature; if (!memberRef.Name.Equals(".ctor")) { throw new MetaDataLoader.IllegalMetaDataFormatException("Custom attribute with unexpected memberRef name: " + memberRef.Name); } MetaDataObject methodParent = memberRef.Class; this.typeDefOrRef = methodParent; if (methodParent is MetaDataTypeDefinition) { this.name = ((MetaDataTypeDefinition)methodParent).FullName; } else if (methodParent is MetaDataTypeReference) { this.name = ((MetaDataTypeReference)methodParent).FullName; } else { throw new MetaDataLoader.IllegalMetaDataFormatException("Custom attribute with unexpected class type: " + methodParent); } } else { throw new MetaDataLoader.IllegalMetaDataFormatException("Custom attribute with unexpected type: " + this.type); } Signature.Param[] parameters = signature.Parameters; int fixedCount = parameters.Length; this.fixedArgs = new Object[fixedCount]; MemoryStream stream = new MemoryStream(this.buffer, 2, this.buffer.Length - 2, false); BinaryReader reader = new BinaryReader(stream); for (int i = 0; i < fixedCount; i++) { Signature.Param parameter = parameters[i]; Signature.Type paramType = parameter.Type; Object value = ExtractParameter(paramType, reader, resolver, resolvers); fixedArgs[i] = value; } short namedCount = ((reader.PeekChar() == -1) ? (short)0 : reader.ReadInt16()); if (namedCount > this.buffer.Length && this.Name.Equals("System.Runtime.CompilerServices.RequiredAttributeAttribute")) { // Some CLR libraries have been compiled against a version of // mscorlib that had a fixed parameter to RequiredAttribute. // Simply ignore whatever the parameter was! namedCount = 0; } this.namedArgs = new NamedArg[namedCount]; for (int i = 0; i < namedCount; i++) { SerializationTypes propOrField = (SerializationTypes) reader.ReadByte(); ElementTypes fieldType = (ElementTypes)reader.ReadByte(); ElementTypes arrayType = ElementTypes.END; switch (fieldType) { case ElementTypes.SZARRAY: { arrayType = (ElementTypes)reader.ReadByte(); if (arrayType == (ElementTypes)SerializationTypes.ENUM) { throw new Exception("Not implemented: Array of ENUM " + "for named field/property"); } break; } case (ElementTypes)SerializationTypes.ENUM: { String enumName = ExtractString(reader); if (enumName.Length == 0) { throw new Exception("Empty enum name"); } // Hope it is a 4-byte enum fieldType = (ElementTypes)SerializationTypes.U4; break; } case (ElementTypes)SerializationTypes.TAGGED_OBJECT: { throw new Exception("Not implemented: " + fieldType + " for named field/property"); } default: { break; } } String name = ExtractString(reader); Object value; if (fieldType == ElementTypes.SZARRAY) { value = ExtractArrayValue(arrayType, reader); } else { value = ExtractValue(fieldType, reader); } if (propOrField == SerializationTypes.FIELD || propOrField == SerializationTypes.PROPERTY) { this.namedArgs[i] = new NamedArg(propOrField == SerializationTypes.FIELD, -1, name, value); } else { throw new MetaDataLoader.IllegalMetaDataFormatException("Unknown prop-or-field type: " + propOrField); } } }
// This is technically not a constructor method, but it is meant to // be used to set up the object internal void resolveReferences(MetaDataMethod parent) { this.parent = parent; }
// CLR Profiler seems to blow up when a function has this many // parameters. A fix is to change the fields to internal and set them // from MetaDataLoader (the only place to "new MetaData"), but I think // that is an unreasonable permanent change just to support that tool. internal MetaData(String name, MetaDataMethod entryPoint, int imageBase, MetaDataModule[] moduleArray, MetaDataTypeReference[] typeRefArray, MetaDataTypeDefinition[] typeDefArray, MetaDataFieldPtr[] fieldPtrArray, MetaDataField[] fieldArray, MetaDataMethodPtr[] methodPtrArray, MetaDataMethod[] methodArray, MetaDataParamPtr[] paramPtrArray, MetaDataParam[] paramArray, MetaDataInterfaceImpl[] interfaceImplArray, MetaDataMemberRef[] memberRefArray, MetaDataConstant[] constantArray, MetaDataCustomAttribute[] customAttributeArray, MetaDataFieldMarshal[] fieldMarshalArray, MetaDataDeclSecurity[] declSecurityArray, MetaDataClassLayout[] classLayoutArray, MetaDataFieldLayout[] fieldLayoutArray, MetaDataStandAloneSig[] standAloneSigArray, MetaDataEventMap[] eventMapArray, MetaDataEventPtr[] eventPtrArray, MetaDataEvent[] eventArray, MetaDataPropertyMap[] propertyMapArray, MetaDataPropertyPtr[] propertyPtrArray, MetaDataProperty[] propertyArray, MetaDataMethodSemantics[] methodSemanticsArray, MetaDataMethodImpl[] methodImplArray, MetaDataModuleRef[] moduleRefArray, MetaDataTypeSpec[] typeSpecArray, MetaDataImplMap[] implMapArray, MetaDataFieldRVA[] fieldRVAArray, MetaDataAssembly[] assemblyArray, MetaDataAssemblyProcessor[] assemblyProcessorArray, MetaDataAssemblyOS[] assemblyOSArray, MetaDataAssemblyRef[] assemblyRefArray, MetaDataAssemblyRefProcessor[] assemblyRefProcessorArray, MetaDataAssemblyRefOS[] assemblyRefOSArray, MetaDataFile[] fileArray, MetaDataExportedType[] exportedTypeArray, MetaDataManifestResource[] manifestResourceArray, MetaDataNestedClass[] nestedClassArray, Object[] relocations, MetaDataVtableFixup[] vtableFixupArray, MetaDataDelayImportTable delayImportTable) { this.name = name; this.entryPoint = entryPoint; this.imageBase = imageBase; this.moduleArray = moduleArray; this.typeRefArray = typeRefArray; this.typeDefArray = typeDefArray; this.fieldPtrArray = fieldPtrArray; this.fieldArray = fieldArray; this.methodPtrArray = methodPtrArray; this.methodArray = methodArray; this.paramPtrArray = paramPtrArray; this.paramArray = paramArray; this.interfaceImplArray = interfaceImplArray; this.memberRefArray = memberRefArray; this.constantArray = constantArray; this.customAttributeArray = customAttributeArray; this.fieldMarshalArray = fieldMarshalArray; this.declSecurityArray = declSecurityArray; this.classLayoutArray = classLayoutArray; this.fieldLayoutArray = fieldLayoutArray; this.standAloneSigArray = standAloneSigArray; this.eventMapArray = eventMapArray; this.eventPtrArray = eventPtrArray; this.eventArray = eventArray; this.propertyMapArray = propertyMapArray; this.propertyPtrArray = propertyPtrArray; this.propertyArray = propertyArray; this.methodSemanticsArray = methodSemanticsArray; this.methodImplArray = methodImplArray; this.moduleRefArray = moduleRefArray; this.typeSpecArray = typeSpecArray; this.implMapArray = implMapArray; this.fieldRVAArray = fieldRVAArray; this.assemblyArray = assemblyArray; this.assemblyProcessorArray = assemblyProcessorArray; this.assemblyOSArray = assemblyOSArray; this.assemblyRefArray = assemblyRefArray; this.assemblyRefProcessorArray = assemblyRefProcessorArray; this.assemblyRefOSArray = assemblyRefOSArray; this.fileArray = fileArray; this.exportedTypeArray = exportedTypeArray; this.manifestResourceArray = manifestResourceArray; this.nestedClassArray = nestedClassArray; this.relocations = relocations; this.vtableFixupArray = vtableFixupArray; this.delayImportTable = delayImportTable; foreach (MetaDataTypeDefinition typeDef in typeDefArray) { typeDef.resolveReferences(this); } }