From 22d466262bff9b44047e812dc340f05c68ff3441 Mon Sep 17 00:00:00 2001 From: liiir1985 Date: Sun, 24 Apr 2016 19:06:35 +0800 Subject: [PATCH] Initial commit --- .gitignore | 3 + ILRuntime.sln | 40 + ILRuntime/ILRuntime.csproj | 57 + ILRuntime/Properties/AssemblyInfo.cs | 36 + Mono.Cecil.20/Mono.Cecil.20.csproj | 177 + .../MonoCecil/Mono.Cecil.Cil/Code.cs | 252 ++ .../MonoCecil/Mono.Cecil.Cil/CodeReader.cs | 394 ++ .../MonoCecil/Mono.Cecil.Cil/CodeWriter.cs | 38 + .../MonoCecil/Mono.Cecil.Cil/Document.cs | 112 + .../Mono.Cecil.Cil/ExceptionHandler.cs | 89 + .../MonoCecil/Mono.Cecil.Cil/ILProcessor.cs | 278 ++ .../MonoCecil/Mono.Cecil.Cil/Instruction.cs | 321 ++ .../MonoCecil/Mono.Cecil.Cil/MethodBody.cs | 267 ++ .../MonoCecil/Mono.Cecil.Cil/OpCode.cs | 455 +++ .../MonoCecil/Mono.Cecil.Cil/OpCodes.cs | 912 +++++ .../MonoCecil/Mono.Cecil.Cil/SequencePoint.cs | 70 + .../MonoCecil/Mono.Cecil.Cil/Symbols.cs | 243 ++ .../Mono.Cecil.Cil/VariableDefinition.cs | 52 + .../Mono.Cecil.Cil/VariableReference.cs | 75 + .../MonoCecil/Mono.Cecil.Metadata/BlobHeap.cs | 61 + .../MonoCecil/Mono.Cecil.Metadata/Buffers.cs | 36 + .../Mono.Cecil.Metadata/CodedIndex.cs | 46 + .../Mono.Cecil.Metadata/ElementType.cs | 73 + .../MonoCecil/Mono.Cecil.Metadata/GuidHeap.cs | 59 + .../MonoCecil/Mono.Cecil.Metadata/Heap.cs | 48 + .../Mono.Cecil.Metadata/MetadataToken.cs | 105 + .../MonoCecil/Mono.Cecil.Metadata/Row.cs | 175 + .../Mono.Cecil.Metadata/StringHeap.cs | 81 + .../Mono.Cecil.Metadata/TableHeap.cs | 111 + .../Mono.Cecil.Metadata/TokenType.cs | 56 + .../Mono.Cecil.Metadata/UserStringHeap.cs | 61 + .../Mono.Cecil.Metadata/Utilities.cs | 354 ++ .../Mono.Cecil.PE/BinaryStreamReader.cs | 51 + .../Mono.Cecil.PE/BinaryStreamWriter.cs | 31 + .../MonoCecil/Mono.Cecil.PE/ByteBuffer.cs | 184 + .../ByteBufferEqualityComparer.cs | 78 + .../MonoCecil/Mono.Cecil.PE/DataDirectory.cs | 50 + .../MonoCecil/Mono.Cecil.PE/Image.cs | 166 + .../MonoCecil/Mono.Cecil.PE/ImageReader.cs | 694 ++++ .../MonoCecil/Mono.Cecil.PE/ImageWriter.cs | 0 .../MonoCecil/Mono.Cecil.PE/Section.cs | 43 + .../MonoCecil/Mono.Cecil.PE/TextMap.cs | 0 .../MonoCecil/Mono.Cecil/ArrayType.cs | 159 + .../Mono.Cecil/AssemblyDefinition.cs | 163 + .../MonoCecil/Mono.Cecil/AssemblyFlags.cs | 42 + .../Mono.Cecil/AssemblyHashAlgorithm.cs | 36 + .../Mono.Cecil/AssemblyLinkedResource.cs | 57 + .../Mono.Cecil/AssemblyNameDefinition.cs | 50 + .../Mono.Cecil/AssemblyNameReference.cs | 296 ++ .../MonoCecil/Mono.Cecil/AssemblyReader.cs | 3287 +++++++++++++++++ .../MonoCecil/Mono.Cecil/AssemblyWriter.cs | 47 + .../Mono.Cecil/BaseAssemblyResolver.cs | 172 + .../MonoCecil/Mono.Cecil/CallSite.cs | 124 + .../MonoCecil/Mono.Cecil/CustomAttribute.cs | 231 ++ .../Mono.Cecil/DefaultAssemblyResolver.cs | 70 + .../MonoCecil/Mono.Cecil/EmbeddedResource.cs | 105 + .../MonoCecil/Mono.Cecil/EventAttributes.cs | 39 + .../MonoCecil/Mono.Cecil/EventDefinition.cs | 170 + .../MonoCecil/Mono.Cecil/EventReference.cs | 57 + .../MonoCecil/Mono.Cecil/ExportedType.cs | 249 ++ .../MonoCecil/Mono.Cecil/FieldAttributes.cs | 59 + .../MonoCecil/Mono.Cecil/FieldDefinition.cs | 271 ++ .../MonoCecil/Mono.Cecil/FieldReference.cs | 83 + .../MonoCecil/Mono.Cecil/FileAttributes.cs | 35 + .../Mono.Cecil/FunctionPointerType.cs | 128 + .../Mono.Cecil/GenericInstanceMethod.cs | 95 + .../Mono.Cecil/GenericInstanceType.cs | 93 + .../MonoCecil/Mono.Cecil/GenericParameter.cs | 277 ++ .../Mono.Cecil/GenericParameterAttributes.cs | 45 + .../MonoCecil/Mono.Cecil/IConstantProvider.cs | 57 + .../Mono.Cecil/ICustomAttributeProvider.cs | 63 + .../MonoCecil/Mono.Cecil/IGenericInstance.cs | 66 + .../Mono.Cecil/IGenericParameterProvider.cs | 79 + .../Mono.Cecil/IMarshalInfoProvider.cs | 59 + .../MonoCecil/Mono.Cecil/IMemberDefinition.cs | 105 + .../MonoCecil/Mono.Cecil/IMetadataScope.cs | 41 + .../Mono.Cecil/IMetadataTokenProvider.cs | 35 + .../MonoCecil/Mono.Cecil/IMethodSignature.cs | 75 + Mono.Cecil.20/MonoCecil/Mono.Cecil/Import.cs | 286 ++ .../MonoCecil/Mono.Cecil/LinkedResource.cs | 60 + .../Mono.Cecil/ManifestResourceAttributes.cs | 39 + .../MonoCecil/Mono.Cecil/MarshalInfo.cs | 171 + .../Mono.Cecil/MemberDefinitionCollection.cs | 92 + .../MonoCecil/Mono.Cecil/MemberReference.cs | 101 + .../MonoCecil/Mono.Cecil/MetadataResolver.cs | 369 ++ .../MonoCecil/Mono.Cecil/MetadataSystem.cs | 395 ++ .../MonoCecil/Mono.Cecil/MethodAttributes.cs | 66 + .../Mono.Cecil/MethodCallingConvention.cs | 40 + .../MonoCecil/Mono.Cecil/MethodDefinition.cs | 570 +++ .../Mono.Cecil/MethodImplAttributes.cs | 53 + .../MonoCecil/Mono.Cecil/MethodReference.cs | 239 ++ .../MonoCecil/Mono.Cecil/MethodReturnType.cs | 111 + .../Mono.Cecil/MethodSemanticsAttributes.cs | 43 + .../Mono.Cecil/MethodSpecification.cs | 103 + .../MonoCecil/Mono.Cecil/Modifiers.cs | 137 + .../MonoCecil/Mono.Cecil/ModuleDefinition.cs | 755 ++++ .../MonoCecil/Mono.Cecil/ModuleKind.cs | 64 + .../MonoCecil/Mono.Cecil/ModuleReference.cs | 67 + .../MonoCecil/Mono.Cecil/NativeType.cs | 73 + .../MonoCecil/Mono.Cecil/PInvokeAttributes.cs | 62 + .../MonoCecil/Mono.Cecil/PInvokeInfo.cs | 138 + .../Mono.Cecil/ParameterAttributes.cs | 45 + .../Mono.Cecil/ParameterDefinition.cs | 186 + .../ParameterDefinitionCollection.cs | 80 + .../Mono.Cecil/ParameterReference.cs | 75 + .../MonoCecil/Mono.Cecil/PinnedType.cs | 53 + .../MonoCecil/Mono.Cecil/PointerType.cs | 61 + .../Mono.Cecil/PropertyAttributes.cs | 41 + .../Mono.Cecil/PropertyDefinition.cs | 259 ++ .../MonoCecil/Mono.Cecil/PropertyReference.cs | 59 + .../MonoCecil/Mono.Cecil/ReferenceType.cs | 61 + .../MonoCecil/Mono.Cecil/Resource.cs | 76 + .../Mono.Cecil/SecurityDeclaration.cs | 210 ++ .../MonoCecil/Mono.Cecil/SentinelType.cs | 53 + .../MonoCecil/Mono.Cecil/TargetRuntime.cs | 37 + .../MonoCecil/Mono.Cecil/TypeAttributes.cs | 81 + .../MonoCecil/Mono.Cecil/TypeDefinition.cs | 599 +++ .../Mono.Cecil/TypeDefinitionCollection.cs | 118 + .../MonoCecil/Mono.Cecil/TypeParser.cs | 584 +++ .../MonoCecil/Mono.Cecil/TypeReference.cs | 370 ++ .../MonoCecil/Mono.Cecil/TypeSpecification.cs | 94 + .../MonoCecil/Mono.Cecil/TypeSystem.cs | 332 ++ .../MonoCecil/Mono.Cecil/VariantType.cs | 53 + .../Mono.Collections.Generic/Collection.cs | 420 +++ .../ReadOnlyCollection.cs | 112 + .../CryptoConvert.cs | 0 .../CryptoService.cs | 33 + Mono.Cecil.20/MonoCecil/Mono/Actions.cs | 38 + Mono.Cecil.20/MonoCecil/Mono/Empty.cs | 53 + Mono.Cecil.20/MonoCecil/Mono/Funcs.cs | 39 + Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj | 85 + Mono.Cecil.Mdb/Properties/AssemblyInfo.cs | 29 + .../mdb/Mono.Cecil.Mdb/MdbReader.cs | 177 + .../mdb/Mono.Cecil.Mdb/MdbReaderProvider.cs | 19 + .../AnonymousScopeEntry.cs | 73 + .../CapturedScope.cs | 28 + .../CapturedVariable.cs | 38 + .../CodeBlockEntry.cs | 62 + .../CompileUnitEntry.cs | 171 + .../ICompileUnit.cs | 11 + .../IMethodDef.cs | 15 + .../ISourceFile.cs | 11 + .../LineNumberEntry.cs | 75 + .../LineNumberTable.cs | 233 ++ .../LocalVariableEntry.cs | 32 + .../MethodEntry.cs | 385 ++ .../MonoSymbolFile.cs | 635 ++++ .../MonoSymbolFileException.cs | 13 + .../MonoSymbolWriter.cs | 182 + .../MyBinaryReader.cs | 23 + .../MyBinaryWriter.cs | 15 + .../NamespaceEntry.cs | 47 + .../NamespaceInfo.cs | 11 + .../OffsetTable.cs | 107 + .../ScopeVariable.cs | 28 + .../SourceFileEntry.cs | 131 + .../SourceMethodBuilder.cs | 175 + .../SourceMethodImpl.cs | 37 + .../SymbolDocumentWriterImpl.cs | 33 + .../SymbolWriterImpl.cs | 162 + Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj | 87 + Mono.Cecil.Pdb/Properties/AssemblyInfo.cs | 36 + .../pdb/Microsoft.Cci.Pdb/BitAccess.cs | 249 ++ .../pdb/Microsoft.Cci.Pdb/BitSet.cs | 74 + .../pdb/Microsoft.Cci.Pdb/CvInfo.cs | 2435 ++++++++++++ .../pdb/Microsoft.Cci.Pdb/DataStream.cs | 111 + .../pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs | 41 + .../pdb/Microsoft.Cci.Pdb/DbiHeader.cs | 59 + .../pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs | 57 + .../pdb/Microsoft.Cci.Pdb/DbiSecCon.cs | 42 + .../pdb/Microsoft.Cci.Pdb/IntHashTable.cs | 583 +++ .../pdb/Microsoft.Cci.Pdb/Interfaces.cs | 77 + .../pdb/Microsoft.Cci.Pdb/MsfDirectory.cs | 58 + .../pdb/Microsoft.Cci.Pdb/PdbConstant.cs | 89 + .../Microsoft.Cci.Pdb/PdbDebugException.cs | 20 + .../pdb/Microsoft.Cci.Pdb/PdbException.cs | 20 + .../pdb/Microsoft.Cci.Pdb/PdbFile.cs | 439 +++ .../pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs | 90 + .../pdb/Microsoft.Cci.Pdb/PdbFunction.cs | 519 +++ .../pdb/Microsoft.Cci.Pdb/PdbLine.cs | 29 + .../pdb/Microsoft.Cci.Pdb/PdbLines.cs | 23 + .../pdb/Microsoft.Cci.Pdb/PdbReader.cs | 40 + .../pdb/Microsoft.Cci.Pdb/PdbScope.cs | 122 + .../pdb/Microsoft.Cci.Pdb/PdbSlot.cs | 40 + .../pdb/Microsoft.Cci.Pdb/PdbSource.cs | 29 + .../SourceLocationProvider.cs | 33 + .../ISymUnmanagedDocumentWriter.cs | 28 + .../Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs | 34 + .../pdb/Mono.Cecil.Pdb/ModuleMetadata.cs | 4 + .../pdb/Mono.Cecil.Pdb/PdbHelper.cs | 212 ++ .../pdb/Mono.Cecil.Pdb/PdbReader.cs | 286 ++ .../pdb/Mono.Cecil.Pdb/PdbWriter.cs | 34 + .../pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs | 29 + .../pdb/Mono.Cecil.Pdb/SymWriter.cs | 37 + 194 files changed, 30819 insertions(+) create mode 100644 .gitignore create mode 100644 ILRuntime.sln create mode 100644 ILRuntime/ILRuntime.csproj create mode 100644 ILRuntime/Properties/AssemblyInfo.cs create mode 100644 Mono.Cecil.20/Mono.Cecil.20.csproj create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Code.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeReader.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeWriter.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Document.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ExceptionHandler.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ILProcessor.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Instruction.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/MethodBody.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCode.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCodes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/SequencePoint.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Symbols.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/BlobHeap.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Buffers.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/CodedIndex.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/ElementType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/GuidHeap.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Heap.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/MetadataToken.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Row.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/StringHeap.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TableHeap.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TokenType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/UserStringHeap.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Utilities.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamReader.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamWriter.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBuffer.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBufferEqualityComparer.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/DataDirectory.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Image.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageReader.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageWriter.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Section.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/TextMap.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ArrayType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyFlags.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyHashAlgorithm.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyLinkedResource.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyReader.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyWriter.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/BaseAssemblyResolver.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/CallSite.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/CustomAttribute.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/DefaultAssemblyResolver.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/EmbeddedResource.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/EventAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/EventDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/EventReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ExportedType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/FileAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/FunctionPointerType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceMethod.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameter.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameterAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/IConstantProvider.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ICustomAttributeProvider.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericInstance.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericParameterProvider.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/IMarshalInfoProvider.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/IMemberDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataScope.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataTokenProvider.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/IMethodSignature.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/Import.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/LinkedResource.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ManifestResourceAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MarshalInfo.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberDefinitionCollection.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataResolver.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataSystem.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodCallingConvention.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodImplAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReturnType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSemanticsAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSpecification.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/Modifiers.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleKind.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/NativeType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeInfo.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinitionCollection.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/PinnedType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/PointerType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/ReferenceType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/Resource.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/SecurityDeclaration.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/SentinelType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/TargetRuntime.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeAttributes.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinition.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinitionCollection.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeParser.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeReference.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSpecification.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSystem.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Cecil/VariantType.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/Collection.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/ReadOnlyCollection.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoConvert.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoService.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono/Actions.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono/Empty.cs create mode 100644 Mono.Cecil.20/MonoCecil/Mono/Funcs.cs create mode 100644 Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj create mode 100644 Mono.Cecil.Mdb/Properties/AssemblyInfo.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReader.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReaderProvider.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/AnonymousScopeEntry.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedScope.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedVariable.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CodeBlockEntry.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CompileUnitEntry.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ICompileUnit.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/IMethodDef.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ISourceFile.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberEntry.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberTable.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LocalVariableEntry.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MethodEntry.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFileException.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryReader.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryWriter.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceEntry.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceInfo.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/OffsetTable.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ScopeVariable.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceFileEntry.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodImpl.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolDocumentWriterImpl.cs create mode 100644 Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs create mode 100644 Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj create mode 100644 Mono.Cecil.Pdb/Properties/AssemblyInfo.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitAccess.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitSet.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/CvInfo.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DataStream.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiHeader.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiSecCon.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/IntHashTable.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/Interfaces.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/MsfDirectory.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbConstant.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbDebugException.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbException.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFile.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFunction.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLine.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLines.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbReader.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbScope.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSlot.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSource.cs create mode 100644 Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs create mode 100644 Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs create mode 100644 Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs create mode 100644 Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs create mode 100644 Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbHelper.cs create mode 100644 Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbReader.cs create mode 100644 Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbWriter.cs create mode 100644 Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs create mode 100644 Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymWriter.cs diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..56061a31 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.suo +bin/ +obj/ \ No newline at end of file diff --git a/ILRuntime.sln b/ILRuntime.sln new file mode 100644 index 00000000..97c1d356 --- /dev/null +++ b/ILRuntime.sln @@ -0,0 +1,40 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 14 +VisualStudioVersion = 14.0.24720.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILRuntime", "ILRuntime\ILRuntime.csproj", "{79EF2F29-89D1-4097-986C-5E4EEFE0FA33}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.20", "Mono.Cecil.20\Mono.Cecil.20.csproj", "{D3785D8B-4D85-4546-8763-47FC848C13E0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Mdb", "Mono.Cecil.Mdb\Mono.Cecil.Mdb.csproj", "{86F36240-E07C-4840-9C8B-9CD94C03EC62}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil.Pdb", "Mono.Cecil.Pdb\Mono.Cecil.Pdb.csproj", "{CEA7A85F-2523-4AD0-8296-6E8E0A2E6DF7}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {79EF2F29-89D1-4097-986C-5E4EEFE0FA33}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {79EF2F29-89D1-4097-986C-5E4EEFE0FA33}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79EF2F29-89D1-4097-986C-5E4EEFE0FA33}.Release|Any CPU.ActiveCfg = Release|Any CPU + {79EF2F29-89D1-4097-986C-5E4EEFE0FA33}.Release|Any CPU.Build.0 = Release|Any CPU + {D3785D8B-4D85-4546-8763-47FC848C13E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D3785D8B-4D85-4546-8763-47FC848C13E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D3785D8B-4D85-4546-8763-47FC848C13E0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D3785D8B-4D85-4546-8763-47FC848C13E0}.Release|Any CPU.Build.0 = Release|Any CPU + {86F36240-E07C-4840-9C8B-9CD94C03EC62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {86F36240-E07C-4840-9C8B-9CD94C03EC62}.Debug|Any CPU.Build.0 = Debug|Any CPU + {86F36240-E07C-4840-9C8B-9CD94C03EC62}.Release|Any CPU.ActiveCfg = Release|Any CPU + {86F36240-E07C-4840-9C8B-9CD94C03EC62}.Release|Any CPU.Build.0 = Release|Any CPU + {CEA7A85F-2523-4AD0-8296-6E8E0A2E6DF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CEA7A85F-2523-4AD0-8296-6E8E0A2E6DF7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CEA7A85F-2523-4AD0-8296-6E8E0A2E6DF7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CEA7A85F-2523-4AD0-8296-6E8E0A2E6DF7}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/ILRuntime/ILRuntime.csproj b/ILRuntime/ILRuntime.csproj new file mode 100644 index 00000000..6a5a44dc --- /dev/null +++ b/ILRuntime/ILRuntime.csproj @@ -0,0 +1,57 @@ + + + + + Debug + AnyCPU + {79EF2F29-89D1-4097-986C-5E4EEFE0FA33} + Library + Properties + ILRuntime + ILRuntime + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ILRuntime/Properties/AssemblyInfo.cs b/ILRuntime/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..e2b3d0c9 --- /dev/null +++ b/ILRuntime/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("ILRuntime")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("ILRuntime")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +//将 ComVisible 设置为 false 将使此程序集中的类型 +//对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("79ef2f29-89d1-4097-986c-5e4eefe0fa33")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: : +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Mono.Cecil.20/Mono.Cecil.20.csproj b/Mono.Cecil.20/Mono.Cecil.20.csproj new file mode 100644 index 00000000..fa034e72 --- /dev/null +++ b/Mono.Cecil.20/Mono.Cecil.20.csproj @@ -0,0 +1,177 @@ + + + + + Debug + AnyCPU + {D3785D8B-4D85-4546-8763-47FC848C13E0} + Library + Properties + Mono.Cecil + Mono.Cecil.20 + v2.0 + 512 + + + + + true + full + false + ..\bin\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Code.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Code.cs new file mode 100644 index 00000000..fa88b63d --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Code.cs @@ -0,0 +1,252 @@ +// +// Code.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Cil { + + public enum Code { + Nop, + Break, + Ldarg_0, + Ldarg_1, + Ldarg_2, + Ldarg_3, + Ldloc_0, + Ldloc_1, + Ldloc_2, + Ldloc_3, + Stloc_0, + Stloc_1, + Stloc_2, + Stloc_3, + Ldarg_S, + Ldarga_S, + Starg_S, + Ldloc_S, + Ldloca_S, + Stloc_S, + Ldnull, + Ldc_I4_M1, + Ldc_I4_0, + Ldc_I4_1, + Ldc_I4_2, + Ldc_I4_3, + Ldc_I4_4, + Ldc_I4_5, + Ldc_I4_6, + Ldc_I4_7, + Ldc_I4_8, + Ldc_I4_S, + Ldc_I4, + Ldc_I8, + Ldc_R4, + Ldc_R8, + Dup, + Pop, + Jmp, + Call, + Calli, + Ret, + Br_S, + Brfalse_S, + Brtrue_S, + Beq_S, + Bge_S, + Bgt_S, + Ble_S, + Blt_S, + Bne_Un_S, + Bge_Un_S, + Bgt_Un_S, + Ble_Un_S, + Blt_Un_S, + Br, + Brfalse, + Brtrue, + Beq, + Bge, + Bgt, + Ble, + Blt, + Bne_Un, + Bge_Un, + Bgt_Un, + Ble_Un, + Blt_Un, + Switch, + Ldind_I1, + Ldind_U1, + Ldind_I2, + Ldind_U2, + Ldind_I4, + Ldind_U4, + Ldind_I8, + Ldind_I, + Ldind_R4, + Ldind_R8, + Ldind_Ref, + Stind_Ref, + Stind_I1, + Stind_I2, + Stind_I4, + Stind_I8, + Stind_R4, + Stind_R8, + Add, + Sub, + Mul, + Div, + Div_Un, + Rem, + Rem_Un, + And, + Or, + Xor, + Shl, + Shr, + Shr_Un, + Neg, + Not, + Conv_I1, + Conv_I2, + Conv_I4, + Conv_I8, + Conv_R4, + Conv_R8, + Conv_U4, + Conv_U8, + Callvirt, + Cpobj, + Ldobj, + Ldstr, + Newobj, + Castclass, + Isinst, + Conv_R_Un, + Unbox, + Throw, + Ldfld, + Ldflda, + Stfld, + Ldsfld, + Ldsflda, + Stsfld, + Stobj, + Conv_Ovf_I1_Un, + Conv_Ovf_I2_Un, + Conv_Ovf_I4_Un, + Conv_Ovf_I8_Un, + Conv_Ovf_U1_Un, + Conv_Ovf_U2_Un, + Conv_Ovf_U4_Un, + Conv_Ovf_U8_Un, + Conv_Ovf_I_Un, + Conv_Ovf_U_Un, + Box, + Newarr, + Ldlen, + Ldelema, + Ldelem_I1, + Ldelem_U1, + Ldelem_I2, + Ldelem_U2, + Ldelem_I4, + Ldelem_U4, + Ldelem_I8, + Ldelem_I, + Ldelem_R4, + Ldelem_R8, + Ldelem_Ref, + Stelem_I, + Stelem_I1, + Stelem_I2, + Stelem_I4, + Stelem_I8, + Stelem_R4, + Stelem_R8, + Stelem_Ref, + Ldelem_Any, + Stelem_Any, + Unbox_Any, + Conv_Ovf_I1, + Conv_Ovf_U1, + Conv_Ovf_I2, + Conv_Ovf_U2, + Conv_Ovf_I4, + Conv_Ovf_U4, + Conv_Ovf_I8, + Conv_Ovf_U8, + Refanyval, + Ckfinite, + Mkrefany, + Ldtoken, + Conv_U2, + Conv_U1, + Conv_I, + Conv_Ovf_I, + Conv_Ovf_U, + Add_Ovf, + Add_Ovf_Un, + Mul_Ovf, + Mul_Ovf_Un, + Sub_Ovf, + Sub_Ovf_Un, + Endfinally, + Leave, + Leave_S, + Stind_I, + Conv_U, + Arglist, + Ceq, + Cgt, + Cgt_Un, + Clt, + Clt_Un, + Ldftn, + Ldvirtftn, + Ldarg, + Ldarga, + Starg, + Ldloc, + Ldloca, + Stloc, + Localloc, + Endfilter, + Unaligned, + Volatile, + Tail, + Initobj, + Constrained, + Cpblk, + Initblk, + No, + Rethrow, + Sizeof, + Refanytype, + Readonly, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeReader.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeReader.cs new file mode 100644 index 00000000..fde16dec --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeReader.cs @@ -0,0 +1,394 @@ +// +// CodeReader.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.PE; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil.Cil +{ + + sealed class CodeReader : ByteBuffer + { + + readonly internal MetadataReader reader; + + int start; + Section code_section; + + MethodDefinition method; + MethodBody body; + + int Offset + { + get { return base.position - start; } + } + + public CodeReader(Section section, MetadataReader reader) + : base(section.Data) + { + this.code_section = section; + this.reader = reader; + } + + public MethodBody ReadMethodBody(MethodDefinition method) + { + this.method = method; + this.body = new MethodBody(method); + + reader.context = method; + + ReadMethodBody(); + + return this.body; + } + + public void MoveTo(int rva) + { + if (!IsInSection(rva)) + { + code_section = reader.image.GetSectionAtVirtualAddress((uint)rva); + Reset(code_section.Data); + } + + base.position = rva - (int)code_section.VirtualAddress; + } + + bool IsInSection(int rva) + { + return code_section.VirtualAddress <= rva && rva < code_section.VirtualAddress + code_section.SizeOfRawData; + } + + void ReadMethodBody() + { + MoveTo(method.RVA); + + var flags = ReadByte(); + switch (flags & 0x3) + { + case 0x2: // tiny + body.code_size = flags >> 2; + body.MaxStackSize = 8; + ReadCode(); + break; + case 0x3: // fat + base.position--; + ReadFatMethod(); + break; + default: + throw new InvalidOperationException(); + } + + var symbol_reader = reader.module.symbol_reader; + + if (symbol_reader != null) + { + var instructions = body.Instructions; + symbol_reader.Read(body, offset => GetInstruction(instructions, offset)); + } + } + + void ReadFatMethod() + { + var flags = ReadUInt16(); + body.max_stack_size = ReadUInt16(); + body.code_size = (int)ReadUInt32(); + body.local_var_token = new MetadataToken(ReadUInt32()); + body.init_locals = (flags & 0x10) != 0; + + if (body.local_var_token.RID != 0) + body.variables = ReadVariables(body.local_var_token); + + ReadCode(); + + if ((flags & 0x8) != 0) + ReadSection(); + } + + public VariableDefinitionCollection ReadVariables(MetadataToken local_var_token) + { + var position = reader.position; + var variables = reader.ReadVariables(local_var_token); + reader.position = position; + + return variables; + } + + void ReadCode() + { + start = position; + var code_size = body.code_size; + + if (code_size < 0 || buffer.Length <= (uint)(code_size + position)) + code_size = 0; + + var end = start + code_size; + var instructions = body.instructions = new InstructionCollection((code_size + 1) / 2); + + while (position < end) + { + var offset = base.position - start; + var opcode = ReadOpCode(); + var current = new Instruction(offset, opcode); + + if (opcode.OperandType != OperandType.InlineNone) + current.operand = ReadOperand(current); + + instructions.Add(current); + } + + ResolveBranches(instructions); + } + + OpCode ReadOpCode() + { + var il_opcode = ReadByte(); + return il_opcode != 0xfe + ? OpCodes.OneByteOpCode[il_opcode] + : OpCodes.TwoBytesOpCode[ReadByte()]; + } + + object ReadOperand(Instruction instruction) + { + switch (instruction.opcode.OperandType) + { + case OperandType.InlineSwitch: + var length = ReadInt32(); + var base_offset = Offset + (4 * length); + var branches = new int[length]; + for (int i = 0; i < length; i++) + branches[i] = base_offset + ReadInt32(); + return branches; + case OperandType.ShortInlineBrTarget: + return ReadSByte() + Offset; + case OperandType.InlineBrTarget: + return ReadInt32() + Offset; + case OperandType.ShortInlineI: + if (instruction.opcode == OpCodes.Ldc_I4_S) + return ReadSByte(); + + return ReadByte(); + case OperandType.InlineI: + return ReadInt32(); + case OperandType.ShortInlineR: + return ReadSingle(); + case OperandType.InlineR: + return ReadDouble(); + case OperandType.InlineI8: + return ReadInt64(); + case OperandType.ShortInlineVar: + return GetVariable(ReadByte()); + case OperandType.InlineVar: + return GetVariable(ReadUInt16()); + case OperandType.ShortInlineArg: + return GetParameter(ReadByte()); + case OperandType.InlineArg: + return GetParameter(ReadUInt16()); + case OperandType.InlineSig: + return GetCallSite(ReadToken()); + case OperandType.InlineString: + return GetString(ReadToken()); + case OperandType.InlineTok: + case OperandType.InlineType: + case OperandType.InlineMethod: + case OperandType.InlineField: + return reader.LookupToken(ReadToken()); + default: + throw new NotSupportedException(); + } + } + + public string GetString(MetadataToken token) + { + return reader.image.UserStringHeap.Read(token.RID); + } + + public ParameterDefinition GetParameter(int index) + { + return Mixin.GetParameter(body, index); + } + + public VariableDefinition GetVariable(int index) + { + return Mixin.GetVariable(body, index); + } + + public CallSite GetCallSite(MetadataToken token) + { + return reader.ReadCallSite(token); + } + + void ResolveBranches(Collection instructions) + { + var items = instructions.items; + var size = instructions.size; + + for (int i = 0; i < size; i++) + { + var instruction = items[i]; + switch (instruction.opcode.OperandType) + { + case OperandType.ShortInlineBrTarget: + case OperandType.InlineBrTarget: + instruction.operand = GetInstruction((int)instruction.operand); + break; + case OperandType.InlineSwitch: + var offsets = (int[])instruction.operand; + var branches = new Instruction[offsets.Length]; + for (int j = 0; j < offsets.Length; j++) + branches[j] = GetInstruction(offsets[j]); + + instruction.operand = branches; + break; + } + } + } + + Instruction GetInstruction(int offset) + { + return GetInstruction(body.Instructions, offset); + } + + static Instruction GetInstruction(Collection instructions, int offset) + { + var size = instructions.size; + var items = instructions.items; + if (offset < 0 || offset > items[size - 1].offset) + return null; + + int min = 0; + int max = size - 1; + while (min <= max) + { + int mid = min + ((max - min) / 2); + var instruction = items[mid]; + var instruction_offset = instruction.offset; + + if (offset == instruction_offset) + return instruction; + + if (offset < instruction_offset) + max = mid - 1; + else + min = mid + 1; + } + + return null; + } + + void ReadSection() + { + Align(4); + + const byte fat_format = 0x40; + const byte more_sects = 0x80; + + var flags = ReadByte(); + if ((flags & fat_format) == 0) + ReadSmallSection(); + else + ReadFatSection(); + + if ((flags & more_sects) != 0) + ReadSection(); + } + + void ReadSmallSection() + { + var count = ReadByte() / 12; + Advance(2); + + ReadExceptionHandlers( + count, + () => (int)ReadUInt16(), + () => (int)ReadByte()); + } + + void ReadFatSection() + { + position--; + var count = (ReadInt32() >> 8) / 24; + + ReadExceptionHandlers( + count, + ReadInt32, + ReadInt32); + } + + // inline ? + void ReadExceptionHandlers(int count, Func read_entry, Func read_length) + { + for (int i = 0; i < count; i++) + { + var handler = new ExceptionHandler( + (ExceptionHandlerType)(read_entry() & 0x7)); + + handler.TryStart = GetInstruction(read_entry()); + handler.TryEnd = GetInstruction(handler.TryStart.Offset + read_length()); + + handler.HandlerStart = GetInstruction(read_entry()); + handler.HandlerEnd = GetInstruction(handler.HandlerStart.Offset + read_length()); + + ReadExceptionHandlerSpecific(handler); + + this.body.ExceptionHandlers.Add(handler); + } + } + + void ReadExceptionHandlerSpecific(ExceptionHandler handler) + { + switch (handler.HandlerType) + { + case ExceptionHandlerType.Catch: + handler.CatchType = (TypeReference)reader.LookupToken(ReadToken()); + break; + case ExceptionHandlerType.Filter: + handler.FilterStart = GetInstruction(ReadInt32()); + break; + default: + Advance(4); + break; + } + } + + void Align(int align) + { + align--; + Advance(((position + align) & ~align) - position); + } + + public MetadataToken ReadToken() + { + return new MetadataToken(ReadUInt32()); + } + + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeWriter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeWriter.cs new file mode 100644 index 00000000..7c41343c --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/CodeWriter.cs @@ -0,0 +1,38 @@ +// +// CodeWriter.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; + +using Mono.Collections.Generic; + +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using RVA = System.UInt32; + diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Document.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Document.cs new file mode 100644 index 00000000..1dbdc447 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Document.cs @@ -0,0 +1,112 @@ +// +// Document.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil.Cil { + + public enum DocumentType { + Other, + Text, + } + + public enum DocumentHashAlgorithm { + None, + MD5, + SHA1, + } + + public enum DocumentLanguage { + Other, + C, + Cpp, + CSharp, + Basic, + Java, + Cobol, + Pascal, + Cil, + JScript, + Smc, + MCpp, + FSharp, + } + + public enum DocumentLanguageVendor { + Other, + Microsoft, + } + + public sealed class Document { + + string url; + + byte type; + byte hash_algorithm; + byte language; + byte language_vendor; + + byte [] hash; + + public string Url { + get { return url; } + set { url = value; } + } + + public DocumentType Type { + get { return (DocumentType) type; } + set { type = (byte) value; } + } + + public DocumentHashAlgorithm HashAlgorithm { + get { return (DocumentHashAlgorithm) hash_algorithm; } + set { hash_algorithm = (byte) value; } + } + + public DocumentLanguage Language { + get { return (DocumentLanguage) language; } + set { language = (byte) value; } + } + + public DocumentLanguageVendor LanguageVendor { + get { return (DocumentLanguageVendor) language_vendor; } + set { language_vendor = (byte) value; } + } + + public byte [] Hash { + get { return hash; } + set { hash = value; } + } + + public Document (string url) + { + this.url = url; + this.hash = Empty.Array; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ExceptionHandler.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ExceptionHandler.cs new file mode 100644 index 00000000..c61ff235 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ExceptionHandler.cs @@ -0,0 +1,89 @@ +// +// ExceptionHandler.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Cil { + + public enum ExceptionHandlerType { + Catch = 0, + Filter = 1, + Finally = 2, + Fault = 4, + } + + public sealed class ExceptionHandler { + + Instruction try_start; + Instruction try_end; + Instruction filter_start; + Instruction handler_start; + Instruction handler_end; + + TypeReference catch_type; + ExceptionHandlerType handler_type; + + public Instruction TryStart { + get { return try_start; } + set { try_start = value; } + } + + public Instruction TryEnd { + get { return try_end; } + set { try_end = value; } + } + + public Instruction FilterStart { + get { return filter_start; } + set { filter_start = value; } + } + + public Instruction HandlerStart { + get { return handler_start; } + set { handler_start = value; } + } + + public Instruction HandlerEnd { + get { return handler_end; } + set { handler_end = value; } + } + + public TypeReference CatchType { + get { return catch_type; } + set { catch_type = value; } + } + + public ExceptionHandlerType HandlerType { + get { return handler_type; } + set { handler_type = value; } + } + + public ExceptionHandler (ExceptionHandlerType handlerType) + { + this.handler_type = handlerType; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ILProcessor.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ILProcessor.cs new file mode 100644 index 00000000..64368e62 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/ILProcessor.cs @@ -0,0 +1,278 @@ +// +// ILProcessor.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil.Cil { + + public sealed class ILProcessor { + + readonly MethodBody body; + readonly Collection instructions; + + public MethodBody Body { + get { return body; } + } + + internal ILProcessor (MethodBody body) + { + this.body = body; + this.instructions = body.Instructions; + } + + public Instruction Create (OpCode opcode) + { + return Instruction.Create (opcode); + } + + public Instruction Create (OpCode opcode, TypeReference type) + { + return Instruction.Create (opcode, type); + } + + public Instruction Create (OpCode opcode, CallSite site) + { + return Instruction.Create (opcode, site); + } + + public Instruction Create (OpCode opcode, MethodReference method) + { + return Instruction.Create (opcode, method); + } + + public Instruction Create (OpCode opcode, FieldReference field) + { + return Instruction.Create (opcode, field); + } + + public Instruction Create (OpCode opcode, string value) + { + return Instruction.Create (opcode, value); + } + + public Instruction Create (OpCode opcode, sbyte value) + { + return Instruction.Create (opcode, value); + } + + public Instruction Create (OpCode opcode, byte value) + { + if (opcode.OperandType == OperandType.ShortInlineVar) + return Instruction.Create (opcode, body.Variables [value]); + + if (opcode.OperandType == OperandType.ShortInlineArg) + return Instruction.Create (opcode, Mixin.GetParameter (body,value)); + + return Instruction.Create (opcode, value); + } + + public Instruction Create (OpCode opcode, int value) + { + if (opcode.OperandType == OperandType.InlineVar) + return Instruction.Create (opcode, body.Variables [value]); + + if (opcode.OperandType == OperandType.InlineArg) + return Instruction.Create (opcode, Mixin.GetParameter (body,value)); + + return Instruction.Create (opcode, value); + } + + public Instruction Create (OpCode opcode, long value) + { + return Instruction.Create (opcode, value); + } + + public Instruction Create (OpCode opcode, float value) + { + return Instruction.Create (opcode, value); + } + + public Instruction Create (OpCode opcode, double value) + { + return Instruction.Create (opcode, value); + } + + public Instruction Create (OpCode opcode, Instruction target) + { + return Instruction.Create (opcode, target); + } + + public Instruction Create (OpCode opcode, Instruction [] targets) + { + return Instruction.Create (opcode, targets); + } + + public Instruction Create (OpCode opcode, VariableDefinition variable) + { + return Instruction.Create (opcode, variable); + } + + public Instruction Create (OpCode opcode, ParameterDefinition parameter) + { + return Instruction.Create (opcode, parameter); + } + + public void Emit (OpCode opcode) + { + Append (Create (opcode)); + } + + public void Emit (OpCode opcode, TypeReference type) + { + Append (Create (opcode, type)); + } + + public void Emit (OpCode opcode, MethodReference method) + { + Append (Create (opcode, method)); + } + + public void Emit (OpCode opcode, CallSite site) + { + Append (Create (opcode, site)); + } + + public void Emit (OpCode opcode, FieldReference field) + { + Append (Create (opcode, field)); + } + + public void Emit (OpCode opcode, string value) + { + Append (Create (opcode, value)); + } + + public void Emit (OpCode opcode, byte value) + { + Append (Create (opcode, value)); + } + + public void Emit (OpCode opcode, sbyte value) + { + Append (Create (opcode, value)); + } + + public void Emit (OpCode opcode, int value) + { + Append (Create (opcode, value)); + } + + public void Emit (OpCode opcode, long value) + { + Append (Create (opcode, value)); + } + + public void Emit (OpCode opcode, float value) + { + Append (Create (opcode, value)); + } + + public void Emit (OpCode opcode, double value) + { + Append (Create (opcode, value)); + } + + public void Emit (OpCode opcode, Instruction target) + { + Append (Create (opcode, target)); + } + + public void Emit (OpCode opcode, Instruction [] targets) + { + Append (Create (opcode, targets)); + } + + public void Emit (OpCode opcode, VariableDefinition variable) + { + Append (Create (opcode, variable)); + } + + public void Emit (OpCode opcode, ParameterDefinition parameter) + { + Append (Create (opcode, parameter)); + } + + public void InsertBefore (Instruction target, Instruction instruction) + { + if (target == null) + throw new ArgumentNullException ("target"); + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + var index = instructions.IndexOf (target); + if (index == -1) + throw new ArgumentOutOfRangeException ("target"); + + instructions.Insert (index, instruction); + } + + public void InsertAfter (Instruction target, Instruction instruction) + { + if (target == null) + throw new ArgumentNullException ("target"); + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + var index = instructions.IndexOf (target); + if (index == -1) + throw new ArgumentOutOfRangeException ("target"); + + instructions.Insert (index + 1, instruction); + } + + public void Append (Instruction instruction) + { + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + instructions.Add (instruction); + } + + public void Replace (Instruction target, Instruction instruction) + { + if (target == null) + throw new ArgumentNullException ("target"); + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + InsertAfter (target, instruction); + Remove (target); + } + + public void Remove (Instruction instruction) + { + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + if (!instructions.Remove (instruction)) + throw new ArgumentOutOfRangeException ("instruction"); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Instruction.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Instruction.cs new file mode 100644 index 00000000..c28d4c99 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Instruction.cs @@ -0,0 +1,321 @@ +// +// Instruction.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; + +namespace Mono.Cecil.Cil { + + public sealed class Instruction { + + internal int offset; + internal OpCode opcode; + internal object operand; + + internal Instruction previous; + internal Instruction next; + + SequencePoint sequence_point; + + public int Offset { + get { return offset; } + set { offset = value; } + } + + public OpCode OpCode { + get { return opcode; } + set { opcode = value; } + } + + public object Operand { + get { return operand; } + set { operand = value; } + } + + public Instruction Previous { + get { return previous; } + set { previous = value; } + } + + public Instruction Next { + get { return next; } + set { next = value; } + } + + public SequencePoint SequencePoint { + get { return sequence_point; } + set { sequence_point = value; } + } + + internal Instruction (int offset, OpCode opCode) + { + this.offset = offset; + this.opcode = opCode; + } + + internal Instruction (OpCode opcode, object operand) + { + this.opcode = opcode; + this.operand = operand; + } + + public int GetSize () + { + int size = opcode.Size; + + switch (opcode.OperandType) { + case OperandType.InlineSwitch: + return size + (1 + ((Instruction []) operand).Length) * 4; + case OperandType.InlineI8: + case OperandType.InlineR: + return size + 8; + case OperandType.InlineBrTarget: + case OperandType.InlineField: + case OperandType.InlineI: + case OperandType.InlineMethod: + case OperandType.InlineString: + case OperandType.InlineTok: + case OperandType.InlineType: + case OperandType.ShortInlineR: + case OperandType.InlineSig: + return size + 4; + case OperandType.InlineArg: + case OperandType.InlineVar: + return size + 2; + case OperandType.ShortInlineBrTarget: + case OperandType.ShortInlineI: + case OperandType.ShortInlineArg: + case OperandType.ShortInlineVar: + return size + 1; + default: + return size; + } + } + + public override string ToString () + { + var instruction = new StringBuilder (); + + AppendLabel (instruction, this); + instruction.Append (':'); + instruction.Append (' '); + instruction.Append (opcode.Name); + + if (operand == null) + return instruction.ToString (); + + instruction.Append (' '); + + switch (opcode.OperandType) { + case OperandType.ShortInlineBrTarget: + case OperandType.InlineBrTarget: + AppendLabel (instruction, (Instruction) operand); + break; + case OperandType.InlineSwitch: + var labels = (Instruction []) operand; + for (int i = 0; i < labels.Length; i++) { + if (i > 0) + instruction.Append (','); + + AppendLabel (instruction, labels [i]); + } + break; + case OperandType.InlineString: + instruction.Append ('\"'); + instruction.Append (operand); + instruction.Append ('\"'); + break; + default: + instruction.Append (operand); + break; + } + + return instruction.ToString (); + } + + static void AppendLabel (StringBuilder builder, Instruction instruction) + { + builder.Append ("IL_"); + builder.Append (instruction.offset.ToString ("x4")); + } + + public static Instruction Create (OpCode opcode) + { + if (opcode.OperandType != OperandType.InlineNone) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, null); + } + + public static Instruction Create (OpCode opcode, TypeReference type) + { + if (type == null) + throw new ArgumentNullException ("type"); + if (opcode.OperandType != OperandType.InlineType && + opcode.OperandType != OperandType.InlineTok) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, type); + } + + public static Instruction Create (OpCode opcode, CallSite site) + { + if (site == null) + throw new ArgumentNullException ("site"); + if (opcode.Code != Code.Calli) + throw new ArgumentException ("code"); + + return new Instruction (opcode, site); + } + + public static Instruction Create (OpCode opcode, MethodReference method) + { + if (method == null) + throw new ArgumentNullException ("method"); + if (opcode.OperandType != OperandType.InlineMethod && + opcode.OperandType != OperandType.InlineTok) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, method); + } + + public static Instruction Create (OpCode opcode, FieldReference field) + { + if (field == null) + throw new ArgumentNullException ("field"); + if (opcode.OperandType != OperandType.InlineField && + opcode.OperandType != OperandType.InlineTok) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, field); + } + + public static Instruction Create (OpCode opcode, string value) + { + if (value == null) + throw new ArgumentNullException ("value"); + if (opcode.OperandType != OperandType.InlineString) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, value); + } + + public static Instruction Create (OpCode opcode, sbyte value) + { + if (opcode.OperandType != OperandType.ShortInlineI && + opcode != OpCodes.Ldc_I4_S) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, value); + } + + public static Instruction Create (OpCode opcode, byte value) + { + if (opcode.OperandType != OperandType.ShortInlineI || + opcode == OpCodes.Ldc_I4_S) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, value); + } + + public static Instruction Create (OpCode opcode, int value) + { + if (opcode.OperandType != OperandType.InlineI) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, value); + } + + public static Instruction Create (OpCode opcode, long value) + { + if (opcode.OperandType != OperandType.InlineI8) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, value); + } + + public static Instruction Create (OpCode opcode, float value) + { + if (opcode.OperandType != OperandType.ShortInlineR) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, value); + } + + public static Instruction Create (OpCode opcode, double value) + { + if (opcode.OperandType != OperandType.InlineR) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, value); + } + + public static Instruction Create (OpCode opcode, Instruction target) + { + if (target == null) + throw new ArgumentNullException ("target"); + if (opcode.OperandType != OperandType.InlineBrTarget && + opcode.OperandType != OperandType.ShortInlineBrTarget) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, target); + } + + public static Instruction Create (OpCode opcode, Instruction [] targets) + { + if (targets == null) + throw new ArgumentNullException ("targets"); + if (opcode.OperandType != OperandType.InlineSwitch) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, targets); + } + + public static Instruction Create (OpCode opcode, VariableDefinition variable) + { + if (variable == null) + throw new ArgumentNullException ("variable"); + if (opcode.OperandType != OperandType.ShortInlineVar && + opcode.OperandType != OperandType.InlineVar) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, variable); + } + + public static Instruction Create (OpCode opcode, ParameterDefinition parameter) + { + if (parameter == null) + throw new ArgumentNullException ("parameter"); + if (opcode.OperandType != OperandType.ShortInlineArg && + opcode.OperandType != OperandType.InlineArg) + throw new ArgumentException ("opcode"); + + return new Instruction (opcode, parameter); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/MethodBody.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/MethodBody.cs new file mode 100644 index 00000000..29045cd4 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/MethodBody.cs @@ -0,0 +1,267 @@ +// +// MethodBody.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Threading; + +using Mono.Collections.Generic; + +namespace Mono.Cecil.Cil +{ + + public sealed class MethodBody : IVariableDefinitionProvider + { + + readonly internal MethodDefinition method; + + internal ParameterDefinition this_parameter; + internal int max_stack_size; + internal int code_size; + internal bool init_locals; + internal MetadataToken local_var_token; + + internal Collection instructions; + internal Collection exceptions; + internal Collection variables; + Scope scope; + + public MethodDefinition Method + { + get { return method; } + } + + public int MaxStackSize + { + get { return max_stack_size; } + set { max_stack_size = value; } + } + + public int CodeSize + { + get { return code_size; } + } + + public bool InitLocals + { + get { return init_locals; } + set { init_locals = value; } + } + + public MetadataToken LocalVarToken + { + get { return local_var_token; } + set { local_var_token = value; } + } + + public Collection Instructions + { + get { return instructions ?? (instructions = new InstructionCollection()); } + } + + public bool HasExceptionHandlers + { + get { return !Mixin.IsNullOrEmpty(exceptions); } + } + + public Collection ExceptionHandlers + { + get { return exceptions ?? (exceptions = new Collection()); } + } + + public bool HasVariables + { + get { return !Mixin.IsNullOrEmpty(variables); } + } + + public Collection Variables + { + get { return variables ?? (variables = new VariableDefinitionCollection()); } + } + + public Scope Scope + { + get { return scope; } + set { scope = value; } + } + + public ParameterDefinition ThisParameter + { + get + { + if (method == null || method.DeclaringType == null) + throw new NotSupportedException(); + + if (!method.HasThis) + return null; + + if (this_parameter == null) + this_parameter = ThisParameterFor(method); + + return this_parameter; + } + } + + static ParameterDefinition ThisParameterFor(MethodDefinition method) + { + var declaring_type = method.DeclaringType; + var type = declaring_type.IsValueType || declaring_type.IsPrimitive + ? new PointerType(declaring_type) + : declaring_type as TypeReference; + + return new ParameterDefinition(type, method); + } + + public MethodBody(MethodDefinition method) + { + this.method = method; + } + + public ILProcessor GetILProcessor() + { + return new ILProcessor(this); + } + } + + public interface IVariableDefinitionProvider + { + bool HasVariables { get; } + Collection Variables { get; } + } + + class VariableDefinitionCollection : Collection + { + + internal VariableDefinitionCollection() + { + } + + internal VariableDefinitionCollection(int capacity) + : base(capacity) + { + } + + protected override void OnAdd(VariableDefinition item, int index) + { + item.index = index; + } + + protected override void OnInsert(VariableDefinition item, int index) + { + item.index = index; + + for (int i = index; i < size; i++) + items[i].index = i + 1; + } + + protected override void OnSet(VariableDefinition item, int index) + { + item.index = index; + } + + protected override void OnRemove(VariableDefinition item, int index) + { + item.index = -1; + + for (int i = index + 1; i < size; i++) + items[i].index = i - 1; + } + } + + class InstructionCollection : Collection + { + + internal InstructionCollection() + { + } + + internal InstructionCollection(int capacity) + : base(capacity) + { + } + + protected override void OnAdd(Instruction item, int index) + { + if (index == 0) + return; + + var previous = items[index - 1]; + previous.next = item; + item.previous = previous; + } + + protected override void OnInsert(Instruction item, int index) + { + if (size == 0) + return; + + var current = items[index]; + if (current == null) + { + var last = items[index - 1]; + last.next = item; + item.previous = last; + return; + } + + var previous = current.previous; + if (previous != null) + { + previous.next = item; + item.previous = previous; + } + + current.previous = item; + item.next = current; + } + + protected override void OnSet(Instruction item, int index) + { + var current = items[index]; + + item.previous = current.previous; + item.next = current.next; + + current.previous = null; + current.next = null; + } + + protected override void OnRemove(Instruction item, int index) + { + var previous = item.previous; + if (previous != null) + previous.next = item.next; + + var next = item.next; + if (next != null) + next.previous = item.previous; + + item.previous = null; + item.next = null; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCode.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCode.cs new file mode 100644 index 00000000..1a144213 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCode.cs @@ -0,0 +1,455 @@ +// +// OpCode.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Cil { + + public enum FlowControl { + Branch, + Break, + Call, + Cond_Branch, + Meta, + Next, + Phi, + Return, + Throw, + } + + public enum OpCodeType { + Annotation, + Macro, + Nternal, + Objmodel, + Prefix, + Primitive, + } + + public enum OperandType { + InlineBrTarget, + InlineField, + InlineI, + InlineI8, + InlineMethod, + InlineNone, + InlinePhi, + InlineR, + InlineSig, + InlineString, + InlineSwitch, + InlineTok, + InlineType, + InlineVar, + InlineArg, + ShortInlineBrTarget, + ShortInlineI, + ShortInlineR, + ShortInlineVar, + ShortInlineArg, + } + + public enum StackBehaviour { + Pop0, + Pop1, + Pop1_pop1, + Popi, + Popi_pop1, + Popi_popi, + Popi_popi8, + Popi_popi_popi, + Popi_popr4, + Popi_popr8, + Popref, + Popref_pop1, + Popref_popi, + Popref_popi_popi, + Popref_popi_popi8, + Popref_popi_popr4, + Popref_popi_popr8, + Popref_popi_popref, + PopAll, + Push0, + Push1, + Push1_push1, + Pushi, + Pushi8, + Pushr4, + Pushr8, + Pushref, + Varpop, + Varpush, + } + + public struct OpCode { + + readonly byte op1; + readonly byte op2; + readonly byte code; + readonly byte flow_control; + readonly byte opcode_type; + readonly byte operand_type; + readonly byte stack_behavior_pop; + readonly byte stack_behavior_push; + + public string Name { + get { return OpCodeNames.names [(int) Code]; } + } + + public int Size { + get { return op1 == 0xff ? 1 : 2; } + } + + public byte Op1 { + get { return op1; } + } + + public byte Op2 { + get { return op2; } + } + + public short Value { + get { return op1 == 0xff ? op2 : (short) ((op1 << 8) | op2); } + } + + public Code Code { + get { return (Code) code; } + } + + public FlowControl FlowControl { + get { return (FlowControl) flow_control; } + } + + public OpCodeType OpCodeType { + get { return (OpCodeType) opcode_type; } + } + + public OperandType OperandType { + get { return (OperandType) operand_type; } + } + + public StackBehaviour StackBehaviourPop { + get { return (StackBehaviour) stack_behavior_pop; } + } + + public StackBehaviour StackBehaviourPush { + get { return (StackBehaviour) stack_behavior_push; } + } + + internal OpCode (int x, int y) + { + this.op1 = (byte) ((x >> 0) & 0xff); + this.op2 = (byte) ((x >> 8) & 0xff); + this.code = (byte) ((x >> 16) & 0xff); + this.flow_control = (byte) ((x >> 24) & 0xff); + + this.opcode_type = (byte) ((y >> 0) & 0xff); + this.operand_type = (byte) ((y >> 8) & 0xff); + this.stack_behavior_pop = (byte) ((y >> 16) & 0xff); + this.stack_behavior_push = (byte) ((y >> 24) & 0xff); + + if (op1 == 0xff) + OpCodes.OneByteOpCode [op2] = this; + else + OpCodes.TwoBytesOpCode [op2] = this; + } + + public override int GetHashCode () + { + return Value; + } + + public override bool Equals (object obj) + { + if (!(obj is OpCode)) + return false; + + var opcode = (OpCode) obj; + return op1 == opcode.op1 && op2 == opcode.op2; + } + + public bool Equals (OpCode opcode) + { + return op1 == opcode.op1 && op2 == opcode.op2; + } + + public static bool operator == (OpCode one, OpCode other) + { + return one.op1 == other.op1 && one.op2 == other.op2; + } + + public static bool operator != (OpCode one, OpCode other) + { + return one.op1 != other.op1 || one.op2 != other.op2; + } + + public override string ToString () + { + return Name; + } + } + + static class OpCodeNames { + + internal static readonly string [] names; + + static OpCodeNames () + { + var table = new byte [] { + 3, 110, 111, 112, + 5, 98, 114, 101, 97, 107, + 7, 108, 100, 97, 114, 103, 46, 48, + 7, 108, 100, 97, 114, 103, 46, 49, + 7, 108, 100, 97, 114, 103, 46, 50, + 7, 108, 100, 97, 114, 103, 46, 51, + 7, 108, 100, 108, 111, 99, 46, 48, + 7, 108, 100, 108, 111, 99, 46, 49, + 7, 108, 100, 108, 111, 99, 46, 50, + 7, 108, 100, 108, 111, 99, 46, 51, + 7, 115, 116, 108, 111, 99, 46, 48, + 7, 115, 116, 108, 111, 99, 46, 49, + 7, 115, 116, 108, 111, 99, 46, 50, + 7, 115, 116, 108, 111, 99, 46, 51, + 7, 108, 100, 97, 114, 103, 46, 115, + 8, 108, 100, 97, 114, 103, 97, 46, 115, + 7, 115, 116, 97, 114, 103, 46, 115, + 7, 108, 100, 108, 111, 99, 46, 115, + 8, 108, 100, 108, 111, 99, 97, 46, 115, + 7, 115, 116, 108, 111, 99, 46, 115, + 6, 108, 100, 110, 117, 108, 108, + 9, 108, 100, 99, 46, 105, 52, 46, 109, 49, + 8, 108, 100, 99, 46, 105, 52, 46, 48, + 8, 108, 100, 99, 46, 105, 52, 46, 49, + 8, 108, 100, 99, 46, 105, 52, 46, 50, + 8, 108, 100, 99, 46, 105, 52, 46, 51, + 8, 108, 100, 99, 46, 105, 52, 46, 52, + 8, 108, 100, 99, 46, 105, 52, 46, 53, + 8, 108, 100, 99, 46, 105, 52, 46, 54, + 8, 108, 100, 99, 46, 105, 52, 46, 55, + 8, 108, 100, 99, 46, 105, 52, 46, 56, + 8, 108, 100, 99, 46, 105, 52, 46, 115, + 6, 108, 100, 99, 46, 105, 52, + 6, 108, 100, 99, 46, 105, 56, + 6, 108, 100, 99, 46, 114, 52, + 6, 108, 100, 99, 46, 114, 56, + 3, 100, 117, 112, + 3, 112, 111, 112, + 3, 106, 109, 112, + 4, 99, 97, 108, 108, + 5, 99, 97, 108, 108, 105, + 3, 114, 101, 116, + 4, 98, 114, 46, 115, + 9, 98, 114, 102, 97, 108, 115, 101, 46, 115, + 8, 98, 114, 116, 114, 117, 101, 46, 115, + 5, 98, 101, 113, 46, 115, + 5, 98, 103, 101, 46, 115, + 5, 98, 103, 116, 46, 115, + 5, 98, 108, 101, 46, 115, + 5, 98, 108, 116, 46, 115, + 8, 98, 110, 101, 46, 117, 110, 46, 115, + 8, 98, 103, 101, 46, 117, 110, 46, 115, + 8, 98, 103, 116, 46, 117, 110, 46, 115, + 8, 98, 108, 101, 46, 117, 110, 46, 115, + 8, 98, 108, 116, 46, 117, 110, 46, 115, + 2, 98, 114, + 7, 98, 114, 102, 97, 108, 115, 101, + 6, 98, 114, 116, 114, 117, 101, + 3, 98, 101, 113, + 3, 98, 103, 101, + 3, 98, 103, 116, + 3, 98, 108, 101, + 3, 98, 108, 116, + 6, 98, 110, 101, 46, 117, 110, + 6, 98, 103, 101, 46, 117, 110, + 6, 98, 103, 116, 46, 117, 110, + 6, 98, 108, 101, 46, 117, 110, + 6, 98, 108, 116, 46, 117, 110, + 6, 115, 119, 105, 116, 99, 104, + 8, 108, 100, 105, 110, 100, 46, 105, 49, + 8, 108, 100, 105, 110, 100, 46, 117, 49, + 8, 108, 100, 105, 110, 100, 46, 105, 50, + 8, 108, 100, 105, 110, 100, 46, 117, 50, + 8, 108, 100, 105, 110, 100, 46, 105, 52, + 8, 108, 100, 105, 110, 100, 46, 117, 52, + 8, 108, 100, 105, 110, 100, 46, 105, 56, + 7, 108, 100, 105, 110, 100, 46, 105, + 8, 108, 100, 105, 110, 100, 46, 114, 52, + 8, 108, 100, 105, 110, 100, 46, 114, 56, + 9, 108, 100, 105, 110, 100, 46, 114, 101, 102, + 9, 115, 116, 105, 110, 100, 46, 114, 101, 102, + 8, 115, 116, 105, 110, 100, 46, 105, 49, + 8, 115, 116, 105, 110, 100, 46, 105, 50, + 8, 115, 116, 105, 110, 100, 46, 105, 52, + 8, 115, 116, 105, 110, 100, 46, 105, 56, + 8, 115, 116, 105, 110, 100, 46, 114, 52, + 8, 115, 116, 105, 110, 100, 46, 114, 56, + 3, 97, 100, 100, + 3, 115, 117, 98, + 3, 109, 117, 108, + 3, 100, 105, 118, + 6, 100, 105, 118, 46, 117, 110, + 3, 114, 101, 109, + 6, 114, 101, 109, 46, 117, 110, + 3, 97, 110, 100, + 2, 111, 114, + 3, 120, 111, 114, + 3, 115, 104, 108, + 3, 115, 104, 114, + 6, 115, 104, 114, 46, 117, 110, + 3, 110, 101, 103, + 3, 110, 111, 116, + 7, 99, 111, 110, 118, 46, 105, 49, + 7, 99, 111, 110, 118, 46, 105, 50, + 7, 99, 111, 110, 118, 46, 105, 52, + 7, 99, 111, 110, 118, 46, 105, 56, + 7, 99, 111, 110, 118, 46, 114, 52, + 7, 99, 111, 110, 118, 46, 114, 56, + 7, 99, 111, 110, 118, 46, 117, 52, + 7, 99, 111, 110, 118, 46, 117, 56, + 8, 99, 97, 108, 108, 118, 105, 114, 116, + 5, 99, 112, 111, 98, 106, + 5, 108, 100, 111, 98, 106, + 5, 108, 100, 115, 116, 114, + 6, 110, 101, 119, 111, 98, 106, + 9, 99, 97, 115, 116, 99, 108, 97, 115, 115, + 6, 105, 115, 105, 110, 115, 116, + 9, 99, 111, 110, 118, 46, 114, 46, 117, 110, + 5, 117, 110, 98, 111, 120, + 5, 116, 104, 114, 111, 119, + 5, 108, 100, 102, 108, 100, + 6, 108, 100, 102, 108, 100, 97, + 5, 115, 116, 102, 108, 100, + 6, 108, 100, 115, 102, 108, 100, + 7, 108, 100, 115, 102, 108, 100, 97, + 6, 115, 116, 115, 102, 108, 100, + 5, 115, 116, 111, 98, 106, + 14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 49, 46, 117, 110, + 14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 50, 46, 117, 110, + 14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 52, 46, 117, 110, + 14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 56, 46, 117, 110, + 14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 49, 46, 117, 110, + 14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 50, 46, 117, 110, + 14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 52, 46, 117, 110, + 14, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 56, 46, 117, 110, + 13, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 46, 117, 110, + 13, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 46, 117, 110, + 3, 98, 111, 120, + 6, 110, 101, 119, 97, 114, 114, + 5, 108, 100, 108, 101, 110, + 7, 108, 100, 101, 108, 101, 109, 97, + 9, 108, 100, 101, 108, 101, 109, 46, 105, 49, + 9, 108, 100, 101, 108, 101, 109, 46, 117, 49, + 9, 108, 100, 101, 108, 101, 109, 46, 105, 50, + 9, 108, 100, 101, 108, 101, 109, 46, 117, 50, + 9, 108, 100, 101, 108, 101, 109, 46, 105, 52, + 9, 108, 100, 101, 108, 101, 109, 46, 117, 52, + 9, 108, 100, 101, 108, 101, 109, 46, 105, 56, + 8, 108, 100, 101, 108, 101, 109, 46, 105, + 9, 108, 100, 101, 108, 101, 109, 46, 114, 52, + 9, 108, 100, 101, 108, 101, 109, 46, 114, 56, + 10, 108, 100, 101, 108, 101, 109, 46, 114, 101, 102, + 8, 115, 116, 101, 108, 101, 109, 46, 105, + 9, 115, 116, 101, 108, 101, 109, 46, 105, 49, + 9, 115, 116, 101, 108, 101, 109, 46, 105, 50, + 9, 115, 116, 101, 108, 101, 109, 46, 105, 52, + 9, 115, 116, 101, 108, 101, 109, 46, 105, 56, + 9, 115, 116, 101, 108, 101, 109, 46, 114, 52, + 9, 115, 116, 101, 108, 101, 109, 46, 114, 56, + 10, 115, 116, 101, 108, 101, 109, 46, 114, 101, 102, + 10, 108, 100, 101, 108, 101, 109, 46, 97, 110, 121, + 10, 115, 116, 101, 108, 101, 109, 46, 97, 110, 121, + 9, 117, 110, 98, 111, 120, 46, 97, 110, 121, + 11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 49, + 11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 49, + 11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 50, + 11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 50, + 11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 52, + 11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 52, + 11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, 56, + 11, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, 56, + 9, 114, 101, 102, 97, 110, 121, 118, 97, 108, + 8, 99, 107, 102, 105, 110, 105, 116, 101, + 8, 109, 107, 114, 101, 102, 97, 110, 121, + 7, 108, 100, 116, 111, 107, 101, 110, + 7, 99, 111, 110, 118, 46, 117, 50, + 7, 99, 111, 110, 118, 46, 117, 49, + 6, 99, 111, 110, 118, 46, 105, + 10, 99, 111, 110, 118, 46, 111, 118, 102, 46, 105, + 10, 99, 111, 110, 118, 46, 111, 118, 102, 46, 117, + 7, 97, 100, 100, 46, 111, 118, 102, + 10, 97, 100, 100, 46, 111, 118, 102, 46, 117, 110, + 7, 109, 117, 108, 46, 111, 118, 102, + 10, 109, 117, 108, 46, 111, 118, 102, 46, 117, 110, + 7, 115, 117, 98, 46, 111, 118, 102, + 10, 115, 117, 98, 46, 111, 118, 102, 46, 117, 110, + 10, 101, 110, 100, 102, 105, 110, 97, 108, 108, 121, + 5, 108, 101, 97, 118, 101, + 7, 108, 101, 97, 118, 101, 46, 115, + 7, 115, 116, 105, 110, 100, 46, 105, + 6, 99, 111, 110, 118, 46, 117, + 7, 97, 114, 103, 108, 105, 115, 116, + 3, 99, 101, 113, + 3, 99, 103, 116, + 6, 99, 103, 116, 46, 117, 110, + 3, 99, 108, 116, + 6, 99, 108, 116, 46, 117, 110, + 5, 108, 100, 102, 116, 110, + 9, 108, 100, 118, 105, 114, 116, 102, 116, 110, + 5, 108, 100, 97, 114, 103, + 6, 108, 100, 97, 114, 103, 97, + 5, 115, 116, 97, 114, 103, + 5, 108, 100, 108, 111, 99, + 6, 108, 100, 108, 111, 99, 97, + 5, 115, 116, 108, 111, 99, + 8, 108, 111, 99, 97, 108, 108, 111, 99, + 9, 101, 110, 100, 102, 105, 108, 116, 101, 114, + 10, 117, 110, 97, 108, 105, 103, 110, 101, 100, 46, + 9, 118, 111, 108, 97, 116, 105, 108, 101, 46, + 5, 116, 97, 105, 108, 46, + 7, 105, 110, 105, 116, 111, 98, 106, + 12, 99, 111, 110, 115, 116, 114, 97, 105, 110, 101, 100, 46, + 5, 99, 112, 98, 108, 107, + 7, 105, 110, 105, 116, 98, 108, 107, + 3, 110, 111, 46, + 7, 114, 101, 116, 104, 114, 111, 119, + 6, 115, 105, 122, 101, 111, 102, + 10, 114, 101, 102, 97, 110, 121, 116, 121, 112, 101, + 9, 114, 101, 97, 100, 111, 110, 108, 121, 46, + }; + + names = new string [219]; + + for (int i = 0, p = 0; i < names.Length; i++) { + var buffer = new char [table [p++]]; + + for (int j = 0; j < buffer.Length; j++) + buffer [j] = (char) table [p++]; + + names [i] = new string (buffer); + } + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCodes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCodes.cs new file mode 100644 index 00000000..85712ec8 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/OpCodes.cs @@ -0,0 +1,912 @@ +// +// OpCodes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Cil { + + public static class OpCodes { + + internal static readonly OpCode [] OneByteOpCode = new OpCode [0xe0 + 1]; + internal static readonly OpCode [] TwoBytesOpCode = new OpCode [0x1e + 1]; + + public static readonly OpCode Nop = new OpCode ( + 0xff << 0 | 0x00 << 8 | (byte) Code.Nop << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Break = new OpCode ( + 0xff << 0 | 0x01 << 8 | (byte) Code.Break << 16 | (byte) FlowControl.Break << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldarg_0 = new OpCode ( + 0xff << 0 | 0x02 << 8 | (byte) Code.Ldarg_0 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldarg_1 = new OpCode ( + 0xff << 0 | 0x03 << 8 | (byte) Code.Ldarg_1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldarg_2 = new OpCode ( + 0xff << 0 | 0x04 << 8 | (byte) Code.Ldarg_2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldarg_3 = new OpCode ( + 0xff << 0 | 0x05 << 8 | (byte) Code.Ldarg_3 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldloc_0 = new OpCode ( + 0xff << 0 | 0x06 << 8 | (byte) Code.Ldloc_0 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldloc_1 = new OpCode ( + 0xff << 0 | 0x07 << 8 | (byte) Code.Ldloc_1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldloc_2 = new OpCode ( + 0xff << 0 | 0x08 << 8 | (byte) Code.Ldloc_2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldloc_3 = new OpCode ( + 0xff << 0 | 0x09 << 8 | (byte) Code.Ldloc_3 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Stloc_0 = new OpCode ( + 0xff << 0 | 0x0a << 8 | (byte) Code.Stloc_0 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stloc_1 = new OpCode ( + 0xff << 0 | 0x0b << 8 | (byte) Code.Stloc_1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stloc_2 = new OpCode ( + 0xff << 0 | 0x0c << 8 | (byte) Code.Stloc_2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stloc_3 = new OpCode ( + 0xff << 0 | 0x0d << 8 | (byte) Code.Stloc_3 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldarg_S = new OpCode ( + 0xff << 0 | 0x0e << 8 | (byte) Code.Ldarg_S << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineArg << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldarga_S = new OpCode ( + 0xff << 0 | 0x0f << 8 | (byte) Code.Ldarga_S << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineArg << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Starg_S = new OpCode ( + 0xff << 0 | 0x10 << 8 | (byte) Code.Starg_S << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineArg << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldloc_S = new OpCode ( + 0xff << 0 | 0x11 << 8 | (byte) Code.Ldloc_S << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineVar << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldloca_S = new OpCode ( + 0xff << 0 | 0x12 << 8 | (byte) Code.Ldloca_S << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineVar << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Stloc_S = new OpCode ( + 0xff << 0 | 0x13 << 8 | (byte) Code.Stloc_S << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineVar << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldnull = new OpCode ( + 0xff << 0 | 0x14 << 8 | (byte) Code.Ldnull << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushref << 24); + + public static readonly OpCode Ldc_I4_M1 = new OpCode ( + 0xff << 0 | 0x15 << 8 | (byte) Code.Ldc_I4_M1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_0 = new OpCode ( + 0xff << 0 | 0x16 << 8 | (byte) Code.Ldc_I4_0 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_1 = new OpCode ( + 0xff << 0 | 0x17 << 8 | (byte) Code.Ldc_I4_1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_2 = new OpCode ( + 0xff << 0 | 0x18 << 8 | (byte) Code.Ldc_I4_2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_3 = new OpCode ( + 0xff << 0 | 0x19 << 8 | (byte) Code.Ldc_I4_3 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_4 = new OpCode ( + 0xff << 0 | 0x1a << 8 | (byte) Code.Ldc_I4_4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_5 = new OpCode ( + 0xff << 0 | 0x1b << 8 | (byte) Code.Ldc_I4_5 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_6 = new OpCode ( + 0xff << 0 | 0x1c << 8 | (byte) Code.Ldc_I4_6 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_7 = new OpCode ( + 0xff << 0 | 0x1d << 8 | (byte) Code.Ldc_I4_7 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_8 = new OpCode ( + 0xff << 0 | 0x1e << 8 | (byte) Code.Ldc_I4_8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4_S = new OpCode ( + 0xff << 0 | 0x1f << 8 | (byte) Code.Ldc_I4_S << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineI << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I4 = new OpCode ( + 0xff << 0 | 0x20 << 8 | (byte) Code.Ldc_I4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineI << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldc_I8 = new OpCode ( + 0xff << 0 | 0x21 << 8 | (byte) Code.Ldc_I8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineI8 << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Ldc_R4 = new OpCode ( + 0xff << 0 | 0x22 << 8 | (byte) Code.Ldc_R4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.ShortInlineR << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushr4 << 24); + + public static readonly OpCode Ldc_R8 = new OpCode ( + 0xff << 0 | 0x23 << 8 | (byte) Code.Ldc_R8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineR << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushr8 << 24); + + public static readonly OpCode Dup = new OpCode ( + 0xff << 0 | 0x25 << 8 | (byte) Code.Dup << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push1_push1 << 24); + + public static readonly OpCode Pop = new OpCode ( + 0xff << 0 | 0x26 << 8 | (byte) Code.Pop << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Jmp = new OpCode ( + 0xff << 0 | 0x27 << 8 | (byte) Code.Jmp << 16 | (byte) FlowControl.Call << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Call = new OpCode ( + 0xff << 0 | 0x28 << 8 | (byte) Code.Call << 16 | (byte) FlowControl.Call << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Varpush << 24); + + public static readonly OpCode Calli = new OpCode ( + 0xff << 0 | 0x29 << 8 | (byte) Code.Calli << 16 | (byte) FlowControl.Call << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineSig << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Varpush << 24); + + public static readonly OpCode Ret = new OpCode ( + 0xff << 0 | 0x2a << 8 | (byte) Code.Ret << 16 | (byte) FlowControl.Return << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Br_S = new OpCode ( + 0xff << 0 | 0x2b << 8 | (byte) Code.Br_S << 16 | (byte) FlowControl.Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Brfalse_S = new OpCode ( + 0xff << 0 | 0x2c << 8 | (byte) Code.Brfalse_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Brtrue_S = new OpCode ( + 0xff << 0 | 0x2d << 8 | (byte) Code.Brtrue_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Beq_S = new OpCode ( + 0xff << 0 | 0x2e << 8 | (byte) Code.Beq_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bge_S = new OpCode ( + 0xff << 0 | 0x2f << 8 | (byte) Code.Bge_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bgt_S = new OpCode ( + 0xff << 0 | 0x30 << 8 | (byte) Code.Bgt_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ble_S = new OpCode ( + 0xff << 0 | 0x31 << 8 | (byte) Code.Ble_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Blt_S = new OpCode ( + 0xff << 0 | 0x32 << 8 | (byte) Code.Blt_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bne_Un_S = new OpCode ( + 0xff << 0 | 0x33 << 8 | (byte) Code.Bne_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bge_Un_S = new OpCode ( + 0xff << 0 | 0x34 << 8 | (byte) Code.Bge_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bgt_Un_S = new OpCode ( + 0xff << 0 | 0x35 << 8 | (byte) Code.Bgt_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ble_Un_S = new OpCode ( + 0xff << 0 | 0x36 << 8 | (byte) Code.Ble_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Blt_Un_S = new OpCode ( + 0xff << 0 | 0x37 << 8 | (byte) Code.Blt_Un_S << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Br = new OpCode ( + 0xff << 0 | 0x38 << 8 | (byte) Code.Br << 16 | (byte) FlowControl.Branch << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Brfalse = new OpCode ( + 0xff << 0 | 0x39 << 8 | (byte) Code.Brfalse << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Brtrue = new OpCode ( + 0xff << 0 | 0x3a << 8 | (byte) Code.Brtrue << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Beq = new OpCode ( + 0xff << 0 | 0x3b << 8 | (byte) Code.Beq << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bge = new OpCode ( + 0xff << 0 | 0x3c << 8 | (byte) Code.Bge << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bgt = new OpCode ( + 0xff << 0 | 0x3d << 8 | (byte) Code.Bgt << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ble = new OpCode ( + 0xff << 0 | 0x3e << 8 | (byte) Code.Ble << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Blt = new OpCode ( + 0xff << 0 | 0x3f << 8 | (byte) Code.Blt << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bne_Un = new OpCode ( + 0xff << 0 | 0x40 << 8 | (byte) Code.Bne_Un << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bge_Un = new OpCode ( + 0xff << 0 | 0x41 << 8 | (byte) Code.Bge_Un << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Bgt_Un = new OpCode ( + 0xff << 0 | 0x42 << 8 | (byte) Code.Bgt_Un << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ble_Un = new OpCode ( + 0xff << 0 | 0x43 << 8 | (byte) Code.Ble_Un << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Blt_Un = new OpCode ( + 0xff << 0 | 0x44 << 8 | (byte) Code.Blt_Un << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Switch = new OpCode ( + 0xff << 0 | 0x45 << 8 | (byte) Code.Switch << 16 | (byte) FlowControl.Cond_Branch << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineSwitch << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldind_I1 = new OpCode ( + 0xff << 0 | 0x46 << 8 | (byte) Code.Ldind_I1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldind_U1 = new OpCode ( + 0xff << 0 | 0x47 << 8 | (byte) Code.Ldind_U1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldind_I2 = new OpCode ( + 0xff << 0 | 0x48 << 8 | (byte) Code.Ldind_I2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldind_U2 = new OpCode ( + 0xff << 0 | 0x49 << 8 | (byte) Code.Ldind_U2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldind_I4 = new OpCode ( + 0xff << 0 | 0x4a << 8 | (byte) Code.Ldind_I4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldind_U4 = new OpCode ( + 0xff << 0 | 0x4b << 8 | (byte) Code.Ldind_U4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldind_I8 = new OpCode ( + 0xff << 0 | 0x4c << 8 | (byte) Code.Ldind_I8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Ldind_I = new OpCode ( + 0xff << 0 | 0x4d << 8 | (byte) Code.Ldind_I << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldind_R4 = new OpCode ( + 0xff << 0 | 0x4e << 8 | (byte) Code.Ldind_R4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushr4 << 24); + + public static readonly OpCode Ldind_R8 = new OpCode ( + 0xff << 0 | 0x4f << 8 | (byte) Code.Ldind_R8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushr8 << 24); + + public static readonly OpCode Ldind_Ref = new OpCode ( + 0xff << 0 | 0x50 << 8 | (byte) Code.Ldind_Ref << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushref << 24); + + public static readonly OpCode Stind_Ref = new OpCode ( + 0xff << 0 | 0x51 << 8 | (byte) Code.Stind_Ref << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stind_I1 = new OpCode ( + 0xff << 0 | 0x52 << 8 | (byte) Code.Stind_I1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stind_I2 = new OpCode ( + 0xff << 0 | 0x53 << 8 | (byte) Code.Stind_I2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stind_I4 = new OpCode ( + 0xff << 0 | 0x54 << 8 | (byte) Code.Stind_I4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stind_I8 = new OpCode ( + 0xff << 0 | 0x55 << 8 | (byte) Code.Stind_I8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi8 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stind_R4 = new OpCode ( + 0xff << 0 | 0x56 << 8 | (byte) Code.Stind_R4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popr4 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stind_R8 = new OpCode ( + 0xff << 0 | 0x57 << 8 | (byte) Code.Stind_R8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popr8 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Add = new OpCode ( + 0xff << 0 | 0x58 << 8 | (byte) Code.Add << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Sub = new OpCode ( + 0xff << 0 | 0x59 << 8 | (byte) Code.Sub << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Mul = new OpCode ( + 0xff << 0 | 0x5a << 8 | (byte) Code.Mul << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Div = new OpCode ( + 0xff << 0 | 0x5b << 8 | (byte) Code.Div << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Div_Un = new OpCode ( + 0xff << 0 | 0x5c << 8 | (byte) Code.Div_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Rem = new OpCode ( + 0xff << 0 | 0x5d << 8 | (byte) Code.Rem << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Rem_Un = new OpCode ( + 0xff << 0 | 0x5e << 8 | (byte) Code.Rem_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode And = new OpCode ( + 0xff << 0 | 0x5f << 8 | (byte) Code.And << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Or = new OpCode ( + 0xff << 0 | 0x60 << 8 | (byte) Code.Or << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Xor = new OpCode ( + 0xff << 0 | 0x61 << 8 | (byte) Code.Xor << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Shl = new OpCode ( + 0xff << 0 | 0x62 << 8 | (byte) Code.Shl << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Shr = new OpCode ( + 0xff << 0 | 0x63 << 8 | (byte) Code.Shr << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Shr_Un = new OpCode ( + 0xff << 0 | 0x64 << 8 | (byte) Code.Shr_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Neg = new OpCode ( + 0xff << 0 | 0x65 << 8 | (byte) Code.Neg << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Not = new OpCode ( + 0xff << 0 | 0x66 << 8 | (byte) Code.Not << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Conv_I1 = new OpCode ( + 0xff << 0 | 0x67 << 8 | (byte) Code.Conv_I1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_I2 = new OpCode ( + 0xff << 0 | 0x68 << 8 | (byte) Code.Conv_I2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_I4 = new OpCode ( + 0xff << 0 | 0x69 << 8 | (byte) Code.Conv_I4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_I8 = new OpCode ( + 0xff << 0 | 0x6a << 8 | (byte) Code.Conv_I8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Conv_R4 = new OpCode ( + 0xff << 0 | 0x6b << 8 | (byte) Code.Conv_R4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushr4 << 24); + + public static readonly OpCode Conv_R8 = new OpCode ( + 0xff << 0 | 0x6c << 8 | (byte) Code.Conv_R8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushr8 << 24); + + public static readonly OpCode Conv_U4 = new OpCode ( + 0xff << 0 | 0x6d << 8 | (byte) Code.Conv_U4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_U8 = new OpCode ( + 0xff << 0 | 0x6e << 8 | (byte) Code.Conv_U8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Callvirt = new OpCode ( + 0xff << 0 | 0x6f << 8 | (byte) Code.Callvirt << 16 | (byte) FlowControl.Call << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Varpush << 24); + + public static readonly OpCode Cpobj = new OpCode ( + 0xff << 0 | 0x70 << 8 | (byte) Code.Cpobj << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldobj = new OpCode ( + 0xff << 0 | 0x71 << 8 | (byte) Code.Ldobj << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldstr = new OpCode ( + 0xff << 0 | 0x72 << 8 | (byte) Code.Ldstr << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineString << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushref << 24); + + public static readonly OpCode Newobj = new OpCode ( + 0xff << 0 | 0x73 << 8 | (byte) Code.Newobj << 16 | (byte) FlowControl.Call << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Varpop << 16 | (byte) StackBehaviour.Pushref << 24); + + public static readonly OpCode Castclass = new OpCode ( + 0xff << 0 | 0x74 << 8 | (byte) Code.Castclass << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushref << 24); + + public static readonly OpCode Isinst = new OpCode ( + 0xff << 0 | 0x75 << 8 | (byte) Code.Isinst << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_R_Un = new OpCode ( + 0xff << 0 | 0x76 << 8 | (byte) Code.Conv_R_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushr8 << 24); + + public static readonly OpCode Unbox = new OpCode ( + 0xff << 0 | 0x79 << 8 | (byte) Code.Unbox << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Throw = new OpCode ( + 0xff << 0 | 0x7a << 8 | (byte) Code.Throw << 16 | (byte) FlowControl.Throw << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldfld = new OpCode ( + 0xff << 0 | 0x7b << 8 | (byte) Code.Ldfld << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldflda = new OpCode ( + 0xff << 0 | 0x7c << 8 | (byte) Code.Ldflda << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Stfld = new OpCode ( + 0xff << 0 | 0x7d << 8 | (byte) Code.Stfld << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Popref_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldsfld = new OpCode ( + 0xff << 0 | 0x7e << 8 | (byte) Code.Ldsfld << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldsflda = new OpCode ( + 0xff << 0 | 0x7f << 8 | (byte) Code.Ldsflda << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Stsfld = new OpCode ( + 0xff << 0 | 0x80 << 8 | (byte) Code.Stsfld << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineField << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stobj = new OpCode ( + 0xff << 0 | 0x81 << 8 | (byte) Code.Stobj << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi_pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Conv_Ovf_I1_Un = new OpCode ( + 0xff << 0 | 0x82 << 8 | (byte) Code.Conv_Ovf_I1_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_I2_Un = new OpCode ( + 0xff << 0 | 0x83 << 8 | (byte) Code.Conv_Ovf_I2_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_I4_Un = new OpCode ( + 0xff << 0 | 0x84 << 8 | (byte) Code.Conv_Ovf_I4_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_I8_Un = new OpCode ( + 0xff << 0 | 0x85 << 8 | (byte) Code.Conv_Ovf_I8_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Conv_Ovf_U1_Un = new OpCode ( + 0xff << 0 | 0x86 << 8 | (byte) Code.Conv_Ovf_U1_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_U2_Un = new OpCode ( + 0xff << 0 | 0x87 << 8 | (byte) Code.Conv_Ovf_U2_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_U4_Un = new OpCode ( + 0xff << 0 | 0x88 << 8 | (byte) Code.Conv_Ovf_U4_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_U8_Un = new OpCode ( + 0xff << 0 | 0x89 << 8 | (byte) Code.Conv_Ovf_U8_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Conv_Ovf_I_Un = new OpCode ( + 0xff << 0 | 0x8a << 8 | (byte) Code.Conv_Ovf_I_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_U_Un = new OpCode ( + 0xff << 0 | 0x8b << 8 | (byte) Code.Conv_Ovf_U_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Box = new OpCode ( + 0xff << 0 | 0x8c << 8 | (byte) Code.Box << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushref << 24); + + public static readonly OpCode Newarr = new OpCode ( + 0xff << 0 | 0x8d << 8 | (byte) Code.Newarr << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushref << 24); + + public static readonly OpCode Ldlen = new OpCode ( + 0xff << 0 | 0x8e << 8 | (byte) Code.Ldlen << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelema = new OpCode ( + 0xff << 0 | 0x8f << 8 | (byte) Code.Ldelema << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelem_I1 = new OpCode ( + 0xff << 0 | 0x90 << 8 | (byte) Code.Ldelem_I1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelem_U1 = new OpCode ( + 0xff << 0 | 0x91 << 8 | (byte) Code.Ldelem_U1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelem_I2 = new OpCode ( + 0xff << 0 | 0x92 << 8 | (byte) Code.Ldelem_I2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelem_U2 = new OpCode ( + 0xff << 0 | 0x93 << 8 | (byte) Code.Ldelem_U2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelem_I4 = new OpCode ( + 0xff << 0 | 0x94 << 8 | (byte) Code.Ldelem_I4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelem_U4 = new OpCode ( + 0xff << 0 | 0x95 << 8 | (byte) Code.Ldelem_U4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelem_I8 = new OpCode ( + 0xff << 0 | 0x96 << 8 | (byte) Code.Ldelem_I8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Ldelem_I = new OpCode ( + 0xff << 0 | 0x97 << 8 | (byte) Code.Ldelem_I << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldelem_R4 = new OpCode ( + 0xff << 0 | 0x98 << 8 | (byte) Code.Ldelem_R4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushr4 << 24); + + public static readonly OpCode Ldelem_R8 = new OpCode ( + 0xff << 0 | 0x99 << 8 | (byte) Code.Ldelem_R8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushr8 << 24); + + public static readonly OpCode Ldelem_Ref = new OpCode ( + 0xff << 0 | 0x9a << 8 | (byte) Code.Ldelem_Ref << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Pushref << 24); + + public static readonly OpCode Stelem_I = new OpCode ( + 0xff << 0 | 0x9b << 8 | (byte) Code.Stelem_I << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stelem_I1 = new OpCode ( + 0xff << 0 | 0x9c << 8 | (byte) Code.Stelem_I1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stelem_I2 = new OpCode ( + 0xff << 0 | 0x9d << 8 | (byte) Code.Stelem_I2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stelem_I4 = new OpCode ( + 0xff << 0 | 0x9e << 8 | (byte) Code.Stelem_I4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stelem_I8 = new OpCode ( + 0xff << 0 | 0x9f << 8 | (byte) Code.Stelem_I8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popi8 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stelem_R4 = new OpCode ( + 0xff << 0 | 0xa0 << 8 | (byte) Code.Stelem_R4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popr4 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stelem_R8 = new OpCode ( + 0xff << 0 | 0xa1 << 8 | (byte) Code.Stelem_R8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popr8 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stelem_Ref = new OpCode ( + 0xff << 0 | 0xa2 << 8 | (byte) Code.Stelem_Ref << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popref_popi_popref << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldelem_Any = new OpCode ( + 0xff << 0 | 0xa3 << 8 | (byte) Code.Ldelem_Any << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref_popi << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Stelem_Any = new OpCode ( + 0xff << 0 | 0xa4 << 8 | (byte) Code.Stelem_Any << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref_popi_popref << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Unbox_Any = new OpCode ( + 0xff << 0 | 0xa5 << 8 | (byte) Code.Unbox_Any << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Conv_Ovf_I1 = new OpCode ( + 0xff << 0 | 0xb3 << 8 | (byte) Code.Conv_Ovf_I1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_U1 = new OpCode ( + 0xff << 0 | 0xb4 << 8 | (byte) Code.Conv_Ovf_U1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_I2 = new OpCode ( + 0xff << 0 | 0xb5 << 8 | (byte) Code.Conv_Ovf_I2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_U2 = new OpCode ( + 0xff << 0 | 0xb6 << 8 | (byte) Code.Conv_Ovf_U2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_I4 = new OpCode ( + 0xff << 0 | 0xb7 << 8 | (byte) Code.Conv_Ovf_I4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_U4 = new OpCode ( + 0xff << 0 | 0xb8 << 8 | (byte) Code.Conv_Ovf_U4 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_I8 = new OpCode ( + 0xff << 0 | 0xb9 << 8 | (byte) Code.Conv_Ovf_I8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Conv_Ovf_U8 = new OpCode ( + 0xff << 0 | 0xba << 8 | (byte) Code.Conv_Ovf_U8 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi8 << 24); + + public static readonly OpCode Refanyval = new OpCode ( + 0xff << 0 | 0xc2 << 8 | (byte) Code.Refanyval << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ckfinite = new OpCode ( + 0xff << 0 | 0xc3 << 8 | (byte) Code.Ckfinite << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushr8 << 24); + + public static readonly OpCode Mkrefany = new OpCode ( + 0xff << 0 | 0xc6 << 8 | (byte) Code.Mkrefany << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldtoken = new OpCode ( + 0xff << 0 | 0xd0 << 8 | (byte) Code.Ldtoken << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineTok << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_U2 = new OpCode ( + 0xff << 0 | 0xd1 << 8 | (byte) Code.Conv_U2 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_U1 = new OpCode ( + 0xff << 0 | 0xd2 << 8 | (byte) Code.Conv_U1 << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_I = new OpCode ( + 0xff << 0 | 0xd3 << 8 | (byte) Code.Conv_I << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_I = new OpCode ( + 0xff << 0 | 0xd4 << 8 | (byte) Code.Conv_Ovf_I << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Conv_Ovf_U = new OpCode ( + 0xff << 0 | 0xd5 << 8 | (byte) Code.Conv_Ovf_U << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Add_Ovf = new OpCode ( + 0xff << 0 | 0xd6 << 8 | (byte) Code.Add_Ovf << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Add_Ovf_Un = new OpCode ( + 0xff << 0 | 0xd7 << 8 | (byte) Code.Add_Ovf_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Mul_Ovf = new OpCode ( + 0xff << 0 | 0xd8 << 8 | (byte) Code.Mul_Ovf << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Mul_Ovf_Un = new OpCode ( + 0xff << 0 | 0xd9 << 8 | (byte) Code.Mul_Ovf_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Sub_Ovf = new OpCode ( + 0xff << 0 | 0xda << 8 | (byte) Code.Sub_Ovf << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Sub_Ovf_Un = new OpCode ( + 0xff << 0 | 0xdb << 8 | (byte) Code.Sub_Ovf_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Endfinally = new OpCode ( + 0xff << 0 | 0xdc << 8 | (byte) Code.Endfinally << 16 | (byte) FlowControl.Return << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Leave = new OpCode ( + 0xff << 0 | 0xdd << 8 | (byte) Code.Leave << 16 | (byte) FlowControl.Branch << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineBrTarget << 8 | (byte) StackBehaviour.PopAll << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Leave_S = new OpCode ( + 0xff << 0 | 0xde << 8 | (byte) Code.Leave_S << 16 | (byte) FlowControl.Branch << 24, + (byte) OpCodeType.Macro << 0 | (byte) OperandType.ShortInlineBrTarget << 8 | (byte) StackBehaviour.PopAll << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Stind_I = new OpCode ( + 0xff << 0 | 0xdf << 8 | (byte) Code.Stind_I << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Conv_U = new OpCode ( + 0xff << 0 | 0xe0 << 8 | (byte) Code.Conv_U << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Arglist = new OpCode ( + 0xfe << 0 | 0x00 << 8 | (byte) Code.Arglist << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ceq = new OpCode ( + 0xfe << 0 | 0x01 << 8 | (byte) Code.Ceq << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Cgt = new OpCode ( + 0xfe << 0 | 0x02 << 8 | (byte) Code.Cgt << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Cgt_Un = new OpCode ( + 0xfe << 0 | 0x03 << 8 | (byte) Code.Cgt_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Clt = new OpCode ( + 0xfe << 0 | 0x04 << 8 | (byte) Code.Clt << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Clt_Un = new OpCode ( + 0xfe << 0 | 0x05 << 8 | (byte) Code.Clt_Un << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1_pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldftn = new OpCode ( + 0xfe << 0 | 0x06 << 8 | (byte) Code.Ldftn << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldvirtftn = new OpCode ( + 0xfe << 0 | 0x07 << 8 | (byte) Code.Ldvirtftn << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineMethod << 8 | (byte) StackBehaviour.Popref << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Ldarg = new OpCode ( + 0xfe << 0 | 0x09 << 8 | (byte) Code.Ldarg << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineArg << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldarga = new OpCode ( + 0xfe << 0 | 0x0a << 8 | (byte) Code.Ldarga << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineArg << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Starg = new OpCode ( + 0xfe << 0 | 0x0b << 8 | (byte) Code.Starg << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineArg << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Ldloc = new OpCode ( + 0xfe << 0 | 0x0c << 8 | (byte) Code.Ldloc << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineVar << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push1 << 24); + + public static readonly OpCode Ldloca = new OpCode ( + 0xfe << 0 | 0x0d << 8 | (byte) Code.Ldloca << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineVar << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Stloc = new OpCode ( + 0xfe << 0 | 0x0e << 8 | (byte) Code.Stloc << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineVar << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Localloc = new OpCode ( + 0xfe << 0 | 0x0f << 8 | (byte) Code.Localloc << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Endfilter = new OpCode ( + 0xfe << 0 | 0x11 << 8 | (byte) Code.Endfilter << 16 | (byte) FlowControl.Return << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Unaligned = new OpCode ( + 0xfe << 0 | 0x12 << 8 | (byte) Code.Unaligned << 16 | (byte) FlowControl.Meta << 24, + (byte) OpCodeType.Prefix << 0 | (byte) OperandType.ShortInlineI << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Volatile = new OpCode ( + 0xfe << 0 | 0x13 << 8 | (byte) Code.Volatile << 16 | (byte) FlowControl.Meta << 24, + (byte) OpCodeType.Prefix << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Tail = new OpCode ( + 0xfe << 0 | 0x14 << 8 | (byte) Code.Tail << 16 | (byte) FlowControl.Meta << 24, + (byte) OpCodeType.Prefix << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Initobj = new OpCode ( + 0xfe << 0 | 0x15 << 8 | (byte) Code.Initobj << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Constrained = new OpCode ( + 0xfe << 0 | 0x16 << 8 | (byte) Code.Constrained << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Prefix << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Cpblk = new OpCode ( + 0xfe << 0 | 0x17 << 8 | (byte) Code.Cpblk << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Initblk = new OpCode ( + 0xfe << 0 | 0x18 << 8 | (byte) Code.Initblk << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Popi_popi_popi << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode No = new OpCode ( + 0xfe << 0 | 0x19 << 8 | (byte) Code.No << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Prefix << 0 | (byte) OperandType.ShortInlineI << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Rethrow = new OpCode ( + 0xfe << 0 | 0x1a << 8 | (byte) Code.Rethrow << 16 | (byte) FlowControl.Throw << 24, + (byte) OpCodeType.Objmodel << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + + public static readonly OpCode Sizeof = new OpCode ( + 0xfe << 0 | 0x1c << 8 | (byte) Code.Sizeof << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineType << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Refanytype = new OpCode ( + 0xfe << 0 | 0x1d << 8 | (byte) Code.Refanytype << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Primitive << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop1 << 16 | (byte) StackBehaviour.Pushi << 24); + + public static readonly OpCode Readonly = new OpCode ( + 0xfe << 0 | 0x1e << 8 | (byte) Code.Readonly << 16 | (byte) FlowControl.Next << 24, + (byte) OpCodeType.Prefix << 0 | (byte) OperandType.InlineNone << 8 | (byte) StackBehaviour.Pop0 << 16 | (byte) StackBehaviour.Push0 << 24); + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/SequencePoint.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/SequencePoint.cs new file mode 100644 index 00000000..ef87e30f --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/SequencePoint.cs @@ -0,0 +1,70 @@ +// +// SequencePoint.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Cil { + + public sealed class SequencePoint { + + Document document; + + int start_line; + int start_column; + int end_line; + int end_column; + + public int StartLine { + get { return start_line; } + set { start_line = value; } + } + + public int StartColumn { + get { return start_column; } + set { start_column = value; } + } + + public int EndLine { + get { return end_line; } + set { end_line = value; } + } + + public int EndColumn { + get { return end_column; } + set { end_column = value; } + } + + public Document Document { + get { return document; } + set { document = value; } + } + + public SequencePoint (Document document) + { + this.document = document; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Symbols.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Symbols.cs new file mode 100644 index 00000000..0774d9ca --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/Symbols.cs @@ -0,0 +1,243 @@ +// +// Symbols.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; +using System.Runtime.InteropServices; +using SR = System.Reflection; + +using Mono.Collections.Generic; + +namespace Mono.Cecil.Cil { + + [StructLayout (LayoutKind.Sequential)] + public struct ImageDebugDirectory { + public int Characteristics; + public int TimeDateStamp; + public short MajorVersion; + public short MinorVersion; + public int Type; + public int SizeOfData; + public int AddressOfRawData; + public int PointerToRawData; + } + + public sealed class Scope : IVariableDefinitionProvider { + + Instruction start; + Instruction end; + + Collection scopes; + Collection variables; + + public Instruction Start { + get { return start; } + set { start = value; } + } + + public Instruction End { + get { return end; } + set { end = value; } + } + + public bool HasScopes { + get { return !Mixin.IsNullOrEmpty (scopes); } + } + + public Collection Scopes { + get { + if (scopes == null) + scopes = new Collection (); + + return scopes; + } + } + + public bool HasVariables { + get { return !Mixin.IsNullOrEmpty (variables); } + } + + public Collection Variables { + get { + if (variables == null) + variables = new Collection (); + + return variables; + } + } + } + + public struct InstructionSymbol { + + public readonly int Offset; + public readonly SequencePoint SequencePoint; + + public InstructionSymbol (int offset, SequencePoint sequencePoint) + { + this.Offset = offset; + this.SequencePoint = sequencePoint; + } + } + + public sealed class MethodSymbols { + + internal int code_size; + internal string method_name; + internal MetadataToken method_token; + internal MetadataToken local_var_token; + internal Collection variables; + public Collection instructions; + + public bool HasVariables { + get { return !Mixin.IsNullOrEmpty (variables); } + } + + public Collection Variables { + get { + if (variables == null) + variables = new Collection (); + + return variables; + } + } + + public Collection Instructions { + get { + if (instructions == null) + instructions = new Collection (); + + return instructions; + } + } + + public int CodeSize { + get { return code_size; } + } + + public string MethodName { + get { return method_name; } + } + + public MetadataToken MethodToken { + get { return method_token; } + } + + public MetadataToken LocalVarToken { + get { return local_var_token; } + } + + internal MethodSymbols (string methodName) + { + this.method_name = methodName; + } + + public MethodSymbols (MetadataToken methodToken) + { + this.method_token = methodToken; + } + } + + public delegate Instruction InstructionMapper (int offset); + + public interface ISymbolReader : IDisposable { + + bool ProcessDebugHeader (ImageDebugDirectory directory, byte [] header); + void Read (MethodBody body, InstructionMapper mapper); + void Read (MethodSymbols symbols); + } + + public interface ISymbolReaderProvider { + + ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName); + ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream); + } + + static class SymbolProvider { + + static readonly string symbol_kind = Type.GetType ("Mono.Runtime") != null ? "Mdb" : "Pdb"; + + static SR.AssemblyName GetPlatformSymbolAssemblyName () + { + var cecil_name = typeof (SymbolProvider).Assembly.GetName (); + + var name = new SR.AssemblyName { + Name = "Mono.Cecil." + symbol_kind, + Version = cecil_name.Version, + }; + + name.SetPublicKeyToken (cecil_name.GetPublicKeyToken ()); + + return name; + } + + static Type GetPlatformType (string fullname) + { + var type = Type.GetType (fullname); + if (type != null) + return type; + + var assembly_name = GetPlatformSymbolAssemblyName (); + + type = Type.GetType (fullname + ", " + assembly_name.FullName); + if (type != null) + return type; + + try { + var assembly = SR.Assembly.Load (assembly_name); + if (assembly != null) + return assembly.GetType (fullname); + } catch (FileNotFoundException) { + + } + + return null; + } + + static ISymbolReaderProvider reader_provider; + + public static ISymbolReaderProvider GetPlatformReaderProvider () + { + if (reader_provider != null) + return reader_provider; + + var type = GetPlatformType (GetProviderTypeName ("ReaderProvider")); + if (type == null) + return null; + + return reader_provider = (ISymbolReaderProvider) Activator.CreateInstance (type); + } + + static string GetProviderTypeName (string name) + { + return "Mono.Cecil." + symbol_kind + "." + symbol_kind + name; + } + + + } + +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableDefinition.cs new file mode 100644 index 00000000..f501bca6 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableDefinition.cs @@ -0,0 +1,52 @@ +// +// VariableDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Cil { + + public sealed class VariableDefinition : VariableReference { + + public bool IsPinned { + get { return variable_type.IsPinned; } + } + + public VariableDefinition (TypeReference variableType) + : base (variableType) + { + } + + public VariableDefinition (string name, TypeReference variableType) + : base (name, variableType) + { + } + + public override VariableDefinition Resolve () + { + return this; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableReference.cs new file mode 100644 index 00000000..ce0b4cdb --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Cil/VariableReference.cs @@ -0,0 +1,75 @@ +// +// VariableReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Cil { + + public abstract class VariableReference { + + string name; + internal int index = -1; + protected TypeReference variable_type; + + public string Name { + get { return name; } + set { name = value; } + } + + public TypeReference VariableType { + get { return variable_type; } + set { variable_type = value; } + } + + public int Index { + get { return index; } + } + + internal VariableReference (TypeReference variable_type) + : this (string.Empty, variable_type) + { + } + + internal VariableReference (string name, TypeReference variable_type) + { + this.name = name; + this.variable_type = variable_type; + } + + public abstract VariableDefinition Resolve (); + + public override string ToString () + { + if (!string.IsNullOrEmpty (name)) + return name; + + if (index >= 0) + return "V_" + index; + + return string.Empty; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/BlobHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/BlobHeap.cs new file mode 100644 index 00000000..e19d0ced --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/BlobHeap.cs @@ -0,0 +1,61 @@ +// +// BlobHeap.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.PE; + +namespace Mono.Cecil.Metadata +{ + + sealed class BlobHeap : Heap + { + + public BlobHeap(Section section, uint start, uint size) + : base(section, start, size) + { + } + + public byte[] Read(uint index) + { + if (index == 0 || index > Size - 1) + return Empty.Array; + + var data = Section.Data; + + int position = (int)(index + Offset); + int length = (int)Mixin.ReadCompressedUInt32(data, ref position); + + var buffer = new byte[length]; + + Buffer.BlockCopy(data, position, buffer, 0, length); + + return buffer; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Buffers.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Buffers.cs new file mode 100644 index 00000000..97b48d8b --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Buffers.cs @@ -0,0 +1,36 @@ +// +// TableHeapBuffer.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Text; + +using Mono.Cecil.PE; + +using RVA = System.UInt32; + diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/CodedIndex.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/CodedIndex.cs new file mode 100644 index 00000000..3e30fd87 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/CodedIndex.cs @@ -0,0 +1,46 @@ +// +// CodedIndex.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Metadata { + + enum CodedIndex { + TypeDefOrRef, + HasConstant, + HasCustomAttribute, + HasFieldMarshal, + HasDeclSecurity, + MemberRefParent, + HasSemantics, + MethodDefOrRef, + MemberForwarded, + Implementation, + CustomAttributeType, + ResolutionScope, + TypeOrMethodDef + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/ElementType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/ElementType.cs new file mode 100644 index 00000000..72fc1cca --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/ElementType.cs @@ -0,0 +1,73 @@ +// +// ElementType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil.Metadata { + + enum ElementType : byte { + None = 0x00, + Void = 0x01, + Boolean = 0x02, + Char = 0x03, + I1 = 0x04, + U1 = 0x05, + I2 = 0x06, + U2 = 0x07, + I4 = 0x08, + U4 = 0x09, + I8 = 0x0a, + U8 = 0x0b, + R4 = 0x0c, + R8 = 0x0d, + String = 0x0e, + Ptr = 0x0f, // Followed by token + ByRef = 0x10, // Followed by token + ValueType = 0x11, // Followed by token + Class = 0x12, // Followed by token + Var = 0x13, // Followed by generic parameter number + Array = 0x14, // + GenericInst = 0x15, // ... */ + TypedByRef = 0x16, + I = 0x18, // System.IntPtr + U = 0x19, // System.UIntPtr + FnPtr = 0x1b, // Followed by full method signature + Object = 0x1c, // System.Object + SzArray = 0x1d, // Single-dim array with 0 lower bound + MVar = 0x1e, // Followed by generic parameter number + CModReqD = 0x1f, // Required modifier : followed by a TypeDef or TypeRef token + CModOpt = 0x20, // Optional modifier : followed by a TypeDef or TypeRef token + Internal = 0x21, // Implemented within the CLI + Modifier = 0x40, // Or'd with following element types + Sentinel = 0x41, // Sentinel for varargs method signature + Pinned = 0x45, // Denotes a local variable that points at a pinned object + + // special undocumented constants + Type = 0x50, + Boxed = 0x51, + Enum = 0x55 + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/GuidHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/GuidHeap.cs new file mode 100644 index 00000000..1adc0795 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/GuidHeap.cs @@ -0,0 +1,59 @@ +// +// GuidHeap.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.PE; + +namespace Mono.Cecil.Metadata { + + sealed class GuidHeap : Heap { + + public GuidHeap (Section section, uint start, uint size) + : base (section, start, size) + { + } + + public Guid Read (uint index) + { + if (index == 0) + return new Guid (); + + const int guid_size = 16; + + var buffer = new byte [guid_size]; + + index--; + + Buffer.BlockCopy (Section.Data, (int) (Offset + index), buffer, 0, guid_size); + + return new Guid (buffer); + + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Heap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Heap.cs new file mode 100644 index 00000000..bc21acde --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Heap.cs @@ -0,0 +1,48 @@ +// +// Heap.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using Mono.Cecil.PE; + +namespace Mono.Cecil.Metadata { + + abstract class Heap { + + public int IndexSize; + + public readonly Section Section; + public readonly uint Offset; + public readonly uint Size; + + protected Heap (Section section, uint offset, uint size) + { + this.Section = section; + this.Offset = offset; + this.Size = size; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/MetadataToken.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/MetadataToken.cs new file mode 100644 index 00000000..bda56b0f --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/MetadataToken.cs @@ -0,0 +1,105 @@ +// +// MetadataToken.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public struct MetadataToken { + + readonly uint token; + + public uint RID { + get { return token & 0x00ffffff; } + } + + public TokenType TokenType { + get { return (TokenType) (token & 0xff000000); } + } + + public static readonly MetadataToken Zero = new MetadataToken ((uint) 0); + + public MetadataToken (uint token) + { + this.token = token; + } + + public MetadataToken (TokenType type) + : this (type, 0) + { + } + + public MetadataToken (TokenType type, uint rid) + { + token = (uint) type | rid; + } + + public MetadataToken (TokenType type, int rid) + { + token = (uint) type | (uint) rid; + } + + public int ToInt32 () + { + return (int) token; + } + + public uint ToUInt32 () + { + return token; + } + + public override int GetHashCode () + { + return (int) token; + } + + public override bool Equals (object obj) + { + if (obj is MetadataToken) { + var other = (MetadataToken) obj; + return other.token == token; + } + + return false; + } + + public static bool operator == (MetadataToken one, MetadataToken other) + { + return one.token == other.token; + } + + public static bool operator != (MetadataToken one, MetadataToken other) + { + return one.token != other.token; + } + + public override string ToString () + { + return string.Format ("[{0}:0x{1}]", TokenType, RID.ToString ("x4")); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Row.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Row.cs new file mode 100644 index 00000000..9975b7ba --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Row.cs @@ -0,0 +1,175 @@ +// +// Row.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Collections.Generic; + +namespace Mono.Cecil.Metadata { + + class Row { + internal T1 Col1; + internal T2 Col2; + + public Row (T1 col1, T2 col2) + { + Col1 = col1; + Col2 = col2; + } + } + + class Row + { + internal T1 Col1; + internal T2 Col2; + internal T3 Col3; + + public Row (T1 col1, T2 col2, T3 col3) + { + Col1 = col1; + Col2 = col2; + Col3 = col3; + } + } + + class Row + { + internal T1 Col1; + internal T2 Col2; + internal T3 Col3; + internal T4 Col4; + + public Row (T1 col1, T2 col2, T3 col3, T4 col4) + { + Col1 = col1; + Col2 = col2; + Col3 = col3; + Col4 = col4; + } + } + + class Row + { + internal T1 Col1; + internal T2 Col2; + internal T3 Col3; + internal T4 Col4; + internal T5 Col5; + + public Row (T1 col1, T2 col2, T3 col3, T4 col4, T5 col5) + { + Col1 = col1; + Col2 = col2; + Col3 = col3; + Col4 = col4; + Col5 = col5; + } + } + + class Row + { + internal T1 Col1; + internal T2 Col2; + internal T3 Col3; + internal T4 Col4; + internal T5 Col5; + internal T6 Col6; + + public Row (T1 col1, T2 col2, T3 col3, T4 col4, T5 col5, T6 col6) + { + Col1 = col1; + Col2 = col2; + Col3 = col3; + Col4 = col4; + Col5 = col5; + Col6 = col6; + } + } + + class Row + { + internal T1 Col1; + internal T2 Col2; + internal T3 Col3; + internal T4 Col4; + internal T5 Col5; + internal T6 Col6; + internal T7 Col7; + internal T8 Col8; + internal T9 Col9; + + public Row (T1 col1, T2 col2, T3 col3, T4 col4, T5 col5, T6 col6, T7 col7, T8 col8, T9 col9) + { + Col1 = col1; + Col2 = col2; + Col3 = col3; + Col4 = col4; + Col5 = col5; + Col6 = col6; + Col7 = col7; + Col8 = col8; + Col9 = col9; + } + } + + sealed class RowEqualityComparer : IEqualityComparer>, IEqualityComparer>, IEqualityComparer> { + + public bool Equals (Row x, Row y) + { + return x.Col1 == y.Col1 + && x.Col2 == y.Col2; + } + + public int GetHashCode (Row obj) + { + string x = obj.Col1, y = obj.Col2; + return (x != null ? x.GetHashCode () : 0) ^ (y != null ? y.GetHashCode () : 0); + } + + public bool Equals (Row x, Row y) + { + return x.Col1 == y.Col1 + && x.Col2 == y.Col2; + } + + public int GetHashCode (Row obj) + { + return (int) (obj.Col1 ^ obj.Col2); + } + + public bool Equals (Row x, Row y) + { + return x.Col1 == y.Col1 + && x.Col2 == y.Col2 + && x.Col3 == y.Col3; + } + + public int GetHashCode (Row obj) + { + return (int) (obj.Col1 ^ obj.Col2 ^ obj.Col3); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/StringHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/StringHeap.cs new file mode 100644 index 00000000..4a0a0af4 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/StringHeap.cs @@ -0,0 +1,81 @@ +// +// StringHeap.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Text; + +using Mono.Cecil.PE; + +namespace Mono.Cecil.Metadata { + + class StringHeap : Heap { + + readonly Dictionary strings = new Dictionary (); + + public StringHeap (Section section, uint start, uint size) + : base (section, start, size) + { + } + + public string Read (uint index) + { + if (index == 0) + return string.Empty; + + string @string; + if (strings.TryGetValue (index, out @string)) + return @string; + + if (index > Size - 1) + return string.Empty; + + @string = ReadStringAt (index); + if (@string.Length != 0) + strings.Add (index, @string); + + return @string; + } + + protected virtual string ReadStringAt (uint index) + { + int length = 0; + byte [] data = Section.Data; + int start = (int) (index + Offset); + + for (int i = start; ; i++) { + if (data [i] == 0) + break; + + length++; + } + + return Encoding.UTF8.GetString (data, start, length); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TableHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TableHeap.cs new file mode 100644 index 00000000..9bc0edd3 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TableHeap.cs @@ -0,0 +1,111 @@ +// +// TableHeap.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using Mono.Cecil.PE; + +namespace Mono.Cecil.Metadata { + + enum Table : byte { + Module = 0x00, + TypeRef = 0x01, + TypeDef = 0x02, + FieldPtr = 0x03, + Field = 0x04, + MethodPtr = 0x05, + Method = 0x06, + ParamPtr = 0x07, + Param = 0x08, + InterfaceImpl = 0x09, + MemberRef = 0x0a, + Constant = 0x0b, + CustomAttribute = 0x0c, + FieldMarshal = 0x0d, + DeclSecurity = 0x0e, + ClassLayout = 0x0f, + FieldLayout = 0x10, + StandAloneSig = 0x11, + EventMap = 0x12, + EventPtr = 0x13, + Event = 0x14, + PropertyMap = 0x15, + PropertyPtr = 0x16, + Property = 0x17, + MethodSemantics = 0x18, + MethodImpl = 0x19, + ModuleRef = 0x1a, + TypeSpec = 0x1b, + ImplMap = 0x1c, + FieldRVA = 0x1d, + EncLog = 0x1e, + EncMap = 0x1f, + Assembly = 0x20, + AssemblyProcessor = 0x21, + AssemblyOS = 0x22, + AssemblyRef = 0x23, + AssemblyRefProcessor = 0x24, + AssemblyRefOS = 0x25, + File = 0x26, + ExportedType = 0x27, + ManifestResource = 0x28, + NestedClass = 0x29, + GenericParam = 0x2a, + MethodSpec = 0x2b, + GenericParamConstraint = 0x2c, + } + + struct TableInformation { + public uint Offset; + public uint Length; + public uint RowSize; + } + + sealed class TableHeap : Heap { + + public long Valid; + public long Sorted; + + public const int TableCount = 45; + + public readonly TableInformation [] Tables = new TableInformation [TableCount]; + + public TableInformation this [Table table] { + get { return Tables [(int) table]; } + } + + public TableHeap (Section section, uint start, uint size) + : base (section, start, size) + { + } + + public bool HasTable (Table table) + { + return (Valid & (1L << (int) table)) != 0; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TokenType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TokenType.cs new file mode 100644 index 00000000..2c2010ff --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/TokenType.cs @@ -0,0 +1,56 @@ +// +// TokenType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public enum TokenType : uint { + Module = 0x00000000, + TypeRef = 0x01000000, + TypeDef = 0x02000000, + Field = 0x04000000, + Method = 0x06000000, + Param = 0x08000000, + InterfaceImpl = 0x09000000, + MemberRef = 0x0a000000, + CustomAttribute = 0x0c000000, + Permission = 0x0e000000, + Signature = 0x11000000, + Event = 0x14000000, + Property = 0x17000000, + ModuleRef = 0x1a000000, + TypeSpec = 0x1b000000, + Assembly = 0x20000000, + AssemblyRef = 0x23000000, + File = 0x26000000, + ExportedType = 0x27000000, + ManifestResource = 0x28000000, + GenericParam = 0x2a000000, + MethodSpec = 0x2b000000, + String = 0x70000000, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/UserStringHeap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/UserStringHeap.cs new file mode 100644 index 00000000..3d3c5b6f --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/UserStringHeap.cs @@ -0,0 +1,61 @@ +// +// UserStringHeap.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.PE; + +namespace Mono.Cecil.Metadata +{ + + sealed class UserStringHeap : StringHeap + { + + public UserStringHeap(Section section, uint start, uint size) + : base(section, start, size) + { + } + + protected override string ReadStringAt(uint index) + { + byte[] data = Section.Data; + int start = (int)(index + Offset); + + uint length = (uint)(Mixin.ReadCompressedUInt32(data, ref start) & ~1); + if (length < 1) + return string.Empty; + + var chars = new char[length / 2]; + + for (int i = start, j = 0; i < start + length; i += 2) + chars[j++] = (char)(data[i] | (data[i + 1] << 8)); + + return new string(chars); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Utilities.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Utilities.cs new file mode 100644 index 00000000..71200e3e --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.Metadata/Utilities.cs @@ -0,0 +1,354 @@ +// +// Utilities.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil +{ + + static partial class Mixin + { + + public static uint ReadCompressedUInt32(byte[] data, ref int position) + { + uint integer; + if ((data[position] & 0x80) == 0) + { + integer = data[position]; + position++; + } + else if ((data[position] & 0x40) == 0) + { + integer = (uint)(data[position] & ~0x80) << 8; + integer |= data[position + 1]; + position += 2; + } + else + { + integer = (uint)(data[position] & ~0xc0) << 24; + integer |= (uint)data[position + 1] << 16; + integer |= (uint)data[position + 2] << 8; + integer |= (uint)data[position + 3]; + position += 4; + } + return integer; + } + + public static MetadataToken GetMetadataToken(CodedIndex self, uint data) + { + uint rid; + TokenType token_type; + switch (self) + { + case CodedIndex.TypeDefOrRef: + rid = data >> 2; + switch (data & 3) + { + case 0: + token_type = TokenType.TypeDef; goto ret; + case 1: + token_type = TokenType.TypeRef; goto ret; + case 2: + token_type = TokenType.TypeSpec; goto ret; + default: + goto exit; + } + case CodedIndex.HasConstant: + rid = data >> 2; + switch (data & 3) + { + case 0: + token_type = TokenType.Field; goto ret; + case 1: + token_type = TokenType.Param; goto ret; + case 2: + token_type = TokenType.Property; goto ret; + default: + goto exit; + } + case CodedIndex.HasCustomAttribute: + rid = data >> 5; + switch (data & 31) + { + case 0: + token_type = TokenType.Method; goto ret; + case 1: + token_type = TokenType.Field; goto ret; + case 2: + token_type = TokenType.TypeRef; goto ret; + case 3: + token_type = TokenType.TypeDef; goto ret; + case 4: + token_type = TokenType.Param; goto ret; + case 5: + token_type = TokenType.InterfaceImpl; goto ret; + case 6: + token_type = TokenType.MemberRef; goto ret; + case 7: + token_type = TokenType.Module; goto ret; + case 8: + token_type = TokenType.Permission; goto ret; + case 9: + token_type = TokenType.Property; goto ret; + case 10: + token_type = TokenType.Event; goto ret; + case 11: + token_type = TokenType.Signature; goto ret; + case 12: + token_type = TokenType.ModuleRef; goto ret; + case 13: + token_type = TokenType.TypeSpec; goto ret; + case 14: + token_type = TokenType.Assembly; goto ret; + case 15: + token_type = TokenType.AssemblyRef; goto ret; + case 16: + token_type = TokenType.File; goto ret; + case 17: + token_type = TokenType.ExportedType; goto ret; + case 18: + token_type = TokenType.ManifestResource; goto ret; + case 19: + token_type = TokenType.GenericParam; goto ret; + default: + goto exit; + } + case CodedIndex.HasFieldMarshal: + rid = data >> 1; + switch (data & 1) + { + case 0: + token_type = TokenType.Field; goto ret; + case 1: + token_type = TokenType.Param; goto ret; + default: + goto exit; + } + case CodedIndex.HasDeclSecurity: + rid = data >> 2; + switch (data & 3) + { + case 0: + token_type = TokenType.TypeDef; goto ret; + case 1: + token_type = TokenType.Method; goto ret; + case 2: + token_type = TokenType.Assembly; goto ret; + default: + goto exit; + } + case CodedIndex.MemberRefParent: + rid = data >> 3; + switch (data & 7) + { + case 0: + token_type = TokenType.TypeDef; goto ret; + case 1: + token_type = TokenType.TypeRef; goto ret; + case 2: + token_type = TokenType.ModuleRef; goto ret; + case 3: + token_type = TokenType.Method; goto ret; + case 4: + token_type = TokenType.TypeSpec; goto ret; + default: + goto exit; + } + case CodedIndex.HasSemantics: + rid = data >> 1; + switch (data & 1) + { + case 0: + token_type = TokenType.Event; goto ret; + case 1: + token_type = TokenType.Property; goto ret; + default: + goto exit; + } + case CodedIndex.MethodDefOrRef: + rid = data >> 1; + switch (data & 1) + { + case 0: + token_type = TokenType.Method; goto ret; + case 1: + token_type = TokenType.MemberRef; goto ret; + default: + goto exit; + } + case CodedIndex.MemberForwarded: + rid = data >> 1; + switch (data & 1) + { + case 0: + token_type = TokenType.Field; goto ret; + case 1: + token_type = TokenType.Method; goto ret; + default: + goto exit; + } + case CodedIndex.Implementation: + rid = data >> 2; + switch (data & 3) + { + case 0: + token_type = TokenType.File; goto ret; + case 1: + token_type = TokenType.AssemblyRef; goto ret; + case 2: + token_type = TokenType.ExportedType; goto ret; + default: + goto exit; + } + case CodedIndex.CustomAttributeType: + rid = data >> 3; + switch (data & 7) + { + case 2: + token_type = TokenType.Method; goto ret; + case 3: + token_type = TokenType.MemberRef; goto ret; + default: + goto exit; + } + case CodedIndex.ResolutionScope: + rid = data >> 2; + switch (data & 3) + { + case 0: + token_type = TokenType.Module; goto ret; + case 1: + token_type = TokenType.ModuleRef; goto ret; + case 2: + token_type = TokenType.AssemblyRef; goto ret; + case 3: + token_type = TokenType.TypeRef; goto ret; + default: + goto exit; + } + case CodedIndex.TypeOrMethodDef: + rid = data >> 1; + switch (data & 1) + { + case 0: + token_type = TokenType.TypeDef; goto ret; + case 1: + token_type = TokenType.Method; goto ret; + default: goto exit; + } + default: + goto exit; + } + ret: + return new MetadataToken(token_type, rid); + exit: + return MetadataToken.Zero; + } + + + public static int GetSize(CodedIndex self, Func counter) + { + int bits; + Table[] tables; + + switch (self) + { + case CodedIndex.TypeDefOrRef: + bits = 2; + tables = new[] { Table.TypeDef, Table.TypeRef, Table.TypeSpec }; + break; + case CodedIndex.HasConstant: + bits = 2; + tables = new[] { Table.Field, Table.Param, Table.Property }; + break; + case CodedIndex.HasCustomAttribute: + bits = 5; + tables = new[] { + Table.Method, Table.Field, Table.TypeRef, Table.TypeDef, Table.Param, Table.InterfaceImpl, Table.MemberRef, + Table.Module, Table.DeclSecurity, Table.Property, Table.Event, Table.StandAloneSig, Table.ModuleRef, + Table.TypeSpec, Table.Assembly, Table.AssemblyRef, Table.File, Table.ExportedType, + Table.ManifestResource, Table.GenericParam + }; + break; + case CodedIndex.HasFieldMarshal: + bits = 1; + tables = new[] { Table.Field, Table.Param }; + break; + case CodedIndex.HasDeclSecurity: + bits = 2; + tables = new[] { Table.TypeDef, Table.Method, Table.Assembly }; + break; + case CodedIndex.MemberRefParent: + bits = 3; + tables = new[] { Table.TypeDef, Table.TypeRef, Table.ModuleRef, Table.Method, Table.TypeSpec }; + break; + case CodedIndex.HasSemantics: + bits = 1; + tables = new[] { Table.Event, Table.Property }; + break; + case CodedIndex.MethodDefOrRef: + bits = 1; + tables = new[] { Table.Method, Table.MemberRef }; + break; + case CodedIndex.MemberForwarded: + bits = 1; + tables = new[] { Table.Field, Table.Method }; + break; + case CodedIndex.Implementation: + bits = 2; + tables = new[] { Table.File, Table.AssemblyRef, Table.ExportedType }; + break; + case CodedIndex.CustomAttributeType: + bits = 3; + tables = new[] { Table.Method, Table.MemberRef }; + break; + case CodedIndex.ResolutionScope: + bits = 2; + tables = new[] { Table.Module, Table.ModuleRef, Table.AssemblyRef, Table.TypeRef }; + break; + case CodedIndex.TypeOrMethodDef: + bits = 1; + tables = new[] { Table.TypeDef, Table.Method }; + break; + default: + throw new ArgumentException(); + } + + int max = 0; + + for (int i = 0; i < tables.Length; i++) + { + max = System.Math.Max(counter(tables[i]), max); + } + + return max < (1 << (16 - bits)) ? 2 : 4; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamReader.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamReader.cs new file mode 100644 index 00000000..ec2477c3 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamReader.cs @@ -0,0 +1,51 @@ +// +// BinaryStreamReader.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; + +namespace Mono.Cecil.PE { + + class BinaryStreamReader : BinaryReader { + + public BinaryStreamReader (Stream stream) + : base (stream) + { + } + + protected void Advance (int bytes) + { + BaseStream.Seek (bytes, SeekOrigin.Current); + } + + protected DataDirectory ReadDataDirectory () + { + return new DataDirectory (ReadUInt32 (), ReadUInt32 ()); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamWriter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamWriter.cs new file mode 100644 index 00000000..00a79755 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/BinaryStreamWriter.cs @@ -0,0 +1,31 @@ +// +// BinaryStreamWriter.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; + diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBuffer.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBuffer.cs new file mode 100644 index 00000000..a09812aa --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBuffer.cs @@ -0,0 +1,184 @@ +// +// ByteBuffer.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil.PE { + + class ByteBuffer { + + internal byte [] buffer; + internal int length; + internal int position; + + public ByteBuffer () + { + this.buffer = Empty.Array; + } + + public ByteBuffer (int length) + { + this.buffer = new byte [length]; + } + + public ByteBuffer (byte [] buffer) + { + this.buffer = buffer ?? Empty.Array; + this.length = this.buffer.Length; + } + + public void Reset (byte [] buffer) + { + this.buffer = buffer ?? Empty.Array; + this.length = this.buffer.Length; + } + + public void Advance (int length) + { + position += length; + } + + public byte ReadByte () + { + return buffer [position++]; + } + + public sbyte ReadSByte () + { + return (sbyte) ReadByte (); + } + + public byte [] ReadBytes (int length) + { + var bytes = new byte [length]; + Buffer.BlockCopy (buffer, position, bytes, 0, length); + position += length; + return bytes; + } + + public ushort ReadUInt16 () + { + ushort value = (ushort) (buffer [position] + | (buffer [position + 1] << 8)); + position += 2; + return value; + } + + public short ReadInt16 () + { + return (short) ReadUInt16 (); + } + + public uint ReadUInt32 () + { + uint value = (uint) (buffer [position] + | (buffer [position + 1] << 8) + | (buffer [position + 2] << 16) + | (buffer [position + 3] << 24)); + position += 4; + return value; + } + + public int ReadInt32 () + { + return (int) ReadUInt32 (); + } + + public ulong ReadUInt64 () + { + uint low = ReadUInt32 (); + uint high = ReadUInt32 (); + + return (((ulong) high) << 32) | low; + } + + public long ReadInt64 () + { + return (long) ReadUInt64 (); + } + + public uint ReadCompressedUInt32 () + { + byte first = ReadByte (); + if ((first & 0x80) == 0) + return first; + + if ((first & 0x40) == 0) + return ((uint) (first & ~0x80) << 8) + | ReadByte (); + + return ((uint) (first & ~0xc0) << 24) + | (uint) ReadByte () << 16 + | (uint) ReadByte () << 8 + | ReadByte (); + } + + public int ReadCompressedInt32 () + { + var value = (int) (ReadCompressedUInt32 () >> 1); + if ((value & 1) == 0) + return value; + if (value < 0x40) + return value - 0x40; + if (value < 0x2000) + return value - 0x2000; + if (value < 0x10000000) + return value - 0x10000000; + return value - 0x20000000; + } + + public float ReadSingle () + { + if (!BitConverter.IsLittleEndian) { + var bytes = ReadBytes (4); + Array.Reverse (bytes); + return BitConverter.ToSingle (bytes, 0); + } + + float value = BitConverter.ToSingle (buffer, position); + position += 4; + return value; + } + + public double ReadDouble () + { + if (!BitConverter.IsLittleEndian) { + var bytes = ReadBytes (8); + Array.Reverse (bytes); + return BitConverter.ToDouble (bytes, 0); + } + + double value = BitConverter.ToDouble (buffer, position); + position += 8; + return value; + } + + + + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBufferEqualityComparer.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBufferEqualityComparer.cs new file mode 100644 index 00000000..70e89164 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ByteBufferEqualityComparer.cs @@ -0,0 +1,78 @@ +// +// ByteBufferEqualityComparer.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; + +namespace Mono.Cecil.PE { + + sealed class ByteBufferEqualityComparer : IEqualityComparer { + + public bool Equals (ByteBuffer x, ByteBuffer y) + { + if (x.length != y.length) + return false; + + var x_buffer = x.buffer; + var y_buffer = y.buffer; + + for (int i = 0; i < x.length; i++) + if (x_buffer [i] != y_buffer [i]) + return false; + + return true; + } + + public int GetHashCode (ByteBuffer buffer) + { +#if !BYTE_BUFFER_WELL_DISTRIBUTED_HASH + var hash = 0; + var bytes = buffer.buffer; + for (int i = 0; i < buffer.length; i++) + hash = (hash * 37) ^ bytes [i]; + + return hash; +#else + const uint p = 16777619; + uint hash = 2166136261; + + var bytes = buffer.buffer; + for (int i = 0; i < buffer.length; i++) + hash = (hash ^ bytes [i]) * p; + + hash += hash << 13; + hash ^= hash >> 7; + hash += hash << 3; + hash ^= hash >> 17; + hash += hash << 5; + + return (int) hash; +#endif + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/DataDirectory.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/DataDirectory.cs new file mode 100644 index 00000000..fedd0e2d --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/DataDirectory.cs @@ -0,0 +1,50 @@ +// +// DataDirectory.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + struct DataDirectory { + + public readonly RVA VirtualAddress; + public readonly uint Size; + + public bool IsZero { + get { return VirtualAddress == 0 && Size == 0; } + } + + public DataDirectory (RVA rva, uint size) + { + this.VirtualAddress = rva; + this.Size = size; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Image.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Image.cs new file mode 100644 index 00000000..62b8d9f7 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Image.cs @@ -0,0 +1,166 @@ +// +// Image.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE +{ + + sealed class Image + { + + public ModuleKind Kind; + public TargetRuntime Runtime; + public TargetArchitecture Architecture; + public ModuleCharacteristics Characteristics; + public string FileName; + + public Section[] Sections; + + public Section MetadataSection; + + public uint EntryPointToken; + public ModuleAttributes Attributes; + + public DataDirectory Debug; + public DataDirectory Resources; + public DataDirectory StrongName; + + public StringHeap StringHeap; + public BlobHeap BlobHeap; + public UserStringHeap UserStringHeap; + public GuidHeap GuidHeap; + public TableHeap TableHeap; + + readonly int[] coded_index_sizes = new int[13]; + + readonly Func counter; + + public Image() + { + counter = GetTableLength; + } + + public bool HasTable(Table table) + { + return GetTableLength(table) > 0; + } + + public int GetTableLength(Table table) + { + return (int)TableHeap[table].Length; + } + + public int GetTableIndexSize(Table table) + { + return GetTableLength(table) < 65536 ? 2 : 4; + } + + public int GetCodedIndexSize(CodedIndex coded_index) + { + var index = (int)coded_index; + var size = coded_index_sizes[index]; + if (size != 0) + return size; + + return coded_index_sizes[index] = Mixin.GetSize(coded_index, counter); + } + + public uint ResolveVirtualAddress(RVA rva) + { + var section = GetSectionAtVirtualAddress(rva); + if (section == null) + throw new ArgumentOutOfRangeException(); + + return ResolveVirtualAddressInSection(rva, section); + } + + public uint ResolveVirtualAddressInSection(RVA rva, Section section) + { + return rva + section.PointerToRawData - section.VirtualAddress; + } + + public Section GetSection(string name) + { + var sections = this.Sections; + for (int i = 0; i < sections.Length; i++) + { + var section = sections[i]; + if (section.Name == name) + return section; + } + + return null; + } + + public Section GetSectionAtVirtualAddress(RVA rva) + { + var sections = this.Sections; + for (int i = 0; i < sections.Length; i++) + { + var section = sections[i]; + if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.SizeOfRawData) + return section; + } + + return null; + } + + public ImageDebugDirectory GetDebugHeader(out byte[] header) + { + var section = GetSectionAtVirtualAddress(Debug.VirtualAddress); + var buffer = new ByteBuffer(section.Data); + buffer.position = (int)(Debug.VirtualAddress - section.VirtualAddress); + + var directory = new ImageDebugDirectory + { + Characteristics = buffer.ReadInt32(), + TimeDateStamp = buffer.ReadInt32(), + MajorVersion = buffer.ReadInt16(), + MinorVersion = buffer.ReadInt16(), + Type = buffer.ReadInt32(), + SizeOfData = buffer.ReadInt32(), + AddressOfRawData = buffer.ReadInt32(), + PointerToRawData = buffer.ReadInt32(), + }; + + buffer.position = (int)(directory.PointerToRawData - section.PointerToRawData); + + header = new byte[directory.SizeOfData]; + Buffer.BlockCopy(buffer.buffer, buffer.position, header, 0, header.Length); + + return directory; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageReader.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageReader.cs new file mode 100644 index 00000000..00d0c672 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageReader.cs @@ -0,0 +1,694 @@ +// +// ImageReader.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; + +using Mono.Cecil.Metadata; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE +{ + + sealed class ImageReader : BinaryStreamReader + { + + readonly Image image; + + DataDirectory cli; + DataDirectory metadata; + + public ImageReader(Stream stream) + : base(stream) + { + image = new Image(); + + image.FileName = Mixin.GetFullyQualifiedName(stream); + } + + void MoveTo(DataDirectory directory) + { + BaseStream.Position = image.ResolveVirtualAddress(directory.VirtualAddress); + } + + void MoveTo(uint position) + { + BaseStream.Position = position; + } + + void ReadImage() + { + if (BaseStream.Length < 128) + throw new BadImageFormatException(); + + // - DOSHeader + + // PE 2 + // Start 58 + // Lfanew 4 + // End 64 + + if (ReadUInt16() != 0x5a4d) + throw new BadImageFormatException(); + + Advance(58); + + MoveTo(ReadUInt32()); + + if (ReadUInt32() != 0x00004550) + throw new BadImageFormatException(); + + // - PEFileHeader + + // Machine 2 + image.Architecture = ReadArchitecture(); + + // NumberOfSections 2 + ushort sections = ReadUInt16(); + + // TimeDateStamp 4 + // PointerToSymbolTable 4 + // NumberOfSymbols 4 + // OptionalHeaderSize 2 + Advance(14); + + // Characteristics 2 + ushort characteristics = ReadUInt16(); + + ushort subsystem, dll_characteristics; + ReadOptionalHeaders(out subsystem, out dll_characteristics); + ReadSections(sections); + ReadCLIHeader(); + ReadMetadata(); + + image.Kind = GetModuleKind(characteristics, subsystem); + image.Characteristics = (ModuleCharacteristics)dll_characteristics; + } + + TargetArchitecture ReadArchitecture() + { + var machine = ReadUInt16(); + switch (machine) + { + case 0x014c: + return TargetArchitecture.I386; + case 0x8664: + return TargetArchitecture.AMD64; + case 0x0200: + return TargetArchitecture.IA64; + case 0x01c4: + return TargetArchitecture.ARMv7; + } + + throw new NotSupportedException(); + } + + static ModuleKind GetModuleKind(ushort characteristics, ushort subsystem) + { + if ((characteristics & 0x2000) != 0) // ImageCharacteristics.Dll + return ModuleKind.Dll; + + if (subsystem == 0x2 || subsystem == 0x9) // SubSystem.WindowsGui || SubSystem.WindowsCeGui + return ModuleKind.Windows; + + return ModuleKind.Console; + } + + void ReadOptionalHeaders(out ushort subsystem, out ushort dll_characteristics) + { + // - PEOptionalHeader + // - StandardFieldsHeader + + // Magic 2 + bool pe64 = ReadUInt16() == 0x20b; + + // pe32 || pe64 + + // LMajor 1 + // LMinor 1 + // CodeSize 4 + // InitializedDataSize 4 + // UninitializedDataSize4 + // EntryPointRVA 4 + // BaseOfCode 4 + // BaseOfData 4 || 0 + + // - NTSpecificFieldsHeader + + // ImageBase 4 || 8 + // SectionAlignment 4 + // FileAlignement 4 + // OSMajor 2 + // OSMinor 2 + // UserMajor 2 + // UserMinor 2 + // SubSysMajor 2 + // SubSysMinor 2 + // Reserved 4 + // ImageSize 4 + // HeaderSize 4 + // FileChecksum 4 + Advance(66); + + // SubSystem 2 + subsystem = ReadUInt16(); + + // DLLFlags 2 + dll_characteristics = ReadUInt16(); + // StackReserveSize 4 || 8 + // StackCommitSize 4 || 8 + // HeapReserveSize 4 || 8 + // HeapCommitSize 4 || 8 + // LoaderFlags 4 + // NumberOfDataDir 4 + + // - DataDirectoriesHeader + + // ExportTable 8 + // ImportTable 8 + // ResourceTable 8 + // ExceptionTable 8 + // CertificateTable 8 + // BaseRelocationTable 8 + + Advance(pe64 ? 88 : 72); + + // Debug 8 + image.Debug = ReadDataDirectory(); + + // Copyright 8 + // GlobalPtr 8 + // TLSTable 8 + // LoadConfigTable 8 + // BoundImport 8 + // IAT 8 + // DelayImportDescriptor8 + Advance(56); + + // CLIHeader 8 + cli = ReadDataDirectory(); + + if (cli.IsZero) + throw new BadImageFormatException(); + + // Reserved 8 + Advance(8); + } + + string ReadAlignedString(int length) + { + int read = 0; + var buffer = new char[length]; + while (read < length) + { + var current = ReadByte(); + if (current == 0) + break; + + buffer[read++] = (char)current; + } + + Advance(-1 + ((read + 4) & ~3) - read); + + return new string(buffer, 0, read); + } + + string ReadZeroTerminatedString(int length) + { + int read = 0; + var buffer = new char[length]; + var bytes = ReadBytes(length); + while (read < length) + { + var current = bytes[read]; + if (current == 0) + break; + + buffer[read++] = (char)current; + } + + return new string(buffer, 0, read); + } + + void ReadSections(ushort count) + { + var sections = new Section[count]; + + for (int i = 0; i < count; i++) + { + var section = new Section(); + + // Name + section.Name = ReadZeroTerminatedString(8); + + // VirtualSize 4 + Advance(4); + + // VirtualAddress 4 + section.VirtualAddress = ReadUInt32(); + // SizeOfRawData 4 + section.SizeOfRawData = ReadUInt32(); + // PointerToRawData 4 + section.PointerToRawData = ReadUInt32(); + + // PointerToRelocations 4 + // PointerToLineNumbers 4 + // NumberOfRelocations 2 + // NumberOfLineNumbers 2 + // Characteristics 4 + Advance(16); + + sections[i] = section; + + ReadSectionData(section); + } + + image.Sections = sections; + } + + void ReadSectionData(Section section) + { + var position = BaseStream.Position; + + MoveTo(section.PointerToRawData); + + var length = (int)section.SizeOfRawData; + var data = new byte[length]; + int offset = 0, read; + + while ((read = Read(data, offset, length - offset)) > 0) + offset += read; + + section.Data = data; + + BaseStream.Position = position; + } + + void ReadCLIHeader() + { + MoveTo(cli); + + // - CLIHeader + + // Cb 4 + // MajorRuntimeVersion 2 + // MinorRuntimeVersion 2 + Advance(8); + + // Metadata 8 + metadata = ReadDataDirectory(); + // Flags 4 + image.Attributes = (ModuleAttributes)ReadUInt32(); + // EntryPointToken 4 + image.EntryPointToken = ReadUInt32(); + // Resources 8 + image.Resources = ReadDataDirectory(); + // StrongNameSignature 8 + image.StrongName = ReadDataDirectory(); + // CodeManagerTable 8 + // VTableFixups 8 + // ExportAddressTableJumps 8 + // ManagedNativeHeader 8 + } + + void ReadMetadata() + { + MoveTo(metadata); + + if (ReadUInt32() != 0x424a5342) + throw new BadImageFormatException(); + + // MajorVersion 2 + // MinorVersion 2 + // Reserved 4 + Advance(8); + + var version = ReadZeroTerminatedString(ReadInt32()); + image.Runtime = Mixin.ParseRuntime(version); + + // Flags 2 + Advance(2); + + var streams = ReadUInt16(); + + var section = image.GetSectionAtVirtualAddress(metadata.VirtualAddress); + if (section == null) + throw new BadImageFormatException(); + + image.MetadataSection = section; + + for (int i = 0; i < streams; i++) + ReadMetadataStream(section); + + if (image.TableHeap != null) + ReadTableHeap(); + } + + void ReadMetadataStream(Section section) + { + // Offset 4 + uint start = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32(); // relative to the section start + + // Size 4 + uint size = ReadUInt32(); + + var name = ReadAlignedString(16); + switch (name) + { + case "#~": + case "#-": + image.TableHeap = new TableHeap(section, start, size); + break; + case "#Strings": + image.StringHeap = new StringHeap(section, start, size); + break; + case "#Blob": + image.BlobHeap = new BlobHeap(section, start, size); + break; + case "#GUID": + image.GuidHeap = new GuidHeap(section, start, size); + break; + case "#US": + image.UserStringHeap = new UserStringHeap(section, start, size); + break; + } + } + + void ReadTableHeap() + { + var heap = image.TableHeap; + + uint start = heap.Section.PointerToRawData; + + MoveTo(heap.Offset + start); + + // Reserved 4 + // MajorVersion 1 + // MinorVersion 1 + Advance(6); + + // HeapSizes 1 + var sizes = ReadByte(); + + // Reserved2 1 + Advance(1); + + // Valid 8 + heap.Valid = ReadInt64(); + + // Sorted 8 + heap.Sorted = ReadInt64(); + + for (int i = 0; i < TableHeap.TableCount; i++) + { + if (!heap.HasTable((Table)i)) + continue; + + heap.Tables[i].Length = ReadUInt32(); + } + + SetIndexSize(image.StringHeap, sizes, 0x1); + SetIndexSize(image.GuidHeap, sizes, 0x2); + SetIndexSize(image.BlobHeap, sizes, 0x4); + + ComputeTableInformations(); + } + + static void SetIndexSize(Heap heap, uint sizes, byte flag) + { + if (heap == null) + return; + + heap.IndexSize = (sizes & flag) > 0 ? 4 : 2; + } + + int GetTableIndexSize(Table table) + { + return image.GetTableIndexSize(table); + } + + int GetCodedIndexSize(CodedIndex index) + { + return image.GetCodedIndexSize(index); + } + + void ComputeTableInformations() + { + uint offset = (uint)BaseStream.Position - image.MetadataSection.PointerToRawData; // header + + int stridx_size = image.StringHeap.IndexSize; + int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2; + + var heap = image.TableHeap; + var tables = heap.Tables; + + for (int i = 0; i < TableHeap.TableCount; i++) + { + var table = (Table)i; + if (!heap.HasTable(table)) + continue; + + int size; + switch (table) + { + case Table.Module: + size = 2 // Generation + + stridx_size // Name + + (image.GuidHeap.IndexSize * 3); // Mvid, EncId, EncBaseId + break; + case Table.TypeRef: + size = GetCodedIndexSize(CodedIndex.ResolutionScope) // ResolutionScope + + (stridx_size * 2); // Name, Namespace + break; + case Table.TypeDef: + size = 4 // Flags + + (stridx_size * 2) // Name, Namespace + + GetCodedIndexSize(CodedIndex.TypeDefOrRef) // BaseType + + GetTableIndexSize(Table.Field) // FieldList + + GetTableIndexSize(Table.Method); // MethodList + break; + case Table.FieldPtr: + size = GetTableIndexSize(Table.Field); // Field + break; + case Table.Field: + size = 2 // Flags + + stridx_size // Name + + blobidx_size; // Signature + break; + case Table.MethodPtr: + size = GetTableIndexSize(Table.Method); // Method + break; + case Table.Method: + size = 8 // Rva 4, ImplFlags 2, Flags 2 + + stridx_size // Name + + blobidx_size // Signature + + GetTableIndexSize(Table.Param); // ParamList + break; + case Table.ParamPtr: + size = GetTableIndexSize(Table.Param); // Param + break; + case Table.Param: + size = 4 // Flags 2, Sequence 2 + + stridx_size; // Name + break; + case Table.InterfaceImpl: + size = GetTableIndexSize(Table.TypeDef) // Class + + GetCodedIndexSize(CodedIndex.TypeDefOrRef); // Interface + break; + case Table.MemberRef: + size = GetCodedIndexSize(CodedIndex.MemberRefParent) // Class + + stridx_size // Name + + blobidx_size; // Signature + break; + case Table.Constant: + size = 2 // Type + + GetCodedIndexSize(CodedIndex.HasConstant) // Parent + + blobidx_size; // Value + break; + case Table.CustomAttribute: + size = GetCodedIndexSize(CodedIndex.HasCustomAttribute) // Parent + + GetCodedIndexSize(CodedIndex.CustomAttributeType) // Type + + blobidx_size; // Value + break; + case Table.FieldMarshal: + size = GetCodedIndexSize(CodedIndex.HasFieldMarshal) // Parent + + blobidx_size; // NativeType + break; + case Table.DeclSecurity: + size = 2 // Action + + GetCodedIndexSize(CodedIndex.HasDeclSecurity) // Parent + + blobidx_size; // PermissionSet + break; + case Table.ClassLayout: + size = 6 // PackingSize 2, ClassSize 4 + + GetTableIndexSize(Table.TypeDef); // Parent + break; + case Table.FieldLayout: + size = 4 // Offset + + GetTableIndexSize(Table.Field); // Field + break; + case Table.StandAloneSig: + size = blobidx_size; // Signature + break; + case Table.EventMap: + size = GetTableIndexSize(Table.TypeDef) // Parent + + GetTableIndexSize(Table.Event); // EventList + break; + case Table.EventPtr: + size = GetTableIndexSize(Table.Event); // Event + break; + case Table.Event: + size = 2 // Flags + + stridx_size // Name + + GetCodedIndexSize(CodedIndex.TypeDefOrRef); // EventType + break; + case Table.PropertyMap: + size = GetTableIndexSize(Table.TypeDef) // Parent + + GetTableIndexSize(Table.Property); // PropertyList + break; + case Table.PropertyPtr: + size = GetTableIndexSize(Table.Property); // Property + break; + case Table.Property: + size = 2 // Flags + + stridx_size // Name + + blobidx_size; // Type + break; + case Table.MethodSemantics: + size = 2 // Semantics + + GetTableIndexSize(Table.Method) // Method + + GetCodedIndexSize(CodedIndex.HasSemantics); // Association + break; + case Table.MethodImpl: + size = GetTableIndexSize(Table.TypeDef) // Class + + GetCodedIndexSize(CodedIndex.MethodDefOrRef) // MethodBody + + GetCodedIndexSize(CodedIndex.MethodDefOrRef); // MethodDeclaration + break; + case Table.ModuleRef: + size = stridx_size; // Name + break; + case Table.TypeSpec: + size = blobidx_size; // Signature + break; + case Table.ImplMap: + size = 2 // MappingFlags + + GetCodedIndexSize(CodedIndex.MemberForwarded) // MemberForwarded + + stridx_size // ImportName + + GetTableIndexSize(Table.ModuleRef); // ImportScope + break; + case Table.FieldRVA: + size = 4 // RVA + + GetTableIndexSize(Table.Field); // Field + break; + case Table.EncLog: + case Table.EncMap: + size = 4; + break; + case Table.Assembly: + size = 16 // HashAlgId 4, Version 4 * 2, Flags 4 + + blobidx_size // PublicKey + + (stridx_size * 2); // Name, Culture + break; + case Table.AssemblyProcessor: + size = 4; // Processor + break; + case Table.AssemblyOS: + size = 12; // Platform 4, Version 2 * 4 + break; + case Table.AssemblyRef: + size = 12 // Version 2 * 4 + Flags 4 + + (blobidx_size * 2) // PublicKeyOrToken, HashValue + + (stridx_size * 2); // Name, Culture + break; + case Table.AssemblyRefProcessor: + size = 4 // Processor + + GetTableIndexSize(Table.AssemblyRef); // AssemblyRef + break; + case Table.AssemblyRefOS: + size = 12 // Platform 4, Version 2 * 4 + + GetTableIndexSize(Table.AssemblyRef); // AssemblyRef + break; + case Table.File: + size = 4 // Flags + + stridx_size // Name + + blobidx_size; // HashValue + break; + case Table.ExportedType: + size = 8 // Flags 4, TypeDefId 4 + + (stridx_size * 2) // Name, Namespace + + GetCodedIndexSize(CodedIndex.Implementation); // Implementation + break; + case Table.ManifestResource: + size = 8 // Offset, Flags + + stridx_size // Name + + GetCodedIndexSize(CodedIndex.Implementation); // Implementation + break; + case Table.NestedClass: + size = GetTableIndexSize(Table.TypeDef) // NestedClass + + GetTableIndexSize(Table.TypeDef); // EnclosingClass + break; + case Table.GenericParam: + size = 4 // Number, Flags + + GetCodedIndexSize(CodedIndex.TypeOrMethodDef) // Owner + + stridx_size; // Name + break; + case Table.MethodSpec: + size = GetCodedIndexSize(CodedIndex.MethodDefOrRef) // Method + + blobidx_size; // Instantiation + break; + case Table.GenericParamConstraint: + size = GetTableIndexSize(Table.GenericParam) // Owner + + GetCodedIndexSize(CodedIndex.TypeDefOrRef); // Constraint + break; + default: + throw new NotSupportedException(); + } + + tables[i].RowSize = (uint)size; + tables[i].Offset = offset; + + offset += (uint)size * tables[i].Length; + } + } + + public static Image ReadImageFrom(Stream stream) + { + try + { + var reader = new ImageReader(stream); + reader.ReadImage(); + return reader.image; + } + catch (EndOfStreamException e) + { + throw new BadImageFormatException(Mixin.GetFullyQualifiedName(stream), e); + } + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageWriter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/ImageWriter.cs new file mode 100644 index 00000000..e69de29b diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Section.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Section.cs new file mode 100644 index 00000000..6a4c7bab --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/Section.cs @@ -0,0 +1,43 @@ +// +// Section.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + sealed class Section { + public string Name; + public RVA VirtualAddress; + public uint VirtualSize; + public uint SizeOfRawData; + public uint PointerToRawData; + public byte [] Data; + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/TextMap.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil.PE/TextMap.cs new file mode 100644 index 00000000..e69de29b diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ArrayType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ArrayType.cs new file mode 100644 index 00000000..55c59d87 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ArrayType.cs @@ -0,0 +1,159 @@ +// +// ArrayType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; +using Mono.Collections.Generic; +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public struct ArrayDimension { + + int? lower_bound; + int? upper_bound; + + public int? LowerBound { + get { return lower_bound; } + set { lower_bound = value; } + } + + public int? UpperBound { + get { return upper_bound; } + set { upper_bound = value; } + } + + public bool IsSized { + get { return lower_bound.HasValue || upper_bound.HasValue; } + } + + public ArrayDimension (int? lowerBound, int? upperBound) + { + this.lower_bound = lowerBound; + this.upper_bound = upperBound; + } + + public override string ToString () + { + return !IsSized + ? string.Empty + : lower_bound + "..." + upper_bound; + } + } + + public sealed class ArrayType : TypeSpecification { + + Collection dimensions; + + public Collection Dimensions { + get { + if (dimensions != null) + return dimensions; + + dimensions = new Collection (); + dimensions.Add (new ArrayDimension ()); + return dimensions; + } + } + + public int Rank { + get { return dimensions == null ? 1 : dimensions.Count; } + } + + public bool IsVector { + get { + if (dimensions == null) + return true; + + if (dimensions.Count > 1) + return false; + + var dimension = dimensions [0]; + + return !dimension.IsSized; + } + } + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override string Name { + get { return base.Name + Suffix; } + } + + public override string FullName { + get { return base.FullName + Suffix; } + } + + string Suffix { + get { + if (IsVector) + return "[]"; + + var suffix = new StringBuilder (); + suffix.Append ("["); + for (int i = 0; i < dimensions.Count; i++) { + if (i > 0) + suffix.Append (","); + + suffix.Append (dimensions [i].ToString ()); + } + suffix.Append ("]"); + + return suffix.ToString (); + } + } + + public override bool IsArray { + get { return true; } + } + + public ArrayType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.Array; + } + + public ArrayType (TypeReference type, int rank) + : this (type) + { + Mixin.CheckType (type); + + if (rank == 1) + return; + + dimensions = new Collection (rank); + for (int i = 0; i < rank; i++) + dimensions.Add (new ArrayDimension ()); + this.etype = MD.ElementType.Array; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyDefinition.cs new file mode 100644 index 00000000..4ae62ee4 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyDefinition.cs @@ -0,0 +1,163 @@ +// +// AssemblyDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; + +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider + { + + AssemblyNameDefinition name; + + internal ModuleDefinition main_module; + Collection modules; + Collection custom_attributes; + Collection security_declarations; + + public AssemblyNameDefinition Name + { + get { return name; } + set { name = value; } + } + + public string FullName + { + get { return name != null ? name.FullName : string.Empty; } + } + + public MetadataToken MetadataToken + { + get { return new MetadataToken(TokenType.Assembly, 1); } + set { } + } + + public Collection Modules + { + get + { + if (modules != null) + return modules; + + if (main_module.HasImage) + return main_module.Read(ref modules, this, (_, reader) => reader.ReadModules()); + + return modules = new Collection(1) { main_module }; + } + } + + public ModuleDefinition MainModule + { + get { return main_module; } + } + + public MethodDefinition EntryPoint + { + get { return main_module.EntryPoint; } + set { main_module.EntryPoint = value; } + } + + public bool HasCustomAttributes + { + get + { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, main_module); + } + } + + public Collection CustomAttributes + { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, main_module)); } + } + + public bool HasSecurityDeclarations + { + get + { + if (security_declarations != null) + return security_declarations.Count > 0; + + return Mixin.GetHasSecurityDeclarations(this, main_module); + } + } + + public Collection SecurityDeclarations + { + get { return security_declarations ?? (Mixin.GetSecurityDeclarations(this, ref security_declarations, main_module)); } + } + + internal AssemblyDefinition() + { + } + + + + public static AssemblyDefinition ReadAssembly(string fileName) + { + return ReadAssembly(ModuleDefinition.ReadModule(fileName)); + } + + public static AssemblyDefinition ReadAssembly(string fileName, ReaderParameters parameters) + { + return ReadAssembly(ModuleDefinition.ReadModule(fileName, parameters)); + } + + public static AssemblyDefinition ReadAssembly(Stream stream) + { + return ReadAssembly(ModuleDefinition.ReadModule(stream)); + } + + public static AssemblyDefinition ReadAssembly(Stream stream, ReaderParameters parameters) + { + return ReadAssembly(ModuleDefinition.ReadModule(stream, parameters)); + } + + static AssemblyDefinition ReadAssembly(ModuleDefinition module) + { + var assembly = module.Assembly; + if (assembly == null) + throw new ArgumentException(); + + return assembly; + } + + + + public override string ToString() + { + return this.FullName; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyFlags.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyFlags.cs new file mode 100644 index 00000000..72a0eb06 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyFlags.cs @@ -0,0 +1,42 @@ +// +// AssemblyFlags.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum AssemblyAttributes : uint { + PublicKey = 0x0001, + SideBySideCompatible = 0x0000, + Retargetable = 0x0100, + WindowsRuntime = 0x0200, + DisableJITCompileOptimizer = 0x4000, + EnableJITCompileTracking = 0x8000, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyHashAlgorithm.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyHashAlgorithm.cs new file mode 100644 index 00000000..79a5699d --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyHashAlgorithm.cs @@ -0,0 +1,36 @@ +// +// AssemblyHashAlgorithm.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public enum AssemblyHashAlgorithm : uint { + None = 0x0000, + Reserved = 0x8003, // MD5 + SHA1 = 0x8004 + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyLinkedResource.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyLinkedResource.cs new file mode 100644 index 00000000..4d8bac0b --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyLinkedResource.cs @@ -0,0 +1,57 @@ +// +// AssemblyLinkedResource.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + public sealed class AssemblyLinkedResource : Resource { + + AssemblyNameReference reference; + + public AssemblyNameReference Assembly { + get { return reference; } + set { reference = value; } + } + + public override ResourceType ResourceType { + get { return ResourceType.AssemblyLinked; } + } + + public AssemblyLinkedResource (string name, ManifestResourceAttributes flags) + : base (name, flags) + { + } + + public AssemblyLinkedResource (string name, ManifestResourceAttributes flags, AssemblyNameReference reference) + : base (name, flags) + { + this.reference = reference; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameDefinition.cs new file mode 100644 index 00000000..dc6b9057 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameDefinition.cs @@ -0,0 +1,50 @@ +// +// AssemblyNameDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + public sealed class AssemblyNameDefinition : AssemblyNameReference { + + public override byte [] Hash { + get { return Empty.Array; } + } + + internal AssemblyNameDefinition () + { + this.token = new MetadataToken (TokenType.Assembly, 1); + } + + public AssemblyNameDefinition (string name, Version version) + : base (name, version) + { + this.token = new MetadataToken (TokenType.Assembly, 1); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameReference.cs new file mode 100644 index 00000000..da77d504 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyNameReference.cs @@ -0,0 +1,296 @@ +// +// AssemblyNameReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Globalization; +using System.Security.Cryptography; +using System.Text; + +namespace Mono.Cecil +{ + + public class AssemblyNameReference : IMetadataScope + { + + string name; + string culture; + Version version; + uint attributes; + byte[] public_key; + byte[] public_key_token; + AssemblyHashAlgorithm hash_algorithm; + byte[] hash; + + internal MetadataToken token; + + string full_name; + + public string Name + { + get { return name; } + set + { + name = value; + full_name = null; + } + } + + public string Culture + { + get { return culture; } + set + { + culture = value; + full_name = null; + } + } + + public Version Version + { + get { return version; } + set + { + version = value; + full_name = null; + } + } + + public AssemblyAttributes Attributes + { + get { return (AssemblyAttributes)attributes; } + set { attributes = (uint)value; } + } + + public bool HasPublicKey + { + get { return Mixin.GetAttributes(attributes,(uint)AssemblyAttributes.PublicKey); } + set { attributes =Mixin.SetAttributes(attributes,(uint)AssemblyAttributes.PublicKey, value); } + } + + public bool IsSideBySideCompatible + { + get { return Mixin.GetAttributes(attributes,(uint)AssemblyAttributes.SideBySideCompatible); } + set { attributes =Mixin.SetAttributes(attributes,(uint)AssemblyAttributes.SideBySideCompatible, value); } + } + + public bool IsRetargetable + { + get { return Mixin.GetAttributes(attributes,(uint)AssemblyAttributes.Retargetable); } + set { attributes =Mixin.SetAttributes(attributes,(uint)AssemblyAttributes.Retargetable, value); } + } + + public bool IsWindowsRuntime + { + get { return Mixin.GetAttributes(attributes,(uint)AssemblyAttributes.WindowsRuntime); } + set { attributes =Mixin.SetAttributes(attributes,(uint)AssemblyAttributes.WindowsRuntime, value); } + } + + public byte[] PublicKey + { + get { return public_key ?? Empty.Array; } + set + { + public_key = value; + HasPublicKey = !Mixin.IsNullOrEmpty(public_key); + public_key_token = Empty.Array; + full_name = null; + } + } + + public byte[] PublicKeyToken + { + get + { + if (Mixin.IsNullOrEmpty(public_key_token) && !Mixin.IsNullOrEmpty(public_key)) + { + var hash = HashPublicKey(); + // we need the last 8 bytes in reverse order + byte[] local_public_key_token = new byte[8]; + Array.Copy(hash, (hash.Length - 8), local_public_key_token, 0, 8); + Array.Reverse(local_public_key_token, 0, 8); + public_key_token = local_public_key_token; // publish only once finished (required for thread-safety) + } + return public_key_token ?? Empty.Array; + } + set + { + public_key_token = value; + full_name = null; + } + } + + byte[] HashPublicKey() + { + HashAlgorithm algorithm; + + switch (hash_algorithm) + { + case AssemblyHashAlgorithm.Reserved: + + throw new NotSupportedException(); + + default: + // None default to SHA1 + algorithm = new SHA1Managed(); + break; + + } + + using (algorithm) + return algorithm.ComputeHash(public_key); + } + + public virtual MetadataScopeType MetadataScopeType + { + get { return MetadataScopeType.AssemblyNameReference; } + } + + public string FullName + { + get + { + if (full_name != null) + return full_name; + + const string sep = ", "; + + var builder = new StringBuilder(); + builder.Append(name); + if (version != null) + { + builder.Append(sep); + builder.Append("Version="); + builder.Append(version.ToString()); + } + builder.Append(sep); + builder.Append("Culture="); + builder.Append(string.IsNullOrEmpty(culture) ? "neutral" : culture); + builder.Append(sep); + builder.Append("PublicKeyToken="); + + var pk_token = PublicKeyToken; + if (!Mixin.IsNullOrEmpty(pk_token) && pk_token.Length > 0) + { + for (int i = 0; i < pk_token.Length; i++) + { + builder.Append(pk_token[i].ToString("x2")); + } + } + else + builder.Append("null"); + + return full_name = builder.ToString(); + } + } + + public static AssemblyNameReference Parse(string fullName) + { + if (fullName == null) + throw new ArgumentNullException("fullName"); + if (fullName.Length == 0) + throw new ArgumentException("Name can not be empty"); + + var name = new AssemblyNameReference(); + var tokens = fullName.Split(','); + for (int i = 0; i < tokens.Length; i++) + { + var token = tokens[i].Trim(); + + if (i == 0) + { + name.Name = token; + continue; + } + + var parts = token.Split('='); + if (parts.Length != 2) + throw new ArgumentException("Malformed name"); + + switch (parts[0].ToLowerInvariant()) + { + case "version": + name.Version = new Version(parts[1]); + break; + case "culture": + name.Culture = parts[1]; + break; + case "publickeytoken": + var pk_token = parts[1]; + if (pk_token == "null") + break; + + name.PublicKeyToken = new byte[pk_token.Length / 2]; + for (int j = 0; j < name.PublicKeyToken.Length; j++) + name.PublicKeyToken[j] = Byte.Parse(pk_token.Substring(j * 2, 2), NumberStyles.HexNumber); + + break; + } + } + + return name; + } + + public AssemblyHashAlgorithm HashAlgorithm + { + get { return hash_algorithm; } + set { hash_algorithm = value; } + } + + public virtual byte[] Hash + { + get { return hash; } + set { hash = value; } + } + + public MetadataToken MetadataToken + { + get { return token; } + set { token = value; } + } + + internal AssemblyNameReference() + { + } + + public AssemblyNameReference(string name, Version version) + { + if (name == null) + throw new ArgumentNullException("name"); + + this.name = name; + this.version = version; + this.hash_algorithm = AssemblyHashAlgorithm.None; + this.token = new MetadataToken(TokenType.AssemblyRef); + } + + public override string ToString() + { + return this.FullName; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyReader.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyReader.cs new file mode 100644 index 00000000..ecf70faa --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyReader.cs @@ -0,0 +1,3287 @@ +// +// AssemblyReader.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +using Mono.Collections.Generic; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using RVA = System.UInt32; + +namespace Mono.Cecil +{ + + abstract class ModuleReader + { + + readonly protected Image image; + readonly protected ModuleDefinition module; + + protected ModuleReader(Image image, ReadingMode mode) + { + this.image = image; + this.module = new ModuleDefinition(image); + this.module.ReadingMode = mode; + } + + protected abstract void ReadModule(); + + protected void ReadModuleManifest(MetadataReader reader) + { + reader.Populate(module); + + ReadAssembly(reader); + } + + void ReadAssembly(MetadataReader reader) + { + var name = reader.ReadAssemblyNameDefinition(); + if (name == null) + { + module.kind = ModuleKind.NetModule; + return; + } + + var assembly = new AssemblyDefinition(); + assembly.Name = name; + + module.assembly = assembly; + assembly.main_module = module; + } + + public static ModuleDefinition CreateModuleFrom(Image image, ReaderParameters parameters) + { + var module = ReadModule(image, parameters); + + ReadSymbols(module, parameters); + + if (parameters.AssemblyResolver != null) + module.assembly_resolver = parameters.AssemblyResolver; + + if (parameters.MetadataResolver != null) + module.metadata_resolver = parameters.MetadataResolver; + + return module; + } + + static void ReadSymbols(ModuleDefinition module, ReaderParameters parameters) + { + var symbol_reader_provider = parameters.SymbolReaderProvider; + + if (symbol_reader_provider == null && parameters.ReadSymbols) + symbol_reader_provider = SymbolProvider.GetPlatformReaderProvider(); + + if (symbol_reader_provider != null) + { + module.SymbolReaderProvider = symbol_reader_provider; + + var reader = parameters.SymbolStream != null + ? symbol_reader_provider.GetSymbolReader(module, parameters.SymbolStream) + : symbol_reader_provider.GetSymbolReader(module, module.FullyQualifiedName); + + module.ReadSymbols(reader); + } + } + + static ModuleDefinition ReadModule(Image image, ReaderParameters parameters) + { + var reader = CreateModuleReader(image, parameters.ReadingMode); + reader.ReadModule(); + return reader.module; + } + + static ModuleReader CreateModuleReader(Image image, ReadingMode mode) + { + switch (mode) + { + case ReadingMode.Immediate: + return new ImmediateModuleReader(image); + case ReadingMode.Deferred: + return new DeferredModuleReader(image); + default: + throw new ArgumentException(); + } + } + } + + sealed class ImmediateModuleReader : ModuleReader + { + + public ImmediateModuleReader(Image image) + : base(image, ReadingMode.Immediate) + { + } + + protected override void ReadModule() + { + this.module.Read(this.module, (module, reader) => + { + ReadModuleManifest(reader); + ReadModule(module); + return module; + }); + } + + public static void ReadModule(ModuleDefinition module) + { + if (module.HasAssemblyReferences) + Read(module.AssemblyReferences); + if (module.HasResources) + Read(module.Resources); + if (module.HasModuleReferences) + Read(module.ModuleReferences); + if (module.HasTypes) + ReadTypes(module.Types); + if (module.HasExportedTypes) + Read(module.ExportedTypes); + if (module.HasCustomAttributes) + Read(module.CustomAttributes); + + var assembly = module.Assembly; + if (assembly == null) + return; + + if (assembly.HasCustomAttributes) + Read(assembly.CustomAttributes); + if (assembly.HasSecurityDeclarations) + Read(assembly.SecurityDeclarations); + } + + static void ReadTypes(Collection types) + { + for (int i = 0; i < types.Count; i++) + ReadType(types[i]); + } + + static void ReadType(TypeDefinition type) + { + ReadGenericParameters(type); + + if (type.HasInterfaces) + Read(type.Interfaces); + + if (type.HasNestedTypes) + ReadTypes(type.NestedTypes); + + if (type.HasLayoutInfo) + Read(type.ClassSize); + + if (type.HasFields) + ReadFields(type); + + if (type.HasMethods) + ReadMethods(type); + + if (type.HasProperties) + ReadProperties(type); + + if (type.HasEvents) + ReadEvents(type); + + ReadSecurityDeclarations(type); + ReadCustomAttributes(type); + } + + static void ReadGenericParameters(IGenericParameterProvider provider) + { + if (!provider.HasGenericParameters) + return; + + var parameters = provider.GenericParameters; + + for (int i = 0; i < parameters.Count; i++) + { + var parameter = parameters[i]; + + if (parameter.HasConstraints) + Read(parameter.Constraints); + + if (parameter.HasCustomAttributes) + Read(parameter.CustomAttributes); + } + } + + static void ReadSecurityDeclarations(ISecurityDeclarationProvider provider) + { + if (provider.HasSecurityDeclarations) + Read(provider.SecurityDeclarations); + } + + static void ReadCustomAttributes(ICustomAttributeProvider provider) + { + if (provider.HasCustomAttributes) + Read(provider.CustomAttributes); + } + + static void ReadFields(TypeDefinition type) + { + var fields = type.Fields; + + for (int i = 0; i < fields.Count; i++) + { + var field = fields[i]; + + if (field.HasConstant) + Read(field.Constant); + + if (field.HasLayoutInfo) + Read(field.Offset); + + if (field.RVA > 0) + Read(field.InitialValue); + + if (field.HasMarshalInfo) + Read(field.MarshalInfo); + + ReadCustomAttributes(field); + } + } + + static void ReadMethods(TypeDefinition type) + { + var methods = type.Methods; + + for (int i = 0; i < methods.Count; i++) + { + var method = methods[i]; + + ReadGenericParameters(method); + + if (method.HasParameters) + ReadParameters(method); + + if (method.HasOverrides) + Read(method.Overrides); + + if (method.IsPInvokeImpl) + Read(method.PInvokeInfo); + + ReadSecurityDeclarations(method); + ReadCustomAttributes(method); + + var return_type = method.MethodReturnType; + if (return_type.HasConstant) + Read(return_type.Constant); + + if (return_type.HasMarshalInfo) + Read(return_type.MarshalInfo); + + ReadCustomAttributes(return_type); + } + } + + static void ReadParameters(MethodDefinition method) + { + var parameters = method.Parameters; + + for (int i = 0; i < parameters.Count; i++) + { + var parameter = parameters[i]; + + if (parameter.HasConstant) + Read(parameter.Constant); + + if (parameter.HasMarshalInfo) + Read(parameter.MarshalInfo); + + ReadCustomAttributes(parameter); + } + } + + static void ReadProperties(TypeDefinition type) + { + var properties = type.Properties; + + for (int i = 0; i < properties.Count; i++) + { + var property = properties[i]; + + Read(property.GetMethod); + + if (property.HasConstant) + Read(property.Constant); + + ReadCustomAttributes(property); + } + } + + static void ReadEvents(TypeDefinition type) + { + var events = type.Events; + + for (int i = 0; i < events.Count; i++) + { + var @event = events[i]; + + Read(@event.AddMethod); + + ReadCustomAttributes(@event); + } + } + + static void Read(object collection) + { + } + } + + sealed class DeferredModuleReader : ModuleReader + { + + public DeferredModuleReader(Image image) + : base(image, ReadingMode.Deferred) + { + } + + protected override void ReadModule() + { + this.module.Read(this.module, (module, reader) => + { + ReadModuleManifest(reader); + return module; + }); + } + } + + sealed class MetadataReader : ByteBuffer + { + + readonly internal Image image; + readonly internal ModuleDefinition module; + readonly internal MetadataSystem metadata; + + internal IGenericContext context; + internal CodeReader code; + + uint Position + { + get { return (uint)base.position; } + set { base.position = (int)value; } + } + + public MetadataReader(ModuleDefinition module) + : base(module.Image.MetadataSection.Data) + { + this.image = module.Image; + this.module = module; + this.metadata = module.MetadataSystem; + this.code = new CodeReader(image.MetadataSection, this); + } + + int GetCodedIndexSize(CodedIndex index) + { + return image.GetCodedIndexSize(index); + } + + uint ReadByIndexSize(int size) + { + if (size == 4) + return ReadUInt32(); + else + return ReadUInt16(); + } + + byte[] ReadBlob() + { + var blob_heap = image.BlobHeap; + if (blob_heap == null) + { + position += 2; + return Empty.Array; + } + + return blob_heap.Read(ReadBlobIndex()); + } + + byte[] ReadBlob(uint signature) + { + var blob_heap = image.BlobHeap; + if (blob_heap == null) + return Empty.Array; + + return blob_heap.Read(signature); + } + + uint ReadBlobIndex() + { + var blob_heap = image.BlobHeap; + return ReadByIndexSize(blob_heap != null ? blob_heap.IndexSize : 2); + } + + string ReadString() + { + return image.StringHeap.Read(ReadByIndexSize(image.StringHeap.IndexSize)); + } + + uint ReadStringIndex() + { + return ReadByIndexSize(image.StringHeap.IndexSize); + } + + uint ReadTableIndex(Table table) + { + return ReadByIndexSize(image.GetTableIndexSize(table)); + } + + MetadataToken ReadMetadataToken(CodedIndex index) + { + return Mixin.GetMetadataToken(index, ReadByIndexSize(GetCodedIndexSize(index))); + } + + int MoveTo(Table table) + { + var info = image.TableHeap[table]; + if (info.Length != 0) + Position = info.Offset; + + return (int)info.Length; + } + + bool MoveTo(Table table, uint row) + { + var info = image.TableHeap[table]; + var length = info.Length; + if (length == 0 || row > length) + return false; + + Position = info.Offset + (info.RowSize * (row - 1)); + return true; + } + + public AssemblyNameDefinition ReadAssemblyNameDefinition() + { + if (MoveTo(Table.Assembly) == 0) + return null; + + var name = new AssemblyNameDefinition(); + + name.HashAlgorithm = (AssemblyHashAlgorithm)ReadUInt32(); + + PopulateVersionAndFlags(name); + + name.PublicKey = ReadBlob(); + + PopulateNameAndCulture(name); + + return name; + } + + public ModuleDefinition Populate(ModuleDefinition module) + { + if (MoveTo(Table.Module) == 0) + return module; + + Advance(2); // Generation + + module.Name = ReadString(); + module.Mvid = image.GuidHeap.Read(ReadByIndexSize(image.GuidHeap.IndexSize)); + + return module; + } + + void InitializeAssemblyReferences() + { + if (metadata.AssemblyReferences != null) + return; + + int length = MoveTo(Table.AssemblyRef); + var references = metadata.AssemblyReferences = new AssemblyNameReference[length]; + + for (uint i = 0; i < length; i++) + { + var reference = new AssemblyNameReference(); + reference.token = new MetadataToken(TokenType.AssemblyRef, i + 1); + + PopulateVersionAndFlags(reference); + + var key_or_token = ReadBlob(); + + if (reference.HasPublicKey) + reference.PublicKey = key_or_token; + else + reference.PublicKeyToken = key_or_token; + + PopulateNameAndCulture(reference); + + reference.Hash = ReadBlob(); + + references[i] = reference; + } + } + + public Collection ReadAssemblyReferences() + { + InitializeAssemblyReferences(); + + return new Collection(metadata.AssemblyReferences); + } + + public MethodDefinition ReadEntryPoint() + { + if (module.Image.EntryPointToken == 0) + return null; + + var token = new MetadataToken(module.Image.EntryPointToken); + return GetMethodDefinition(token.RID); + } + + public Collection ReadModules() + { + var modules = new Collection(1); + modules.Add(this.module); + + int length = MoveTo(Table.File); + for (uint i = 1; i <= length; i++) + { + var attributes = (FileAttributes)ReadUInt32(); + var name = ReadString(); + ReadBlobIndex(); + + if (attributes != FileAttributes.ContainsMetaData) + continue; + + var parameters = new ReaderParameters + { + ReadingMode = module.ReadingMode, + SymbolReaderProvider = module.SymbolReaderProvider, + }; + + modules.Add(ModuleDefinition.ReadModule( + GetModuleFileName(name), parameters)); + } + + return modules; + } + + string GetModuleFileName(string name) + { + if (module.FullyQualifiedName == null) + throw new NotSupportedException(); + + var path = Path.GetDirectoryName(module.FullyQualifiedName); + return Path.Combine(path, name); + } + + void InitializeModuleReferences() + { + if (metadata.ModuleReferences != null) + return; + + int length = MoveTo(Table.ModuleRef); + var references = metadata.ModuleReferences = new ModuleReference[length]; + + for (uint i = 0; i < length; i++) + { + var reference = new ModuleReference(ReadString()); + reference.token = new MetadataToken(TokenType.ModuleRef, i + 1); + + references[i] = reference; + } + } + + public Collection ReadModuleReferences() + { + InitializeModuleReferences(); + + return new Collection(metadata.ModuleReferences); + } + + public bool HasFileResource() + { + int length = MoveTo(Table.File); + if (length == 0) + return false; + + for (uint i = 1; i <= length; i++) + if (ReadFileRecord(i).Col1 == FileAttributes.ContainsNoMetaData) + return true; + + return false; + } + + public Collection ReadResources() + { + int length = MoveTo(Table.ManifestResource); + var resources = new Collection(length); + + for (int i = 1; i <= length; i++) + { + var offset = ReadUInt32(); + var flags = (ManifestResourceAttributes)ReadUInt32(); + var name = ReadString(); + var implementation = ReadMetadataToken(CodedIndex.Implementation); + + Resource resource; + + if (implementation.RID == 0) + { + resource = new EmbeddedResource(name, flags, offset, this); + } + else if (implementation.TokenType == TokenType.AssemblyRef) + { + resource = new AssemblyLinkedResource(name, flags) + { + Assembly = (AssemblyNameReference)GetTypeReferenceScope(implementation), + }; + } + else if (implementation.TokenType == TokenType.File) + { + var file_record = ReadFileRecord(implementation.RID); + + resource = new LinkedResource(name, flags) + { + File = file_record.Col2, + hash = ReadBlob(file_record.Col3) + }; + } + else + throw new NotSupportedException(); + + resources.Add(resource); + } + + return resources; + } + + Row ReadFileRecord(uint rid) + { + var position = this.position; + + if (!MoveTo(Table.File, rid)) + throw new ArgumentException(); + + var record = new Row( + (FileAttributes)ReadUInt32(), + ReadString(), + ReadBlobIndex()); + + this.position = position; + + return record; + } + + public MemoryStream GetManagedResourceStream(uint offset) + { + var rva = image.Resources.VirtualAddress; + var section = image.GetSectionAtVirtualAddress(rva); + var position = (rva - section.VirtualAddress) + offset; + var buffer = section.Data; + + var length = buffer[position] + | (buffer[position + 1] << 8) + | (buffer[position + 2] << 16) + | (buffer[position + 3] << 24); + + return new MemoryStream(buffer, (int)position + 4, length); + } + + void PopulateVersionAndFlags(AssemblyNameReference name) + { + name.Version = new Version( + ReadUInt16(), + ReadUInt16(), + ReadUInt16(), + ReadUInt16()); + + name.Attributes = (AssemblyAttributes)ReadUInt32(); + } + + void PopulateNameAndCulture(AssemblyNameReference name) + { + name.Name = ReadString(); + name.Culture = ReadString(); + } + + public TypeDefinitionCollection ReadTypes() + { + InitializeTypeDefinitions(); + var mtypes = metadata.Types; + var type_count = mtypes.Length - metadata.NestedTypes.Count; + var types = new TypeDefinitionCollection(module, type_count); + + for (int i = 0; i < mtypes.Length; i++) + { + var type = mtypes[i]; + if (IsNested(type.Attributes)) + continue; + + types.Add(type); + } + + if (image.HasTable(Table.MethodPtr) || image.HasTable(Table.FieldPtr)) + CompleteTypes(); + + return types; + } + + void CompleteTypes() + { + var types = metadata.Types; + + for (int i = 0; i < types.Length; i++) + { + var type = types[i]; + + InitializeCollection(type.Fields); + InitializeCollection(type.Methods); + } + } + + void InitializeTypeDefinitions() + { + if (metadata.Types != null) + return; + + InitializeNestedTypes(); + InitializeFields(); + InitializeMethods(); + + int length = MoveTo(Table.TypeDef); + var types = metadata.Types = new TypeDefinition[length]; + + for (uint i = 0; i < length; i++) + { + if (types[i] != null) + continue; + + types[i] = ReadType(i + 1); + } + } + + static bool IsNested(TypeAttributes attributes) + { + switch (attributes & TypeAttributes.VisibilityMask) + { + case TypeAttributes.NestedAssembly: + case TypeAttributes.NestedFamANDAssem: + case TypeAttributes.NestedFamily: + case TypeAttributes.NestedFamORAssem: + case TypeAttributes.NestedPrivate: + case TypeAttributes.NestedPublic: + return true; + default: + return false; + } + } + + public bool HasNestedTypes(TypeDefinition type) + { + uint[] mapping; + InitializeNestedTypes(); + + if (!metadata.TryGetNestedTypeMapping(type, out mapping)) + return false; + + return mapping.Length > 0; + } + + public Collection ReadNestedTypes(TypeDefinition type) + { + InitializeNestedTypes(); + uint[] mapping; + if (!metadata.TryGetNestedTypeMapping(type, out mapping)) + return new MemberDefinitionCollection(type); + + var nested_types = new MemberDefinitionCollection(type, mapping.Length); + + for (int i = 0; i < mapping.Length; i++) + { + var nested_type = GetTypeDefinition(mapping[i]); + + if (nested_type != null) + nested_types.Add(nested_type); + } + + metadata.RemoveNestedTypeMapping(type); + + return nested_types; + } + + void InitializeNestedTypes() + { + if (metadata.NestedTypes != null) + return; + + var length = MoveTo(Table.NestedClass); + + metadata.NestedTypes = new Dictionary(length); + metadata.ReverseNestedTypes = new Dictionary(length); + + if (length == 0) + return; + + for (int i = 1; i <= length; i++) + { + var nested = ReadTableIndex(Table.TypeDef); + var declaring = ReadTableIndex(Table.TypeDef); + + AddNestedMapping(declaring, nested); + } + } + + void AddNestedMapping(uint declaring, uint nested) + { + metadata.SetNestedTypeMapping(declaring, AddMapping(metadata.NestedTypes, declaring, nested)); + metadata.SetReverseNestedTypeMapping(nested, declaring); + } + + static TValue[] AddMapping(Dictionary cache, TKey key, TValue value) + { + TValue[] mapped; + if (!cache.TryGetValue(key, out mapped)) + { + mapped = new[] { value }; + return mapped; + } + + var new_mapped = new TValue[mapped.Length + 1]; + Array.Copy(mapped, new_mapped, mapped.Length); + new_mapped[mapped.Length] = value; + return new_mapped; + } + + TypeDefinition ReadType(uint rid) + { + if (!MoveTo(Table.TypeDef, rid)) + return null; + + var attributes = (TypeAttributes)ReadUInt32(); + var name = ReadString(); + var @namespace = ReadString(); + var type = new TypeDefinition(@namespace, name, attributes); + type.token = new MetadataToken(TokenType.TypeDef, rid); + type.scope = module; + type.module = module; + + metadata.AddTypeDefinition(type); + + this.context = type; + + type.BaseType = GetTypeDefOrRef(ReadMetadataToken(CodedIndex.TypeDefOrRef)); + + type.fields_range = ReadFieldsRange(rid); + type.methods_range = ReadMethodsRange(rid); + + if (IsNested(attributes)) + type.DeclaringType = GetNestedTypeDeclaringType(type); + + return type; + } + + TypeDefinition GetNestedTypeDeclaringType(TypeDefinition type) + { + uint declaring_rid; + if (!metadata.TryGetReverseNestedTypeMapping(type, out declaring_rid)) + return null; + + metadata.RemoveReverseNestedTypeMapping(type); + return GetTypeDefinition(declaring_rid); + } + + Range ReadFieldsRange(uint type_index) + { + return ReadListRange(type_index, Table.TypeDef, Table.Field); + } + + Range ReadMethodsRange(uint type_index) + { + return ReadListRange(type_index, Table.TypeDef, Table.Method); + } + + Range ReadListRange(uint current_index, Table current, Table target) + { + var list = new Range(); + + list.Start = ReadTableIndex(target); + + uint next_index; + var current_table = image.TableHeap[current]; + + if (current_index == current_table.Length) + next_index = image.TableHeap[target].Length + 1; + else + { + var position = Position; + Position += (uint)(current_table.RowSize - image.GetTableIndexSize(target)); + next_index = ReadTableIndex(target); + Position = position; + } + + list.Length = next_index - list.Start; + + return list; + } + + public Row ReadTypeLayout(TypeDefinition type) + { + InitializeTypeLayouts(); + Row class_layout; + var rid = type.token.RID; + if (!metadata.ClassLayouts.TryGetValue(rid, out class_layout)) + return new Row(Mixin.NoDataMarker, Mixin.NoDataMarker); + + type.PackingSize = (short)class_layout.Col1; + type.ClassSize = (int)class_layout.Col2; + + metadata.ClassLayouts.Remove(rid); + + return new Row((short)class_layout.Col1, (int)class_layout.Col2); + } + + void InitializeTypeLayouts() + { + if (metadata.ClassLayouts != null) + return; + + int length = MoveTo(Table.ClassLayout); + + var class_layouts = metadata.ClassLayouts = new Dictionary>(length); + + for (uint i = 0; i < length; i++) + { + var packing_size = ReadUInt16(); + var class_size = ReadUInt32(); + + var parent = ReadTableIndex(Table.TypeDef); + + class_layouts.Add(parent, new Row(packing_size, class_size)); + } + } + + public TypeReference GetTypeDefOrRef(MetadataToken token) + { + return (TypeReference)LookupToken(token); + } + + public TypeDefinition GetTypeDefinition(uint rid) + { + InitializeTypeDefinitions(); + + var type = metadata.GetTypeDefinition(rid); + if (type != null) + return type; + + return ReadTypeDefinition(rid); + } + + TypeDefinition ReadTypeDefinition(uint rid) + { + if (!MoveTo(Table.TypeDef, rid)) + return null; + + return ReadType(rid); + } + + void InitializeTypeReferences() + { + if (metadata.TypeReferences != null) + return; + + metadata.TypeReferences = new TypeReference[image.GetTableLength(Table.TypeRef)]; + } + + public TypeReference GetTypeReference(string scope, string full_name) + { + InitializeTypeReferences(); + + var length = metadata.TypeReferences.Length; + + for (uint i = 1; i <= length; i++) + { + var type = GetTypeReference(i); + + if (type.FullName != full_name) + continue; + + if (string.IsNullOrEmpty(scope)) + return type; + + if (type.Scope.Name == scope) + return type; + } + + return null; + } + + TypeReference GetTypeReference(uint rid) + { + InitializeTypeReferences(); + + var type = metadata.GetTypeReference(rid); + if (type != null) + return type; + + return ReadTypeReference(rid); + } + + TypeReference ReadTypeReference(uint rid) + { + if (!MoveTo(Table.TypeRef, rid)) + return null; + + TypeReference declaring_type = null; + IMetadataScope scope; + + var scope_token = ReadMetadataToken(CodedIndex.ResolutionScope); + + var name = ReadString(); + var @namespace = ReadString(); + + var type = new TypeReference( + @namespace, + name, + module, + null); + + type.token = new MetadataToken(TokenType.TypeRef, rid); + + metadata.AddTypeReference(type); + + if (scope_token.TokenType == TokenType.TypeRef) + { + declaring_type = GetTypeDefOrRef(scope_token); + + scope = declaring_type != null + ? declaring_type.Scope + : module; + } + else + scope = GetTypeReferenceScope(scope_token); + + type.scope = scope; + type.DeclaringType = declaring_type; + + MetadataSystem.TryProcessPrimitiveTypeReference(type); + + return type; + } + + IMetadataScope GetTypeReferenceScope(MetadataToken scope) + { + switch (scope.TokenType) + { + case TokenType.AssemblyRef: + InitializeAssemblyReferences(); + return metadata.AssemblyReferences[(int)scope.RID - 1]; + case TokenType.ModuleRef: + InitializeModuleReferences(); + return metadata.ModuleReferences[(int)scope.RID - 1]; + case TokenType.Module: + return module; + default: + throw new NotSupportedException(); + } + } + + public IEnumerable GetTypeReferences() + { + InitializeTypeReferences(); + + var length = image.GetTableLength(Table.TypeRef); + + var type_references = new TypeReference[length]; + + for (uint i = 1; i <= length; i++) + type_references[i - 1] = GetTypeReference(i); + + return type_references; + } + + TypeReference GetTypeSpecification(uint rid) + { + if (!MoveTo(Table.TypeSpec, rid)) + return null; + + var reader = ReadSignature(ReadBlobIndex()); + var type = reader.ReadTypeSignature(); + if (type.token.RID == 0) + type.token = new MetadataToken(TokenType.TypeSpec, rid); + + return type; + } + + SignatureReader ReadSignature(uint signature) + { + return new SignatureReader(signature, this); + } + + public bool HasInterfaces(TypeDefinition type) + { + InitializeInterfaces(); + MetadataToken[] mapping; + + return metadata.TryGetInterfaceMapping(type, out mapping); + } + + public Collection ReadInterfaces(TypeDefinition type) + { + InitializeInterfaces(); + MetadataToken[] mapping; + + if (!metadata.TryGetInterfaceMapping(type, out mapping)) + return new Collection(); + + var interfaces = new Collection(mapping.Length); + + this.context = type; + + for (int i = 0; i < mapping.Length; i++) + interfaces.Add(GetTypeDefOrRef(mapping[i])); + + metadata.RemoveInterfaceMapping(type); + + return interfaces; + } + + void InitializeInterfaces() + { + if (metadata.Interfaces != null) + return; + + int length = MoveTo(Table.InterfaceImpl); + + metadata.Interfaces = new Dictionary(length); + + for (int i = 0; i < length; i++) + { + var type = ReadTableIndex(Table.TypeDef); + var @interface = ReadMetadataToken(CodedIndex.TypeDefOrRef); + + AddInterfaceMapping(type, @interface); + } + } + + void AddInterfaceMapping(uint type, MetadataToken @interface) + { + metadata.SetInterfaceMapping(type, AddMapping(metadata.Interfaces, type, @interface)); + } + + public Collection ReadFields(TypeDefinition type) + { + var fields_range = type.fields_range; + if (fields_range.Length == 0) + return new MemberDefinitionCollection(type); + + var fields = new MemberDefinitionCollection(type, (int)fields_range.Length); + this.context = type; + + if (!MoveTo(Table.FieldPtr, fields_range.Start)) + { + if (!MoveTo(Table.Field, fields_range.Start)) + return fields; + + for (uint i = 0; i < fields_range.Length; i++) + ReadField(fields_range.Start + i, fields); + } + else + ReadPointers(Table.FieldPtr, Table.Field, fields_range, fields, ReadField); + + return fields; + } + + void ReadField(uint field_rid, Collection fields) + { + var attributes = (FieldAttributes)ReadUInt16(); + var name = ReadString(); + var signature = ReadBlobIndex(); + + var field = new FieldDefinition(name, attributes, ReadFieldType(signature)); + field.token = new MetadataToken(TokenType.Field, field_rid); + metadata.AddFieldDefinition(field); + + if (IsDeleted(field)) + return; + + fields.Add(field); + } + + void InitializeFields() + { + if (metadata.Fields != null) + return; + + metadata.Fields = new FieldDefinition[image.GetTableLength(Table.Field)]; + } + + TypeReference ReadFieldType(uint signature) + { + var reader = ReadSignature(signature); + + const byte field_sig = 0x6; + + if (reader.ReadByte() != field_sig) + throw new NotSupportedException(); + + return reader.ReadTypeSignature(); + } + + public int ReadFieldRVA(FieldDefinition field) + { + InitializeFieldRVAs(); + var rid = field.token.RID; + + RVA rva; + if (!metadata.FieldRVAs.TryGetValue(rid, out rva)) + return 0; + + var size = GetFieldTypeSize(field.FieldType); + + if (size == 0 || rva == 0) + return 0; + + metadata.FieldRVAs.Remove(rid); + + field.InitialValue = GetFieldInitializeValue(size, rva); + + return (int)rva; + } + + byte[] GetFieldInitializeValue(int size, RVA rva) + { + var section = image.GetSectionAtVirtualAddress(rva); + if (section == null) + return Empty.Array; + + var value = new byte[size]; + Buffer.BlockCopy(section.Data, (int)(rva - section.VirtualAddress), value, 0, size); + return value; + } + + static int GetFieldTypeSize(TypeReference type) + { + int size = 0; + + switch (type.etype) + { + case ElementType.Boolean: + case ElementType.U1: + case ElementType.I1: + size = 1; + break; + case ElementType.U2: + case ElementType.I2: + case ElementType.Char: + size = 2; + break; + case ElementType.U4: + case ElementType.I4: + case ElementType.R4: + size = 4; + break; + case ElementType.U8: + case ElementType.I8: + case ElementType.R8: + size = 8; + break; + case ElementType.Ptr: + case ElementType.FnPtr: + size = IntPtr.Size; + break; + case ElementType.CModOpt: + case ElementType.CModReqD: + return GetFieldTypeSize(((IModifierType)type).ElementType); + default: + var field_type = Mixin.CheckedResolve(type); + if (field_type.HasLayoutInfo) + size = field_type.ClassSize; + + break; + } + + return size; + } + + void InitializeFieldRVAs() + { + if (metadata.FieldRVAs != null) + return; + + int length = MoveTo(Table.FieldRVA); + + var field_rvas = metadata.FieldRVAs = new Dictionary(length); + + for (int i = 0; i < length; i++) + { + var rva = ReadUInt32(); + var field = ReadTableIndex(Table.Field); + + field_rvas.Add(field, rva); + } + } + + public int ReadFieldLayout(FieldDefinition field) + { + InitializeFieldLayouts(); + var rid = field.token.RID; + uint offset; + if (!metadata.FieldLayouts.TryGetValue(rid, out offset)) + return Mixin.NoDataMarker; + + metadata.FieldLayouts.Remove(rid); + + return (int)offset; + } + + void InitializeFieldLayouts() + { + if (metadata.FieldLayouts != null) + return; + + int length = MoveTo(Table.FieldLayout); + + var field_layouts = metadata.FieldLayouts = new Dictionary(length); + + for (int i = 0; i < length; i++) + { + var offset = ReadUInt32(); + var field = ReadTableIndex(Table.Field); + + field_layouts.Add(field, offset); + } + } + + public bool HasEvents(TypeDefinition type) + { + InitializeEvents(); + + Range range; + if (!metadata.TryGetEventsRange(type, out range)) + return false; + + return range.Length > 0; + } + + public Collection ReadEvents(TypeDefinition type) + { + InitializeEvents(); + Range range; + + if (!metadata.TryGetEventsRange(type, out range)) + return new MemberDefinitionCollection(type); + + var events = new MemberDefinitionCollection(type, (int)range.Length); + + metadata.RemoveEventsRange(type); + + if (range.Length == 0) + return events; + + this.context = type; + + if (!MoveTo(Table.EventPtr, range.Start)) + { + if (!MoveTo(Table.Event, range.Start)) + return events; + + for (uint i = 0; i < range.Length; i++) + ReadEvent(range.Start + i, events); + } + else + ReadPointers(Table.EventPtr, Table.Event, range, events, ReadEvent); + + return events; + } + + void ReadEvent(uint event_rid, Collection events) + { + var attributes = (EventAttributes)ReadUInt16(); + var name = ReadString(); + var event_type = GetTypeDefOrRef(ReadMetadataToken(CodedIndex.TypeDefOrRef)); + + var @event = new EventDefinition(name, attributes, event_type); + @event.token = new MetadataToken(TokenType.Event, event_rid); + + if (IsDeleted(@event)) + return; + + events.Add(@event); + } + + void InitializeEvents() + { + if (metadata.Events != null) + return; + + int length = MoveTo(Table.EventMap); + + metadata.Events = new Dictionary(length); + + for (uint i = 1; i <= length; i++) + { + var type_rid = ReadTableIndex(Table.TypeDef); + Range events_range = ReadEventsRange(i); + metadata.AddEventsRange(type_rid, events_range); + } + } + + Range ReadEventsRange(uint rid) + { + return ReadListRange(rid, Table.EventMap, Table.Event); + } + + public bool HasProperties(TypeDefinition type) + { + InitializeProperties(); + + Range range; + if (!metadata.TryGetPropertiesRange(type, out range)) + return false; + + return range.Length > 0; + } + + public Collection ReadProperties(TypeDefinition type) + { + InitializeProperties(); + + Range range; + + if (!metadata.TryGetPropertiesRange(type, out range)) + return new MemberDefinitionCollection(type); + + metadata.RemovePropertiesRange(type); + + var properties = new MemberDefinitionCollection(type, (int)range.Length); + + if (range.Length == 0) + return properties; + + this.context = type; + + if (!MoveTo(Table.PropertyPtr, range.Start)) + { + if (!MoveTo(Table.Property, range.Start)) + return properties; + for (uint i = 0; i < range.Length; i++) + ReadProperty(range.Start + i, properties); + } + else + ReadPointers(Table.PropertyPtr, Table.Property, range, properties, ReadProperty); + + return properties; + } + + void ReadProperty(uint property_rid, Collection properties) + { + var attributes = (PropertyAttributes)ReadUInt16(); + var name = ReadString(); + var signature = ReadBlobIndex(); + + var reader = ReadSignature(signature); + const byte property_signature = 0x8; + + var calling_convention = reader.ReadByte(); + + if ((calling_convention & property_signature) == 0) + throw new NotSupportedException(); + + var has_this = (calling_convention & 0x20) != 0; + + reader.ReadCompressedUInt32(); // count + + var property = new PropertyDefinition(name, attributes, reader.ReadTypeSignature()); + property.HasThis = has_this; + property.token = new MetadataToken(TokenType.Property, property_rid); + + if (IsDeleted(property)) + return; + + properties.Add(property); + } + + void InitializeProperties() + { + if (metadata.Properties != null) + return; + + int length = MoveTo(Table.PropertyMap); + + metadata.Properties = new Dictionary(length); + + for (uint i = 1; i <= length; i++) + { + var type_rid = ReadTableIndex(Table.TypeDef); + var properties_range = ReadPropertiesRange(i); + metadata.AddPropertiesRange(type_rid, properties_range); + } + } + + Range ReadPropertiesRange(uint rid) + { + return ReadListRange(rid, Table.PropertyMap, Table.Property); + } + + MethodSemanticsAttributes ReadMethodSemantics(MethodDefinition method) + { + InitializeMethodSemantics(); + Row row; + if (!metadata.Semantics.TryGetValue(method.token.RID, out row)) + return MethodSemanticsAttributes.None; + + var type = method.DeclaringType; + + switch (row.Col1) + { + case MethodSemanticsAttributes.AddOn: + GetEvent(type, row.Col2).add_method = method; + break; + case MethodSemanticsAttributes.Fire: + GetEvent(type, row.Col2).invoke_method = method; + break; + case MethodSemanticsAttributes.RemoveOn: + GetEvent(type, row.Col2).remove_method = method; + break; + case MethodSemanticsAttributes.Getter: + GetProperty(type, row.Col2).get_method = method; + break; + case MethodSemanticsAttributes.Setter: + GetProperty(type, row.Col2).set_method = method; + break; + case MethodSemanticsAttributes.Other: + switch (row.Col2.TokenType) + { + case TokenType.Event: + { + var @event = GetEvent(type, row.Col2); + if (@event.other_methods == null) + @event.other_methods = new Collection(); + + @event.other_methods.Add(method); + break; + } + case TokenType.Property: + { + var property = GetProperty(type, row.Col2); + if (property.other_methods == null) + property.other_methods = new Collection(); + + property.other_methods.Add(method); + + break; + } + default: + throw new NotSupportedException(); + } + break; + default: + throw new NotSupportedException(); + } + + metadata.Semantics.Remove(method.token.RID); + + return row.Col1; + } + + static EventDefinition GetEvent(TypeDefinition type, MetadataToken token) + { + if (token.TokenType != TokenType.Event) + throw new ArgumentException(); + + return GetMember(type.Events, token); + } + + static PropertyDefinition GetProperty(TypeDefinition type, MetadataToken token) + { + if (token.TokenType != TokenType.Property) + throw new ArgumentException(); + + return GetMember(type.Properties, token); + } + + static TMember GetMember(Collection members, MetadataToken token) where TMember : IMemberDefinition + { + for (int i = 0; i < members.Count; i++) + { + var member = members[i]; + if (member.MetadataToken == token) + return member; + } + + throw new ArgumentException(); + } + + void InitializeMethodSemantics() + { + if (metadata.Semantics != null) + return; + + int length = MoveTo(Table.MethodSemantics); + + var semantics = metadata.Semantics = new Dictionary>(0); + + for (uint i = 0; i < length; i++) + { + var attributes = (MethodSemanticsAttributes)ReadUInt16(); + var method_rid = ReadTableIndex(Table.Method); + var association = ReadMetadataToken(CodedIndex.HasSemantics); + + semantics[method_rid] = new Row(attributes, association); + } + } + + public PropertyDefinition ReadMethods(PropertyDefinition property) + { + ReadAllSemantics(property.DeclaringType); + return property; + } + + public EventDefinition ReadMethods(EventDefinition @event) + { + ReadAllSemantics(@event.DeclaringType); + return @event; + } + + public MethodSemanticsAttributes ReadAllSemantics(MethodDefinition method) + { + ReadAllSemantics(method.DeclaringType); + + return method.SemanticsAttributes; + } + + void ReadAllSemantics(TypeDefinition type) + { + var methods = type.Methods; + for (int i = 0; i < methods.Count; i++) + { + var method = methods[i]; + if (method.sem_attrs_ready) + continue; + + method.sem_attrs = ReadMethodSemantics(method); + method.sem_attrs_ready = true; + } + } + + Range ReadParametersRange(uint method_rid) + { + return ReadListRange(method_rid, Table.Method, Table.Param); + } + + public Collection ReadMethods(TypeDefinition type) + { + var methods_range = type.methods_range; + if (methods_range.Length == 0) + return new MemberDefinitionCollection(type); + + var methods = new MemberDefinitionCollection(type, (int)methods_range.Length); + if (!MoveTo(Table.MethodPtr, methods_range.Start)) + { + if (!MoveTo(Table.Method, methods_range.Start)) + return methods; + + for (uint i = 0; i < methods_range.Length; i++) + ReadMethod(methods_range.Start + i, methods); + } + else + ReadPointers(Table.MethodPtr, Table.Method, methods_range, methods, ReadMethod); + + return methods; + } + + void ReadPointers(Table ptr, Table table, Range range, Collection members, Action> reader) + where TMember : IMemberDefinition + { + for (uint i = 0; i < range.Length; i++) + { + MoveTo(ptr, range.Start + i); + + var rid = ReadTableIndex(table); + MoveTo(table, rid); + + reader(rid, members); + } + } + + static bool IsDeleted(IMemberDefinition member) + { + return member.IsSpecialName && member.Name == "_Deleted"; + } + + void InitializeMethods() + { + if (metadata.Methods != null) + return; + + metadata.Methods = new MethodDefinition[image.GetTableLength(Table.Method)]; + } + + void ReadMethod(uint method_rid, Collection methods) + { + var method = new MethodDefinition(); + method.rva = ReadUInt32(); + method.ImplAttributes = (MethodImplAttributes)ReadUInt16(); + method.Attributes = (MethodAttributes)ReadUInt16(); + method.Name = ReadString(); + method.token = new MetadataToken(TokenType.Method, method_rid); + + if (IsDeleted(method)) + return; + + methods.Add(method); // attach method + + var signature = ReadBlobIndex(); + var param_range = ReadParametersRange(method_rid); + + this.context = method; + + ReadMethodSignature(signature, method); + metadata.AddMethodDefinition(method); + + if (param_range.Length == 0) + return; + + var position = base.position; + ReadParameters(method, param_range); + base.position = position; + } + + void ReadParameters(MethodDefinition method, Range param_range) + { + if (!MoveTo(Table.ParamPtr, param_range.Start)) + { + if (!MoveTo(Table.Param, param_range.Start)) + return; + + for (uint i = 0; i < param_range.Length; i++) + ReadParameter(param_range.Start + i, method); + } + else + ReadParameterPointers(method, param_range); + } + + void ReadParameterPointers(MethodDefinition method, Range range) + { + for (uint i = 0; i < range.Length; i++) + { + MoveTo(Table.ParamPtr, range.Start + i); + + var rid = ReadTableIndex(Table.Param); + + MoveTo(Table.Param, rid); + + ReadParameter(rid, method); + } + } + + void ReadParameter(uint param_rid, MethodDefinition method) + { + var attributes = (ParameterAttributes)ReadUInt16(); + var sequence = ReadUInt16(); + var name = ReadString(); + + var parameter = sequence == 0 + ? method.MethodReturnType.Parameter + : method.Parameters[sequence - 1]; + + parameter.token = new MetadataToken(TokenType.Param, param_rid); + parameter.Name = name; + parameter.Attributes = attributes; + } + + void ReadMethodSignature(uint signature, IMethodSignature method) + { + var reader = ReadSignature(signature); + reader.ReadMethodSignature(method); + } + + public PInvokeInfo ReadPInvokeInfo(MethodDefinition method) + { + InitializePInvokes(); + Row row; + + var rid = method.token.RID; + + if (!metadata.PInvokes.TryGetValue(rid, out row)) + return null; + + metadata.PInvokes.Remove(rid); + + return new PInvokeInfo( + row.Col1, + image.StringHeap.Read(row.Col2), + module.ModuleReferences[(int)row.Col3 - 1]); + } + + void InitializePInvokes() + { + if (metadata.PInvokes != null) + return; + + int length = MoveTo(Table.ImplMap); + + var pinvokes = metadata.PInvokes = new Dictionary>(length); + + for (int i = 1; i <= length; i++) + { + var attributes = (PInvokeAttributes)ReadUInt16(); + var method = ReadMetadataToken(CodedIndex.MemberForwarded); + var name = ReadStringIndex(); + var scope = ReadTableIndex(Table.File); + + if (method.TokenType != TokenType.Method) + continue; + + pinvokes.Add(method.RID, new Row(attributes, name, scope)); + } + } + + public bool HasGenericParameters(IGenericParameterProvider provider) + { + InitializeGenericParameters(); + + Range range; + if (!metadata.TryGetGenericParameterRange(provider, out range)) + return false; + + return range.Length > 0; + } + + public Collection ReadGenericParameters(IGenericParameterProvider provider) + { + InitializeGenericParameters(); + + Range range; + if (!metadata.TryGetGenericParameterRange(provider, out range) + || !MoveTo(Table.GenericParam, range.Start)) + return new GenericParameterCollection(provider); + + metadata.RemoveGenericParameterRange(provider); + + var generic_parameters = new GenericParameterCollection(provider, (int)range.Length); + + for (uint i = 0; i < range.Length; i++) + { + ReadUInt16(); // index + var flags = (GenericParameterAttributes)ReadUInt16(); + ReadMetadataToken(CodedIndex.TypeOrMethodDef); + var name = ReadString(); + + var parameter = new GenericParameter(name, provider); + parameter.token = new MetadataToken(TokenType.GenericParam, range.Start + i); + parameter.Attributes = flags; + + generic_parameters.Add(parameter); + } + + return generic_parameters; + } + + void InitializeGenericParameters() + { + if (metadata.GenericParameters != null) + return; + + metadata.GenericParameters = InitializeRanges( + Table.GenericParam, () => + { + Advance(4); + var next = ReadMetadataToken(CodedIndex.TypeOrMethodDef); + ReadStringIndex(); + return next; + }); + } + + Dictionary InitializeRanges(Table table, Func get_next) + { + int length = MoveTo(table); + var ranges = new Dictionary(length); + + if (length == 0) + return ranges; + + MetadataToken owner = MetadataToken.Zero; + Range range = new Range(1, 0); + + for (uint i = 1; i <= length; i++) + { + var next = get_next(); + + if (i == 1) + { + owner = next; + range.Length++; + } + else if (next != owner) + { + if (owner.RID != 0) + ranges.Add(owner, range); + range = new Range(i, 1); + owner = next; + } + else + range.Length++; + } + + if (owner != MetadataToken.Zero && !ranges.ContainsKey(owner)) + ranges.Add(owner, range); + + return ranges; + } + + public bool HasGenericConstraints(GenericParameter generic_parameter) + { + InitializeGenericConstraints(); + + MetadataToken[] mapping; + if (!metadata.TryGetGenericConstraintMapping(generic_parameter, out mapping)) + return false; + + return mapping.Length > 0; + } + + public Collection ReadGenericConstraints(GenericParameter generic_parameter) + { + InitializeGenericConstraints(); + + MetadataToken[] mapping; + if (!metadata.TryGetGenericConstraintMapping(generic_parameter, out mapping)) + return new Collection(); + + var constraints = new Collection(mapping.Length); + + this.context = (IGenericContext)generic_parameter.Owner; + + for (int i = 0; i < mapping.Length; i++) + constraints.Add(GetTypeDefOrRef(mapping[i])); + + metadata.RemoveGenericConstraintMapping(generic_parameter); + + return constraints; + } + + void InitializeGenericConstraints() + { + if (metadata.GenericConstraints != null) + return; + + var length = MoveTo(Table.GenericParamConstraint); + + metadata.GenericConstraints = new Dictionary(length); + + for (int i = 1; i <= length; i++) + AddGenericConstraintMapping( + ReadTableIndex(Table.GenericParam), + ReadMetadataToken(CodedIndex.TypeDefOrRef)); + } + + void AddGenericConstraintMapping(uint generic_parameter, MetadataToken constraint) + { + metadata.SetGenericConstraintMapping( + generic_parameter, + AddMapping(metadata.GenericConstraints, generic_parameter, constraint)); + } + + public bool HasOverrides(MethodDefinition method) + { + InitializeOverrides(); + MetadataToken[] mapping; + + if (!metadata.TryGetOverrideMapping(method, out mapping)) + return false; + + return mapping.Length > 0; + } + + public Collection ReadOverrides(MethodDefinition method) + { + InitializeOverrides(); + + MetadataToken[] mapping; + if (!metadata.TryGetOverrideMapping(method, out mapping)) + return new Collection(); + + var overrides = new Collection(mapping.Length); + + this.context = method; + + for (int i = 0; i < mapping.Length; i++) + overrides.Add((MethodReference)LookupToken(mapping[i])); + + metadata.RemoveOverrideMapping(method); + + return overrides; + } + + void InitializeOverrides() + { + if (metadata.Overrides != null) + return; + + var length = MoveTo(Table.MethodImpl); + + metadata.Overrides = new Dictionary(length); + + for (int i = 1; i <= length; i++) + { + ReadTableIndex(Table.TypeDef); + + var method = ReadMetadataToken(CodedIndex.MethodDefOrRef); + if (method.TokenType != TokenType.Method) + throw new NotSupportedException(); + + var @override = ReadMetadataToken(CodedIndex.MethodDefOrRef); + + AddOverrideMapping(method.RID, @override); + } + } + + void AddOverrideMapping(uint method_rid, MetadataToken @override) + { + metadata.SetOverrideMapping( + method_rid, + AddMapping(metadata.Overrides, method_rid, @override)); + } + + public MethodBody ReadMethodBody(MethodDefinition method) + { + return code.ReadMethodBody(method); + } + + public CallSite ReadCallSite(MetadataToken token) + { + if (!MoveTo(Table.StandAloneSig, token.RID)) + return null; + + var signature = ReadBlobIndex(); + + var call_site = new CallSite(); + + ReadMethodSignature(signature, call_site); + + call_site.MetadataToken = token; + + return call_site; + } + + public VariableDefinitionCollection ReadVariables(MetadataToken local_var_token) + { + if (!MoveTo(Table.StandAloneSig, local_var_token.RID)) + return null; + + var reader = ReadSignature(ReadBlobIndex()); + const byte local_sig = 0x7; + + if (reader.ReadByte() != local_sig) + throw new NotSupportedException(); + + var count = reader.ReadCompressedUInt32(); + if (count == 0) + return null; + + var variables = new VariableDefinitionCollection((int)count); + + for (int i = 0; i < count; i++) + variables.Add(new VariableDefinition(reader.ReadTypeSignature())); + + return variables; + } + + public IMetadataTokenProvider LookupToken(MetadataToken token) + { + var rid = token.RID; + + if (rid == 0) + return null; + + IMetadataTokenProvider element; + var position = this.position; + var context = this.context; + + switch (token.TokenType) + { + case TokenType.TypeDef: + element = GetTypeDefinition(rid); + break; + case TokenType.TypeRef: + element = GetTypeReference(rid); + break; + case TokenType.TypeSpec: + element = GetTypeSpecification(rid); + break; + case TokenType.Field: + element = GetFieldDefinition(rid); + break; + case TokenType.Method: + element = GetMethodDefinition(rid); + break; + case TokenType.MemberRef: + element = GetMemberReference(rid); + break; + case TokenType.MethodSpec: + element = GetMethodSpecification(rid); + break; + default: + return null; + } + + this.position = position; + this.context = context; + + return element; + } + + public FieldDefinition GetFieldDefinition(uint rid) + { + InitializeTypeDefinitions(); + + var field = metadata.GetFieldDefinition(rid); + if (field != null) + return field; + + return LookupField(rid); + } + + FieldDefinition LookupField(uint rid) + { + var type = metadata.GetFieldDeclaringType(rid); + if (type == null) + return null; + + InitializeCollection(type.Fields); + + return metadata.GetFieldDefinition(rid); + } + + public MethodDefinition GetMethodDefinition(uint rid) + { + InitializeTypeDefinitions(); + + var method = metadata.GetMethodDefinition(rid); + if (method != null) + return method; + + return LookupMethod(rid); + } + + MethodDefinition LookupMethod(uint rid) + { + var type = metadata.GetMethodDeclaringType(rid); + if (type == null) + return null; + + InitializeCollection(type.Methods); + + return metadata.GetMethodDefinition(rid); + } + + MethodSpecification GetMethodSpecification(uint rid) + { + if (!MoveTo(Table.MethodSpec, rid)) + return null; + + var element_method = (MethodReference)LookupToken( + ReadMetadataToken(CodedIndex.MethodDefOrRef)); + var signature = ReadBlobIndex(); + + var method_spec = ReadMethodSpecSignature(signature, element_method); + method_spec.token = new MetadataToken(TokenType.MethodSpec, rid); + return method_spec; + } + + MethodSpecification ReadMethodSpecSignature(uint signature, MethodReference method) + { + var reader = ReadSignature(signature); + const byte methodspec_sig = 0x0a; + + var call_conv = reader.ReadByte(); + + if (call_conv != methodspec_sig) + throw new NotSupportedException(); + + var instance = new GenericInstanceMethod(method); + + reader.ReadGenericInstanceSignature(method, instance); + + return instance; + } + + MemberReference GetMemberReference(uint rid) + { + InitializeMemberReferences(); + + var member = metadata.GetMemberReference(rid); + if (member != null) + return member; + + member = ReadMemberReference(rid); + if (member != null && !member.ContainsGenericParameter) + metadata.AddMemberReference(member); + return member; + } + + MemberReference ReadMemberReference(uint rid) + { + if (!MoveTo(Table.MemberRef, rid)) + return null; + + var token = ReadMetadataToken(CodedIndex.MemberRefParent); + var name = ReadString(); + var signature = ReadBlobIndex(); + + MemberReference member; + + switch (token.TokenType) + { + case TokenType.TypeDef: + case TokenType.TypeRef: + case TokenType.TypeSpec: + member = ReadTypeMemberReference(token, name, signature); + break; + case TokenType.Method: + member = ReadMethodMemberReference(token, name, signature); + break; + default: + throw new NotSupportedException(); + } + + member.token = new MetadataToken(TokenType.MemberRef, rid); + + return member; + } + + MemberReference ReadTypeMemberReference(MetadataToken type, string name, uint signature) + { + var declaring_type = GetTypeDefOrRef(type); + + if (!declaring_type.IsArray) + this.context = declaring_type; + + var member = ReadMemberReferenceSignature(signature, declaring_type); + member.Name = name; + + return member; + } + + MemberReference ReadMemberReferenceSignature(uint signature, TypeReference declaring_type) + { + var reader = ReadSignature(signature); + const byte field_sig = 0x6; + + if (reader.buffer[reader.position] == field_sig) + { + reader.position++; + var field = new FieldReference(); + field.DeclaringType = declaring_type; + field.FieldType = reader.ReadTypeSignature(); + return field; + } + else + { + var method = new MethodReference(); + method.DeclaringType = declaring_type; + reader.ReadMethodSignature(method); + return method; + } + } + + MemberReference ReadMethodMemberReference(MetadataToken token, string name, uint signature) + { + var method = GetMethodDefinition(token.RID); + + this.context = method; + + var member = ReadMemberReferenceSignature(signature, method.DeclaringType); + member.Name = name; + + return member; + } + + void InitializeMemberReferences() + { + if (metadata.MemberReferences != null) + return; + + metadata.MemberReferences = new MemberReference[image.GetTableLength(Table.MemberRef)]; + } + + public IEnumerable GetMemberReferences() + { + InitializeMemberReferences(); + + var length = image.GetTableLength(Table.MemberRef); + + var type_system = module.TypeSystem; + + var context = new MethodReference(string.Empty, type_system.Void); + context.DeclaringType = new TypeReference(string.Empty, string.Empty, module, type_system.Corlib); + + var member_references = new MemberReference[length]; + + for (uint i = 1; i <= length; i++) + { + this.context = context; + member_references[i - 1] = GetMemberReference(i); + } + + return member_references; + } + + void InitializeConstants() + { + if (metadata.Constants != null) + return; + + var length = MoveTo(Table.Constant); + + var constants = metadata.Constants = new Dictionary>(length); + + for (uint i = 1; i <= length; i++) + { + var type = (ElementType)ReadUInt16(); + var owner = ReadMetadataToken(CodedIndex.HasConstant); + var signature = ReadBlobIndex(); + + constants.Add(owner, new Row(type, signature)); + } + } + + public object ReadConstant(IConstantProvider owner) + { + InitializeConstants(); + + Row row; + if (!metadata.Constants.TryGetValue(owner.MetadataToken, out row)) + return Mixin.NoValue; + + metadata.Constants.Remove(owner.MetadataToken); + + switch (row.Col1) + { + case ElementType.Class: + case ElementType.Object: + return null; + case ElementType.String: + return ReadConstantString(ReadBlob(row.Col2)); + default: + return ReadConstantPrimitive(row.Col1, row.Col2); + } + } + + static string ReadConstantString(byte[] blob) + { + var length = blob.Length; + if ((length & 1) == 1) + length--; + + return Encoding.Unicode.GetString(blob, 0, length); + } + + object ReadConstantPrimitive(ElementType type, uint signature) + { + var reader = ReadSignature(signature); + return reader.ReadConstantSignature(type); + } + + void InitializeCustomAttributes() + { + if (metadata.CustomAttributes != null) + return; + + metadata.CustomAttributes = InitializeRanges( + Table.CustomAttribute, () => + { + var next = ReadMetadataToken(CodedIndex.HasCustomAttribute); + ReadMetadataToken(CodedIndex.CustomAttributeType); + ReadBlobIndex(); + return next; + }); + } + + public bool HasCustomAttributes(ICustomAttributeProvider owner) + { + InitializeCustomAttributes(); + + Range range; + if (!metadata.TryGetCustomAttributeRange(owner, out range)) + return false; + + return range.Length > 0; + } + + public Collection ReadCustomAttributes(ICustomAttributeProvider owner) + { + InitializeCustomAttributes(); + + Range range; + if (!metadata.TryGetCustomAttributeRange(owner, out range) + || !MoveTo(Table.CustomAttribute, range.Start)) + return new Collection(); + + var custom_attributes = new Collection((int)range.Length); + + for (int i = 0; i < range.Length; i++) + { + ReadMetadataToken(CodedIndex.HasCustomAttribute); + + var constructor = (MethodReference)LookupToken( + ReadMetadataToken(CodedIndex.CustomAttributeType)); + + var signature = ReadBlobIndex(); + + custom_attributes.Add(new CustomAttribute(signature, constructor)); + } + + metadata.RemoveCustomAttributeRange(owner); + + return custom_attributes; + } + + public byte[] ReadCustomAttributeBlob(uint signature) + { + return ReadBlob(signature); + } + + public void ReadCustomAttributeSignature(CustomAttribute attribute) + { + var reader = ReadSignature(attribute.signature); + + if (!reader.CanReadMore()) + return; + + if (reader.ReadUInt16() != 0x0001) + throw new InvalidOperationException(); + + var constructor = attribute.Constructor; + if (constructor.HasParameters) + reader.ReadCustomAttributeConstructorArguments(attribute, constructor.Parameters); + + if (!reader.CanReadMore()) + return; + + var named = reader.ReadUInt16(); + + if (named == 0) + return; + + reader.ReadCustomAttributeNamedArguments(named, ref attribute.fields, ref attribute.properties); + } + + void InitializeMarshalInfos() + { + if (metadata.FieldMarshals != null) + return; + + var length = MoveTo(Table.FieldMarshal); + + var marshals = metadata.FieldMarshals = new Dictionary(length); + + for (int i = 0; i < length; i++) + { + var token = ReadMetadataToken(CodedIndex.HasFieldMarshal); + var signature = ReadBlobIndex(); + if (token.RID == 0) + continue; + + marshals.Add(token, signature); + } + } + + public bool HasMarshalInfo(IMarshalInfoProvider owner) + { + InitializeMarshalInfos(); + + return metadata.FieldMarshals.ContainsKey(owner.MetadataToken); + } + + public MarshalInfo ReadMarshalInfo(IMarshalInfoProvider owner) + { + InitializeMarshalInfos(); + + uint signature; + if (!metadata.FieldMarshals.TryGetValue(owner.MetadataToken, out signature)) + return null; + + var reader = ReadSignature(signature); + + metadata.FieldMarshals.Remove(owner.MetadataToken); + + return reader.ReadMarshalInfo(); + } + + void InitializeSecurityDeclarations() + { + if (metadata.SecurityDeclarations != null) + return; + + metadata.SecurityDeclarations = InitializeRanges( + Table.DeclSecurity, () => + { + ReadUInt16(); + var next = ReadMetadataToken(CodedIndex.HasDeclSecurity); + ReadBlobIndex(); + return next; + }); + } + + public bool HasSecurityDeclarations(ISecurityDeclarationProvider owner) + { + InitializeSecurityDeclarations(); + + Range range; + if (!metadata.TryGetSecurityDeclarationRange(owner, out range)) + return false; + + return range.Length > 0; + } + + public Collection ReadSecurityDeclarations(ISecurityDeclarationProvider owner) + { + InitializeSecurityDeclarations(); + + Range range; + if (!metadata.TryGetSecurityDeclarationRange(owner, out range) + || !MoveTo(Table.DeclSecurity, range.Start)) + return new Collection(); + + var security_declarations = new Collection((int)range.Length); + + for (int i = 0; i < range.Length; i++) + { + var action = (SecurityAction)ReadUInt16(); + ReadMetadataToken(CodedIndex.HasDeclSecurity); + var signature = ReadBlobIndex(); + + security_declarations.Add(new SecurityDeclaration(action, signature, module)); + } + + metadata.RemoveSecurityDeclarationRange(owner); + + return security_declarations; + } + + public byte[] ReadSecurityDeclarationBlob(uint signature) + { + return ReadBlob(signature); + } + + public void ReadSecurityDeclarationSignature(SecurityDeclaration declaration) + { + var signature = declaration.signature; + var reader = ReadSignature(signature); + + if (reader.buffer[reader.position] != '.') + { + ReadXmlSecurityDeclaration(signature, declaration); + return; + } + + reader.position++; + var count = reader.ReadCompressedUInt32(); + var attributes = new Collection((int)count); + + for (int i = 0; i < count; i++) + attributes.Add(reader.ReadSecurityAttribute()); + + declaration.security_attributes = attributes; + } + + void ReadXmlSecurityDeclaration(uint signature, SecurityDeclaration declaration) + { + var blob = ReadBlob(signature); + var attributes = new Collection(1); + + var attribute = new SecurityAttribute( + module.TypeSystem.LookupType("System.Security.Permissions", "PermissionSetAttribute")); + + attribute.properties = new Collection(1); + attribute.properties.Add( + new CustomAttributeNamedArgument( + "XML", + new CustomAttributeArgument( + module.TypeSystem.String, + Encoding.Unicode.GetString(blob, 0, blob.Length)))); + + attributes.Add(attribute); + + declaration.security_attributes = attributes; + } + + public Collection ReadExportedTypes() + { + var length = MoveTo(Table.ExportedType); + if (length == 0) + return new Collection(); + + var exported_types = new Collection(length); + + for (int i = 1; i <= length; i++) + { + var attributes = (TypeAttributes)ReadUInt32(); + var identifier = ReadUInt32(); + var name = ReadString(); + var @namespace = ReadString(); + var implementation = ReadMetadataToken(CodedIndex.Implementation); + + ExportedType declaring_type = null; + IMetadataScope scope = null; + + switch (implementation.TokenType) + { + case TokenType.AssemblyRef: + case TokenType.File: + scope = GetExportedTypeScope(implementation); + break; + case TokenType.ExportedType: + // FIXME: if the table is not properly sorted + declaring_type = exported_types[(int)implementation.RID - 1]; + break; + } + + var exported_type = new ExportedType(@namespace, name, module, scope) + { + Attributes = attributes, + Identifier = (int)identifier, + DeclaringType = declaring_type, + }; + exported_type.token = new MetadataToken(TokenType.ExportedType, i); + + exported_types.Add(exported_type); + } + + return exported_types; + } + + IMetadataScope GetExportedTypeScope(MetadataToken token) + { + var position = this.position; + IMetadataScope scope; + + switch (token.TokenType) + { + case TokenType.AssemblyRef: + InitializeAssemblyReferences(); + scope = metadata.AssemblyReferences[(int)token.RID - 1]; + break; + case TokenType.File: + InitializeModuleReferences(); + scope = GetModuleReferenceFromFile(token); + break; + default: + throw new NotSupportedException(); + } + + this.position = position; + return scope; + } + + ModuleReference GetModuleReferenceFromFile(MetadataToken token) + { + if (!MoveTo(Table.File, token.RID)) + return null; + + ReadUInt32(); + var file_name = ReadString(); + var modules = module.ModuleReferences; + + ModuleReference reference; + for (int i = 0; i < modules.Count; i++) + { + reference = modules[i]; + if (reference.Name == file_name) + return reference; + } + + reference = new ModuleReference(file_name); + modules.Add(reference); + return reference; + } + + static void InitializeCollection(object o) + { + } + } + + sealed class SignatureReader : ByteBuffer + { + + readonly MetadataReader reader; + readonly uint start, sig_length; + + TypeSystem TypeSystem + { + get { return reader.module.TypeSystem; } + } + + public SignatureReader(uint blob, MetadataReader reader) + : base(reader.buffer) + { + this.reader = reader; + + MoveToBlob(blob); + + this.sig_length = ReadCompressedUInt32(); + this.start = (uint)position; + } + + void MoveToBlob(uint blob) + { + position = (int)(reader.image.BlobHeap.Offset + blob); + } + + MetadataToken ReadTypeTokenSignature() + { + return Mixin.GetMetadataToken(CodedIndex.TypeDefOrRef, ReadCompressedUInt32()); + } + + GenericParameter GetGenericParameter(GenericParameterType type, uint var) + { + var context = reader.context; + int index = (int)var; + + if (context == null) + return GetUnboundGenericParameter(type, index); + + IGenericParameterProvider provider; + + switch (type) + { + case GenericParameterType.Type: + provider = context.Type; + break; + case GenericParameterType.Method: + provider = context.Method; + break; + default: + throw new NotSupportedException(); + } + + if (!context.IsDefinition) + CheckGenericContext(provider, index); + + if (index >= provider.GenericParameters.Count) + return GetUnboundGenericParameter(type, index); + + return provider.GenericParameters[index]; + } + + GenericParameter GetUnboundGenericParameter(GenericParameterType type, int index) + { + return new GenericParameter(index, type, reader.module); + } + + static void CheckGenericContext(IGenericParameterProvider owner, int index) + { + var owner_parameters = owner.GenericParameters; + + for (int i = owner_parameters.Count; i <= index; i++) + owner_parameters.Add(new GenericParameter(owner)); + } + + public void ReadGenericInstanceSignature(IGenericParameterProvider provider, IGenericInstance instance) + { + var arity = ReadCompressedUInt32(); + + if (!provider.IsDefinition) + CheckGenericContext(provider, (int)arity - 1); + + var instance_arguments = instance.GenericArguments; + + for (int i = 0; i < arity; i++) + instance_arguments.Add(ReadTypeSignature()); + } + + ArrayType ReadArrayTypeSignature() + { + var array = new ArrayType(ReadTypeSignature()); + + var rank = ReadCompressedUInt32(); + + var sizes = new uint[ReadCompressedUInt32()]; + for (int i = 0; i < sizes.Length; i++) + sizes[i] = ReadCompressedUInt32(); + + var low_bounds = new int[ReadCompressedUInt32()]; + for (int i = 0; i < low_bounds.Length; i++) + low_bounds[i] = ReadCompressedInt32(); + + array.Dimensions.Clear(); + + for (int i = 0; i < rank; i++) + { + int? lower = null, upper = null; + + if (i < low_bounds.Length) + lower = low_bounds[i]; + + if (i < sizes.Length) + upper = lower + (int)sizes[i] - 1; + + array.Dimensions.Add(new ArrayDimension(lower, upper)); + } + + return array; + } + + TypeReference GetTypeDefOrRef(MetadataToken token) + { + return reader.GetTypeDefOrRef(token); + } + + public TypeReference ReadTypeSignature() + { + return ReadTypeSignature((ElementType)ReadByte()); + } + + TypeReference ReadTypeSignature(ElementType etype) + { + switch (etype) + { + case ElementType.ValueType: + { + var value_type = GetTypeDefOrRef(ReadTypeTokenSignature()); + value_type.IsValueType = true; + return value_type; + } + case ElementType.Class: + return GetTypeDefOrRef(ReadTypeTokenSignature()); + case ElementType.Ptr: + return new PointerType(ReadTypeSignature()); + case ElementType.FnPtr: + { + var fptr = new FunctionPointerType(); + ReadMethodSignature(fptr); + return fptr; + } + case ElementType.ByRef: + return new ByReferenceType(ReadTypeSignature()); + case ElementType.Pinned: + return new PinnedType(ReadTypeSignature()); + case ElementType.SzArray: + return new ArrayType(ReadTypeSignature()); + case ElementType.Array: + return ReadArrayTypeSignature(); + case ElementType.CModOpt: + return new OptionalModifierType( + GetTypeDefOrRef(ReadTypeTokenSignature()), ReadTypeSignature()); + case ElementType.CModReqD: + return new RequiredModifierType( + GetTypeDefOrRef(ReadTypeTokenSignature()), ReadTypeSignature()); + case ElementType.Sentinel: + return new SentinelType(ReadTypeSignature()); + case ElementType.Var: + return GetGenericParameter(GenericParameterType.Type, ReadCompressedUInt32()); + case ElementType.MVar: + return GetGenericParameter(GenericParameterType.Method, ReadCompressedUInt32()); + case ElementType.GenericInst: + { + var is_value_type = ReadByte() == (byte)ElementType.ValueType; + var element_type = GetTypeDefOrRef(ReadTypeTokenSignature()); + var generic_instance = new GenericInstanceType(element_type); + + ReadGenericInstanceSignature(element_type, generic_instance); + + if (is_value_type) + { + generic_instance.IsValueType = true; + element_type.GetElementType().IsValueType = true; + } + + return generic_instance; + } + case ElementType.Object: return TypeSystem.Object; + case ElementType.Void: return TypeSystem.Void; + case ElementType.TypedByRef: return TypeSystem.TypedReference; + case ElementType.I: return TypeSystem.IntPtr; + case ElementType.U: return TypeSystem.UIntPtr; + default: return GetPrimitiveType(etype); + } + } + + public void ReadMethodSignature(IMethodSignature method) + { + var calling_convention = ReadByte(); + + const byte has_this = 0x20; + const byte explicit_this = 0x40; + + if ((calling_convention & has_this) != 0) + { + method.HasThis = true; + calling_convention = (byte)(calling_convention & ~has_this); + } + + if ((calling_convention & explicit_this) != 0) + { + method.ExplicitThis = true; + calling_convention = (byte)(calling_convention & ~explicit_this); + } + + method.CallingConvention = (MethodCallingConvention)calling_convention; + + var generic_context = method as MethodReference; + if (generic_context != null && !generic_context.DeclaringType.IsArray) + reader.context = generic_context; + + if ((calling_convention & 0x10) != 0) + { + var arity = ReadCompressedUInt32(); + + if (generic_context != null && !generic_context.IsDefinition) + CheckGenericContext(generic_context, (int)arity - 1); + } + + var param_count = ReadCompressedUInt32(); + + method.MethodReturnType.ReturnType = ReadTypeSignature(); + + if (param_count == 0) + return; + + Collection parameters; + + var method_ref = method as MethodReference; + if (method_ref != null) + parameters = method_ref.parameters = new ParameterDefinitionCollection(method, (int)param_count); + else + parameters = method.Parameters; + + for (int i = 0; i < param_count; i++) + parameters.Add(new ParameterDefinition(ReadTypeSignature())); + } + + public object ReadConstantSignature(ElementType type) + { + return ReadPrimitiveValue(type); + } + + public void ReadCustomAttributeConstructorArguments(CustomAttribute attribute, Collection parameters) + { + var count = parameters.Count; + if (count == 0) + return; + + attribute.arguments = new Collection(count); + + for (int i = 0; i < count; i++) + attribute.arguments.Add( + ReadCustomAttributeFixedArgument(parameters[i].ParameterType)); + } + + CustomAttributeArgument ReadCustomAttributeFixedArgument(TypeReference type) + { + if (type.IsArray) + return ReadCustomAttributeFixedArrayArgument((ArrayType)type); + + return ReadCustomAttributeElement(type); + } + + public void ReadCustomAttributeNamedArguments(ushort count, ref Collection fields, ref Collection properties) + { + for (int i = 0; i < count; i++) + ReadCustomAttributeNamedArgument(ref fields, ref properties); + } + + void ReadCustomAttributeNamedArgument(ref Collection fields, ref Collection properties) + { + var kind = ReadByte(); + var type = ReadCustomAttributeFieldOrPropType(); + var name = ReadUTF8String(); + + Collection container; + switch (kind) + { + case 0x53: + container = GetCustomAttributeNamedArgumentCollection(ref fields); + break; + case 0x54: + container = GetCustomAttributeNamedArgumentCollection(ref properties); + break; + default: + throw new NotSupportedException(); + } + + container.Add(new CustomAttributeNamedArgument(name, ReadCustomAttributeFixedArgument(type))); + } + + static Collection GetCustomAttributeNamedArgumentCollection(ref Collection collection) + { + if (collection != null) + return collection; + + return collection = new Collection(); + } + + CustomAttributeArgument ReadCustomAttributeFixedArrayArgument(ArrayType type) + { + var length = ReadUInt32(); + + if (length == 0xffffffff) + return new CustomAttributeArgument(type, null); + + if (length == 0) + return new CustomAttributeArgument(type, Empty.Array); + + var arguments = new CustomAttributeArgument[length]; + var element_type = type.ElementType; + + for (int i = 0; i < length; i++) + arguments[i] = ReadCustomAttributeElement(element_type); + + return new CustomAttributeArgument(type, arguments); + } + + CustomAttributeArgument ReadCustomAttributeElement(TypeReference type) + { + if (type.IsArray) + return ReadCustomAttributeFixedArrayArgument((ArrayType)type); + + return new CustomAttributeArgument( + type, + type.etype == ElementType.Object + ? ReadCustomAttributeElement(ReadCustomAttributeFieldOrPropType()) + : ReadCustomAttributeElementValue(type)); + } + + object ReadCustomAttributeElementValue(TypeReference type) + { + var etype = type.etype; + + switch (etype) + { + case ElementType.String: + return ReadUTF8String(); + case ElementType.None: + if (Mixin.IsTypeOf(type,"System", "Type")) + return ReadTypeReference(); + + return ReadCustomAttributeEnum(type); + default: + return ReadPrimitiveValue(etype); + } + } + + object ReadPrimitiveValue(ElementType type) + { + switch (type) + { + case ElementType.Boolean: + return ReadByte() == 1; + case ElementType.I1: + return (sbyte)ReadByte(); + case ElementType.U1: + return ReadByte(); + case ElementType.Char: + return (char)ReadUInt16(); + case ElementType.I2: + return ReadInt16(); + case ElementType.U2: + return ReadUInt16(); + case ElementType.I4: + return ReadInt32(); + case ElementType.U4: + return ReadUInt32(); + case ElementType.I8: + return ReadInt64(); + case ElementType.U8: + return ReadUInt64(); + case ElementType.R4: + return ReadSingle(); + case ElementType.R8: + return ReadDouble(); + default: + throw new NotImplementedException(type.ToString()); + } + } + + TypeReference GetPrimitiveType(ElementType etype) + { + switch (etype) + { + case ElementType.Boolean: + return TypeSystem.Boolean; + case ElementType.Char: + return TypeSystem.Char; + case ElementType.I1: + return TypeSystem.SByte; + case ElementType.U1: + return TypeSystem.Byte; + case ElementType.I2: + return TypeSystem.Int16; + case ElementType.U2: + return TypeSystem.UInt16; + case ElementType.I4: + return TypeSystem.Int32; + case ElementType.U4: + return TypeSystem.UInt32; + case ElementType.I8: + return TypeSystem.Int64; + case ElementType.U8: + return TypeSystem.UInt64; + case ElementType.R4: + return TypeSystem.Single; + case ElementType.R8: + return TypeSystem.Double; + case ElementType.String: + return TypeSystem.String; + default: + throw new NotImplementedException(etype.ToString()); + } + } + + TypeReference ReadCustomAttributeFieldOrPropType() + { + var etype = (ElementType)ReadByte(); + + switch (etype) + { + case ElementType.Boxed: + return TypeSystem.Object; + case ElementType.SzArray: + return new ArrayType(ReadCustomAttributeFieldOrPropType()); + case ElementType.Enum: + return ReadTypeReference(); + case ElementType.Type: + return TypeSystem.LookupType("System", "Type"); + default: + return GetPrimitiveType(etype); + } + } + + public TypeReference ReadTypeReference() + { + return TypeParser.ParseType(reader.module, ReadUTF8String()); + } + + object ReadCustomAttributeEnum(TypeReference enum_type) + { + var type = Mixin.CheckedResolve(enum_type); + if (!type.IsEnum) + throw new ArgumentException(); + + return ReadCustomAttributeElementValue(Mixin.GetEnumUnderlyingType(type)); + } + + public SecurityAttribute ReadSecurityAttribute() + { + var attribute = new SecurityAttribute(ReadTypeReference()); + + ReadCompressedUInt32(); + + ReadCustomAttributeNamedArguments( + (ushort)ReadCompressedUInt32(), + ref attribute.fields, + ref attribute.properties); + + return attribute; + } + + public MarshalInfo ReadMarshalInfo() + { + var native = ReadNativeType(); + switch (native) + { + case NativeType.Array: + { + var array = new ArrayMarshalInfo(); + if (CanReadMore()) + array.element_type = ReadNativeType(); + if (CanReadMore()) + array.size_parameter_index = (int)ReadCompressedUInt32(); + if (CanReadMore()) + array.size = (int)ReadCompressedUInt32(); + if (CanReadMore()) + array.size_parameter_multiplier = (int)ReadCompressedUInt32(); + return array; + } + case NativeType.SafeArray: + { + var array = new SafeArrayMarshalInfo(); + if (CanReadMore()) + array.element_type = ReadVariantType(); + return array; + } + case NativeType.FixedArray: + { + var array = new FixedArrayMarshalInfo(); + if (CanReadMore()) + array.size = (int)ReadCompressedUInt32(); + if (CanReadMore()) + array.element_type = ReadNativeType(); + return array; + } + case NativeType.FixedSysString: + { + var sys_string = new FixedSysStringMarshalInfo(); + if (CanReadMore()) + sys_string.size = (int)ReadCompressedUInt32(); + return sys_string; + } + case NativeType.CustomMarshaler: + { + var marshaler = new CustomMarshalInfo(); + var guid_value = ReadUTF8String(); + marshaler.guid = !string.IsNullOrEmpty(guid_value) ? new Guid(guid_value) : Guid.Empty; + marshaler.unmanaged_type = ReadUTF8String(); + marshaler.managed_type = ReadTypeReference(); + marshaler.cookie = ReadUTF8String(); + return marshaler; + } + default: + return new MarshalInfo(native); + } + } + + NativeType ReadNativeType() + { + return (NativeType)ReadByte(); + } + + VariantType ReadVariantType() + { + return (VariantType)ReadByte(); + } + + string ReadUTF8String() + { + if (buffer[position] == 0xff) + { + position++; + return null; + } + + var length = (int)ReadCompressedUInt32(); + if (length == 0) + return string.Empty; + + var @string = Encoding.UTF8.GetString(buffer, position, + buffer[position + length - 1] == 0 ? length - 1 : length); + + position += length; + return @string; + } + + public bool CanReadMore() + { + return position - start < sig_length; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyWriter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyWriter.cs new file mode 100644 index 00000000..824dd349 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/AssemblyWriter.cs @@ -0,0 +1,47 @@ +// +// AssemblyWriter.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +using Mono.Collections.Generic; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using RVA = System.UInt32; +using RID = System.UInt32; +using CodedRID = System.UInt32; +using StringIndex = System.UInt32; +using BlobIndex = System.UInt32; + +namespace Mono.Cecil { + +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/BaseAssemblyResolver.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/BaseAssemblyResolver.cs new file mode 100644 index 00000000..5ec6b600 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/BaseAssemblyResolver.cs @@ -0,0 +1,172 @@ +// +// BaseAssemblyResolver.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public delegate AssemblyDefinition AssemblyResolveEventHandler (object sender, AssemblyNameReference reference); + + public sealed class AssemblyResolveEventArgs : EventArgs { + + readonly AssemblyNameReference reference; + + public AssemblyNameReference AssemblyReference { + get { return reference; } + } + + public AssemblyResolveEventArgs (AssemblyNameReference reference) + { + this.reference = reference; + } + } + + + public class AssemblyResolutionException : FileNotFoundException { + + readonly AssemblyNameReference reference; + + public AssemblyNameReference AssemblyReference { + get { return reference; } + } + + public AssemblyResolutionException (AssemblyNameReference reference) + : base (string.Format ("Failed to resolve assembly: '{0}'", reference)) + { + this.reference = reference; + } + + + } + + public abstract class BaseAssemblyResolver : IAssemblyResolver { + + static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null; + + readonly Collection directories; + + + + public void AddSearchDirectory (string directory) + { + directories.Add (directory); + } + + public void RemoveSearchDirectory (string directory) + { + directories.Remove (directory); + } + + public string [] GetSearchDirectories () + { + var directories = new string [this.directories.size]; + Array.Copy (this.directories.items, directories, directories.Length); + return directories; + } + + public virtual AssemblyDefinition Resolve (string fullName) + { + return Resolve (fullName, new ReaderParameters ()); + } + + public virtual AssemblyDefinition Resolve (string fullName, ReaderParameters parameters) + { + if (fullName == null) + throw new ArgumentNullException ("fullName"); + + return Resolve (AssemblyNameReference.Parse (fullName), parameters); + } + + public event AssemblyResolveEventHandler ResolveFailure; + + protected BaseAssemblyResolver () + { + directories = new Collection (2) { ".", "bin" }; + } + + AssemblyDefinition GetAssembly (string file, ReaderParameters parameters) + { + if (parameters.AssemblyResolver == null) + parameters.AssemblyResolver = this; + + return ModuleDefinition.ReadModule (file, parameters).Assembly; + } + + public virtual AssemblyDefinition Resolve (AssemblyNameReference name) + { + return Resolve (name, new ReaderParameters ()); + } + + public virtual AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters) + { + if (name == null) + throw new ArgumentNullException ("name"); + if (parameters == null) + parameters = new ReaderParameters (); + + var assembly = SearchDirectory (name, directories, parameters); + if (assembly != null) + return assembly; + + + + if (ResolveFailure != null) { + assembly = ResolveFailure (this, name); + if (assembly != null) + return assembly; + } + + throw new AssemblyResolutionException (name); + } + + AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable directories, ReaderParameters parameters) + { + var extensions = new [] { ".exe", ".dll" }; + foreach (var directory in directories) { + foreach (var extension in extensions) { + string file = Path.Combine (directory, name.Name + extension); + if (File.Exists (file)) + return GetAssembly (file, parameters); + } + } + + return null; + } + + static bool IsZero (Version version) + { + return version == null || (version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0); + } + + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/CallSite.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/CallSite.cs new file mode 100644 index 00000000..448ef2a5 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/CallSite.cs @@ -0,0 +1,124 @@ +// +// CallSite.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class CallSite : IMethodSignature { + + readonly MethodReference signature; + + public bool HasThis { + get { return signature.HasThis; } + set { signature.HasThis = value; } + } + + public bool ExplicitThis { + get { return signature.ExplicitThis; } + set { signature.ExplicitThis = value; } + } + + public MethodCallingConvention CallingConvention { + get { return signature.CallingConvention; } + set { signature.CallingConvention = value; } + } + + public bool HasParameters { + get { return signature.HasParameters; } + } + + public Collection Parameters { + get { return signature.Parameters; } + } + + public TypeReference ReturnType { + get { return signature.MethodReturnType.ReturnType; } + set { signature.MethodReturnType.ReturnType = value; } + } + + public MethodReturnType MethodReturnType { + get { return signature.MethodReturnType; } + } + + public string Name { + get { return string.Empty; } + set { throw new InvalidOperationException (); } + } + + public string Namespace { + get { return string.Empty; } + set { throw new InvalidOperationException (); } + } + + public ModuleDefinition Module { + get { return ReturnType.Module; } + } + + public IMetadataScope Scope { + get { return signature.ReturnType.Scope; } + } + + public MetadataToken MetadataToken { + get { return signature.token; } + set { signature.token = value; } + } + + public string FullName { + get { + var signature = new StringBuilder (); + signature.Append (ReturnType.FullName); + Mixin.MethodSignatureFullName (this,signature); + return signature.ToString (); + } + } + + internal CallSite () + { + this.signature = new MethodReference (); + this.signature.token = new MetadataToken (TokenType.Signature, 0); + } + + public CallSite (TypeReference returnType) + : this () + { + if (returnType == null) + throw new ArgumentNullException ("returnType"); + + this.signature.ReturnType = returnType; + } + + public override string ToString () + { + return FullName; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/CustomAttribute.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/CustomAttribute.cs new file mode 100644 index 00000000..26a1a1c8 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/CustomAttribute.cs @@ -0,0 +1,231 @@ +// +// CustomAttribute.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public struct CustomAttributeArgument { + + readonly TypeReference type; + readonly object value; + + public TypeReference Type { + get { return type; } + } + + public object Value { + get { return value; } + } + + public CustomAttributeArgument (TypeReference type, object value) + { + Mixin.CheckType (type); + this.type = type; + this.value = value; + } + } + + public struct CustomAttributeNamedArgument { + + readonly string name; + readonly CustomAttributeArgument argument; + + public string Name { + get { return name; } + } + + public CustomAttributeArgument Argument { + get { return argument; } + } + + public CustomAttributeNamedArgument (string name, CustomAttributeArgument argument) + { + Mixin.CheckName (name); + this.name = name; + this.argument = argument; + } + } + + public interface ICustomAttribute { + + TypeReference AttributeType { get; } + + bool HasFields { get; } + bool HasProperties { get; } + Collection Fields { get; } + Collection Properties { get; } + } + + public sealed class CustomAttribute : ICustomAttribute { + + readonly internal uint signature; + internal bool resolved; + MethodReference constructor; + byte [] blob; + internal Collection arguments; + internal Collection fields; + internal Collection properties; + + public MethodReference Constructor { + get { return constructor; } + set { constructor = value; } + } + + public TypeReference AttributeType { + get { return constructor.DeclaringType; } + } + + public bool IsResolved { + get { return resolved; } + } + + public bool HasConstructorArguments { + get { + Resolve (); + + return !Mixin.IsNullOrEmpty (arguments); + } + } + + public Collection ConstructorArguments { + get { + Resolve (); + + return arguments ?? (arguments = new Collection ()); + } + } + + public bool HasFields { + get { + Resolve (); + + return !Mixin.IsNullOrEmpty (fields); + } + } + + public Collection Fields { + get { + Resolve (); + + return fields ?? (fields = new Collection ()); + } + } + + public bool HasProperties { + get { + Resolve (); + + return !Mixin.IsNullOrEmpty (properties); + } + } + + public Collection Properties { + get { + Resolve (); + + return properties ?? (properties = new Collection ()); + } + } + + internal bool HasImage { + get { return constructor != null && constructor.HasImage; } + } + + internal ModuleDefinition Module { + get { return constructor.Module; } + } + + internal CustomAttribute (uint signature, MethodReference constructor) + { + this.signature = signature; + this.constructor = constructor; + this.resolved = false; + } + + public CustomAttribute (MethodReference constructor) + { + this.constructor = constructor; + this.resolved = true; + } + + public CustomAttribute (MethodReference constructor, byte [] blob) + { + this.constructor = constructor; + this.resolved = false; + this.blob = blob; + } + + public byte [] GetBlob () + { + if (blob != null) + return blob; + + if (!HasImage) + throw new NotSupportedException (); + + return Module.Read (ref blob, this, (attribute, reader) => reader.ReadCustomAttributeBlob (attribute.signature)); + } + + void Resolve () + { + if (resolved || !HasImage) + return; + + Module.Read (this, (attribute, reader) => { + try { + reader.ReadCustomAttributeSignature (attribute); + resolved = true; + } catch (ResolutionException) { + if (arguments != null) + arguments.Clear (); + if (fields != null) + fields.Clear (); + if (properties != null) + properties.Clear (); + + resolved = false; + } + return this; + }); + } + } + + static partial class Mixin { + + public static void CheckName (string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + if (name.Length == 0) + throw new ArgumentException ("Empty name"); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/DefaultAssemblyResolver.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/DefaultAssemblyResolver.cs new file mode 100644 index 00000000..e0baedf7 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/DefaultAssemblyResolver.cs @@ -0,0 +1,70 @@ +// +// DefaultAssemblyResolver.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; + +namespace Mono.Cecil { + + public class DefaultAssemblyResolver : BaseAssemblyResolver { + + readonly IDictionary cache; + + public DefaultAssemblyResolver () + { + cache = new Dictionary (StringComparer.Ordinal); + } + + public override AssemblyDefinition Resolve (AssemblyNameReference name) + { + if (name == null) + throw new ArgumentNullException ("name"); + + AssemblyDefinition assembly; + if (cache.TryGetValue (name.FullName, out assembly)) + return assembly; + + assembly = base.Resolve (name); + cache [name.FullName] = assembly; + + return assembly; + } + + protected void RegisterAssembly (AssemblyDefinition assembly) + { + if (assembly == null) + throw new ArgumentNullException ("assembly"); + + var name = assembly.Name.FullName; + if (cache.ContainsKey (name)) + return; + + cache [name] = assembly; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EmbeddedResource.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EmbeddedResource.cs new file mode 100644 index 00000000..e12dd0b3 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EmbeddedResource.cs @@ -0,0 +1,105 @@ +// +// EmbeddedResource.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; + +namespace Mono.Cecil { + + public sealed class EmbeddedResource : Resource { + + readonly MetadataReader reader; + + uint? offset; + byte [] data; + Stream stream; + + public override ResourceType ResourceType { + get { return ResourceType.Embedded; } + } + + public EmbeddedResource (string name, ManifestResourceAttributes attributes, byte [] data) : + base (name, attributes) + { + this.data = data; + } + + public EmbeddedResource (string name, ManifestResourceAttributes attributes, Stream stream) : + base (name, attributes) + { + this.stream = stream; + } + + internal EmbeddedResource (string name, ManifestResourceAttributes attributes, uint offset, MetadataReader reader) + : base (name, attributes) + { + this.offset = offset; + this.reader = reader; + } + + public Stream GetResourceStream () + { + if (stream != null) + return stream; + + if (data != null) + return new MemoryStream (data); + + if (offset.HasValue) + return reader.GetManagedResourceStream (offset.Value); + + throw new InvalidOperationException (); + } + + public byte [] GetResourceData () + { + if (stream != null) + return ReadStream (stream); + + if (data != null) + return data; + + if (offset.HasValue) + return reader.GetManagedResourceStream (offset.Value).ToArray (); + + throw new InvalidOperationException (); + } + + static byte [] ReadStream (Stream stream) + { + var length = (int) stream.Length; + var data = new byte [length]; + int offset = 0, read; + + while ((read = stream.Read (data, offset, length - offset)) > 0) + offset += read; + + return data; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventAttributes.cs new file mode 100644 index 00000000..815efa57 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventAttributes.cs @@ -0,0 +1,39 @@ +// +// EventAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum EventAttributes : ushort { + None = 0x0000, + SpecialName = 0x0200, // Event is special + RTSpecialName = 0x0400 // CLI provides 'special' behavior, depending upon the name of the event + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventDefinition.cs new file mode 100644 index 00000000..88bfa982 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventDefinition.cs @@ -0,0 +1,170 @@ +// +// EventDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class EventDefinition : EventReference, IMemberDefinition { + + ushort attributes; + + Collection custom_attributes; + + internal MethodDefinition add_method; + internal MethodDefinition invoke_method; + internal MethodDefinition remove_method; + internal Collection other_methods; + + public EventAttributes Attributes { + get { return (EventAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public MethodDefinition AddMethod { + get { + if (add_method != null) + return add_method; + + InitializeMethods (); + return add_method; + } + set { add_method = value; } + } + + public MethodDefinition InvokeMethod { + get { + if (invoke_method != null) + return invoke_method; + + InitializeMethods (); + return invoke_method; + } + set { invoke_method = value; } + } + + public MethodDefinition RemoveMethod { + get { + if (remove_method != null) + return remove_method; + + InitializeMethods (); + return remove_method; + } + set { remove_method = value; } + } + + public bool HasOtherMethods { + get { + if (other_methods != null) + return other_methods.Count > 0; + + InitializeMethods (); + return !Mixin.IsNullOrEmpty (other_methods); + } + } + + public Collection OtherMethods { + get { + if (other_methods != null) + return other_methods; + + InitializeMethods (); + + if (other_methods != null) + return other_methods; + + return other_methods = new Collection (); + } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + } + + #region EventAttributes + + public bool IsSpecialName { + get { return Mixin.GetAttributes(attributes,(ushort) EventAttributes.SpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) EventAttributes.SpecialName, value); } + } + + public bool IsRuntimeSpecialName { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.RTSpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.RTSpecialName, value); } + } + + #endregion + + public new TypeDefinition DeclaringType { + get { return (TypeDefinition) base.DeclaringType; } + set { base.DeclaringType = value; } + } + + public override bool IsDefinition { + get { return true; } + } + + public EventDefinition (string name, EventAttributes attributes, TypeReference eventType) + : base (name, eventType) + { + this.attributes = (ushort) attributes; + this.token = new MetadataToken (TokenType.Event); + } + + void InitializeMethods () + { + var module = this.Module; + lock (module.SyncRoot) { + if (add_method != null + || invoke_method != null + || remove_method != null) + return; + + if (!Mixin.HasImage(module)) + return; + + module.Read (this, (@event, reader) => reader.ReadMethods (@event)); + } + } + + public override EventDefinition Resolve () + { + return this; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventReference.cs new file mode 100644 index 00000000..8952002d --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/EventReference.cs @@ -0,0 +1,57 @@ +// +// EventReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + public abstract class EventReference : MemberReference { + + TypeReference event_type; + + public TypeReference EventType { + get { return event_type; } + set { event_type = value; } + } + + public override string FullName { + get { return event_type.FullName + " " + MemberFullName (); } + } + + protected EventReference (string name, TypeReference eventType) + : base (name) + { + if (eventType == null) + throw new ArgumentNullException ("eventType"); + + event_type = eventType; + } + + public abstract EventDefinition Resolve (); + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ExportedType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ExportedType.cs new file mode 100644 index 00000000..5cc7f2b0 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ExportedType.cs @@ -0,0 +1,249 @@ +// +// ExportedType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + public class ExportedType : IMetadataTokenProvider { + + string @namespace; + string name; + uint attributes; + IMetadataScope scope; + ModuleDefinition module; + int identifier; + ExportedType declaring_type; + internal MetadataToken token; + + public string Namespace { + get { return @namespace; } + set { @namespace = value; } + } + + public string Name { + get { return name; } + set { name = value; } + } + + public TypeAttributes Attributes { + get { return (TypeAttributes) attributes; } + set { attributes = (uint) value; } + } + + public IMetadataScope Scope { + get { + if (declaring_type != null) + return declaring_type.Scope; + + return scope; + } + } + + public ExportedType DeclaringType { + get { return declaring_type; } + set { declaring_type = value; } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + public int Identifier { + get { return identifier; } + set { identifier = value; } + } + + #region TypeAttributes + + public bool IsNotPublic { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } + } + + public bool IsPublic { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } + } + + public bool IsNestedPublic { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } + } + + public bool IsNestedPrivate { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } + } + + public bool IsNestedFamily { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } + } + + public bool IsNestedAssembly { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } + } + + public bool IsNestedFamilyAndAssembly { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } + } + + public bool IsNestedFamilyOrAssembly { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } + } + + public bool IsAutoLayout { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } + } + + public bool IsSequentialLayout { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } + } + + public bool IsExplicitLayout { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } + } + + public bool IsClass { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } + } + + public bool IsInterface { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } + } + + public bool IsAbstract { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Abstract); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Abstract, value); } + } + + public bool IsSealed { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Sealed); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Sealed, value); } + } + + public bool IsSpecialName { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.SpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.SpecialName, value); } + } + + public bool IsImport { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Import); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Import, value); } + } + + public bool IsSerializable { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Serializable); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Serializable, value); } + } + + public bool IsAnsiClass { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } + } + + public bool IsUnicodeClass { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } + } + + public bool IsAutoClass { + get { return Mixin.GetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } + } + + public bool IsBeforeFieldInit { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.BeforeFieldInit); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.BeforeFieldInit, value); } + } + + public bool IsRuntimeSpecialName { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.RTSpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.RTSpecialName, value); } + } + + public bool HasSecurity { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.HasSecurity); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.HasSecurity, value); } + } + + #endregion + + public bool IsForwarder { + get { return Mixin.GetAttributes(attributes,(uint) TypeAttributes.Forwarder); } + set { attributes =Mixin.SetAttributes(attributes,(uint) TypeAttributes.Forwarder, value); } + } + + public string FullName { + get { + if (declaring_type != null) + return declaring_type.FullName + "/" + name; + + if (string.IsNullOrEmpty (@namespace)) + return name; + + return @namespace + "." + name; + } + } + + public ExportedType (string @namespace, string name, ModuleDefinition module, IMetadataScope scope) + { + this.@namespace = @namespace; + this.name = name; + this.scope = scope; + this.module = module; + } + + public override string ToString () + { + return FullName; + } + + public TypeDefinition Resolve () + { + return module.Resolve (CreateReference ()); + } + + internal TypeReference CreateReference () + { + return new TypeReference (@namespace, name, module, scope) { + DeclaringType = declaring_type != null ? declaring_type.CreateReference () : null, + }; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldAttributes.cs new file mode 100644 index 00000000..dd6bf361 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldAttributes.cs @@ -0,0 +1,59 @@ +// +// FieldAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum FieldAttributes : ushort { + FieldAccessMask = 0x0007, + CompilerControlled = 0x0000, // Member not referenceable + Private = 0x0001, // Accessible only by the parent type + FamANDAssem = 0x0002, // Accessible by sub-types only in this assembly + Assembly = 0x0003, // Accessible by anyone in the Assembly + Family = 0x0004, // Accessible only by type and sub-types + FamORAssem = 0x0005, // Accessible by sub-types anywhere, plus anyone in the assembly + Public = 0x0006, // Accessible by anyone who has visibility to this scope field contract attributes + + Static = 0x0010, // Defined on type, else per instance + InitOnly = 0x0020, // Field may only be initialized, not written after init + Literal = 0x0040, // Value is compile time constant + NotSerialized = 0x0080, // Field does not have to be serialized when type is remoted + SpecialName = 0x0200, // Field is special + + // Interop Attributes + PInvokeImpl = 0x2000, // Implementation is forwarded through PInvoke + + // Additional flags + RTSpecialName = 0x0400, // CLI provides 'special' behavior, depending upon the name of the field + HasFieldMarshal = 0x1000, // Field has marshalling information + HasDefault = 0x8000, // Field has default + HasFieldRVA = 0x0100 // Field has RVA + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldDefinition.cs new file mode 100644 index 00000000..f90e8cb7 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldDefinition.cs @@ -0,0 +1,271 @@ +// +// FieldDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class FieldDefinition : FieldReference, IMemberDefinition, IConstantProvider, IMarshalInfoProvider { + + ushort attributes; + Collection custom_attributes; + + int offset = Mixin.NotResolvedMarker; + + internal int rva = Mixin.NotResolvedMarker; + byte [] initial_value; + + object constant = Mixin.NotResolved; + + MarshalInfo marshal_info; + + void ResolveLayout () + { + if (offset != Mixin.NotResolvedMarker) + return; + + if (!HasImage) { + offset = Mixin.NoDataMarker; + return; + } + + offset = Module.Read (this, (field, reader) => reader.ReadFieldLayout (field)); + } + + public bool HasLayoutInfo { + get { + if (offset >= 0) + return true; + + ResolveLayout (); + + return offset >= 0; + } + } + + public int Offset { + get { + if (offset >= 0) + return offset; + + ResolveLayout (); + + return offset >= 0 ? offset : -1; + } + set { offset = value; } + } + + void ResolveRVA () + { + if (rva != Mixin.NotResolvedMarker) + return; + + if (!HasImage) + return; + + rva = Module.Read (this, (field, reader) => reader.ReadFieldRVA (field)); + } + + public int RVA { + get { + if (rva > 0) + return rva; + + ResolveRVA (); + + return rva > 0 ? rva : 0; + } + } + + public byte [] InitialValue { + get { + if (initial_value != null) + return initial_value; + + ResolveRVA (); + + if (initial_value == null) + initial_value = Empty.Array; + + return initial_value; + } + set { initial_value = value; } + } + + public FieldAttributes Attributes { + get { return (FieldAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public bool HasConstant { + get { + Mixin.ResolveConstant(this, ref constant, Module); + + return constant != Mixin.NoValue; + } + set { if (!value) constant = Mixin.NoValue; } + } + + public object Constant { + get { return HasConstant ? constant : null; } + set { constant = value; } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + } + + public bool HasMarshalInfo { + get { + if (marshal_info != null) + return true; + + return Mixin.GetHasMarshalInfo(this, Module); + } + } + + public MarshalInfo MarshalInfo { + get { return marshal_info ?? (Mixin.GetMarshalInfo(this, ref marshal_info, Module)); } + set { marshal_info = value; } + } + + #region FieldAttributes + + public bool IsCompilerControlled { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled, value); } + } + + public bool IsPrivate { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private, value); } + } + + public bool IsFamilyAndAssembly { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem, value); } + } + + public bool IsAssembly { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly, value); } + } + + public bool IsFamily { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family, value); } + } + + public bool IsFamilyOrAssembly { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem, value); } + } + + public bool IsPublic { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public, value); } + } + + public bool IsStatic { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.Static); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.Static, value); } + } + + public bool IsInitOnly { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.InitOnly); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.InitOnly, value); } + } + + public bool IsLiteral { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.Literal); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.Literal, value); } + } + + public bool IsNotSerialized { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.NotSerialized); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.NotSerialized, value); } + } + + public bool IsSpecialName { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.SpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.SpecialName, value); } + } + + public bool IsPInvokeImpl { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.PInvokeImpl); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.PInvokeImpl, value); } + } + + public bool IsRuntimeSpecialName { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.RTSpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.RTSpecialName, value); } + } + + public bool HasDefault { + get { return Mixin.GetAttributes(attributes,(ushort) FieldAttributes.HasDefault); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) FieldAttributes.HasDefault, value); } + } + + #endregion + + public override bool IsDefinition { + get { return true; } + } + + public new TypeDefinition DeclaringType { + get { return (TypeDefinition) base.DeclaringType; } + set { base.DeclaringType = value; } + } + + public FieldDefinition (string name, FieldAttributes attributes, TypeReference fieldType) + : base (name, fieldType) + { + this.attributes = (ushort) attributes; + } + + public override FieldDefinition Resolve () + { + return this; + } + } + + static partial class Mixin { + + public const int NotResolvedMarker = -2; + public const int NoDataMarker = -1; + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldReference.cs new file mode 100644 index 00000000..be58d3d0 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FieldReference.cs @@ -0,0 +1,83 @@ +// +// FieldReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + public class FieldReference : MemberReference { + + TypeReference field_type; + + public TypeReference FieldType { + get { return field_type; } + set { field_type = value; } + } + + public override string FullName { + get { return field_type.FullName + " " + MemberFullName (); } + } + + internal override bool ContainsGenericParameter { + get { return field_type.ContainsGenericParameter || base.ContainsGenericParameter; } + } + + internal FieldReference () + { + this.token = new MetadataToken (TokenType.MemberRef); + } + + public FieldReference (string name, TypeReference fieldType) + : base (name) + { + if (fieldType == null) + throw new ArgumentNullException ("fieldType"); + + this.field_type = fieldType; + this.token = new MetadataToken (TokenType.MemberRef); + } + + public FieldReference (string name, TypeReference fieldType, TypeReference declaringType) + : this (name, fieldType) + { + if (declaringType == null) + throw new ArgumentNullException("declaringType"); + + this.DeclaringType = declaringType; + } + + public virtual FieldDefinition Resolve () + { + var module = this.Module; + if (module == null) + throw new NotSupportedException (); + + return module.Resolve (this); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FileAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FileAttributes.cs new file mode 100644 index 00000000..4d3b6ca7 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FileAttributes.cs @@ -0,0 +1,35 @@ +// +// FileAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + enum FileAttributes : uint { + ContainsMetaData = 0x0000, // This is not a resource file + ContainsNoMetaData = 0x0001, // This is a resource file or other non-metadata-containing file + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/FunctionPointerType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FunctionPointerType.cs new file mode 100644 index 00000000..484afdaf --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/FunctionPointerType.cs @@ -0,0 +1,128 @@ +// +// FunctionPointerType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; +using Mono.Collections.Generic; +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class FunctionPointerType : TypeSpecification, IMethodSignature { + + readonly MethodReference function; + + public bool HasThis { + get { return function.HasThis; } + set { function.HasThis = value; } + } + + public bool ExplicitThis { + get { return function.ExplicitThis; } + set { function.ExplicitThis = value; } + } + + public MethodCallingConvention CallingConvention { + get { return function.CallingConvention; } + set { function.CallingConvention = value; } + } + + public bool HasParameters { + get { return function.HasParameters; } + } + + public Collection Parameters { + get { return function.Parameters; } + } + + public TypeReference ReturnType { + get { return function.MethodReturnType.ReturnType; } + set { function.MethodReturnType.ReturnType = value; } + } + + public MethodReturnType MethodReturnType { + get { return function.MethodReturnType; } + } + + public override string Name { + get { return function.Name; } + set { throw new InvalidOperationException (); } + } + + public override string Namespace { + get { return string.Empty; } + set { throw new InvalidOperationException (); } + } + + public override ModuleDefinition Module { + get { return ReturnType.Module; } + } + + public override IMetadataScope Scope { + get { return function.ReturnType.Scope; } + } + + public override bool IsFunctionPointer { + get { return true; } + } + + internal override bool ContainsGenericParameter { + get { return function.ContainsGenericParameter; } + } + + public override string FullName { + get { + var signature = new StringBuilder (); + signature.Append (function.Name); + signature.Append (" "); + signature.Append (function.ReturnType.FullName); + signature.Append (" *"); + Mixin.MethodSignatureFullName (this,signature); + return signature.ToString (); + } + } + + public FunctionPointerType () + : base (null) + { + this.function = new MethodReference (); + this.function.Name = "method"; + this.etype = MD.ElementType.FnPtr; + } + + public override TypeDefinition Resolve () + { + return null; + } + + public override TypeReference GetElementType () + { + return this; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceMethod.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceMethod.cs new file mode 100644 index 00000000..12dcd21c --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceMethod.cs @@ -0,0 +1,95 @@ +// +// GenericInstanceMethod.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public sealed class GenericInstanceMethod : MethodSpecification, IGenericInstance, IGenericContext + { + + Collection arguments; + + public bool HasGenericArguments + { + get { return !Mixin.IsNullOrEmpty(arguments); } + } + + public Collection GenericArguments + { + get { return arguments ?? (arguments = new Collection()); } + } + + public override bool IsGenericInstance + { + get { return true; } + } + + IGenericParameterProvider IGenericContext.Method + { + get { return ElementMethod; } + } + + IGenericParameterProvider IGenericContext.Type + { + get { return ElementMethod.DeclaringType; } + } + + internal override bool ContainsGenericParameter + { + get { return Mixin.ContainsGenericParameter(this) || base.ContainsGenericParameter; } + } + + public override string FullName + { + get + { + var signature = new StringBuilder(); + var method = this.ElementMethod; + signature.Append(method.ReturnType.FullName) + .Append(" ") + .Append(method.DeclaringType.FullName) + .Append("::") + .Append(method.Name); + Mixin.GenericInstanceFullName(this, signature); + Mixin.MethodSignatureFullName(this, signature); + return signature.ToString(); + + } + } + + public GenericInstanceMethod(MethodReference method) + : base(method) + { + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceType.cs new file mode 100644 index 00000000..1e509d63 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericInstanceType.cs @@ -0,0 +1,93 @@ +// +// GenericInstanceType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; + +using Mono.Collections.Generic; + +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil +{ + + public sealed class GenericInstanceType : TypeSpecification, IGenericInstance, IGenericContext + { + + Collection arguments; + + public bool HasGenericArguments + { + get { return !Mixin.IsNullOrEmpty(arguments); } + } + + public Collection GenericArguments + { + get { return arguments ?? (arguments = new Collection()); } + } + + public override TypeReference DeclaringType + { + get { return ElementType.DeclaringType; } + set { throw new NotSupportedException(); } + } + + public override string FullName + { + get + { + var name = new StringBuilder(); + name.Append(base.FullName); + Mixin.GenericInstanceFullName(this, name); + return name.ToString(); + } + } + + public override bool IsGenericInstance + { + get { return true; } + } + + internal override bool ContainsGenericParameter + { + get { return Mixin.ContainsGenericParameter(this) || base.ContainsGenericParameter; } + } + + IGenericParameterProvider IGenericContext.Type + { + get { return ElementType; } + } + + public GenericInstanceType(TypeReference type) + : base(type) + { + base.IsValueType = type.IsValueType; + this.etype = MD.ElementType.GenericInst; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameter.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameter.cs new file mode 100644 index 00000000..e92728d6 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameter.cs @@ -0,0 +1,277 @@ +// +// GenericParameter.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Collections.Generic; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class GenericParameter : TypeReference, ICustomAttributeProvider { + + internal int position; + internal GenericParameterType type; + internal IGenericParameterProvider owner; + + ushort attributes; + Collection constraints; + Collection custom_attributes; + + public GenericParameterAttributes Attributes { + get { return (GenericParameterAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public int Position { + get { return position; } + } + + public GenericParameterType Type { + get { return type; } + } + + public IGenericParameterProvider Owner { + get { return owner; } + } + + public bool HasConstraints { + get { + if (constraints != null) + return constraints.Count > 0; + + if (HasImage) + return Module.Read (this, (generic_parameter, reader) => reader.HasGenericConstraints (generic_parameter)); + + return false; + } + } + + public Collection Constraints { + get { + if (constraints != null) + return constraints; + + if (HasImage) + return Module.Read (ref constraints, this, (generic_parameter, reader) => reader.ReadGenericConstraints (generic_parameter)); + + return constraints = new Collection (); + } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + } + + public override IMetadataScope Scope { + get { + if (owner == null) + return null; + + return owner.GenericParameterType == GenericParameterType.Method + ? ((MethodReference) owner).DeclaringType.Scope + : ((TypeReference) owner).Scope; + } + } + + public override ModuleDefinition Module { + get { return module ?? owner.Module; } + } + + public override string Name { + get { + if (!string.IsNullOrEmpty (base.Name)) + return base.Name; + + return base.Name = (type == GenericParameterType.Method ? "!!" : "!") + position; + } + } + + public override string Namespace { + get { return string.Empty; } + set { throw new InvalidOperationException (); } + } + + public override string FullName { + get { return Name; } + } + + public override bool IsGenericParameter { + get { return true; } + } + + internal override bool ContainsGenericParameter { + get { return true; } + } + + public override MetadataType MetadataType { + get { return (MetadataType) etype; } + } + + #region GenericParameterAttributes + + public bool IsNonVariant { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant, value); } + } + + public bool IsCovariant { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant, value); } + } + + public bool IsContravariant { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant, value); } + } + + public bool HasReferenceTypeConstraint { + get { return Mixin.GetAttributes(attributes,(ushort) GenericParameterAttributes.ReferenceTypeConstraint); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) GenericParameterAttributes.ReferenceTypeConstraint, value); } + } + + public bool HasNotNullableValueTypeConstraint { + get { return Mixin.GetAttributes(attributes,(ushort) GenericParameterAttributes.NotNullableValueTypeConstraint); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) GenericParameterAttributes.NotNullableValueTypeConstraint, value); } + } + + public bool HasDefaultConstructorConstraint { + get { return Mixin.GetAttributes(attributes,(ushort) GenericParameterAttributes.DefaultConstructorConstraint); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) GenericParameterAttributes.DefaultConstructorConstraint, value); } + } + + #endregion + + public GenericParameter (IGenericParameterProvider owner) + : this (string.Empty, owner) + { + } + + public GenericParameter (string name, IGenericParameterProvider owner) + : base (string.Empty, name) + { + if (owner == null) + throw new ArgumentNullException (); + + this.position = -1; + this.owner = owner; + this.type = owner.GenericParameterType; + this.etype = ConvertGenericParameterType (this.type); + } + + public GenericParameter (int position, GenericParameterType type, ModuleDefinition module) + : base (string.Empty, string.Empty) + { + if (module == null) + throw new ArgumentNullException (); + + this.position = position; + this.type = type; + this.etype = ConvertGenericParameterType (type); + this.module = module; + } + + static ElementType ConvertGenericParameterType (GenericParameterType type) + { + switch (type) { + case GenericParameterType.Type: + return ElementType.Var; + case GenericParameterType.Method: + return ElementType.MVar; + } + + throw new ArgumentOutOfRangeException (); + } + + public override TypeDefinition Resolve () + { + return null; + } + } + + sealed class GenericParameterCollection : Collection { + + readonly IGenericParameterProvider owner; + + internal GenericParameterCollection (IGenericParameterProvider owner) + { + this.owner = owner; + } + + internal GenericParameterCollection (IGenericParameterProvider owner, int capacity) + : base (capacity) + { + this.owner = owner; + } + + protected override void OnAdd (GenericParameter item, int index) + { + UpdateGenericParameter (item, index); + } + + protected override void OnInsert (GenericParameter item, int index) + { + UpdateGenericParameter (item, index); + + for (int i = index; i < size; i++) + items[i].position = i + 1; + } + + protected override void OnSet (GenericParameter item, int index) + { + UpdateGenericParameter (item, index); + } + + void UpdateGenericParameter (GenericParameter item, int index) + { + item.owner = owner; + item.position = index; + item.type = owner.GenericParameterType; + } + + protected override void OnRemove (GenericParameter item, int index) + { + item.owner = null; + item.position = -1; + item.type = GenericParameterType.Type; + + for (int i = index + 1; i < size; i++) + items[i].position = i - 1; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameterAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameterAttributes.cs new file mode 100644 index 00000000..6d77956d --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/GenericParameterAttributes.cs @@ -0,0 +1,45 @@ +// +// GenericParameterAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum GenericParameterAttributes : ushort { + VarianceMask = 0x0003, + NonVariant = 0x0000, + Covariant = 0x0001, + Contravariant = 0x0002, + + SpecialConstraintMask = 0x001c, + ReferenceTypeConstraint = 0x0004, + NotNullableValueTypeConstraint = 0x0008, + DefaultConstructorConstraint = 0x0010 + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IConstantProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IConstantProvider.cs new file mode 100644 index 00000000..def7fb35 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IConstantProvider.cs @@ -0,0 +1,57 @@ +// +// IConstantProvider.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public interface IConstantProvider : IMetadataTokenProvider { + + bool HasConstant { get; set; } + object Constant { get; set; } + } + + static partial class Mixin { + + internal static object NoValue = new object (); + internal static object NotResolved = new object (); + + public static void ResolveConstant ( + IConstantProvider self, + ref object constant, + ModuleDefinition module) + { + lock (module.SyncRoot) { + if (constant != Mixin.NotResolved) + return; + if (Mixin.HasImage (module)) + constant = module.Read (self, (provider, reader) => reader.ReadConstant (provider)); + else + constant = Mixin.NoValue; + } + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ICustomAttributeProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ICustomAttributeProvider.cs new file mode 100644 index 00000000..89aa552c --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ICustomAttributeProvider.cs @@ -0,0 +1,63 @@ +// +// ICustomAttributeProvider.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public interface ICustomAttributeProvider : IMetadataTokenProvider + { + + Collection CustomAttributes { get; } + + bool HasCustomAttributes { get; } + } + + static partial class Mixin + { + + public static bool GetHasCustomAttributes( + ICustomAttributeProvider self, + ModuleDefinition module) + { + return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasCustomAttributes(provider)); + } + + public static Collection GetCustomAttributes( + ICustomAttributeProvider self, + ref Collection variable, + ModuleDefinition module) + { + return Mixin.HasImage(module) + ? module.Read(ref variable, self, (provider, reader) => reader.ReadCustomAttributes(provider)) + : variable = new Collection(); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericInstance.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericInstance.cs new file mode 100644 index 00000000..bc90c2bf --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericInstance.cs @@ -0,0 +1,66 @@ +// +// IGenericInstance.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public interface IGenericInstance : IMetadataTokenProvider { + + bool HasGenericArguments { get; } + Collection GenericArguments { get; } + } + + static partial class Mixin { + + public static bool ContainsGenericParameter (IGenericInstance self) + { + var arguments = self.GenericArguments; + + for (int i = 0; i < arguments.Count; i++) + if (arguments [i].ContainsGenericParameter) + return true; + + return false; + } + + public static void GenericInstanceFullName (IGenericInstance self, StringBuilder builder) + { + builder.Append ("<"); + var arguments = self.GenericArguments; + for (int i = 0; i < arguments.Count; i++) { + if (i > 0) + builder.Append (","); + builder.Append (arguments [i].FullName); + } + builder.Append (">"); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericParameterProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericParameterProvider.cs new file mode 100644 index 00000000..8130174c --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IGenericParameterProvider.cs @@ -0,0 +1,79 @@ +// +// IGenericParameterProvider.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + + +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public interface IGenericParameterProvider : IMetadataTokenProvider + { + + bool HasGenericParameters { get; } + bool IsDefinition { get; } + ModuleDefinition Module { get; } + Collection GenericParameters { get; } + GenericParameterType GenericParameterType { get; } + } + + public enum GenericParameterType + { + Type, + Method + } + + interface IGenericContext + { + + bool IsDefinition { get; } + IGenericParameterProvider Type { get; } + IGenericParameterProvider Method { get; } + } + + static partial class Mixin + { + + public static bool GetHasGenericParameters( + IGenericParameterProvider self, + ModuleDefinition module) + { + return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasGenericParameters(provider)); + } + + public static Collection GetGenericParameters( + IGenericParameterProvider self, + ref Collection collection, + ModuleDefinition module) + { + return Mixin.HasImage(module) + ? module.Read(ref collection, self, (provider, reader) => reader.ReadGenericParameters(provider)) + : collection = new GenericParameterCollection(self); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMarshalInfoProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMarshalInfoProvider.cs new file mode 100644 index 00000000..369f76b2 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMarshalInfoProvider.cs @@ -0,0 +1,59 @@ +// +// IMarshalInfoProvider.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil +{ + + public interface IMarshalInfoProvider : IMetadataTokenProvider + { + + bool HasMarshalInfo { get; } + MarshalInfo MarshalInfo { get; set; } + } + + static partial class Mixin + { + + public static bool GetHasMarshalInfo( + IMarshalInfoProvider self, + ModuleDefinition module) + { + return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasMarshalInfo(provider)); + } + + public static MarshalInfo GetMarshalInfo( + IMarshalInfoProvider self, + ref MarshalInfo variable, + ModuleDefinition module) + { + return Mixin.HasImage(module) + ? module.Read(ref variable, self, (provider, reader) => reader.ReadMarshalInfo(provider)) + : null; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMemberDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMemberDefinition.cs new file mode 100644 index 00000000..af243162 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMemberDefinition.cs @@ -0,0 +1,105 @@ +// +// IMemberDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil +{ + + public interface IMemberDefinition : ICustomAttributeProvider + { + + string Name { get; set; } + string FullName { get; } + + bool IsSpecialName { get; set; } + bool IsRuntimeSpecialName { get; set; } + + TypeDefinition DeclaringType { get; set; } + } + + static partial class Mixin + { + + public static bool GetAttributes(uint self, uint attributes) + { + return (self & attributes) != 0; + } + + public static uint SetAttributes(uint self, uint attributes, bool value) + { + if (value) + return self | attributes; + + return self & ~attributes; + } + + public static bool GetMaskedAttributes(uint self, uint mask, uint attributes) + { + return (self & mask) == attributes; + } + + public static uint SetMaskedAttributes(uint self, uint mask, uint attributes, bool value) + { + if (value) + { + self &= ~mask; + return self | attributes; + } + + return self & ~(mask & attributes); + } + + public static bool GetAttributes(ushort self, ushort attributes) + { + return (self & attributes) != 0; + } + + public static ushort SetAttributes(ushort self, ushort attributes, bool value) + { + if (value) + return (ushort)(self | attributes); + + return (ushort)(self & ~attributes); + } + + public static bool GetMaskedAttributes(ushort self, ushort mask, uint attributes) + { + return (self & mask) == attributes; + } + + public static ushort SetMaskedAttributes(ushort self, ushort mask, uint attributes, bool value) + { + if (value) + { + self = (ushort)(self & ~mask); + return (ushort)(self | attributes); + } + + return (ushort)(self & ~(mask & attributes)); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataScope.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataScope.cs new file mode 100644 index 00000000..04a02281 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataScope.cs @@ -0,0 +1,41 @@ +// +// IMetadataScope.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public enum MetadataScopeType { + AssemblyNameReference, + ModuleReference, + ModuleDefinition, + } + + public interface IMetadataScope : IMetadataTokenProvider { + MetadataScopeType MetadataScopeType { get; } + string Name { get; set; } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataTokenProvider.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataTokenProvider.cs new file mode 100644 index 00000000..6621835b --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMetadataTokenProvider.cs @@ -0,0 +1,35 @@ +// +// IMetadataTokenProvider.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public interface IMetadataTokenProvider { + + MetadataToken MetadataToken { get; set; } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMethodSignature.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMethodSignature.cs new file mode 100644 index 00000000..74d285cf --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/IMethodSignature.cs @@ -0,0 +1,75 @@ +// +// IMethodSignature.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public interface IMethodSignature : IMetadataTokenProvider { + + bool HasThis { get; set; } + bool ExplicitThis { get; set; } + MethodCallingConvention CallingConvention { get; set; } + + bool HasParameters { get; } + Collection Parameters { get; } + TypeReference ReturnType { get; set; } + MethodReturnType MethodReturnType { get; } + } + + static partial class Mixin { + + public static bool HasImplicitThis (IMethodSignature self) + { + return self.HasThis && !self.ExplicitThis; + } + + public static void MethodSignatureFullName (IMethodSignature self, StringBuilder builder) + { + builder.Append ("("); + + if (self.HasParameters) { + var parameters = self.Parameters; + for (int i = 0; i < parameters.Count; i++) { + var parameter = parameters [i]; + if (i > 0) + builder.Append (","); + + if (parameter.ParameterType.IsSentinel) + builder.Append ("...,"); + + builder.Append (parameter.ParameterType.FullName); + } + } + + builder.Append (")"); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Import.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/Import.cs new file mode 100644 index 00000000..c7b63464 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/Import.cs @@ -0,0 +1,286 @@ +// +// Import.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using SR = System.Reflection; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil +{ + + enum ImportGenericKind + { + Definition, + Open, + } + + class MetadataImporter + { + + readonly ModuleDefinition module; + + public MetadataImporter(ModuleDefinition module) + { + this.module = module; + } + + + public TypeReference ImportType(TypeReference type, IGenericContext context) + { + if (Mixin.IsTypeSpecification(type)) + return ImportTypeSpecification(type, context); + + var reference = new TypeReference( + type.Namespace, + type.Name, + module, + ImportScope(type.Scope), + type.IsValueType); + + MetadataSystem.TryProcessPrimitiveTypeReference(reference); + + if (type.IsNested) + reference.DeclaringType = ImportType(type.DeclaringType, context); + + if (type.HasGenericParameters) + ImportGenericParameters(reference, type); + + return reference; + } + + IMetadataScope ImportScope(IMetadataScope scope) + { + switch (scope.MetadataScopeType) + { + case MetadataScopeType.AssemblyNameReference: + return ImportAssemblyName((AssemblyNameReference)scope); + case MetadataScopeType.ModuleDefinition: + return ImportAssemblyName(((ModuleDefinition)scope).Assembly.Name); + case MetadataScopeType.ModuleReference: + throw new NotImplementedException(); + } + + throw new NotSupportedException(); + } + + AssemblyNameReference ImportAssemblyName(AssemblyNameReference name) + { + AssemblyNameReference reference; + if (TryGetAssemblyNameReference(name, out reference)) + return reference; + + reference = new AssemblyNameReference(name.Name, name.Version) + { + Culture = name.Culture, + HashAlgorithm = name.HashAlgorithm, + }; + + var pk_token = !Mixin.IsNullOrEmpty(name.PublicKeyToken) + ? new byte[name.PublicKeyToken.Length] + : Empty.Array; + + if (pk_token.Length > 0) + Buffer.BlockCopy(name.PublicKeyToken, 0, pk_token, 0, pk_token.Length); + + reference.PublicKeyToken = pk_token; + + module.AssemblyReferences.Add(reference); + + return reference; + } + + bool TryGetAssemblyNameReference(AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference) + { + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) + { + var reference = references[i]; + if (name_reference.FullName != reference.FullName) // TODO compare field by field + continue; + + assembly_reference = reference; + return true; + } + + assembly_reference = null; + return false; + } + + static void ImportGenericParameters(IGenericParameterProvider imported, IGenericParameterProvider original) + { + var parameters = original.GenericParameters; + var imported_parameters = imported.GenericParameters; + + for (int i = 0; i < parameters.Count; i++) + imported_parameters.Add(new GenericParameter(parameters[i].Name, imported)); + } + + TypeReference ImportTypeSpecification(TypeReference type, IGenericContext context) + { + switch (type.etype) + { + case ElementType.SzArray: + var vector = (ArrayType)type; + return new ArrayType(ImportType(vector.ElementType, context)); + case ElementType.Ptr: + var pointer = (PointerType)type; + return new PointerType(ImportType(pointer.ElementType, context)); + case ElementType.ByRef: + var byref = (ByReferenceType)type; + return new ByReferenceType(ImportType(byref.ElementType, context)); + case ElementType.Pinned: + var pinned = (PinnedType)type; + return new PinnedType(ImportType(pinned.ElementType, context)); + case ElementType.Sentinel: + var sentinel = (SentinelType)type; + return new SentinelType(ImportType(sentinel.ElementType, context)); + case ElementType.CModOpt: + var modopt = (OptionalModifierType)type; + return new OptionalModifierType( + ImportType(modopt.ModifierType, context), + ImportType(modopt.ElementType, context)); + case ElementType.CModReqD: + var modreq = (RequiredModifierType)type; + return new RequiredModifierType( + ImportType(modreq.ModifierType, context), + ImportType(modreq.ElementType, context)); + case ElementType.Array: + var array = (ArrayType)type; + var imported_array = new ArrayType(ImportType(array.ElementType, context)); + if (array.IsVector) + return imported_array; + + var dimensions = array.Dimensions; + var imported_dimensions = imported_array.Dimensions; + + imported_dimensions.Clear(); + + for (int i = 0; i < dimensions.Count; i++) + { + var dimension = dimensions[i]; + + imported_dimensions.Add(new ArrayDimension(dimension.LowerBound, dimension.UpperBound)); + } + + return imported_array; + case ElementType.GenericInst: + var instance = (GenericInstanceType)type; + var element_type = ImportType(instance.ElementType, context); + var imported_instance = new GenericInstanceType(element_type); + + var arguments = instance.GenericArguments; + var imported_arguments = imported_instance.GenericArguments; + + for (int i = 0; i < arguments.Count; i++) + imported_arguments.Add(ImportType(arguments[i], context)); + + return imported_instance; + case ElementType.Var: + if (context == null || context.Type == null) + throw new InvalidOperationException(); + + return ((TypeReference)context.Type).GetElementType().GenericParameters[((GenericParameter)type).Position]; + case ElementType.MVar: + if (context == null || context.Method == null) + throw new InvalidOperationException(); + + return context.Method.GenericParameters[((GenericParameter)type).Position]; + } + + throw new NotSupportedException(type.etype.ToString()); + } + + public FieldReference ImportField(FieldReference field, IGenericContext context) + { + var declaring_type = ImportType(field.DeclaringType, context); + + return new FieldReference + { + Name = field.Name, + DeclaringType = declaring_type, + FieldType = ImportType(field.FieldType, context ?? declaring_type), + }; + } + + public MethodReference ImportMethod(MethodReference method, IGenericContext context) + { + if (method.IsGenericInstance) + return ImportMethodSpecification(method, context); + + var declaring_type = ImportType(method.DeclaringType, context); + + var reference = new MethodReference + { + Name = method.Name, + HasThis = method.HasThis, + ExplicitThis = method.ExplicitThis, + DeclaringType = declaring_type, + }; + + reference.CallingConvention = method.CallingConvention; + + if (method.HasGenericParameters) + ImportGenericParameters(reference, method); + + reference.ReturnType = ImportType(method.ReturnType, context ?? reference); + + if (!method.HasParameters) + return reference; + + var reference_parameters = reference.Parameters; + + var parameters = method.Parameters; + for (int i = 0; i < parameters.Count; i++) + reference_parameters.Add( + new ParameterDefinition(ImportType(parameters[i].ParameterType, context ?? reference))); + + return reference; + } + + MethodSpecification ImportMethodSpecification(MethodReference method, IGenericContext context) + { + if (!method.IsGenericInstance) + throw new NotSupportedException(); + + var instance = (GenericInstanceMethod)method; + var element_method = ImportMethod(instance.ElementMethod, context); + var imported_instance = new GenericInstanceMethod(element_method); + + var arguments = instance.GenericArguments; + var imported_arguments = imported_instance.GenericArguments; + + for (int i = 0; i < arguments.Count; i++) + imported_arguments.Add(ImportType(arguments[i], context)); + + return imported_instance; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/LinkedResource.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/LinkedResource.cs new file mode 100644 index 00000000..16c1d59b --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/LinkedResource.cs @@ -0,0 +1,60 @@ +// +// LinkedResource.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public sealed class LinkedResource : Resource { + + internal byte [] hash; + string file; + + public byte [] Hash { + get { return hash; } + } + + public string File { + get { return file; } + set { file = value; } + } + + public override ResourceType ResourceType { + get { return ResourceType.Linked; } + } + + public LinkedResource (string name, ManifestResourceAttributes flags) + : base (name, flags) + { + } + + public LinkedResource (string name, ManifestResourceAttributes flags, string file) + : base (name, flags) + { + this.file = file; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ManifestResourceAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ManifestResourceAttributes.cs new file mode 100644 index 00000000..7d6bb190 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ManifestResourceAttributes.cs @@ -0,0 +1,39 @@ +// +// ManifestResourceAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum ManifestResourceAttributes : uint { + VisibilityMask = 0x0007, + Public = 0x0001, // The resource is exported from the Assembly + Private = 0x0002 // The resource is private to the Assembly + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MarshalInfo.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MarshalInfo.cs new file mode 100644 index 00000000..9d587389 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MarshalInfo.cs @@ -0,0 +1,171 @@ +// +// MarshalInfo.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + public class MarshalInfo { + + internal NativeType native; + + public NativeType NativeType { + get { return native; } + set { native = value; } + } + + public MarshalInfo (NativeType native) + { + this.native = native; + } + } + + public sealed class ArrayMarshalInfo : MarshalInfo { + + internal NativeType element_type; + internal int size_parameter_index; + internal int size; + internal int size_parameter_multiplier; + + public NativeType ElementType { + get { return element_type; } + set { element_type = value; } + } + + public int SizeParameterIndex { + get { return size_parameter_index; } + set { size_parameter_index = value; } + } + + public int Size { + get { return size; } + set { size = value; } + } + + public int SizeParameterMultiplier { + get { return size_parameter_multiplier; } + set { size_parameter_multiplier = value; } + } + + public ArrayMarshalInfo () + : base (NativeType.Array) + { + element_type = NativeType.None; + size_parameter_index = -1; + size = -1; + size_parameter_multiplier = -1; + } + } + + public sealed class CustomMarshalInfo : MarshalInfo { + + internal Guid guid; + internal string unmanaged_type; + internal TypeReference managed_type; + internal string cookie; + + public Guid Guid { + get { return guid; } + set { guid = value; } + } + + public string UnmanagedType { + get { return unmanaged_type; } + set { unmanaged_type = value; } + } + + public TypeReference ManagedType { + get { return managed_type; } + set { managed_type = value; } + } + + public string Cookie { + get { return cookie; } + set { cookie = value; } + } + + public CustomMarshalInfo () + : base (NativeType.CustomMarshaler) + { + } + } + + public sealed class SafeArrayMarshalInfo : MarshalInfo { + + internal VariantType element_type; + + public VariantType ElementType { + get { return element_type; } + set { element_type = value; } + } + + public SafeArrayMarshalInfo () + : base (NativeType.SafeArray) + { + element_type = VariantType.None; + } + } + + public sealed class FixedArrayMarshalInfo : MarshalInfo { + + internal NativeType element_type; + internal int size; + + public NativeType ElementType { + get { return element_type; } + set { element_type = value; } + } + + public int Size { + get { return size; } + set { size = value; } + } + + public FixedArrayMarshalInfo () + : base (NativeType.FixedArray) + { + element_type = NativeType.None; + } + } + + public sealed class FixedSysStringMarshalInfo : MarshalInfo { + + internal int size; + + public int Size { + get { return size; } + set { size = value; } + } + + public FixedSysStringMarshalInfo () + : base (NativeType.FixedSysString) + { + size = -1; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberDefinitionCollection.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberDefinitionCollection.cs new file mode 100644 index 00000000..707f36fb --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberDefinitionCollection.cs @@ -0,0 +1,92 @@ +// +// MemberDefinitionCollection.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + class MemberDefinitionCollection : Collection where T : IMemberDefinition { + + TypeDefinition container; + + internal MemberDefinitionCollection (TypeDefinition container) + { + this.container = container; + } + + internal MemberDefinitionCollection (TypeDefinition container, int capacity) + : base (capacity) + { + this.container = container; + } + + protected override void OnAdd (T item, int index) + { + Attach (item); + } + + protected sealed override void OnSet (T item, int index) + { + Attach (item); + } + + protected sealed override void OnInsert (T item, int index) + { + Attach (item); + } + + protected sealed override void OnRemove (T item, int index) + { + Detach (item); + } + + protected sealed override void OnClear () + { + foreach (var definition in this) + Detach (definition); + } + + void Attach (T element) + { + if (element.DeclaringType == container) + return; + + if (element.DeclaringType != null) + throw new ArgumentException ("Member already attached"); + + element.DeclaringType = this.container; + } + + static void Detach (T element) + { + element.DeclaringType = null; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberReference.cs new file mode 100644 index 00000000..b658c513 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MemberReference.cs @@ -0,0 +1,101 @@ +// +// MemberReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public abstract class MemberReference : IMetadataTokenProvider { + + string name; + TypeReference declaring_type; + + internal MetadataToken token; + + public virtual string Name { + get { return name; } + set { name = value; } + } + + public abstract string FullName { + get; + } + + public virtual TypeReference DeclaringType { + get { return declaring_type; } + set { declaring_type = value; } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal bool HasImage { + get { + var module = Module; + if (module == null) + return false; + + return module.HasImage; + } + } + + public virtual ModuleDefinition Module { + get { return declaring_type != null ? declaring_type.Module : null; } + } + + public virtual bool IsDefinition { + get { return false; } + } + + internal virtual bool ContainsGenericParameter { + get { return declaring_type != null && declaring_type.ContainsGenericParameter; } + } + + internal MemberReference () + { + } + + internal MemberReference (string name) + { + this.name = name ?? string.Empty; + } + + internal string MemberFullName () + { + if (declaring_type == null) + return name; + + return declaring_type.FullName + "::" + name; + } + + public override string ToString () + { + return FullName; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataResolver.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataResolver.cs new file mode 100644 index 00000000..9e8abe5b --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataResolver.cs @@ -0,0 +1,369 @@ +// +// MetadataResolver.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public interface IAssemblyResolver + { + AssemblyDefinition Resolve(AssemblyNameReference name); + AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters); + + AssemblyDefinition Resolve(string fullName); + AssemblyDefinition Resolve(string fullName, ReaderParameters parameters); + } + + public interface IMetadataResolver + { + TypeDefinition Resolve(TypeReference type); + FieldDefinition Resolve(FieldReference field); + MethodDefinition Resolve(MethodReference method); + } + + + public class ResolutionException : Exception + { + + readonly MemberReference member; + + public MemberReference Member + { + get { return member; } + } + + public ResolutionException(MemberReference member) + : base("Failed to resolve " + member.FullName) + { + this.member = member; + } + + + } + + public class MetadataResolver : IMetadataResolver + { + + readonly IAssemblyResolver assembly_resolver; + + public IAssemblyResolver AssemblyResolver + { + get { return assembly_resolver; } + } + + public MetadataResolver(IAssemblyResolver assemblyResolver) + { + if (assemblyResolver == null) + throw new ArgumentNullException("assemblyResolver"); + + assembly_resolver = assemblyResolver; + } + + public virtual TypeDefinition Resolve(TypeReference type) + { + if (type == null) + throw new ArgumentNullException("type"); + + type = type.GetElementType(); + + var scope = type.Scope; + switch (scope.MetadataScopeType) + { + case MetadataScopeType.AssemblyNameReference: + var assembly = assembly_resolver.Resolve((AssemblyNameReference)scope); + if (assembly == null) + return null; + + return GetType(assembly.MainModule, type); + case MetadataScopeType.ModuleDefinition: + return GetType((ModuleDefinition)scope, type); + case MetadataScopeType.ModuleReference: + var modules = type.Module.Assembly.Modules; + var module_ref = (ModuleReference)scope; + for (int i = 0; i < modules.Count; i++) + { + var netmodule = modules[i]; + if (netmodule.Name == module_ref.Name) + return GetType(netmodule, type); + } + break; + } + + throw new NotSupportedException(); + } + + static TypeDefinition GetType(ModuleDefinition module, TypeReference reference) + { + var type = GetTypeDefinition(module, reference); + if (type != null) + return type; + + if (!module.HasExportedTypes) + return null; + + var exported_types = module.ExportedTypes; + + for (int i = 0; i < exported_types.Count; i++) + { + var exported_type = exported_types[i]; + if (exported_type.Name != reference.Name) + continue; + + if (exported_type.Namespace != reference.Namespace) + continue; + + return exported_type.Resolve(); + } + + return null; + } + + static TypeDefinition GetTypeDefinition(ModuleDefinition module, TypeReference type) + { + if (!type.IsNested) + return module.GetType(type.Namespace, type.Name); + + var declaring_type = type.DeclaringType.Resolve(); + if (declaring_type == null) + return null; + + return Mixin.GetNestedType(declaring_type, type.Name); + } + + public virtual FieldDefinition Resolve(FieldReference field) + { + if (field == null) + throw new ArgumentNullException("field"); + + var type = Resolve(field.DeclaringType); + if (type == null) + return null; + + if (!type.HasFields) + return null; + + return GetField(type, field); + } + + FieldDefinition GetField(TypeDefinition type, FieldReference reference) + { + while (type != null) + { + var field = GetField(type.Fields, reference); + if (field != null) + return field; + + if (type.BaseType == null) + return null; + + type = Resolve(type.BaseType); + } + + return null; + } + + static FieldDefinition GetField(Collection fields, FieldReference reference) + { + for (int i = 0; i < fields.Count; i++) + { + var field = fields[i]; + + if (field.Name != reference.Name) + continue; + + if (!AreSame(field.FieldType, reference.FieldType)) + continue; + + return field; + } + + return null; + } + + public virtual MethodDefinition Resolve(MethodReference method) + { + if (method == null) + throw new ArgumentNullException("method"); + + var type = Resolve(method.DeclaringType); + if (type == null) + return null; + + method = method.GetElementMethod(); + + if (!type.HasMethods) + return null; + + return GetMethod(type, method); + } + + MethodDefinition GetMethod(TypeDefinition type, MethodReference reference) + { + while (type != null) + { + var method = GetMethod(type.Methods, reference); + if (method != null) + return method; + + if (type.BaseType == null) + return null; + + type = Resolve(type.BaseType); + } + + return null; + } + + public static MethodDefinition GetMethod(Collection methods, MethodReference reference) + { + for (int i = 0; i < methods.Count; i++) + { + var method = methods[i]; + + if (method.Name != reference.Name) + continue; + + if (method.HasGenericParameters != reference.HasGenericParameters) + continue; + + if (method.HasGenericParameters && method.GenericParameters.Count != reference.GenericParameters.Count) + continue; + + if (!AreSame(method.ReturnType, reference.ReturnType)) + continue; + + if (method.HasParameters != reference.HasParameters) + continue; + + if (!method.HasParameters && !reference.HasParameters) + return method; + + if (!AreSame(method.Parameters, reference.Parameters)) + continue; + + return method; + } + + return null; + } + + static bool AreSame(Collection a, Collection b) + { + var count = a.Count; + + if (count != b.Count) + return false; + + if (count == 0) + return true; + + for (int i = 0; i < count; i++) + if (!AreSame(a[i].ParameterType, b[i].ParameterType)) + return false; + + return true; + } + + static bool AreSame(TypeSpecification a, TypeSpecification b) + { + if (!AreSame(a.ElementType, b.ElementType)) + return false; + + if (a.IsGenericInstance) + return AreSame((GenericInstanceType)a, (GenericInstanceType)b); + + if (a.IsRequiredModifier || a.IsOptionalModifier) + return AreSame((IModifierType)a, (IModifierType)b); + + if (a.IsArray) + return AreSame((ArrayType)a, (ArrayType)b); + + return true; + } + + static bool AreSame(ArrayType a, ArrayType b) + { + if (a.Rank != b.Rank) + return false; + + // TODO: dimensions + + return true; + } + + static bool AreSame(IModifierType a, IModifierType b) + { + return AreSame(a.ModifierType, b.ModifierType); + } + + static bool AreSame(GenericInstanceType a, GenericInstanceType b) + { + if (a.GenericArguments.Count != b.GenericArguments.Count) + return false; + + for (int i = 0; i < a.GenericArguments.Count; i++) + if (!AreSame(a.GenericArguments[i], b.GenericArguments[i])) + return false; + + return true; + } + + static bool AreSame(GenericParameter a, GenericParameter b) + { + return a.Position == b.Position; + } + + static bool AreSame(TypeReference a, TypeReference b) + { + if (ReferenceEquals(a, b)) + return true; + + if (a == null || b == null) + return false; + + if (a.etype != b.etype) + return false; + + if (a.IsGenericParameter) + return AreSame((GenericParameter)a, (GenericParameter)b); + + if (Mixin.IsTypeSpecification(a)) + return AreSame((TypeSpecification)a, (TypeSpecification)b); + + if (a.Name != b.Name || a.Namespace != b.Namespace) + return false; + + //TODO: check scope + + return AreSame(a.DeclaringType, b.DeclaringType); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataSystem.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataSystem.cs new file mode 100644 index 00000000..25cc8335 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MetadataSystem.cs @@ -0,0 +1,395 @@ +// +// MetadataSystem.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + struct Range { + public uint Start; + public uint Length; + + public Range (uint index, uint length) + { + this.Start = index; + this.Length = length; + } + } + + sealed class MetadataSystem { + + internal AssemblyNameReference [] AssemblyReferences; + internal ModuleReference [] ModuleReferences; + + internal TypeDefinition [] Types; + internal TypeReference [] TypeReferences; + + internal FieldDefinition [] Fields; + internal MethodDefinition [] Methods; + internal MemberReference [] MemberReferences; + + internal Dictionary NestedTypes; + internal Dictionary ReverseNestedTypes; + internal Dictionary Interfaces; + internal Dictionary> ClassLayouts; + internal Dictionary FieldLayouts; + internal Dictionary FieldRVAs; + internal Dictionary FieldMarshals; + internal Dictionary> Constants; + internal Dictionary Overrides; + internal Dictionary CustomAttributes; + internal Dictionary SecurityDeclarations; + internal Dictionary Events; + internal Dictionary Properties; + internal Dictionary> Semantics; + internal Dictionary> PInvokes; + internal Dictionary GenericParameters; + internal Dictionary GenericConstraints; + + static Dictionary> primitive_value_types; + + static void InitializePrimitives () + { + primitive_value_types = new Dictionary> (18, StringComparer.Ordinal) { + { "Void", new Row (ElementType.Void, false) }, + { "Boolean", new Row (ElementType.Boolean, true) }, + { "Char", new Row (ElementType.Char, true) }, + { "SByte", new Row (ElementType.I1, true) }, + { "Byte", new Row (ElementType.U1, true) }, + { "Int16", new Row (ElementType.I2, true) }, + { "UInt16", new Row (ElementType.U2, true) }, + { "Int32", new Row (ElementType.I4, true) }, + { "UInt32", new Row (ElementType.U4, true) }, + { "Int64", new Row (ElementType.I8, true) }, + { "UInt64", new Row (ElementType.U8, true) }, + { "Single", new Row (ElementType.R4, true) }, + { "Double", new Row (ElementType.R8, true) }, + { "String", new Row (ElementType.String, false) }, + { "TypedReference", new Row (ElementType.TypedByRef, false) }, + { "IntPtr", new Row (ElementType.I, true) }, + { "UIntPtr", new Row (ElementType.U, true) }, + { "Object", new Row (ElementType.Object, false) }, + }; + } + + public static void TryProcessPrimitiveTypeReference (TypeReference type) + { + if (type.Namespace != "System") + return; + + var scope = type.scope; + if (scope == null || scope.MetadataScopeType != MetadataScopeType.AssemblyNameReference) + return; + + Row primitive_data; + if (!TryGetPrimitiveData (type, out primitive_data)) + return; + + type.etype = primitive_data.Col1; + type.IsValueType = primitive_data.Col2; + } + + public static bool TryGetPrimitiveElementType (TypeDefinition type, out ElementType etype) + { + etype = ElementType.None; + + if (type.Namespace != "System") + return false; + + Row primitive_data; + if (TryGetPrimitiveData (type, out primitive_data) &&Mixin .IsPrimitive (primitive_data.Col1)) { + etype = primitive_data.Col1; + return true; + } + + return false; + } + + static bool TryGetPrimitiveData (TypeReference type, out Row primitive_data) + { + if (primitive_value_types == null) + InitializePrimitives (); + + return primitive_value_types.TryGetValue (type.Name, out primitive_data); + } + + public void Clear () + { + if (NestedTypes != null) NestedTypes.Clear (); + if (ReverseNestedTypes != null) ReverseNestedTypes.Clear (); + if (Interfaces != null) Interfaces.Clear (); + if (ClassLayouts != null) ClassLayouts.Clear (); + if (FieldLayouts != null) FieldLayouts.Clear (); + if (FieldRVAs != null) FieldRVAs.Clear (); + if (FieldMarshals != null) FieldMarshals.Clear (); + if (Constants != null) Constants.Clear (); + if (Overrides != null) Overrides.Clear (); + if (CustomAttributes != null) CustomAttributes.Clear (); + if (SecurityDeclarations != null) SecurityDeclarations.Clear (); + if (Events != null) Events.Clear (); + if (Properties != null) Properties.Clear (); + if (Semantics != null) Semantics.Clear (); + if (PInvokes != null) PInvokes.Clear (); + if (GenericParameters != null) GenericParameters.Clear (); + if (GenericConstraints != null) GenericConstraints.Clear (); + } + + public TypeDefinition GetTypeDefinition (uint rid) + { + if (rid < 1 || rid > Types.Length) + return null; + + return Types [rid - 1]; + } + + public void AddTypeDefinition (TypeDefinition type) + { + Types [type.token.RID - 1] = type; + } + + public TypeReference GetTypeReference (uint rid) + { + if (rid < 1 || rid > TypeReferences.Length) + return null; + + return TypeReferences [rid - 1]; + } + + public void AddTypeReference (TypeReference type) + { + TypeReferences [type.token.RID - 1] = type; + } + + public FieldDefinition GetFieldDefinition (uint rid) + { + if (rid < 1 || rid > Fields.Length) + return null; + + return Fields [rid - 1]; + } + + public void AddFieldDefinition (FieldDefinition field) + { + Fields [field.token.RID - 1] = field; + } + + public MethodDefinition GetMethodDefinition (uint rid) + { + if (rid < 1 || rid > Methods.Length) + return null; + + return Methods [rid - 1]; + } + + public void AddMethodDefinition (MethodDefinition method) + { + Methods [method.token.RID - 1] = method; + } + + public MemberReference GetMemberReference (uint rid) + { + if (rid < 1 || rid > MemberReferences.Length) + return null; + + return MemberReferences [rid - 1]; + } + + public void AddMemberReference (MemberReference member) + { + MemberReferences [member.token.RID - 1] = member; + } + + public bool TryGetNestedTypeMapping (TypeDefinition type, out uint [] mapping) + { + return NestedTypes.TryGetValue (type.token.RID, out mapping); + } + + public void SetNestedTypeMapping (uint type_rid, uint [] mapping) + { + NestedTypes [type_rid] = mapping; + } + + public void RemoveNestedTypeMapping (TypeDefinition type) + { + NestedTypes.Remove (type.token.RID); + } + + public bool TryGetReverseNestedTypeMapping (TypeDefinition type, out uint declaring) + { + return ReverseNestedTypes.TryGetValue (type.token.RID, out declaring); + } + + public void SetReverseNestedTypeMapping (uint nested, uint declaring) + { + ReverseNestedTypes.Add (nested, declaring); + } + + public void RemoveReverseNestedTypeMapping (TypeDefinition type) + { + ReverseNestedTypes.Remove (type.token.RID); + } + + public bool TryGetInterfaceMapping (TypeDefinition type, out MetadataToken [] mapping) + { + return Interfaces.TryGetValue (type.token.RID, out mapping); + } + + public void SetInterfaceMapping (uint type_rid, MetadataToken [] mapping) + { + Interfaces [type_rid] = mapping; + } + + public void RemoveInterfaceMapping (TypeDefinition type) + { + Interfaces.Remove (type.token.RID); + } + + public void AddPropertiesRange (uint type_rid, Range range) + { + Properties.Add (type_rid, range); + } + + public bool TryGetPropertiesRange (TypeDefinition type, out Range range) + { + return Properties.TryGetValue (type.token.RID, out range); + } + + public void RemovePropertiesRange (TypeDefinition type) + { + Properties.Remove (type.token.RID); + } + + public void AddEventsRange (uint type_rid, Range range) + { + Events.Add (type_rid, range); + } + + public bool TryGetEventsRange (TypeDefinition type, out Range range) + { + return Events.TryGetValue (type.token.RID, out range); + } + + public void RemoveEventsRange (TypeDefinition type) + { + Events.Remove (type.token.RID); + } + + public bool TryGetGenericParameterRange (IGenericParameterProvider owner, out Range range) + { + return GenericParameters.TryGetValue (owner.MetadataToken, out range); + } + + public void RemoveGenericParameterRange (IGenericParameterProvider owner) + { + GenericParameters.Remove (owner.MetadataToken); + } + + public bool TryGetCustomAttributeRange (ICustomAttributeProvider owner, out Range range) + { + return CustomAttributes.TryGetValue (owner.MetadataToken, out range); + } + + public void RemoveCustomAttributeRange (ICustomAttributeProvider owner) + { + CustomAttributes.Remove (owner.MetadataToken); + } + + public bool TryGetSecurityDeclarationRange (ISecurityDeclarationProvider owner, out Range range) + { + return SecurityDeclarations.TryGetValue (owner.MetadataToken, out range); + } + + public void RemoveSecurityDeclarationRange (ISecurityDeclarationProvider owner) + { + SecurityDeclarations.Remove (owner.MetadataToken); + } + + public bool TryGetGenericConstraintMapping (GenericParameter generic_parameter, out MetadataToken [] mapping) + { + return GenericConstraints.TryGetValue (generic_parameter.token.RID, out mapping); + } + + public void SetGenericConstraintMapping (uint gp_rid, MetadataToken [] mapping) + { + GenericConstraints [gp_rid] = mapping; + } + + public void RemoveGenericConstraintMapping (GenericParameter generic_parameter) + { + GenericConstraints.Remove (generic_parameter.token.RID); + } + + public bool TryGetOverrideMapping (MethodDefinition method, out MetadataToken [] mapping) + { + return Overrides.TryGetValue (method.token.RID, out mapping); + } + + public void SetOverrideMapping (uint rid, MetadataToken [] mapping) + { + Overrides [rid] = mapping; + } + + public void RemoveOverrideMapping (MethodDefinition method) + { + Overrides.Remove (method.token.RID); + } + + public TypeDefinition GetFieldDeclaringType (uint field_rid) + { + return BinaryRangeSearch (Types, field_rid, true); + } + + public TypeDefinition GetMethodDeclaringType (uint method_rid) + { + return BinaryRangeSearch (Types, method_rid, false); + } + + static TypeDefinition BinaryRangeSearch (TypeDefinition [] types, uint rid, bool field) + { + int min = 0; + int max = types.Length - 1; + while (min <= max) { + int mid = min + ((max - min) / 2); + var type = types [mid]; + var range = field ? type.fields_range : type.methods_range; + + if (rid < range.Start) + max = mid - 1; + else if (rid >= range.Start + range.Length) + min = mid + 1; + else + return type; + } + + return null; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodAttributes.cs new file mode 100644 index 00000000..626a97b3 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodAttributes.cs @@ -0,0 +1,66 @@ +// +// MethodAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum MethodAttributes : ushort { + MemberAccessMask = 0x0007, + CompilerControlled = 0x0000, // Member not referenceable + Private = 0x0001, // Accessible only by the parent type + FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly + Assembly = 0x0003, // Accessibly by anyone in the Assembly + Family = 0x0004, // Accessible only by type and sub-types + FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly + Public = 0x0006, // Accessibly by anyone who has visibility to this scope + + Static = 0x0010, // Defined on type, else per instance + Final = 0x0020, // Method may not be overridden + Virtual = 0x0040, // Method is virtual + HideBySig = 0x0080, // Method hides by name+sig, else just by name + + VtableLayoutMask = 0x0100, // Use this mask to retrieve vtable attributes + ReuseSlot = 0x0000, // Method reuses existing slot in vtable + NewSlot = 0x0100, // Method always gets a new slot in the vtable + + CheckAccessOnOverride = 0x0200, // Method can only be overriden if also accessible + Abstract = 0x0400, // Method does not provide an implementation + SpecialName = 0x0800, // Method is special + + // Interop Attributes + PInvokeImpl = 0x2000, // Implementation is forwarded through PInvoke + UnmanagedExport = 0x0008, // Reserved: shall be zero for conforming implementations + + // Additional flags + RTSpecialName = 0x1000, // CLI provides 'special' behavior, depending upon the name of the method + HasSecurity = 0x4000, // Method has security associate with it + RequireSecObject = 0x8000 // Method calls another method containing security code + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodCallingConvention.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodCallingConvention.cs new file mode 100644 index 00000000..bd7188db --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodCallingConvention.cs @@ -0,0 +1,40 @@ +// +// MethodCallingConvention.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public enum MethodCallingConvention : byte { + Default = 0x0, + C = 0x1, + StdCall = 0x2, + ThisCall = 0x3, + FastCall = 0x4, + VarArg = 0x5, + Generic = 0x10, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodDefinition.cs new file mode 100644 index 00000000..c34cd083 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodDefinition.cs @@ -0,0 +1,570 @@ +// +// MethodDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using Mono.Cecil.Cil; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil +{ + + public sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecurityDeclarationProvider + { + + ushort attributes; + ushort impl_attributes; + internal volatile bool sem_attrs_ready; + internal MethodSemanticsAttributes sem_attrs; + Collection custom_attributes; + Collection security_declarations; + + internal RVA rva; + internal PInvokeInfo pinvoke; + Collection overrides; + + internal MethodBody body; + + public MethodAttributes Attributes + { + get { return (MethodAttributes)attributes; } + set { attributes = (ushort)value; } + } + + public MethodImplAttributes ImplAttributes + { + get { return (MethodImplAttributes)impl_attributes; } + set { impl_attributes = (ushort)value; } + } + + public MethodSemanticsAttributes SemanticsAttributes + { + get + { + if (sem_attrs_ready) + return sem_attrs; + + if (HasImage) + { + ReadSemantics(); + return sem_attrs; + } + + sem_attrs = MethodSemanticsAttributes.None; + sem_attrs_ready = true; + return sem_attrs; + } + set { sem_attrs = value; } + } + + internal void ReadSemantics() + { + if (sem_attrs_ready) + return; + + var module = this.Module; + if (module == null) + return; + + if (!module.HasImage) + return; + + module.Read(this, (method, reader) => reader.ReadAllSemantics(method)); + } + + public bool HasSecurityDeclarations + { + get + { + if (security_declarations != null) + return security_declarations.Count > 0; + + return Mixin.GetHasSecurityDeclarations(this, Module); + } + } + + public Collection SecurityDeclarations + { + get { return security_declarations ?? (Mixin.GetSecurityDeclarations(this, ref security_declarations, Module)); } + } + + public bool HasCustomAttributes + { + get + { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, Module); + } + } + + public Collection CustomAttributes + { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + } + + public int RVA + { + get { return (int)rva; } + } + + public bool HasBody + { + get + { + return (attributes & (ushort)MethodAttributes.Abstract) == 0 && + (attributes & (ushort)MethodAttributes.PInvokeImpl) == 0 && + (impl_attributes & (ushort)MethodImplAttributes.InternalCall) == 0 && + (impl_attributes & (ushort)MethodImplAttributes.Native) == 0 && + (impl_attributes & (ushort)MethodImplAttributes.Unmanaged) == 0 && + (impl_attributes & (ushort)MethodImplAttributes.Runtime) == 0; + } + } + + public MethodBody Body + { + get + { + MethodBody localBody = this.body; + if (localBody != null) + return localBody; + + if (!HasBody) + return null; + + if (HasImage && rva != 0) + return Module.Read(ref body, this, (method, reader) => reader.ReadMethodBody(method)); + + return body = new MethodBody(this); + } + set + { + // we reset Body to null in ILSpy to save memory; so we need that operation to be thread-safe + lock (Module.SyncRoot) + { + body = value; + } + } + } + + public bool HasPInvokeInfo + { + get + { + if (pinvoke != null) + return true; + + return IsPInvokeImpl; + } + } + + public PInvokeInfo PInvokeInfo + { + get + { + if (pinvoke != null) + return pinvoke; + + if (HasImage && IsPInvokeImpl) + return Module.Read(ref pinvoke, this, (method, reader) => reader.ReadPInvokeInfo(method)); + + return null; + } + set + { + IsPInvokeImpl = true; + pinvoke = value; + } + } + + public bool HasOverrides + { + get + { + if (overrides != null) + return overrides.Count > 0; + + if (HasImage) + return Module.Read(this, (method, reader) => reader.HasOverrides(method)); + + return false; + } + } + + public Collection Overrides + { + get + { + if (overrides != null) + return overrides; + + if (HasImage) + return Module.Read(ref overrides, this, (method, reader) => reader.ReadOverrides(method)); + + return overrides = new Collection(); + } + } + + public override bool HasGenericParameters + { + get + { + if (generic_parameters != null) + return generic_parameters.Count > 0; + + return Mixin.GetHasGenericParameters(this, Module); + } + } + + public override Collection GenericParameters + { + get { return generic_parameters ?? (Mixin.GetGenericParameters(this, ref generic_parameters, Module)); } + } + + #region MethodAttributes + + public bool IsCompilerControlled + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.CompilerControlled); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.CompilerControlled, value); } + } + + public bool IsPrivate + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Private); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Private, value); } + } + + public bool IsFamilyAndAssembly + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.FamANDAssem); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.FamANDAssem, value); } + } + + public bool IsAssembly + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Assembly); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Assembly, value); } + } + + public bool IsFamily + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Family); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Family, value); } + } + + public bool IsFamilyOrAssembly + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.FamORAssem); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.FamORAssem, value); } + } + + public bool IsPublic + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Public); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.MemberAccessMask, (ushort)MethodAttributes.Public, value); } + } + + public bool IsStatic + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.Static); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.Static, value); } + } + + public bool IsFinal + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.Final); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.Final, value); } + } + + public bool IsVirtual + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.Virtual); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.Virtual, value); } + } + + public bool IsHideBySig + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.HideBySig); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.HideBySig, value); } + } + + public bool IsReuseSlot + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.VtableLayoutMask, (ushort)MethodAttributes.ReuseSlot); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.VtableLayoutMask, (ushort)MethodAttributes.ReuseSlot, value); } + } + + public bool IsNewSlot + { + get { return Mixin.GetMaskedAttributes(attributes,(ushort)MethodAttributes.VtableLayoutMask, (ushort)MethodAttributes.NewSlot); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort)MethodAttributes.VtableLayoutMask, (ushort)MethodAttributes.NewSlot, value); } + } + + public bool IsCheckAccessOnOverride + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.CheckAccessOnOverride); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.CheckAccessOnOverride, value); } + } + + public bool IsAbstract + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.Abstract); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.Abstract, value); } + } + + public bool IsSpecialName + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.SpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.SpecialName, value); } + } + + public bool IsPInvokeImpl + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.PInvokeImpl); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.PInvokeImpl, value); } + } + + public bool IsUnmanagedExport + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.UnmanagedExport); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.UnmanagedExport, value); } + } + + public bool IsRuntimeSpecialName + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.RTSpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.RTSpecialName, value); } + } + + public bool HasSecurity + { + get { return Mixin.GetAttributes(attributes,(ushort)MethodAttributes.HasSecurity); } + set { attributes =Mixin.SetAttributes(attributes,(ushort)MethodAttributes.HasSecurity, value); } + } + + #endregion + + #region MethodImplAttributes + + public bool IsIL + { + get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.IL); } + set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.IL, value); } + } + + public bool IsNative + { + get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.Native); } + set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.Native, value); } + } + + public bool IsRuntime + { + get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.Runtime); } + set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.CodeTypeMask, (ushort)MethodImplAttributes.Runtime, value); } + } + + public bool IsUnmanaged + { + get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.ManagedMask, (ushort)MethodImplAttributes.Unmanaged); } + set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.ManagedMask, (ushort)MethodImplAttributes.Unmanaged, value); } + } + + public bool IsManaged + { + get { return Mixin.GetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.ManagedMask, (ushort)MethodImplAttributes.Managed); } + set { impl_attributes = Mixin.SetMaskedAttributes(impl_attributes,(ushort)MethodImplAttributes.ManagedMask, (ushort)MethodImplAttributes.Managed, value); } + } + + public bool IsForwardRef + { + get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.ForwardRef); } + set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.ForwardRef, value); } + } + + public bool IsPreserveSig + { + get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.PreserveSig); } + set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.PreserveSig, value); } + } + + public bool IsInternalCall + { + get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.InternalCall); } + set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.InternalCall, value); } + } + + public bool IsSynchronized + { + get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.Synchronized); } + set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.Synchronized, value); } + } + + public bool NoInlining + { + get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.NoInlining); } + set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.NoInlining, value); } + } + + public bool NoOptimization + { + get { return Mixin.GetAttributes(impl_attributes, (ushort)MethodImplAttributes.NoOptimization); } + set { impl_attributes = Mixin.SetAttributes(impl_attributes,(ushort)MethodImplAttributes.NoOptimization, value); } + } + + #endregion + + #region MethodSemanticsAttributes + + public bool IsSetter + { + get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.Setter); } + set { Mixin.SetSemantics(this, MethodSemanticsAttributes.Setter, value); } + } + + public bool IsGetter + { + get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.Getter); } + set { Mixin.SetSemantics(this, MethodSemanticsAttributes.Getter, value); } + } + + public bool IsOther + { + get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.Other); } + set { Mixin.SetSemantics(this, MethodSemanticsAttributes.Other, value); } + } + + public bool IsAddOn + { + get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.AddOn); } + set { Mixin.SetSemantics(this, MethodSemanticsAttributes.AddOn, value); } + } + + public bool IsRemoveOn + { + get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.RemoveOn); } + set { Mixin.SetSemantics(this, MethodSemanticsAttributes.RemoveOn, value); } + } + + public bool IsFire + { + get { return Mixin.GetSemantics(this, MethodSemanticsAttributes.Fire); } + set { Mixin.SetSemantics(this, MethodSemanticsAttributes.Fire, value); } + } + + #endregion + + public new TypeDefinition DeclaringType + { + get { return (TypeDefinition)base.DeclaringType; } + set { base.DeclaringType = value; } + } + + public bool IsConstructor + { + get + { + return this.IsRuntimeSpecialName + && this.IsSpecialName + && (this.Name == ".cctor" || this.Name == ".ctor"); + } + } + + public override bool IsDefinition + { + get { return true; } + } + + internal MethodDefinition() + { + this.token = new MetadataToken(TokenType.Method); + } + + public MethodDefinition(string name, MethodAttributes attributes, TypeReference returnType) + : base(name, returnType) + { + this.attributes = (ushort)attributes; + this.HasThis = !this.IsStatic; + this.token = new MetadataToken(TokenType.Method); + } + + public override MethodDefinition Resolve() + { + return this; + } + } + + static partial class Mixin + { + + public static ParameterDefinition GetParameter(MethodBody self, int index) + { + var method = self.method; + + if (method.HasThis) + { + if (index == 0) + return self.ThisParameter; + + index--; + } + + var parameters = method.Parameters; + + if (index < 0 || index >= parameters.size) + return null; + + return parameters[index]; + } + + public static VariableDefinition GetVariable(MethodBody self, int index) + { + var variables = self.Variables; + + if (index < 0 || index >= variables.size) + return null; + + return variables[index]; + } + + public static bool GetSemantics(MethodDefinition self, MethodSemanticsAttributes semantics) + { + return (self.SemanticsAttributes & semantics) != 0; + } + + public static void SetSemantics(MethodDefinition self, MethodSemanticsAttributes semantics, bool value) + { + if (value) + self.SemanticsAttributes |= semantics; + else + self.SemanticsAttributes &= ~semantics; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodImplAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodImplAttributes.cs new file mode 100644 index 00000000..b24fcf70 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodImplAttributes.cs @@ -0,0 +1,53 @@ +// +// MethodImplAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum MethodImplAttributes : ushort { + CodeTypeMask = 0x0003, + IL = 0x0000, // Method impl is CIL + Native = 0x0001, // Method impl is native + OPTIL = 0x0002, // Reserved: shall be zero in conforming implementations + Runtime = 0x0003, // Method impl is provided by the runtime + + ManagedMask = 0x0004, // Flags specifying whether the code is managed or unmanaged + Unmanaged = 0x0004, // Method impl is unmanaged, otherwise managed + Managed = 0x0000, // Method impl is managed + + // Implementation info and interop + ForwardRef = 0x0010, // Indicates method is defined; used primarily in merge scenarios + PreserveSig = 0x0080, // Reserved: conforming implementations may ignore + InternalCall = 0x1000, // Reserved: shall be zero in conforming implementations + Synchronized = 0x0020, // Method is single threaded through the body + NoOptimization = 0x0040, // Method is not optimized by the JIT. + NoInlining = 0x0008, // Method may not be inlined + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReference.cs new file mode 100644 index 00000000..fbd7174b --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReference.cs @@ -0,0 +1,239 @@ +// +// MethodReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public class MethodReference : MemberReference, IMethodSignature, IGenericParameterProvider, IGenericContext + { + + internal ParameterDefinitionCollection parameters; + MethodReturnType return_type; + + bool has_this; + bool explicit_this; + MethodCallingConvention calling_convention; + internal Collection generic_parameters; + + public virtual bool HasThis + { + get { return has_this; } + set { has_this = value; } + } + + public virtual bool ExplicitThis + { + get { return explicit_this; } + set { explicit_this = value; } + } + + public virtual MethodCallingConvention CallingConvention + { + get { return calling_convention; } + set { calling_convention = value; } + } + + public virtual bool HasParameters + { + get { return !Mixin.IsNullOrEmpty(parameters); } + } + + public virtual Collection Parameters + { + get + { + if (parameters == null) + parameters = new ParameterDefinitionCollection(this); + + return parameters; + } + } + + IGenericParameterProvider IGenericContext.Type + { + get + { + var declaring_type = this.DeclaringType; + var instance = declaring_type as GenericInstanceType; + if (instance != null) + return instance.ElementType; + + return declaring_type; + } + } + + IGenericParameterProvider IGenericContext.Method + { + get { return this; } + } + + GenericParameterType IGenericParameterProvider.GenericParameterType + { + get { return GenericParameterType.Method; } + } + + public virtual bool HasGenericParameters + { + get { return !Mixin.IsNullOrEmpty(generic_parameters); } + } + + public virtual Collection GenericParameters + { + get + { + if (generic_parameters != null) + return generic_parameters; + + return generic_parameters = new GenericParameterCollection(this); + } + } + + public TypeReference ReturnType + { + get + { + var return_type = MethodReturnType; + return return_type != null ? return_type.ReturnType : null; + } + set + { + var return_type = MethodReturnType; + if (return_type != null) + return_type.ReturnType = value; + } + } + + public virtual MethodReturnType MethodReturnType + { + get { return return_type; } + set { return_type = value; } + } + + public override string FullName + { + get + { + var builder = new StringBuilder(); + builder.Append(ReturnType.FullName) + .Append(" ") + .Append(MemberFullName()); + Mixin.MethodSignatureFullName(this, builder); + return builder.ToString(); + } + } + + public virtual bool IsGenericInstance + { + get { return false; } + } + + internal override bool ContainsGenericParameter + { + get + { + if (this.ReturnType.ContainsGenericParameter || base.ContainsGenericParameter) + return true; + + var parameters = this.Parameters; + + for (int i = 0; i < parameters.Count; i++) + if (parameters[i].ParameterType.ContainsGenericParameter) + return true; + + return false; + } + } + + internal MethodReference() + { + this.return_type = new MethodReturnType(this); + this.token = new MetadataToken(TokenType.MemberRef); + } + + public MethodReference(string name, TypeReference returnType) + : base(name) + { + if (returnType == null) + throw new ArgumentNullException("returnType"); + + this.return_type = new MethodReturnType(this); + this.return_type.ReturnType = returnType; + this.token = new MetadataToken(TokenType.MemberRef); + } + + public MethodReference(string name, TypeReference returnType, TypeReference declaringType) + : this(name, returnType) + { + if (declaringType == null) + throw new ArgumentNullException("declaringType"); + + this.DeclaringType = declaringType; + } + + public virtual MethodReference GetElementMethod() + { + return this; + } + + public virtual MethodDefinition Resolve() + { + var module = this.Module; + if (module == null) + throw new NotSupportedException(); + + return module.Resolve(this); + } + } + + static partial class Mixin + { + + public static bool IsVarArg(IMethodSignature self) + { + return (self.CallingConvention & MethodCallingConvention.VarArg) != 0; + } + + public static int GetSentinelPosition(IMethodSignature self) + { + if (!self.HasParameters) + return -1; + + var parameters = self.Parameters; + for (int i = 0; i < parameters.Count; i++) + if (parameters[i].ParameterType.IsSentinel) + return i; + + return -1; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReturnType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReturnType.cs new file mode 100644 index 00000000..0fab2f24 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodReturnType.cs @@ -0,0 +1,111 @@ +// +// MethodReturnType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Threading; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class MethodReturnType : IConstantProvider, ICustomAttributeProvider, IMarshalInfoProvider { + + internal IMethodSignature method; + internal ParameterDefinition parameter; + TypeReference return_type; + + public IMethodSignature Method { + get { return method; } + } + + public TypeReference ReturnType { + get { return return_type; } + set { return_type = value; } + } + + internal ParameterDefinition Parameter { + get { + if (parameter == null) + parameter=new ParameterDefinition (return_type, method); + + return parameter; + } + } + + public MetadataToken MetadataToken { + get { return Parameter.MetadataToken; } + set { Parameter.MetadataToken = value; } + } + + public ParameterAttributes Attributes { + get { return Parameter.Attributes; } + set { Parameter.Attributes = value; } + } + + public bool HasCustomAttributes { + get { return parameter != null && parameter.HasCustomAttributes; } + } + + public Collection CustomAttributes { + get { return Parameter.CustomAttributes; } + } + + public bool HasDefault { + get { return parameter != null && parameter.HasDefault; } + set { Parameter.HasDefault = value; } + } + + public bool HasConstant { + get { return parameter != null && parameter.HasConstant; } + set { Parameter.HasConstant = value; } + } + + public object Constant { + get { return Parameter.Constant; } + set { Parameter.Constant = value; } + } + + public bool HasFieldMarshal { + get { return parameter != null && parameter.HasFieldMarshal; } + set { Parameter.HasFieldMarshal = value; } + } + + public bool HasMarshalInfo { + get { return parameter != null && parameter.HasMarshalInfo; } + } + + public MarshalInfo MarshalInfo { + get { return Parameter.MarshalInfo; } + set { Parameter.MarshalInfo = value; } + } + + public MethodReturnType (IMethodSignature method) + { + this.method = method; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSemanticsAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSemanticsAttributes.cs new file mode 100644 index 00000000..dd0f4742 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSemanticsAttributes.cs @@ -0,0 +1,43 @@ +// +// MethodSemanticsattributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum MethodSemanticsAttributes : ushort { + None = 0x0000, + Setter = 0x0001, // Setter for property + Getter = 0x0002, // Getter for property + Other = 0x0004, // Other method for property or event + AddOn = 0x0008, // AddOn method for event + RemoveOn = 0x0010, // RemoveOn method for event + Fire = 0x0020 // Fire method for event + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSpecification.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSpecification.cs new file mode 100644 index 00000000..73b5c14a --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/MethodSpecification.cs @@ -0,0 +1,103 @@ +// +// MethodSpecification.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public abstract class MethodSpecification : MethodReference { + + readonly MethodReference method; + + public MethodReference ElementMethod { + get { return method; } + } + + public override string Name { + get { return method.Name; } + set { throw new InvalidOperationException (); } + } + + public override MethodCallingConvention CallingConvention { + get { return method.CallingConvention; } + set { throw new InvalidOperationException (); } + } + + public override bool HasThis { + get { return method.HasThis; } + set { throw new InvalidOperationException (); } + } + + public override bool ExplicitThis { + get { return method.ExplicitThis; } + set { throw new InvalidOperationException (); } + } + + public override MethodReturnType MethodReturnType { + get { return method.MethodReturnType; } + set { throw new InvalidOperationException (); } + } + + public override TypeReference DeclaringType { + get { return method.DeclaringType; } + set { throw new InvalidOperationException (); } + } + + public override ModuleDefinition Module { + get { return method.Module; } + } + + public override bool HasParameters { + get { return method.HasParameters; } + } + + public override Collection Parameters { + get { return method.Parameters; } + } + + internal override bool ContainsGenericParameter { + get { return method.ContainsGenericParameter; } + } + + internal MethodSpecification (MethodReference method) + { + if (method == null) + throw new ArgumentNullException ("method"); + + this.method = method; + this.token = new MetadataToken (TokenType.MethodSpec); + } + + public sealed override MethodReference GetElementMethod () + { + return method.GetElementMethod (); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Modifiers.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/Modifiers.cs new file mode 100644 index 00000000..ad31bc04 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/Modifiers.cs @@ -0,0 +1,137 @@ +// +// Modifiers.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public interface IModifierType { + TypeReference ModifierType { get; } + TypeReference ElementType { get; } + } + + public sealed class OptionalModifierType : TypeSpecification, IModifierType { + + TypeReference modifier_type; + + public TypeReference ModifierType { + get { return modifier_type; } + set { modifier_type = value; } + } + + public override string Name { + get { return base.Name + Suffix; } + } + + public override string FullName { + get { return base.FullName + Suffix; } + } + + string Suffix { + get { return " modopt(" + modifier_type + ")"; } + } + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsOptionalModifier { + get { return true; } + } + + internal override bool ContainsGenericParameter { + get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; } + } + + public OptionalModifierType (TypeReference modifierType, TypeReference type) + : base (type) + { + Mixin.CheckModifier (modifierType, type); + this.modifier_type = modifierType; + this.etype = MD.ElementType.CModOpt; + } + } + + public sealed class RequiredModifierType : TypeSpecification, IModifierType { + + TypeReference modifier_type; + + public TypeReference ModifierType { + get { return modifier_type; } + set { modifier_type = value; } + } + + public override string Name { + get { return base.Name + Suffix; } + } + + public override string FullName { + get { return base.FullName + Suffix; } + } + + string Suffix { + get { return " modreq(" + modifier_type + ")"; } + } + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsRequiredModifier { + get { return true; } + } + + internal override bool ContainsGenericParameter { + get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; } + } + + public RequiredModifierType (TypeReference modifierType, TypeReference type) + : base (type) + { + Mixin.CheckModifier (modifierType, type); + this.modifier_type = modifierType; + this.etype = MD.ElementType.CModReqD; + } + + } + + static partial class Mixin { + + public static void CheckModifier (TypeReference modifierType, TypeReference type) + { + if (modifierType == null) + throw new ArgumentNullException ("modifierType"); + if (type == null) + throw new ArgumentNullException ("type"); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleDefinition.cs new file mode 100644 index 00000000..979d8f9f --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleDefinition.cs @@ -0,0 +1,755 @@ +// +// ModuleDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using SR = System.Reflection; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public enum ReadingMode + { + Immediate = 1, + Deferred = 2, + } + + public sealed class ReaderParameters + { + + ReadingMode reading_mode; + IAssemblyResolver assembly_resolver; + IMetadataResolver metadata_resolver; + Stream symbol_stream; + ISymbolReaderProvider symbol_reader_provider; + bool read_symbols; + + public ReadingMode ReadingMode + { + get { return reading_mode; } + set { reading_mode = value; } + } + + public IAssemblyResolver AssemblyResolver + { + get { return assembly_resolver; } + set { assembly_resolver = value; } + } + + public IMetadataResolver MetadataResolver + { + get { return metadata_resolver; } + set { metadata_resolver = value; } + } + + public Stream SymbolStream + { + get { return symbol_stream; } + set { symbol_stream = value; } + } + + public ISymbolReaderProvider SymbolReaderProvider + { + get { return symbol_reader_provider; } + set { symbol_reader_provider = value; } + } + + public bool ReadSymbols + { + get { return read_symbols; } + set { read_symbols = value; } + } + + public ReaderParameters() + : this(ReadingMode.Deferred) + { + } + + public ReaderParameters(ReadingMode readingMode) + { + this.reading_mode = readingMode; + } + } + + + public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider + { + + internal Image Image; + internal MetadataSystem MetadataSystem; + internal ReadingMode ReadingMode; + internal ISymbolReaderProvider SymbolReaderProvider; + + internal ISymbolReader symbol_reader; + internal IAssemblyResolver assembly_resolver; + internal IMetadataResolver metadata_resolver; + internal TypeSystem type_system; + + readonly MetadataReader reader; + readonly string fq_name; + + internal ModuleKind kind; + TargetRuntime runtime; + TargetArchitecture architecture; + ModuleAttributes attributes; + ModuleCharacteristics characteristics; + Guid mvid; + + internal AssemblyDefinition assembly; + MethodDefinition entry_point; + + Collection custom_attributes; + Collection references; + Collection modules; + Collection resources; + Collection exported_types; + TypeDefinitionCollection types; + + public bool IsMain + { + get { return kind != ModuleKind.NetModule; } + } + + public ModuleKind Kind + { + get { return kind; } + set { kind = value; } + } + + public TargetRuntime Runtime + { + get { return runtime; } + set { runtime = value; } + } + + public TargetArchitecture Architecture + { + get { return architecture; } + set { architecture = value; } + } + + public ModuleAttributes Attributes + { + get { return attributes; } + set { attributes = value; } + } + + public ModuleCharacteristics Characteristics + { + get { return characteristics; } + set { characteristics = value; } + } + + public string FullyQualifiedName + { + get { return fq_name; } + } + + public Guid Mvid + { + get { return mvid; } + set { mvid = value; } + } + + internal bool HasImage + { + get { return Image != null; } + } + + public bool HasSymbols + { + get { return symbol_reader != null; } + } + + public ISymbolReader SymbolReader + { + get { return symbol_reader; } + } + + public override MetadataScopeType MetadataScopeType + { + get { return MetadataScopeType.ModuleDefinition; } + } + + public AssemblyDefinition Assembly + { + get { return assembly; } + } + + + public IAssemblyResolver AssemblyResolver + { + get { return assembly_resolver ?? (assembly_resolver = new DefaultAssemblyResolver()); } + } + + public IMetadataResolver MetadataResolver + { + get + { + if (metadata_resolver == null) + metadata_resolver=new MetadataResolver(this.AssemblyResolver); + + return metadata_resolver; + } + } + + public TypeSystem TypeSystem + { + get + { + if (type_system == null) + type_system = TypeSystem.CreateTypeSystem(this); + return type_system; + } + } + + public bool HasAssemblyReferences + { + get + { + if (references != null) + return references.Count > 0; + + return HasImage && Image.HasTable(Table.AssemblyRef); + } + } + + public Collection AssemblyReferences + { + get + { + if (references != null) + return references; + + if (HasImage) + return Read(ref references, this, (_, reader) => reader.ReadAssemblyReferences()); + + return references = new Collection(); + } + } + + public bool HasModuleReferences + { + get + { + if (modules != null) + return modules.Count > 0; + + return HasImage && Image.HasTable(Table.ModuleRef); + } + } + + public Collection ModuleReferences + { + get + { + if (modules != null) + return modules; + + if (HasImage) + return Read(ref modules, this, (_, reader) => reader.ReadModuleReferences()); + + return modules = new Collection(); + } + } + + public bool HasResources + { + get + { + if (resources != null) + return resources.Count > 0; + + if (HasImage) + return Image.HasTable(Table.ManifestResource) || Read(this, (_, reader) => reader.HasFileResource()); + + return false; + } + } + + public Collection Resources + { + get + { + if (resources != null) + return resources; + + if (HasImage) + return Read(ref resources, this, (_, reader) => reader.ReadResources()); + + return resources = new Collection(); + } + } + + public bool HasCustomAttributes + { + get + { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, this); + } + } + + public Collection CustomAttributes + { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, this)); } + } + + public bool HasTypes + { + get + { + if (types != null) + return types.Count > 0; + + return HasImage && Image.HasTable(Table.TypeDef); + } + } + + public Collection Types + { + get + { + if (types != null) + return types; + + if (HasImage) + return Read(ref types, this, (_, reader) => reader.ReadTypes()); + + return types = new TypeDefinitionCollection(this); + } + } + + public bool HasExportedTypes + { + get + { + if (exported_types != null) + return exported_types.Count > 0; + + return HasImage && Image.HasTable(Table.ExportedType); + } + } + + public Collection ExportedTypes + { + get + { + if (exported_types != null) + return exported_types; + + if (HasImage) + return Read(ref exported_types, this, (_, reader) => reader.ReadExportedTypes()); + + return exported_types = new Collection(); + } + } + + public MethodDefinition EntryPoint + { + get + { + if (entry_point != null) + return entry_point; + + if (HasImage) + return Read(ref entry_point, this, (_, reader) => reader.ReadEntryPoint()); + + return entry_point = null; + } + set { entry_point = value; } + } + + internal ModuleDefinition() + { + this.MetadataSystem = new MetadataSystem(); + this.token = new MetadataToken(TokenType.Module, 1); + } + + internal ModuleDefinition(Image image) + : this() + { + this.Image = image; + this.kind = image.Kind; + this.runtime = image.Runtime; + this.architecture = image.Architecture; + this.attributes = image.Attributes; + this.characteristics = image.Characteristics; + this.fq_name = image.FileName; + + this.reader = new MetadataReader(this); + } + + public bool HasTypeReference(string fullName) + { + return HasTypeReference(string.Empty, fullName); + } + + public bool HasTypeReference(string scope, string fullName) + { + CheckFullName(fullName); + + if (!HasImage) + return false; + + return GetTypeReference(scope, fullName) != null; + } + + public bool TryGetTypeReference(string fullName, out TypeReference type) + { + return TryGetTypeReference(string.Empty, fullName, out type); + } + + public bool TryGetTypeReference(string scope, string fullName, out TypeReference type) + { + CheckFullName(fullName); + + if (!HasImage) + { + type = null; + return false; + } + + return (type = GetTypeReference(scope, fullName)) != null; + } + + TypeReference GetTypeReference(string scope, string fullname) + { + return Read(new Row(scope, fullname), (row, reader) => reader.GetTypeReference(row.Col1, row.Col2)); + } + + public IEnumerable GetTypeReferences() + { + if (!HasImage) + return Empty.Array; + + return Read(this, (_, reader) => reader.GetTypeReferences()); + } + + public IEnumerable GetMemberReferences() + { + if (!HasImage) + return Empty.Array; + + return Read(this, (_, reader) => reader.GetMemberReferences()); + } + + public TypeReference GetType(string fullName, bool runtimeName) + { + return runtimeName + ? TypeParser.ParseType(this, fullName) + : GetType(fullName); + } + + public TypeDefinition GetType(string fullName) + { + CheckFullName(fullName); + + var position = fullName.IndexOf('/'); + if (position > 0) + return GetNestedType(fullName); + + return ((TypeDefinitionCollection)this.Types).GetType(fullName); + } + + public TypeDefinition GetType(string @namespace, string name) + { + Mixin.CheckName(name); + + return ((TypeDefinitionCollection)this.Types).GetType(@namespace ?? string.Empty, name); + } + + public IEnumerable GetTypes() + { + return GetTypes(Types); + } + + static IEnumerable GetTypes(Collection types) + { + for (int i = 0; i < types.Count; i++) + { + var type = types[i]; + + yield return type; + + if (!type.HasNestedTypes) + continue; + + foreach (var nested in GetTypes(type.NestedTypes)) + yield return nested; + } + } + + static void CheckFullName(string fullName) + { + if (fullName == null) + throw new ArgumentNullException("fullName"); + if (fullName.Length == 0) + throw new ArgumentException(); + } + + TypeDefinition GetNestedType(string fullname) + { + var names = fullname.Split('/'); + var type = GetType(names[0]); + + if (type == null) + return null; + + for (int i = 1; i < names.Length; i++) + { + var nested_type = Mixin.GetNestedType(type, names[i]); + if (nested_type == null) + return null; + + type = nested_type; + } + + return type; + } + + internal FieldDefinition Resolve(FieldReference field) + { + return MetadataResolver.Resolve(field); + } + + internal MethodDefinition Resolve(MethodReference method) + { + return MetadataResolver.Resolve(method); + } + + internal TypeDefinition Resolve(TypeReference type) + { + return MetadataResolver.Resolve(type); + } + + + public IMetadataTokenProvider LookupToken(int token) + { + return LookupToken(new MetadataToken((uint)token)); + } + + public IMetadataTokenProvider LookupToken(MetadataToken token) + { + return Read(token, (t, reader) => reader.LookupToken(t)); + } + + readonly object module_lock = new object(); + + internal object SyncRoot + { + get { return module_lock; } + } + + internal TRet Read(TItem item, Func read) + { + lock (module_lock) + { + var position = reader.position; + var context = reader.context; + + var ret = read(item, reader); + + reader.position = position; + reader.context = context; + + return ret; + } + } + + internal TRet Read(ref TRet variable, TItem item, Func read) where TRet : class + { + lock (module_lock) + { + if (variable != null) + return variable; + + var position = reader.position; + var context = reader.context; + + var ret = read(item, reader); + + reader.position = position; + reader.context = context; + + return variable = ret; + } + } + + public bool HasDebugHeader + { + get { return Image != null && !Image.Debug.IsZero; } + } + + public ImageDebugDirectory GetDebugHeader(out byte[] header) + { + if (!HasDebugHeader) + throw new InvalidOperationException(); + + return Image.GetDebugHeader(out header); + } + + void ProcessDebugHeader() + { + if (!HasDebugHeader) + return; + + byte[] header; + var directory = GetDebugHeader(out header); + + if (!symbol_reader.ProcessDebugHeader(directory, header)) + throw new InvalidOperationException(); + } + + + + public void ReadSymbols() + { + if (string.IsNullOrEmpty(fq_name)) + throw new InvalidOperationException(); + + var provider = SymbolProvider.GetPlatformReaderProvider(); + if (provider == null) + throw new InvalidOperationException(); + + ReadSymbols(provider.GetSymbolReader(this, fq_name)); + } + + public void ReadSymbols(ISymbolReader reader) + { + if (reader == null) + throw new ArgumentNullException("reader"); + + symbol_reader = reader; + + ProcessDebugHeader(); + } + + public static ModuleDefinition ReadModule(string fileName) + { + return ReadModule(fileName, new ReaderParameters(ReadingMode.Deferred)); + } + + public static ModuleDefinition ReadModule(Stream stream) + { + return ReadModule(stream, new ReaderParameters(ReadingMode.Deferred)); + } + + public static ModuleDefinition ReadModule(string fileName, ReaderParameters parameters) + { + using (var stream = GetFileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)) + { + return ReadModule(stream, parameters); + } + } + + static void CheckStream(object stream) + { + if (stream == null) + throw new ArgumentNullException("stream"); + } + + public static ModuleDefinition ReadModule(Stream stream, ReaderParameters parameters) + { + CheckStream(stream); + if (!stream.CanRead || !stream.CanSeek) + throw new ArgumentException(); + Mixin.CheckParameters(parameters); + + return ModuleReader.CreateModuleFrom( + ImageReader.ReadImageFrom(stream), + parameters); + } + + static Stream GetFileStream(string fileName, FileMode mode, FileAccess access, FileShare share) + { + if (fileName == null) + throw new ArgumentNullException("fileName"); + if (fileName.Length == 0) + throw new ArgumentException(); + + return new FileStream(fileName, mode, access, share); + } + + + + } + + static partial class Mixin + { + + public static void CheckParameters(object parameters) + { + if (parameters == null) + throw new ArgumentNullException("parameters"); + } + + public static bool HasImage(ModuleDefinition self) + { + return self != null && self.HasImage; + } + + public static bool IsCorlib(ModuleDefinition module) + { + if (module.Assembly == null) + return false; + + return module.Assembly.Name.Name == "mscorlib"; + } + + public static string GetFullyQualifiedName(Stream self) + { + + return string.Empty; + } + + public static TargetRuntime ParseRuntime(string self) + { + switch (self[1]) + { + case '1': + return self[3] == '0' + ? TargetRuntime.Net_1_0 + : TargetRuntime.Net_1_1; + case '2': + return TargetRuntime.Net_2_0; + case '4': + default: + return TargetRuntime.Net_4_0; + } + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleKind.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleKind.cs new file mode 100644 index 00000000..c29da887 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleKind.cs @@ -0,0 +1,64 @@ +// +// ModuleKind.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + public enum ModuleKind { + Dll, + Console, + Windows, + NetModule, + } + + public enum TargetArchitecture { + I386, + AMD64, + IA64, + ARMv7, + } + + [Flags] + public enum ModuleAttributes { + ILOnly = 1, + Required32Bit = 2, + StrongNameSigned = 8, + Preferred32Bit = 0x00020000, + } + + [Flags] + public enum ModuleCharacteristics { + HighEntropyVA = 0x0020, + DynamicBase = 0x0040, + NoSEH = 0x0400, + NXCompat = 0x0100, + AppContainer = 0x1000, + TerminalServerAware = 0x8000, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleReference.cs new file mode 100644 index 00000000..3934b3ce --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ModuleReference.cs @@ -0,0 +1,67 @@ +// +// ModuleReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public class ModuleReference : IMetadataScope { + + string name; + + internal MetadataToken token; + + public string Name { + get { return name; } + set { name = value; } + } + + public virtual MetadataScopeType MetadataScopeType { + get { return MetadataScopeType.ModuleReference; } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal ModuleReference () + { + this.token = new MetadataToken (TokenType.ModuleRef); + } + + public ModuleReference (string name) + : this () + { + this.name = name; + } + + public override string ToString () + { + return name; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/NativeType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/NativeType.cs new file mode 100644 index 00000000..88da9805 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/NativeType.cs @@ -0,0 +1,73 @@ +// +// NativeType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public enum NativeType { + None = 0x66, + + Boolean = 0x02, + I1 = 0x03, + U1 = 0x04, + I2 = 0x05, + U2 = 0x06, + I4 = 0x07, + U4 = 0x08, + I8 = 0x09, + U8 = 0x0a, + R4 = 0x0b, + R8 = 0x0c, + LPStr = 0x14, + Int = 0x1f, + UInt = 0x20, + Func = 0x26, + Array = 0x2a, + + // Msft specific + Currency = 0x0f, + BStr = 0x13, + LPWStr = 0x15, + LPTStr = 0x16, + FixedSysString = 0x17, + IUnknown = 0x19, + IDispatch = 0x1a, + Struct = 0x1b, + IntF = 0x1c, + SafeArray = 0x1d, + FixedArray = 0x1e, + ByValStr = 0x22, + ANSIBStr = 0x23, + TBStr = 0x24, + VariantBool = 0x25, + ASAny = 0x28, + LPStruct = 0x2b, + CustomMarshaler = 0x2c, + Error = 0x2d, + Max = 0x50 + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeAttributes.cs new file mode 100644 index 00000000..bb368382 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeAttributes.cs @@ -0,0 +1,62 @@ +// +// PInvokeAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum PInvokeAttributes : ushort { + NoMangle = 0x0001, // PInvoke is to use the member name as specified + + // Character set + CharSetMask = 0x0006, + CharSetNotSpec = 0x0000, + CharSetAnsi = 0x0002, + CharSetUnicode = 0x0004, + CharSetAuto = 0x0006, + + SupportsLastError = 0x0040, // Information about target function. Not relevant for fields + + // Calling convetion + CallConvMask = 0x0700, + CallConvWinapi = 0x0100, + CallConvCdecl = 0x0200, + CallConvStdCall = 0x0300, + CallConvThiscall = 0x0400, + CallConvFastcall = 0x0500, + + BestFitMask = 0x0030, + BestFitEnabled = 0x0010, + BestFitDisabled = 0x0020, + + ThrowOnUnmappableCharMask = 0x3000, + ThrowOnUnmappableCharEnabled = 0x1000, + ThrowOnUnmappableCharDisabled = 0x2000, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeInfo.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeInfo.cs new file mode 100644 index 00000000..9babf103 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PInvokeInfo.cs @@ -0,0 +1,138 @@ +// +// PInvokeInfo.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public sealed class PInvokeInfo { + + ushort attributes; + string entry_point; + ModuleReference module; + + public PInvokeAttributes Attributes { + get { return (PInvokeAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public string EntryPoint { + get { return entry_point; } + set { entry_point = value; } + } + + public ModuleReference Module { + get { return module; } + set { module = value; } + } + + #region PInvokeAttributes + + public bool IsNoMangle { + get { return Mixin.GetAttributes(attributes,(ushort) PInvokeAttributes.NoMangle); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) PInvokeAttributes.NoMangle, value); } + } + + public bool IsCharSetNotSpec { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec, value); } + } + + public bool IsCharSetAnsi { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi, value); } + } + + public bool IsCharSetUnicode { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode, value); } + } + + public bool IsCharSetAuto { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto, value); } + } + + public bool SupportsLastError { + get { return Mixin.GetAttributes(attributes,(ushort) PInvokeAttributes.SupportsLastError); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) PInvokeAttributes.SupportsLastError, value); } + } + + public bool IsCallConvWinapi { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi, value); } + } + + public bool IsCallConvCdecl { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl, value); } + } + + public bool IsCallConvStdCall { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall, value); } + } + + public bool IsCallConvThiscall { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall, value); } + } + + public bool IsCallConvFastcall { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall, value); } + } + + public bool IsBestFitEnabled { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled, value); } + } + + public bool IsBestFitDisabled { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled, value); } + } + + public bool IsThrowOnUnmappableCharEnabled { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled, value); } + } + + public bool IsThrowOnUnmappableCharDisabled { + get { return Mixin.GetMaskedAttributes(attributes,(ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled, value); } + } + + #endregion + + public PInvokeInfo (PInvokeAttributes attributes, string entryPoint, ModuleReference module) + { + this.attributes = (ushort) attributes; + this.entry_point = entryPoint; + this.module = module; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterAttributes.cs new file mode 100644 index 00000000..e0bc825d --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterAttributes.cs @@ -0,0 +1,45 @@ +// +// ParameterAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum ParameterAttributes : ushort { + None = 0x0000, + In = 0x0001, // Param is [In] + Out = 0x0002, // Param is [Out] + Lcid = 0x0004, + Retval = 0x0008, + Optional = 0x0010, // Param is optional + HasDefault = 0x1000, // Param has default value + HasFieldMarshal = 0x2000, // Param has field marshal + Unused = 0xcfe0 // Reserved: shall be zero in a conforming implementation + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinition.cs new file mode 100644 index 00000000..3a6b3a8d --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinition.cs @@ -0,0 +1,186 @@ +// +// ParameterDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public sealed class ParameterDefinition : ParameterReference, ICustomAttributeProvider, IConstantProvider, IMarshalInfoProvider + { + + ushort attributes; + + internal IMethodSignature method; + + object constant = Mixin.NotResolved; + Collection custom_attributes; + MarshalInfo marshal_info; + + public ParameterAttributes Attributes + { + get { return (ParameterAttributes)attributes; } + set { attributes = (ushort)value; } + } + + public IMethodSignature Method + { + get { return method; } + } + + public int Sequence + { + get + { + if (method == null) + return -1; + + return Mixin.HasImplicitThis(method) ? index + 1 : index; + } + } + + public bool HasConstant + { + get + { + Mixin.ResolveConstant(this, ref constant, parameter_type.Module); + + return constant != Mixin.NoValue; + } + set { if (!value) constant = Mixin.NoValue; } + } + + public object Constant + { + get { return HasConstant ? constant : null; } + set { constant = value; } + } + + public bool HasCustomAttributes + { + get + { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, parameter_type.Module); + } + } + + public Collection CustomAttributes + { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, parameter_type.Module)); } + } + + public bool HasMarshalInfo + { + get + { + if (marshal_info != null) + return true; + + return Mixin.GetHasMarshalInfo(this, parameter_type.Module); + } + } + + public MarshalInfo MarshalInfo + { + get { return marshal_info ?? (Mixin.GetMarshalInfo(this, ref marshal_info, parameter_type.Module)); } + set { marshal_info = value; } + } + + #region ParameterAttributes + + public bool IsIn + { + get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.In); } + set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.In, value); } + } + + public bool IsOut + { + get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.Out); } + set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.Out, value); } + } + + public bool IsLcid + { + get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.Lcid); } + set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.Lcid, value); } + } + + public bool IsReturnValue + { + get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.Retval); } + set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.Retval, value); } + } + + public bool IsOptional + { + get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.Optional); } + set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.Optional, value); } + } + + public bool HasDefault + { + get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.HasDefault); } + set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.HasDefault, value); } + } + + public bool HasFieldMarshal + { + get { return Mixin.GetAttributes(attributes, (ushort)ParameterAttributes.HasFieldMarshal); } + set { attributes = Mixin.SetAttributes(attributes, (ushort)ParameterAttributes.HasFieldMarshal, value); } + } + + #endregion + + internal ParameterDefinition(TypeReference parameterType, IMethodSignature method) + : this(string.Empty, ParameterAttributes.None, parameterType) + { + this.method = method; + } + + public ParameterDefinition(TypeReference parameterType) + : this(string.Empty, ParameterAttributes.None, parameterType) + { + } + + public ParameterDefinition(string name, ParameterAttributes attributes, TypeReference parameterType) + : base(name, parameterType) + { + this.attributes = (ushort)attributes; + this.token = new MetadataToken(TokenType.Param); + } + + public override ParameterDefinition Resolve() + { + return this; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinitionCollection.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinitionCollection.cs new file mode 100644 index 00000000..bd8b1c13 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterDefinitionCollection.cs @@ -0,0 +1,80 @@ +// +// ParameterDefinitionCollection.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + sealed class ParameterDefinitionCollection : Collection { + + readonly IMethodSignature method; + + internal ParameterDefinitionCollection (IMethodSignature method) + { + this.method = method; + } + + internal ParameterDefinitionCollection (IMethodSignature method, int capacity) + : base (capacity) + { + this.method = method; + } + + protected override void OnAdd (ParameterDefinition item, int index) + { + item.method = method; + item.index = index; + } + + protected override void OnInsert (ParameterDefinition item, int index) + { + item.method = method; + item.index = index; + + for (int i = index; i < size; i++) + items [i].index = i + 1; + } + + protected override void OnSet (ParameterDefinition item, int index) + { + item.method = method; + item.index = index; + } + + protected override void OnRemove (ParameterDefinition item, int index) + { + item.method = null; + item.index = -1; + + for (int i = index + 1; i < size; i++) + items [i].index = i - 1; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterReference.cs new file mode 100644 index 00000000..46b057cd --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ParameterReference.cs @@ -0,0 +1,75 @@ +// +// ParameterReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + public abstract class ParameterReference : IMetadataTokenProvider { + + string name; + internal int index = -1; + protected TypeReference parameter_type; + internal MetadataToken token; + + public string Name { + get { return name; } + set { name = value; } + } + + public int Index { + get { return index; } + } + + public TypeReference ParameterType { + get { return parameter_type; } + set { parameter_type = value; } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal ParameterReference (string name, TypeReference parameterType) + { + if (parameterType == null) + throw new ArgumentNullException ("parameterType"); + + this.name = name ?? string.Empty; + this.parameter_type = parameterType; + } + + public override string ToString () + { + return name; + } + + public abstract ParameterDefinition Resolve (); + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PinnedType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PinnedType.cs new file mode 100644 index 00000000..ff59cfb7 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PinnedType.cs @@ -0,0 +1,53 @@ +// +// PinnedType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class PinnedType : TypeSpecification { + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsPinned { + get { return true; } + } + + public PinnedType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.Pinned; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PointerType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PointerType.cs new file mode 100644 index 00000000..a142e144 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PointerType.cs @@ -0,0 +1,61 @@ +// +// PointerType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class PointerType : TypeSpecification { + + public override string Name { + get { return base.Name + "*"; } + } + + public override string FullName { + get { return base.FullName + "*"; } + } + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsPointer { + get { return true; } + } + + public PointerType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.Ptr; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyAttributes.cs new file mode 100644 index 00000000..1be0413f --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyAttributes.cs @@ -0,0 +1,41 @@ +// +// PropertyAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum PropertyAttributes : ushort { + None = 0x0000, + SpecialName = 0x0200, // Property is special + RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding + HasDefault = 0x1000, // Property has default + Unused = 0xe9ff // Reserved: shall be zero in a conforming implementation + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyDefinition.cs new file mode 100644 index 00000000..7435ab49 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyDefinition.cs @@ -0,0 +1,259 @@ +// +// PropertyDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Text; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class PropertyDefinition : PropertyReference, IMemberDefinition, IConstantProvider { + + bool? has_this; + ushort attributes; + + Collection custom_attributes; + + internal MethodDefinition get_method; + internal MethodDefinition set_method; + internal Collection other_methods; + + object constant = Mixin.NotResolved; + + public PropertyAttributes Attributes { + get { return (PropertyAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public bool HasThis { + get { + if (has_this.HasValue) + return has_this.Value; + + if (GetMethod != null) + return get_method.HasThis; + + if (SetMethod != null) + return set_method.HasThis; + + return false; + } + set { has_this = value; } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + } + + public MethodDefinition GetMethod { + get { + if (get_method != null) + return get_method; + + InitializeMethods (); + return get_method; + } + set { get_method = value; } + } + + public MethodDefinition SetMethod { + get { + if (set_method != null) + return set_method; + + InitializeMethods (); + return set_method; + } + set { set_method = value; } + } + + public bool HasOtherMethods { + get { + if (other_methods != null) + return other_methods.Count > 0; + + InitializeMethods (); + return !Mixin.IsNullOrEmpty (other_methods); + } + } + + public Collection OtherMethods { + get { + if (other_methods != null) + return other_methods; + + InitializeMethods (); + + if (other_methods != null) + return other_methods; + + return other_methods = new Collection (); + } + } + + public bool HasParameters { + get { + InitializeMethods (); + + if (get_method != null) + return get_method.HasParameters; + + if (set_method != null) + return set_method.HasParameters && set_method.Parameters.Count > 1; + + return false; + } + } + + public override Collection Parameters { + get { + InitializeMethods (); + + if (get_method != null) + return MirrorParameters (get_method, 0); + + if (set_method != null) + return MirrorParameters (set_method, 1); + + return new Collection (); + } + } + + static Collection MirrorParameters (MethodDefinition method, int bound) + { + var parameters = new Collection (); + if (!method.HasParameters) + return parameters; + + var original_parameters = method.Parameters; + var end = original_parameters.Count - bound; + + for (int i = 0; i < end; i++) + parameters.Add (original_parameters [i]); + + return parameters; + } + + public bool HasConstant { + get { + Mixin.ResolveConstant(this, ref constant, Module); + + return constant != Mixin.NoValue; + } + set { if (!value) constant = Mixin.NoValue; } + } + + public object Constant { + get { return HasConstant ? constant : null; } + set { constant = value; } + } + + #region PropertyAttributes + + public bool IsSpecialName { + get { return Mixin.GetAttributes(attributes,(ushort) PropertyAttributes.SpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) PropertyAttributes.SpecialName, value); } + } + + public bool IsRuntimeSpecialName { + get { return Mixin.GetAttributes(attributes,(ushort) PropertyAttributes.RTSpecialName); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) PropertyAttributes.RTSpecialName, value); } + } + + public bool HasDefault { + get { return Mixin.GetAttributes(attributes,(ushort) PropertyAttributes.HasDefault); } + set { attributes =Mixin.SetAttributes(attributes,(ushort) PropertyAttributes.HasDefault, value); } + } + + #endregion + + public new TypeDefinition DeclaringType { + get { return (TypeDefinition) base.DeclaringType; } + set { base.DeclaringType = value; } + } + + public override bool IsDefinition { + get { return true; } + } + + public override string FullName { + get { + var builder = new StringBuilder (); + builder.Append (PropertyType.ToString ()); + builder.Append (' '); + builder.Append (MemberFullName ()); + builder.Append ('('); + if (HasParameters) { + var parameters = Parameters; + for (int i = 0; i < parameters.Count; i++) { + if (i > 0) + builder.Append (','); + builder.Append (parameters [i].ParameterType.FullName); + } + } + builder.Append (')'); + return builder.ToString (); + } + } + + public PropertyDefinition (string name, PropertyAttributes attributes, TypeReference propertyType) + : base (name, propertyType) + { + this.attributes = (ushort) attributes; + this.token = new MetadataToken (TokenType.Property); + } + + void InitializeMethods () + { + var module = this.Module; + lock (module.SyncRoot) { + if (get_method != null || set_method != null) + return; + + if (!Mixin.HasImage(module)) + return; + + module.Read (this, (property, reader) => reader.ReadMethods (property)); + } + } + + public override PropertyDefinition Resolve () + { + return this; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyReference.cs new file mode 100644 index 00000000..0dcfc952 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/PropertyReference.cs @@ -0,0 +1,59 @@ +// +// PropertyReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public abstract class PropertyReference : MemberReference { + + TypeReference property_type; + + public TypeReference PropertyType { + get { return property_type; } + set { property_type = value; } + } + + public abstract Collection Parameters { + get; + } + + internal PropertyReference (string name, TypeReference propertyType) + : base (name) + { + if (propertyType == null) + throw new ArgumentNullException ("propertyType"); + + property_type = propertyType; + } + + public abstract PropertyDefinition Resolve (); + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/ReferenceType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ReferenceType.cs new file mode 100644 index 00000000..7940c617 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/ReferenceType.cs @@ -0,0 +1,61 @@ +// +// ByReferenceType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class ByReferenceType : TypeSpecification { + + public override string Name { + get { return base.Name + "&"; } + } + + public override string FullName { + get { return base.FullName + "&"; } + } + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsByReference { + get { return true; } + } + + public ByReferenceType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.ByRef; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/Resource.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/Resource.cs new file mode 100644 index 00000000..94b3e156 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/Resource.cs @@ -0,0 +1,76 @@ +// +// ResourceType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public enum ResourceType { + Linked, + Embedded, + AssemblyLinked, + } + + public abstract class Resource { + + string name; + uint attributes; + + public string Name { + get { return name; } + set { name = value; } + } + + public ManifestResourceAttributes Attributes { + get { return (ManifestResourceAttributes) attributes; } + set { attributes = (uint) value; } + } + + public abstract ResourceType ResourceType { + get; + } + + #region ManifestResourceAttributes + + public bool IsPublic { + get { return Mixin.GetMaskedAttributes(attributes,(uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public, value); } + } + + public bool IsPrivate { + get { return Mixin.GetMaskedAttributes(attributes,(uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private); } + set { attributes = Mixin.SetMaskedAttributes(attributes,(uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private, value); } + } + + #endregion + + internal Resource (string name, ManifestResourceAttributes attributes) + { + this.name = name; + this.attributes = (uint) attributes; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/SecurityDeclaration.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/SecurityDeclaration.cs new file mode 100644 index 00000000..1a23403e --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/SecurityDeclaration.cs @@ -0,0 +1,210 @@ +// +// SecurityDeclaration.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Threading; +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public enum SecurityAction : ushort + { + Request = 1, + Demand = 2, + Assert = 3, + Deny = 4, + PermitOnly = 5, + LinkDemand = 6, + InheritDemand = 7, + RequestMinimum = 8, + RequestOptional = 9, + RequestRefuse = 10, + PreJitGrant = 11, + PreJitDeny = 12, + NonCasDemand = 13, + NonCasLinkDemand = 14, + NonCasInheritance = 15 + } + + public interface ISecurityDeclarationProvider : IMetadataTokenProvider + { + + bool HasSecurityDeclarations { get; } + Collection SecurityDeclarations { get; } + } + + public sealed class SecurityAttribute : ICustomAttribute + { + + TypeReference attribute_type; + + internal Collection fields; + internal Collection properties; + + public TypeReference AttributeType + { + get { return attribute_type; } + set { attribute_type = value; } + } + + public bool HasFields + { + get { return !Mixin.IsNullOrEmpty(fields); } + } + + public Collection Fields + { + get { return fields ?? (fields = new Collection()); } + } + + public bool HasProperties + { + get { return !Mixin.IsNullOrEmpty(properties); } + } + + public Collection Properties + { + get { return properties ?? (properties = new Collection()); } + } + + public SecurityAttribute(TypeReference attributeType) + { + this.attribute_type = attributeType; + } + } + + public sealed class SecurityDeclaration + { + + readonly internal uint signature; + byte[] blob; + readonly ModuleDefinition module; + + internal bool resolved; + SecurityAction action; + internal Collection security_attributes; + + public SecurityAction Action + { + get { return action; } + set { action = value; } + } + + public bool HasSecurityAttributes + { + get + { + Resolve(); + + return !Mixin.IsNullOrEmpty(security_attributes); + } + } + + public Collection SecurityAttributes + { + get + { + Resolve(); + + return security_attributes ?? (security_attributes = new Collection()); + } + } + + internal bool HasImage + { + get { return module != null && module.HasImage; } + } + + internal SecurityDeclaration(SecurityAction action, uint signature, ModuleDefinition module) + { + this.action = action; + this.signature = signature; + this.module = module; + } + + public SecurityDeclaration(SecurityAction action) + { + this.action = action; + this.resolved = true; + } + + public SecurityDeclaration(SecurityAction action, byte[] blob) + { + this.action = action; + this.resolved = false; + this.blob = blob; + } + + public byte[] GetBlob() + { + if (blob != null) + return blob; + + if (!HasImage || signature == 0) + throw new NotSupportedException(); + + return blob = module.Read(this, (declaration, reader) => reader.ReadSecurityDeclarationBlob(declaration.signature)); + } + + void Resolve() + { + if (resolved || !HasImage) + return; + + module.Read(this, (declaration, reader) => + { + reader.ReadSecurityDeclarationSignature(declaration); + return this; + }); + + resolved = true; + } + } + + static partial class Mixin + { + + public static bool GetHasSecurityDeclarations( + ISecurityDeclarationProvider self, + ModuleDefinition module) + { + return Mixin.HasImage(module) && module.Read(self, (provider, reader) => reader.HasSecurityDeclarations(provider)); + } + + public static Collection GetSecurityDeclarations( + ISecurityDeclarationProvider self, + ref Collection variable, + ModuleDefinition module) + { + return Mixin.HasImage(module) + ? module.Read(ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations(provider)) + : variable = new Collection(); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/SentinelType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/SentinelType.cs new file mode 100644 index 00000000..664d75bf --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/SentinelType.cs @@ -0,0 +1,53 @@ +// +// SentinelType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using MD = Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public sealed class SentinelType : TypeSpecification { + + public override bool IsValueType { + get { return false; } + set { throw new InvalidOperationException (); } + } + + public override bool IsSentinel { + get { return true; } + } + + public SentinelType (TypeReference type) + : base (type) + { + Mixin.CheckType (type); + this.etype = MD.ElementType.Sentinel; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TargetRuntime.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TargetRuntime.cs new file mode 100644 index 00000000..9b49a5f7 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TargetRuntime.cs @@ -0,0 +1,37 @@ +// +// TargetRuntime.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public enum TargetRuntime { + Net_1_0, + Net_1_1, + Net_2_0, + Net_4_0, + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeAttributes.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeAttributes.cs new file mode 100644 index 00000000..86fbc4db --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeAttributes.cs @@ -0,0 +1,81 @@ +// +// TypeAttributes.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + public enum TypeAttributes : uint { + // Visibility attributes + VisibilityMask = 0x00000007, // Use this mask to retrieve visibility information + NotPublic = 0x00000000, // Class has no public scope + Public = 0x00000001, // Class has public scope + NestedPublic = 0x00000002, // Class is nested with public visibility + NestedPrivate = 0x00000003, // Class is nested with private visibility + NestedFamily = 0x00000004, // Class is nested with family visibility + NestedAssembly = 0x00000005, // Class is nested with assembly visibility + NestedFamANDAssem = 0x00000006, // Class is nested with family and assembly visibility + NestedFamORAssem = 0x00000007, // Class is nested with family or assembly visibility + + // Class layout attributes + LayoutMask = 0x00000018, // Use this mask to retrieve class layout information + AutoLayout = 0x00000000, // Class fields are auto-laid out + SequentialLayout = 0x00000008, // Class fields are laid out sequentially + ExplicitLayout = 0x00000010, // Layout is supplied explicitly + + // Class semantics attributes + ClassSemanticMask = 0x00000020, // Use this mask to retrieve class semantics information + Class = 0x00000000, // Type is a class + Interface = 0x00000020, // Type is an interface + + // Special semantics in addition to class semantics + Abstract = 0x00000080, // Class is abstract + Sealed = 0x00000100, // Class cannot be extended + SpecialName = 0x00000400, // Class name is special + + // Implementation attributes + Import = 0x00001000, // Class/Interface is imported + Serializable = 0x00002000, // Class is serializable + WindowsRuntime = 0x00004000, // Windows Runtime type + + // String formatting attributes + StringFormatMask = 0x00030000, // Use this mask to retrieve string information for native interop + AnsiClass = 0x00000000, // LPSTR is interpreted as ANSI + UnicodeClass = 0x00010000, // LPSTR is interpreted as Unicode + AutoClass = 0x00020000, // LPSTR is interpreted automatically + + // Class initialization attributes + BeforeFieldInit = 0x00100000, // Initialize the class before first static field access + + // Additional flags + RTSpecialName = 0x00000800, // CLI provides 'special' behavior, depending upon the name of the Type + HasSecurity = 0x00040000, // Type has security associate with it + Forwarder = 0x00200000, // Exported type is a type forwarder + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinition.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinition.cs new file mode 100644 index 00000000..a71b3571 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinition.cs @@ -0,0 +1,599 @@ +// +// TypeDefinition.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public sealed class TypeDefinition : TypeReference, IMemberDefinition, ISecurityDeclarationProvider + { + + uint attributes; + TypeReference base_type; + internal Range fields_range; + internal Range methods_range; + + short packing_size = Mixin.NotResolvedMarker; + int class_size = Mixin.NotResolvedMarker; + + Collection interfaces; + Collection nested_types; + Collection methods; + Collection fields; + Collection events; + Collection properties; + Collection custom_attributes; + Collection security_declarations; + + public TypeAttributes Attributes + { + get { return (TypeAttributes)attributes; } + set { attributes = (uint)value; } + } + + public TypeReference BaseType + { + get { return base_type; } + set { base_type = value; } + } + + void ResolveLayout() + { + if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker) + return; + + if (!HasImage) + { + packing_size = Mixin.NoDataMarker; + class_size = Mixin.NoDataMarker; + return; + } + + var row = Module.Read(this, (type, reader) => reader.ReadTypeLayout(type)); + + packing_size = row.Col1; + class_size = row.Col2; + } + + public bool HasLayoutInfo + { + get + { + if (packing_size >= 0 || class_size >= 0) + return true; + + ResolveLayout(); + + return packing_size >= 0 || class_size >= 0; + } + } + + public short PackingSize + { + get + { + if (packing_size >= 0) + return packing_size; + + ResolveLayout(); + + return packing_size >= 0 ? packing_size : (short)-1; + } + set { packing_size = value; } + } + + public int ClassSize + { + get + { + if (class_size >= 0) + return class_size; + + ResolveLayout(); + + return class_size >= 0 ? class_size : -1; + } + set { class_size = value; } + } + + public bool HasInterfaces + { + get + { + if (interfaces != null) + return interfaces.Count > 0; + + if (HasImage) + return Module.Read(this, (type, reader) => reader.HasInterfaces(type)); + + return false; + } + } + + public Collection Interfaces + { + get + { + if (interfaces != null) + return interfaces; + + if (HasImage) + return Module.Read(ref interfaces, this, (type, reader) => reader.ReadInterfaces(type)); + + return interfaces = new Collection(); + } + } + + public bool HasNestedTypes + { + get + { + if (nested_types != null) + return nested_types.Count > 0; + + if (HasImage) + return Module.Read(this, (type, reader) => reader.HasNestedTypes(type)); + + return false; + } + } + + public Collection NestedTypes + { + get + { + if (nested_types != null) + return nested_types; + + if (HasImage) + return Module.Read(ref nested_types, this, (type, reader) => reader.ReadNestedTypes(type)); + + return nested_types = new MemberDefinitionCollection(this); + } + } + + public bool HasMethods + { + get + { + if (methods != null) + return methods.Count > 0; + + if (HasImage) + return methods_range.Length > 0; + + return false; + } + } + + public Collection Methods + { + get + { + if (methods != null) + return methods; + + if (HasImage) + return Module.Read(ref methods, this, (type, reader) => reader.ReadMethods(type)); + + return methods = new MemberDefinitionCollection(this); + } + } + + public bool HasFields + { + get + { + if (fields != null) + return fields.Count > 0; + + if (HasImage) + return fields_range.Length > 0; + + return false; + } + } + + public Collection Fields + { + get + { + if (fields != null) + return fields; + + if (HasImage) + return Module.Read(ref fields, this, (type, reader) => reader.ReadFields(type)); + + return fields = new MemberDefinitionCollection(this); + } + } + + public bool HasEvents + { + get + { + if (events != null) + return events.Count > 0; + + if (HasImage) + return Module.Read(this, (type, reader) => reader.HasEvents(type)); + + return false; + } + } + + public Collection Events + { + get + { + if (events != null) + return events; + + if (HasImage) + return Module.Read(ref events, this, (type, reader) => reader.ReadEvents(type)); + + return events = new MemberDefinitionCollection(this); + } + } + + public bool HasProperties + { + get + { + if (properties != null) + return properties.Count > 0; + + if (HasImage) + return Module.Read(this, (type, reader) => reader.HasProperties(type)); + + return false; + } + } + + public Collection Properties + { + get + { + if (properties != null) + return properties; + + if (HasImage) + return Module.Read(ref properties, this, (type, reader) => reader.ReadProperties(type)); + + return properties = new MemberDefinitionCollection(this); + } + } + + public bool HasSecurityDeclarations + { + get + { + if (security_declarations != null) + return security_declarations.Count > 0; + + return Mixin.GetHasSecurityDeclarations(this, Module); + } + } + + public Collection SecurityDeclarations + { + get { return security_declarations ?? (Mixin.GetSecurityDeclarations(this, ref security_declarations, Module)); } + } + + public bool HasCustomAttributes + { + get + { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return Mixin.GetHasCustomAttributes(this, Module); + } + } + + public Collection CustomAttributes + { + get { return custom_attributes ?? (Mixin.GetCustomAttributes(this, ref custom_attributes, Module)); } + } + + public override bool HasGenericParameters + { + get + { + if (generic_parameters != null) + return generic_parameters.Count > 0; + + return Mixin.GetHasGenericParameters(this, Module); + } + } + + public override Collection GenericParameters + { + get { return generic_parameters ?? (Mixin.GetGenericParameters(this,ref generic_parameters, Module)); } + } + + #region TypeAttributes + + public bool IsNotPublic + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NotPublic); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NotPublic, value); } + } + + public bool IsPublic + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.Public); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.Public, value); } + } + + public bool IsNestedPublic + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedPublic); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedPublic, value); } + } + + public bool IsNestedPrivate + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedPrivate); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedPrivate, value); } + } + + public bool IsNestedFamily + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamily); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamily, value); } + } + + public bool IsNestedAssembly + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedAssembly); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedAssembly, value); } + } + + public bool IsNestedFamilyAndAssembly + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamANDAssem); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamANDAssem, value); } + } + + public bool IsNestedFamilyOrAssembly + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamORAssem); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.VisibilityMask, (uint)TypeAttributes.NestedFamORAssem, value); } + } + + public bool IsAutoLayout + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.AutoLayout); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.AutoLayout, value); } + } + + public bool IsSequentialLayout + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.SequentialLayout); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.SequentialLayout, value); } + } + + public bool IsExplicitLayout + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.ExplicitLayout); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.LayoutMask, (uint)TypeAttributes.ExplicitLayout, value); } + } + + public bool IsClass + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.ClassSemanticMask, (uint)TypeAttributes.Class); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.ClassSemanticMask, (uint)TypeAttributes.Class, value); } + } + + public bool IsInterface + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.ClassSemanticMask, (uint)TypeAttributes.Interface); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.ClassSemanticMask, (uint)TypeAttributes.Interface, value); } + } + + public bool IsAbstract + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.Abstract); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.Abstract, value); } + } + + public bool IsSealed + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.Sealed); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.Sealed, value); } + } + + public bool IsSpecialName + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.SpecialName); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.SpecialName, value); } + } + + public bool IsImport + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.Import); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.Import, value); } + } + + public bool IsSerializable + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.Serializable); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.Serializable, value); } + } + + public bool IsWindowsRuntime + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.WindowsRuntime); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.WindowsRuntime, value); } + } + + public bool IsAnsiClass + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.AnsiClass); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.AnsiClass, value); } + } + + public bool IsUnicodeClass + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.UnicodeClass); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.UnicodeClass, value); } + } + + public bool IsAutoClass + { + get { return Mixin.GetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.AutoClass); } + set { attributes = Mixin.SetMaskedAttributes(attributes, (uint)TypeAttributes.StringFormatMask, (uint)TypeAttributes.AutoClass, value); } + } + + public bool IsBeforeFieldInit + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.BeforeFieldInit); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.BeforeFieldInit, value); } + } + + public bool IsRuntimeSpecialName + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.RTSpecialName); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.RTSpecialName, value); } + } + + public bool HasSecurity + { + get { return Mixin.GetAttributes(attributes, (uint)TypeAttributes.HasSecurity); } + set { attributes = Mixin.SetAttributes(attributes, (uint)TypeAttributes.HasSecurity, value); } + } + + #endregion + + public bool IsEnum + { + get { return base_type != null && Mixin.IsTypeOf(base_type, "System", "Enum"); } + } + + public override bool IsValueType + { + get + { + if (base_type == null) + return false; + + return Mixin.IsTypeOf(base_type, "System", "Enum") || (Mixin.IsTypeOf(base_type, "System", "ValueType") && !Mixin.IsTypeOf(this, "System", "Enum")); + } + } + + public override bool IsPrimitive + { + get + { + ElementType primitive_etype; + return MetadataSystem.TryGetPrimitiveElementType(this, out primitive_etype); + } + } + + public override MetadataType MetadataType + { + get + { + ElementType primitive_etype; + if (MetadataSystem.TryGetPrimitiveElementType(this, out primitive_etype)) + return (MetadataType)primitive_etype; + + return base.MetadataType; + } + } + + public override bool IsDefinition + { + get { return true; } + } + + public new TypeDefinition DeclaringType + { + get { return (TypeDefinition)base.DeclaringType; } + set { base.DeclaringType = value; } + } + + public TypeDefinition(string @namespace, string name, TypeAttributes attributes) + : base(@namespace, name) + { + this.attributes = (uint)attributes; + this.token = new MetadataToken(TokenType.TypeDef); + } + + public TypeDefinition(string @namespace, string name, TypeAttributes attributes, TypeReference baseType) : + this(@namespace, name, attributes) + { + this.BaseType = baseType; + } + + public override TypeDefinition Resolve() + { + return this; + } + } + + static partial class Mixin + { + + public static TypeReference GetEnumUnderlyingType(TypeDefinition self) + { + var fields = self.Fields; + + for (int i = 0; i < fields.Count; i++) + { + var field = fields[i]; + if (!field.IsStatic) + return field.FieldType; + } + + throw new ArgumentException(); + } + + public static TypeDefinition GetNestedType(TypeDefinition self, string name) + { + if (!self.HasNestedTypes) + return null; + + var nested_types = self.NestedTypes; + + for (int i = 0; i < nested_types.Count; i++) + { + var nested_type = nested_types[i]; + if (nested_type.Name == name) + return nested_type; + } + + return null; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinitionCollection.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinitionCollection.cs new file mode 100644 index 00000000..eae71228 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeDefinitionCollection.cs @@ -0,0 +1,118 @@ +// +// TypeDefinitionCollection.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; + +using Mono.Cecil.Metadata; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + using Slot = Row; + + sealed class TypeDefinitionCollection : Collection { + + readonly ModuleDefinition container; + readonly Dictionary name_cache; + + internal TypeDefinitionCollection (ModuleDefinition container) + { + this.container = container; + this.name_cache = new Dictionary (new RowEqualityComparer ()); + } + + internal TypeDefinitionCollection (ModuleDefinition container, int capacity) + : base (capacity) + { + this.container = container; + this.name_cache = new Dictionary (capacity, new RowEqualityComparer ()); + } + + protected override void OnAdd (TypeDefinition item, int index) + { + Attach (item); + } + + protected override void OnSet (TypeDefinition item, int index) + { + Attach (item); + } + + protected override void OnInsert (TypeDefinition item, int index) + { + Attach (item); + } + + protected override void OnRemove (TypeDefinition item, int index) + { + Detach (item); + } + + protected override void OnClear () + { + foreach (var type in this) + Detach (type); + } + + void Attach (TypeDefinition type) + { + if (type.Module != null && type.Module != container) + throw new ArgumentException ("Type already attached"); + + type.module = container; + type.scope = container; + name_cache [new Slot (type.Namespace, type.Name)] = type; + } + + void Detach (TypeDefinition type) + { + type.module = null; + type.scope = null; + name_cache.Remove (new Slot (type.Namespace, type.Name)); + } + + public TypeDefinition GetType (string fullname) + { + string @namespace, name; + TypeParser.SplitFullName (fullname, out @namespace, out name); + + return GetType (@namespace, name); + } + + public TypeDefinition GetType (string @namespace, string name) + { + TypeDefinition type; + if (name_cache.TryGetValue (new Slot (@namespace, name), out type)) + return type; + + return null; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeParser.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeParser.cs new file mode 100644 index 00000000..38d1a49e --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeParser.cs @@ -0,0 +1,584 @@ +// +// TypeParser.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Text; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil +{ + + class TypeParser + { + + class Type + { + public const int Ptr = -1; + public const int ByRef = -2; + public const int SzArray = -3; + + public string type_fullname; + public string[] nested_names; + public int arity; + public int[] specs; + public Type[] generic_arguments; + public string assembly; + } + + readonly string fullname; + readonly int length; + + int position; + + TypeParser(string fullname) + { + this.fullname = fullname; + this.length = fullname.Length; + } + + Type ParseType(bool fq_name) + { + var type = new Type(); + type.type_fullname = ParsePart(); + + type.nested_names = ParseNestedNames(); + + if (TryGetArity(type)) + type.generic_arguments = ParseGenericArguments(type.arity); + + type.specs = ParseSpecs(); + + if (fq_name) + type.assembly = ParseAssemblyName(); + + return type; + } + + static bool TryGetArity(Type type) + { + int arity = 0; + + TryAddArity(type.type_fullname, ref arity); + + var nested_names = type.nested_names; + if (!Mixin.IsNullOrEmpty(nested_names)) + { + for (int i = 0; i < nested_names.Length; i++) + TryAddArity(nested_names[i], ref arity); + } + + type.arity = arity; + return arity > 0; + } + + static bool TryGetArity(string name, out int arity) + { + arity = 0; + var index = name.LastIndexOf('`'); + if (index == -1) + return false; + + return ParseInt32(name.Substring(index + 1), out arity); + } + + static bool ParseInt32(string value, out int result) + { +#if CF + try { + result = int.Parse (value); + return true; + } catch { + result = 0; + return false; + } +#else + return int.TryParse(value, out result); +#endif + } + + static void TryAddArity(string name, ref int arity) + { + int type_arity; + if (!TryGetArity(name, out type_arity)) + return; + + arity += type_arity; + } + + string ParsePart() + { + int start = position; + while (position < length && !IsDelimiter(fullname[position])) + position++; + + return fullname.Substring(start, position - start); + } + + static bool IsDelimiter(char chr) + { + return "+,[]*&".IndexOf(chr) != -1; + } + + void TryParseWhiteSpace() + { + while (position < length && Char.IsWhiteSpace(fullname[position])) + position++; + } + + string[] ParseNestedNames() + { + string[] nested_names = null; + while (TryParse('+')) + Add(ref nested_names, ParsePart()); + + return nested_names; + } + + bool TryParse(char chr) + { + if (position < length && fullname[position] == chr) + { + position++; + return true; + } + + return false; + } + + static void Add(ref T[] array, T item) + { + if (array == null) + { + array = new[] { item }; + return; + } + +#if !CF + Array.Resize(ref array, array.Length + 1); +#else + var copy = new T [array.Length + 1]; + Array.Copy (array, copy, array.Length); + array = copy; +#endif + array[array.Length - 1] = item; + } + + int[] ParseSpecs() + { + int[] specs = null; + + while (position < length) + { + switch (fullname[position]) + { + case '*': + position++; + Add(ref specs, Type.Ptr); + break; + case '&': + position++; + Add(ref specs, Type.ByRef); + break; + case '[': + position++; + switch (fullname[position]) + { + case ']': + position++; + Add(ref specs, Type.SzArray); + break; + case '*': + position++; + Add(ref specs, 1); + break; + default: + var rank = 1; + while (TryParse(',')) + rank++; + + Add(ref specs, rank); + + TryParse(']'); + break; + } + break; + default: + return specs; + } + } + + return specs; + } + + Type[] ParseGenericArguments(int arity) + { + Type[] generic_arguments = null; + + if (position == length || fullname[position] != '[') + return generic_arguments; + + TryParse('['); + + for (int i = 0; i < arity; i++) + { + var fq_argument = TryParse('['); + Add(ref generic_arguments, ParseType(fq_argument)); + if (fq_argument) + TryParse(']'); + + TryParse(','); + TryParseWhiteSpace(); + } + + TryParse(']'); + + return generic_arguments; + } + + string ParseAssemblyName() + { + if (!TryParse(',')) + return string.Empty; + + TryParseWhiteSpace(); + + var start = position; + while (position < length) + { + var chr = fullname[position]; + if (chr == '[' || chr == ']') + break; + + position++; + } + + return fullname.Substring(start, position - start); + } + + public static TypeReference ParseType(ModuleDefinition module, string fullname) + { + if (string.IsNullOrEmpty(fullname)) + return null; + + var parser = new TypeParser(fullname); + return GetTypeReference(module, parser.ParseType(true)); + } + + static TypeReference GetTypeReference(ModuleDefinition module, Type type_info) + { + TypeReference type; + if (!TryGetDefinition(module, type_info, out type)) + type = CreateReference(type_info, module, GetMetadataScope(module, type_info)); + + return CreateSpecs(type, type_info); + } + + static TypeReference CreateSpecs(TypeReference type, Type type_info) + { + type = TryCreateGenericInstanceType(type, type_info); + + var specs = type_info.specs; + if (Mixin.IsNullOrEmpty(specs)) + return type; + + for (int i = 0; i < specs.Length; i++) + { + switch (specs[i]) + { + case Type.Ptr: + type = new PointerType(type); + break; + case Type.ByRef: + type = new ByReferenceType(type); + break; + case Type.SzArray: + type = new ArrayType(type); + break; + default: + var array = new ArrayType(type); + array.Dimensions.Clear(); + + for (int j = 0; j < specs[i]; j++) + array.Dimensions.Add(new ArrayDimension()); + + type = array; + break; + } + } + + return type; + } + + static TypeReference TryCreateGenericInstanceType(TypeReference type, Type type_info) + { + var generic_arguments = type_info.generic_arguments; + if (Mixin.IsNullOrEmpty(generic_arguments)) + return type; + + var instance = new GenericInstanceType(type); + var instance_arguments = instance.GenericArguments; + + for (int i = 0; i < generic_arguments.Length; i++) + instance_arguments.Add(GetTypeReference(type.Module, generic_arguments[i])); + + return instance; + } + + public static void SplitFullName(string fullname, out string @namespace, out string name) + { + var last_dot = fullname.LastIndexOf('.'); + + if (last_dot == -1) + { + @namespace = string.Empty; + name = fullname; + } + else + { + @namespace = fullname.Substring(0, last_dot); + name = fullname.Substring(last_dot + 1); + } + } + + static TypeReference CreateReference(Type type_info, ModuleDefinition module, IMetadataScope scope) + { + string @namespace, name; + SplitFullName(type_info.type_fullname, out @namespace, out name); + + var type = new TypeReference(@namespace, name, module, scope); + MetadataSystem.TryProcessPrimitiveTypeReference(type); + + AdjustGenericParameters(type); + + var nested_names = type_info.nested_names; + if (Mixin.IsNullOrEmpty(nested_names)) + return type; + + for (int i = 0; i < nested_names.Length; i++) + { + type = new TypeReference(string.Empty, nested_names[i], module, null) + { + DeclaringType = type, + }; + + AdjustGenericParameters(type); + } + + return type; + } + + static void AdjustGenericParameters(TypeReference type) + { + int arity; + if (!TryGetArity(type.Name, out arity)) + return; + + for (int i = 0; i < arity; i++) + type.GenericParameters.Add(new GenericParameter(type)); + } + + static IMetadataScope GetMetadataScope(ModuleDefinition module, Type type_info) + { + if (string.IsNullOrEmpty(type_info.assembly)) + return module.TypeSystem.Corlib; + + return MatchReference(module, AssemblyNameReference.Parse(type_info.assembly)); + } + + static AssemblyNameReference MatchReference(ModuleDefinition module, AssemblyNameReference pattern) + { + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) + { + var reference = references[i]; + if (reference.FullName == pattern.FullName) + return reference; + } + + return pattern; + } + + static bool TryGetDefinition(ModuleDefinition module, Type type_info, out TypeReference type) + { + type = null; + if (!TryCurrentModule(module, type_info)) + return false; + + var typedef = module.GetType(type_info.type_fullname); + if (typedef == null) + return false; + + var nested_names = type_info.nested_names; + if (!Mixin.IsNullOrEmpty(nested_names)) + { + for (int i = 0; i < nested_names.Length; i++) + typedef = Mixin.GetNestedType(typedef, nested_names[i]); + } + + type = typedef; + return true; + } + + static bool TryCurrentModule(ModuleDefinition module, Type type_info) + { + if (string.IsNullOrEmpty(type_info.assembly)) + return true; + + if (module.assembly != null && module.assembly.Name.FullName == type_info.assembly) + return true; + + return false; + } + + public static string ToParseable(TypeReference type) + { + if (type == null) + return null; + + var name = new StringBuilder(); + AppendType(type, name, true, true); + return name.ToString(); + } + + static void AppendType(TypeReference type, StringBuilder name, bool fq_name, bool top_level) + { + var declaring_type = type.DeclaringType; + if (declaring_type != null) + { + AppendType(declaring_type, name, false, top_level); + name.Append('+'); + } + + var @namespace = type.Namespace; + if (!string.IsNullOrEmpty(@namespace)) + { + name.Append(@namespace); + name.Append('.'); + } + + name.Append(type.GetElementType().Name); + + if (!fq_name) + return; + + if (Mixin.IsTypeSpecification(type)) + AppendTypeSpecification((TypeSpecification)type, name); + + if (RequiresFullyQualifiedName(type, top_level)) + { + name.Append(", "); + name.Append(GetScopeFullName(type)); + } + } + + static string GetScopeFullName(TypeReference type) + { + var scope = type.Scope; + switch (scope.MetadataScopeType) + { + case MetadataScopeType.AssemblyNameReference: + return ((AssemblyNameReference)scope).FullName; + case MetadataScopeType.ModuleDefinition: + return ((ModuleDefinition)scope).Assembly.Name.FullName; + } + + throw new ArgumentException(); + } + + static void AppendTypeSpecification(TypeSpecification type, StringBuilder name) + { + if (Mixin.IsTypeSpecification(type.ElementType)) + AppendTypeSpecification((TypeSpecification)type.ElementType, name); + + switch (type.etype) + { + case ElementType.Ptr: + name.Append('*'); + break; + case ElementType.ByRef: + name.Append('&'); + break; + case ElementType.SzArray: + case ElementType.Array: + var array = (ArrayType)type; + if (array.IsVector) + { + name.Append("[]"); + } + else + { + name.Append('['); + for (int i = 1; i < array.Rank; i++) + name.Append(','); + name.Append(']'); + } + break; + case ElementType.GenericInst: + var instance = (GenericInstanceType)type; + var arguments = instance.GenericArguments; + + name.Append('['); + + for (int i = 0; i < arguments.Count; i++) + { + if (i > 0) + name.Append(','); + + var argument = arguments[i]; + var requires_fqname = argument.Scope != argument.Module; + + if (requires_fqname) + name.Append('['); + + AppendType(argument, name, true, false); + + if (requires_fqname) + name.Append(']'); + } + + name.Append(']'); + break; + default: + return; + } + } + + static bool RequiresFullyQualifiedName(TypeReference type, bool top_level) + { + if (type.Scope == type.Module) + return false; + + if (type.Scope.Name == "mscorlib" && top_level) + return false; + + return true; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeReference.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeReference.cs new file mode 100644 index 00000000..e7c40eb1 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeReference.cs @@ -0,0 +1,370 @@ +// +// TypeReference.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +namespace Mono.Cecil +{ + + public enum MetadataType : byte + { + Void = ElementType.Void, + Boolean = ElementType.Boolean, + Char = ElementType.Char, + SByte = ElementType.I1, + Byte = ElementType.U1, + Int16 = ElementType.I2, + UInt16 = ElementType.U2, + Int32 = ElementType.I4, + UInt32 = ElementType.U4, + Int64 = ElementType.I8, + UInt64 = ElementType.U8, + Single = ElementType.R4, + Double = ElementType.R8, + String = ElementType.String, + Pointer = ElementType.Ptr, + ByReference = ElementType.ByRef, + ValueType = ElementType.ValueType, + Class = ElementType.Class, + Var = ElementType.Var, + Array = ElementType.Array, + GenericInstance = ElementType.GenericInst, + TypedByReference = ElementType.TypedByRef, + IntPtr = ElementType.I, + UIntPtr = ElementType.U, + FunctionPointer = ElementType.FnPtr, + Object = ElementType.Object, + MVar = ElementType.MVar, + RequiredModifier = ElementType.CModReqD, + OptionalModifier = ElementType.CModOpt, + Sentinel = ElementType.Sentinel, + Pinned = ElementType.Pinned, + } + + public class TypeReference : MemberReference, IGenericParameterProvider, IGenericContext + { + + string @namespace; + bool value_type; + internal IMetadataScope scope; + internal ModuleDefinition module; + + internal ElementType etype = ElementType.None; + + string fullname; + + protected Collection generic_parameters; + + public override string Name + { + get { return base.Name; } + set + { + base.Name = value; + fullname = null; + } + } + + public virtual string Namespace + { + get { return @namespace; } + set + { + @namespace = value; + fullname = null; + } + } + + public virtual bool IsValueType + { + get { return value_type; } + set { value_type = value; } + } + + public override ModuleDefinition Module + { + get + { + if (module != null) + return module; + + var declaring_type = this.DeclaringType; + if (declaring_type != null) + return declaring_type.Module; + + return null; + } + } + + IGenericParameterProvider IGenericContext.Type + { + get { return this; } + } + + IGenericParameterProvider IGenericContext.Method + { + get { return null; } + } + + GenericParameterType IGenericParameterProvider.GenericParameterType + { + get { return GenericParameterType.Type; } + } + + public virtual bool HasGenericParameters + { + get { return !Mixin.IsNullOrEmpty(generic_parameters); } + } + + public virtual Collection GenericParameters + { + get + { + if (generic_parameters != null) + return generic_parameters; + + return generic_parameters = new GenericParameterCollection(this); + } + } + + public virtual IMetadataScope Scope + { + get + { + var declaring_type = this.DeclaringType; + if (declaring_type != null) + return declaring_type.Scope; + + return scope; + } + } + + public bool IsNested + { + get { return this.DeclaringType != null; } + } + + public override TypeReference DeclaringType + { + get { return base.DeclaringType; } + set + { + base.DeclaringType = value; + fullname = null; + } + } + + public override string FullName + { + get + { + if (fullname != null) + return fullname; + + if (IsNested) + return fullname = DeclaringType.FullName + "/" + Name; + + if (string.IsNullOrEmpty(@namespace)) + return fullname = Name; + + return fullname = @namespace + "." + Name; + } + } + + public virtual bool IsByReference + { + get { return false; } + } + + public virtual bool IsPointer + { + get { return false; } + } + + public virtual bool IsSentinel + { + get { return false; } + } + + public virtual bool IsArray + { + get { return false; } + } + + public virtual bool IsGenericParameter + { + get { return false; } + } + + public virtual bool IsGenericInstance + { + get { return false; } + } + + public virtual bool IsRequiredModifier + { + get { return false; } + } + + public virtual bool IsOptionalModifier + { + get { return false; } + } + + public virtual bool IsPinned + { + get { return false; } + } + + public virtual bool IsFunctionPointer + { + get { return false; } + } + + public virtual bool IsPrimitive + { + get { return Mixin.IsPrimitive(etype); } + } + + public virtual MetadataType MetadataType + { + get + { + switch (etype) + { + case ElementType.None: + return IsValueType ? MetadataType.ValueType : MetadataType.Class; + default: + return (MetadataType)etype; + } + } + } + + protected TypeReference(string @namespace, string name) + : base(name) + { + this.@namespace = @namespace ?? string.Empty; + this.token = new MetadataToken(TokenType.TypeRef, 0); + } + + public TypeReference(string @namespace, string name, ModuleDefinition module, IMetadataScope scope) + : this(@namespace, name) + { + this.module = module; + this.scope = scope; + } + + public TypeReference(string @namespace, string name, ModuleDefinition module, IMetadataScope scope, bool valueType) : + this(@namespace, name, module, scope) + { + value_type = valueType; + } + + public virtual TypeReference GetElementType() + { + return this; + } + + public virtual TypeDefinition Resolve() + { + var module = this.Module; + if (module == null) + throw new NotSupportedException(); + + return module.Resolve(this); + } + } + + static partial class Mixin + { + + public static bool IsPrimitive(ElementType self) + { + switch (self) + { + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I: + case ElementType.U: + case ElementType.I1: + case ElementType.U1: + case ElementType.I2: + case ElementType.U2: + case ElementType.I4: + case ElementType.U4: + case ElementType.I8: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: + return true; + default: + return false; + } + } + + public static bool IsTypeOf(TypeReference self, string @namespace, string name) + { + return self.Name == name + && self.Namespace == @namespace; + } + + public static bool IsTypeSpecification(TypeReference type) + { + switch (type.etype) + { + case ElementType.Array: + case ElementType.ByRef: + case ElementType.CModOpt: + case ElementType.CModReqD: + case ElementType.FnPtr: + case ElementType.GenericInst: + case ElementType.MVar: + case ElementType.Pinned: + case ElementType.Ptr: + case ElementType.SzArray: + case ElementType.Sentinel: + case ElementType.Var: + return true; + } + + return false; + } + + public static TypeDefinition CheckedResolve(TypeReference self) + { + var type = self.Resolve(); + if (type == null) + throw new ResolutionException(self); + + return type; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSpecification.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSpecification.cs new file mode 100644 index 00000000..aa9b653f --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSpecification.cs @@ -0,0 +1,94 @@ +// +// TypeSpecification.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public abstract class TypeSpecification : TypeReference { + + readonly TypeReference element_type; + + public TypeReference ElementType { + get { return element_type; } + } + + public override string Name { + get { return element_type.Name; } + set { throw new NotSupportedException (); } + } + + public override string Namespace { + get { return element_type.Namespace; } + set { throw new NotSupportedException (); } + } + + public override IMetadataScope Scope { + get { return element_type.Scope; } + } + + public override ModuleDefinition Module { + get { return element_type.Module; } + } + + public override string FullName { + get { return element_type.FullName; } + } + + internal override bool ContainsGenericParameter { + get { return element_type.ContainsGenericParameter; } + } + + public override MetadataType MetadataType { + get { return (MetadataType) etype; } + } + + internal TypeSpecification (TypeReference type) + : base (null, null) + { + this.element_type = type; + this.token = new MetadataToken (TokenType.TypeSpec); + } + + public override TypeReference GetElementType () + { + return element_type.GetElementType (); + } + } + + static partial class Mixin { + + public static void CheckType (TypeReference type) + { + if (type == null) + throw new ArgumentNullException ("type"); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSystem.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSystem.cs new file mode 100644 index 00000000..c59962cf --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/TypeSystem.cs @@ -0,0 +1,332 @@ +// +// TypeSystem.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil +{ + + public abstract class TypeSystem + { + + sealed class CoreTypeSystem : TypeSystem + { + + public CoreTypeSystem(ModuleDefinition module) + : base(module) + { + } + + internal override TypeReference LookupType(string @namespace, string name) + { + var type = LookupTypeDefinition(@namespace, name) ?? LookupTypeForwarded(@namespace, name); + if (type != null) + return type; + + throw new NotSupportedException(); + } + + TypeReference LookupTypeDefinition(string @namespace, string name) + { + var metadata = module.MetadataSystem; + if (metadata.Types == null) + Initialize(module.Types); + + return module.Read(new Row(@namespace, name), (row, reader) => + { + var types = reader.metadata.Types; + + for (int i = 0; i < types.Length; i++) + { + if (types[i] == null) + types[i] = reader.GetTypeDefinition((uint)i + 1); + + var type = types[i]; + + if (type.Name == row.Col2 && type.Namespace == row.Col1) + return type; + } + + return null; + }); + } + + TypeReference LookupTypeForwarded(string @namespace, string name) + { + if (!module.HasExportedTypes) + return null; + + var exported_types = module.ExportedTypes; + for (int i = 0; i < exported_types.Count; i++) + { + var exported_type = exported_types[i]; + + if (exported_type.Name == name && exported_type.Namespace == @namespace) + return exported_type.CreateReference(); + } + + return null; + } + + static void Initialize(object obj) + { + } + } + + sealed class CommonTypeSystem : TypeSystem + { + + AssemblyNameReference corlib; + + public CommonTypeSystem(ModuleDefinition module) + : base(module) + { + } + + internal override TypeReference LookupType(string @namespace, string name) + { + return CreateTypeReference(@namespace, name); + } + + public AssemblyNameReference GetCorlibReference() + { + if (corlib != null) + return corlib; + + const string mscorlib = "mscorlib"; + const string systemruntime = "System.Runtime"; + + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) + { + var reference = references[i]; + if (reference.Name == mscorlib || reference.Name == systemruntime) + return corlib = reference; + } + + corlib = new AssemblyNameReference + { + Name = mscorlib, + Version = GetCorlibVersion(), + PublicKeyToken = new byte[] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }, + }; + + references.Add(corlib); + + return corlib; + } + + Version GetCorlibVersion() + { + switch (module.Runtime) + { + case TargetRuntime.Net_1_0: + case TargetRuntime.Net_1_1: + return new Version(1, 0, 0, 0); + case TargetRuntime.Net_2_0: + return new Version(2, 0, 0, 0); + case TargetRuntime.Net_4_0: + return new Version(4, 0, 0, 0); + default: + throw new NotSupportedException(); + } + } + + TypeReference CreateTypeReference(string @namespace, string name) + { + return new TypeReference(@namespace, name, module, GetCorlibReference()); + } + } + + readonly ModuleDefinition module; + + TypeReference type_object; + TypeReference type_void; + TypeReference type_bool; + TypeReference type_char; + TypeReference type_sbyte; + TypeReference type_byte; + TypeReference type_int16; + TypeReference type_uint16; + TypeReference type_int32; + TypeReference type_uint32; + TypeReference type_int64; + TypeReference type_uint64; + TypeReference type_single; + TypeReference type_double; + TypeReference type_intptr; + TypeReference type_uintptr; + TypeReference type_string; + TypeReference type_typedref; + + TypeSystem(ModuleDefinition module) + { + this.module = module; + } + + internal static TypeSystem CreateTypeSystem(ModuleDefinition module) + { + if (Mixin.IsCorlib(module)) + return new CoreTypeSystem(module); + + return new CommonTypeSystem(module); + } + + internal abstract TypeReference LookupType(string @namespace, string name); + + TypeReference LookupSystemType(ref TypeReference typeRef, string name, ElementType element_type) + { + lock (module.SyncRoot) + { + if (typeRef != null) + return typeRef; + var type = LookupType("System", name); + type.etype = element_type; + return typeRef = type; + } + } + + TypeReference LookupSystemValueType(ref TypeReference typeRef, string name, ElementType element_type) + { + lock (module.SyncRoot) + { + if (typeRef != null) + return typeRef; + var type = LookupType("System", name); + type.etype = element_type; + type.IsValueType = true; + return typeRef = type; + } + } + + public IMetadataScope Corlib + { + get + { + var common = this as CommonTypeSystem; + if (common == null) + return module; + + return common.GetCorlibReference(); + } + } + + public TypeReference Object + { + get { return type_object ?? (LookupSystemType(ref type_object, "Object", ElementType.Object)); } + } + + public TypeReference Void + { + get { return type_void ?? (LookupSystemType(ref type_void, "Void", ElementType.Void)); } + } + + public TypeReference Boolean + { + get { return type_bool ?? (LookupSystemValueType(ref type_bool, "Boolean", ElementType.Boolean)); } + } + + public TypeReference Char + { + get { return type_char ?? (LookupSystemValueType(ref type_char, "Char", ElementType.Char)); } + } + + public TypeReference SByte + { + get { return type_sbyte ?? (LookupSystemValueType(ref type_sbyte, "SByte", ElementType.I1)); } + } + + public TypeReference Byte + { + get { return type_byte ?? (LookupSystemValueType(ref type_byte, "Byte", ElementType.U1)); } + } + + public TypeReference Int16 + { + get { return type_int16 ?? (LookupSystemValueType(ref type_int16, "Int16", ElementType.I2)); } + } + + public TypeReference UInt16 + { + get { return type_uint16 ?? (LookupSystemValueType(ref type_uint16, "UInt16", ElementType.U2)); } + } + + public TypeReference Int32 + { + get { return type_int32 ?? (LookupSystemValueType(ref type_int32, "Int32", ElementType.I4)); } + } + + public TypeReference UInt32 + { + get { return type_uint32 ?? (LookupSystemValueType(ref type_uint32, "UInt32", ElementType.U4)); } + } + + public TypeReference Int64 + { + get { return type_int64 ?? (LookupSystemValueType(ref type_int64, "Int64", ElementType.I8)); } + } + + public TypeReference UInt64 + { + get { return type_uint64 ?? (LookupSystemValueType(ref type_uint64, "UInt64", ElementType.U8)); } + } + + public TypeReference Single + { + get { return type_single ?? (LookupSystemValueType(ref type_single, "Single", ElementType.R4)); } + } + + public TypeReference Double + { + get { return type_double ?? (LookupSystemValueType(ref type_double, "Double", ElementType.R8)); } + } + + public TypeReference IntPtr + { + get { return type_intptr ?? (LookupSystemValueType(ref type_intptr, "IntPtr", ElementType.I)); } + } + + public TypeReference UIntPtr + { + get { return type_uintptr ?? (LookupSystemValueType(ref type_uintptr, "UIntPtr", ElementType.U)); } + } + + public TypeReference String + { + get { return type_string ?? (LookupSystemType(ref type_string, "String", ElementType.String)); } + } + + public TypeReference TypedReference + { + get { return type_typedref ?? (LookupSystemValueType(ref type_typedref, "TypedReference", ElementType.TypedByRef)); } + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Cecil/VariantType.cs b/Mono.Cecil.20/MonoCecil/Mono.Cecil/VariantType.cs new file mode 100644 index 00000000..76562f6e --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Cecil/VariantType.cs @@ -0,0 +1,53 @@ +// +// VariantType.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +namespace Mono.Cecil { + + public enum VariantType { + None = 0, + I2 = 2, + I4 = 3, + R4 = 4, + R8 = 5, + CY = 6, + Date = 7, + BStr = 8, + Dispatch = 9, + Error = 10, + Bool = 11, + Variant = 12, + Unknown = 13, + Decimal = 14, + I1 = 16, + UI1 = 17, + UI2 = 18, + UI4 = 19, + Int = 22, + UInt = 23 + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/Collection.cs b/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/Collection.cs new file mode 100644 index 00000000..4d927176 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/Collection.cs @@ -0,0 +1,420 @@ +// +// Collection.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Mono.Collections.Generic { + + public class Collection : IList, IList { + + internal T [] items; + internal int size; + int version; + + public int Count { + get { return size; } + } + + public T this [int index] { + get { + if (index >= size) + throw new ArgumentOutOfRangeException (); + + return items [index]; + } + set { + CheckIndex (index); + if (index == size) + throw new ArgumentOutOfRangeException (); + + OnSet (value, index); + + items [index] = value; + } + } + + bool ICollection.IsReadOnly { + get { return false; } + } + + bool IList.IsFixedSize { + get { return false; } + } + + bool IList.IsReadOnly { + get { return false; } + } + + object IList.this [int index] { + get { return this [index]; } + set { + CheckIndex (index); + + try { + this [index] = (T) value; + return; + } catch (InvalidCastException) { + } catch (NullReferenceException) { + } + + throw new ArgumentException (); + } + } + + int ICollection.Count { + get { return Count; } + } + + bool ICollection.IsSynchronized { + get { return false; } + } + + object ICollection.SyncRoot { + get { return this; } + } + + public Collection () + { + items = Empty.Array; + } + + public Collection (int capacity) + { + if (capacity < 0) + throw new ArgumentOutOfRangeException (); + + items = new T [capacity]; + } + + public Collection (ICollection items) + { + if (items == null) + throw new ArgumentNullException ("items"); + + this.items = new T [items.Count]; + items.CopyTo (this.items, 0); + this.size = this.items.Length; + } + + public void Add (T item) + { + if (size == items.Length) + Grow (1); + + OnAdd (item, size); + + items [size++] = item; + version++; + } + + public bool Contains (T item) + { + return IndexOf (item) != -1; + } + + public int IndexOf (T item) + { + return Array.IndexOf (items, item, 0, size); + } + + public void Insert (int index, T item) + { + CheckIndex (index); + if (size == items.Length) + Grow (1); + + OnInsert (item, index); + + Shift (index, 1); + items [index] = item; + version++; + } + + public void RemoveAt (int index) + { + if (index < 0 || index >= size) + throw new ArgumentOutOfRangeException (); + + var item = items [index]; + + OnRemove (item, index); + + Shift (index, -1); + Array.Clear (items, size, 1); + version++; + } + + public bool Remove (T item) + { + var index = IndexOf (item); + if (index == -1) + return false; + + OnRemove (item, index); + + Shift (index, -1); + Array.Clear (items, size, 1); + version++; + + return true; + } + + public void Clear () + { + OnClear (); + + Array.Clear (items, 0, size); + size = 0; + version++; + } + + public void CopyTo (T [] array, int arrayIndex) + { + Array.Copy (items, 0, array, arrayIndex, size); + } + + public T [] ToArray () + { + var array = new T [size]; + Array.Copy (items, 0, array, 0, size); + return array; + } + + void CheckIndex (int index) + { + if (index < 0 || index > size) + throw new ArgumentOutOfRangeException (); + } + + void Shift (int start, int delta) + { + if (delta < 0) + start -= delta; + + if (start < size) + Array.Copy (items, start, items, start + delta, size - start); + + size += delta; + + if (delta < 0) + Array.Clear (items, size, -delta); + } + + protected virtual void OnAdd (T item, int index) + { + } + + protected virtual void OnInsert (T item, int index) + { + } + + protected virtual void OnSet (T item, int index) + { + } + + protected virtual void OnRemove (T item, int index) + { + } + + protected virtual void OnClear () + { + } + + internal virtual void Grow (int desired) + { + int new_size = size + desired; + if (new_size <= items.Length) + return; + + const int default_capacity = 4; + + new_size = System.Math.Max ( + System.Math.Max (items.Length * 2, default_capacity), + new_size); + +#if !CF + Array.Resize (ref items, new_size); +#else + var array = new T [new_size]; + Array.Copy (items, array, size); + items = array; +#endif + } + + int IList.Add (object value) + { + try { + Add ((T) value); + return size - 1; + } catch (InvalidCastException) { + } catch (NullReferenceException) { + } + + throw new ArgumentException (); + } + + void IList.Clear () + { + Clear (); + } + + bool IList.Contains (object value) + { + return ((IList) this).IndexOf (value) > -1; + } + + int IList.IndexOf (object value) + { + try { + return IndexOf ((T) value); + } catch (InvalidCastException) { + } catch (NullReferenceException) { + } + + return -1; + } + + void IList.Insert (int index, object value) + { + CheckIndex (index); + + try { + Insert (index, (T) value); + return; + } catch (InvalidCastException) { + } catch (NullReferenceException) { + } + + throw new ArgumentException (); + } + + void IList.Remove (object value) + { + try { + Remove ((T) value); + } catch (InvalidCastException) { + } catch (NullReferenceException) { + } + } + + void IList.RemoveAt (int index) + { + RemoveAt (index); + } + + void ICollection.CopyTo (Array array, int index) + { + Array.Copy (items, 0, array, index, size); + } + + public Enumerator GetEnumerator () + { + return new Enumerator (this); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return new Enumerator (this); + } + + IEnumerator IEnumerable.GetEnumerator () + { + return new Enumerator (this); + } + + public struct Enumerator : IEnumerator, IDisposable { + + Collection collection; + T current; + + int next; + readonly int version; + + public T Current { + get { return current; } + } + + object IEnumerator.Current { + get { + CheckState (); + + if (next <= 0) + throw new InvalidOperationException (); + + return current; + } + } + + internal Enumerator (Collection collection) + : this () + { + this.collection = collection; + this.version = collection.version; + } + + public bool MoveNext () + { + CheckState (); + + if (next < 0) + return false; + + if (next < collection.size) { + current = collection.items [next++]; + return true; + } + + next = -1; + return false; + } + + public void Reset () + { + CheckState (); + + next = 0; + } + + void CheckState () + { + if (collection == null) + throw new ObjectDisposedException (GetType ().FullName); + + if (version != collection.version) + throw new InvalidOperationException (); + } + + public void Dispose () + { + collection = null; + } + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/ReadOnlyCollection.cs b/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/ReadOnlyCollection.cs new file mode 100644 index 00000000..7f24df69 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Collections.Generic/ReadOnlyCollection.cs @@ -0,0 +1,112 @@ +// +// ReadOnlyCollection.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections; +using System .Collections.Generic; + +namespace Mono.Collections.Generic { + + public sealed class ReadOnlyCollection : Collection, ICollection, IList { + + static ReadOnlyCollection empty; + + public static ReadOnlyCollection Empty { + get { return empty ?? (empty = new ReadOnlyCollection ()); } + } + + bool ICollection.IsReadOnly { + get { return true; } + } + + bool IList.IsFixedSize { + get { return true; } + } + + bool IList.IsReadOnly { + get { return true; } + } + + private ReadOnlyCollection () + { + } + + public ReadOnlyCollection (T [] array) + { + if (array == null) + throw new ArgumentNullException (); + + Initialize (array, array.Length); + } + + public ReadOnlyCollection (Collection collection) + { + if (collection == null) + throw new ArgumentNullException (); + + Initialize (collection.items, collection.size); + } + + void Initialize (T [] items, int size) + { + this.items = new T [size]; + Array.Copy (items, 0, this.items, 0, size); + this.size = size; + } + + internal override void Grow (int desired) + { + throw new InvalidOperationException (); + } + + protected override void OnAdd (T item, int index) + { + throw new InvalidOperationException (); + } + + protected override void OnClear () + { + throw new InvalidOperationException (); + } + + protected override void OnInsert (T item, int index) + { + throw new InvalidOperationException (); + } + + protected override void OnRemove (T item, int index) + { + throw new InvalidOperationException (); + } + + protected override void OnSet (T item, int index) + { + throw new InvalidOperationException (); + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoConvert.cs b/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoConvert.cs new file mode 100644 index 00000000..e69de29b diff --git a/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoService.cs b/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoService.cs new file mode 100644 index 00000000..12590628 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono.Security.Cryptography/CryptoService.cs @@ -0,0 +1,33 @@ +// +// CryptoService.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.IO; +using System.Reflection; +using System.Security.Cryptography; + diff --git a/Mono.Cecil.20/MonoCecil/Mono/Actions.cs b/Mono.Cecil.20/MonoCecil/Mono/Actions.cs new file mode 100644 index 00000000..e64c4fb1 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono/Actions.cs @@ -0,0 +1,38 @@ +// +// Actions.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#if !NET_3_5 && !NET_4_0 + +namespace Mono { + //delegate void Action (); + delegate void Action (T1 arg1, T2 arg2); + //delegate void Action (T1 arg1, T2 arg2, T3 arg3); + //delegate void Action (T1 arg1, T2 arg2, T3 arg3, T4 arg4); +} + +#endif diff --git a/Mono.Cecil.20/MonoCecil/Mono/Empty.cs b/Mono.Cecil.20/MonoCecil/Mono/Empty.cs new file mode 100644 index 00000000..db49b5e3 --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono/Empty.cs @@ -0,0 +1,53 @@ +// +// Empty.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using Mono.Collections.Generic; + +namespace Mono { + + static class Empty { + + public static readonly T [] Array = new T [0]; + } +} + +namespace Mono.Cecil { + + static partial class Mixin { + + public static bool IsNullOrEmpty (T [] self) + { + return self == null || self.Length == 0; + } + + public static bool IsNullOrEmpty (Collection self) + { + return self == null || self.size == 0; + } + } +} diff --git a/Mono.Cecil.20/MonoCecil/Mono/Funcs.cs b/Mono.Cecil.20/MonoCecil/Mono/Funcs.cs new file mode 100644 index 00000000..22ac26ee --- /dev/null +++ b/Mono.Cecil.20/MonoCecil/Mono/Funcs.cs @@ -0,0 +1,39 @@ +// +// Funcs.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +#if !NET_3_5 && !NET_4_0 + +namespace Mono { + delegate TResult Func (); + delegate TResult Func (T arg1); + delegate TResult Func (T1 arg1, T2 arg2); + //delegate TResult Func (T1 arg1, T2 arg2, T3 arg3); + //delegate TResult Func (T1 arg1, T2 arg2, T3 arg3, T4 arg4); +} + +#endif diff --git a/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj b/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj new file mode 100644 index 00000000..bac84da7 --- /dev/null +++ b/Mono.Cecil.Mdb/Mono.Cecil.Mdb.csproj @@ -0,0 +1,85 @@ + + + + + Debug + AnyCPU + {86F36240-E07C-4840-9C8B-9CD94C03EC62} + Library + Properties + Mono.Cecil.Mdb + Mono.Cecil.Mdb + v3.5 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {d3785d8b-4d85-4546-8763-47fc848c13e0} + Mono.Cecil.20 + + + + + + + + \ No newline at end of file diff --git a/Mono.Cecil.Mdb/Properties/AssemblyInfo.cs b/Mono.Cecil.Mdb/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..4ce51b25 --- /dev/null +++ b/Mono.Cecil.Mdb/Properties/AssemblyInfo.cs @@ -0,0 +1,29 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过下列特性集 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Mono.Cecil.Mdb")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Mono.Cecil.Mdb")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 程序集的版本信息由下面四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: ComVisible(false)] \ No newline at end of file diff --git a/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReader.cs b/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReader.cs new file mode 100644 index 00000000..4878afae --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReader.cs @@ -0,0 +1,177 @@ +using Mono.Cecil.Cil; +using Mono.Collections.Generic; +using Mono.CompilerServices.SymbolWriter; +using System; +using System.Collections.Generic; +namespace Mono.Cecil.Mdb +{ + public class MdbReader : ISymbolReader, IDisposable + { + private readonly MonoSymbolFile symbol_file; + private readonly Dictionary documents; + public MdbReader(MonoSymbolFile symFile) + { + this.symbol_file = symFile; + this.documents = new Dictionary(); + } + public bool ProcessDebugHeader(ImageDebugDirectory directory, byte[] header) + { + return true; + } + public void Read(MethodBody body, InstructionMapper mapper) + { + MetadataToken method_token = body.Method.MetadataToken; + MethodEntry entry = this.symbol_file.GetMethodByToken(method_token.ToInt32()); + if (entry != null) + { + Scope[] scopes = MdbReader.ReadScopes(entry, body, mapper); + this.ReadLineNumbers(entry, mapper); + MdbReader.ReadLocalVariables(entry, body, scopes); + } + } + private static void ReadLocalVariables(MethodEntry entry, MethodBody body, Scope[] scopes) + { + LocalVariableEntry[] locals = entry.GetLocals(); + LocalVariableEntry[] array = locals; + for (int i = 0; i < array.Length; i++) + { + LocalVariableEntry local = array[i]; + VariableDefinition variable = body.Variables[local.Index]; + variable.Name = local.Name; + int index = local.BlockIndex; + if (index >= 0 && index < scopes.Length) + { + Scope scope = scopes[index]; + if (scope != null) + { + scope.Variables.Add(variable); + } + } + } + } + private void ReadLineNumbers(MethodEntry entry, InstructionMapper mapper) + { + Document document = null; + LineNumberTable table = entry.GetLineNumberTable(); + LineNumberEntry[] lineNumbers = table.LineNumbers; + for (int i = 0; i < lineNumbers.Length; i++) + { + LineNumberEntry line = lineNumbers[i]; + Instruction instruction = mapper(line.Offset); + if (instruction != null) + { + if (document == null) + { + document = this.GetDocument(entry.CompileUnit.SourceFile); + } + instruction.SequencePoint = new SequencePoint(document) + { + StartLine = line.Row, + EndLine = line.Row + }; + } + } + } + private Document GetDocument(SourceFileEntry file) + { + string file_name = file.FileName; + Document document; + Document result; + if (this.documents.TryGetValue(file_name, out document)) + { + result = document; + } + else + { + document = new Document(file_name); + this.documents.Add(file_name, document); + result = document; + } + return result; + } + private static Scope[] ReadScopes(MethodEntry entry, MethodBody body, InstructionMapper mapper) + { + CodeBlockEntry[] blocks = entry.GetCodeBlocks(); + Scope[] scopes = new Scope[blocks.Length]; + CodeBlockEntry[] array = blocks; + for (int i = 0; i < array.Length; i++) + { + CodeBlockEntry block = array[i]; + if (block.BlockType == CodeBlockEntry.Type.Lexical) + { + Scope scope = new Scope(); + scope.Start = mapper(block.StartOffset); + scope.End = mapper(block.EndOffset); + scopes[block.Index] = scope; + if (body.Scope == null) + { + body.Scope = scope; + } + if (!MdbReader.AddScope(body.Scope, scope)) + { + body.Scope = scope; + } + } + } + return scopes; + } + private static bool AddScope(Scope provider, Scope scope) + { + bool result; + foreach (Scope sub_scope in provider.Scopes) + { + if (MdbReader.AddScope(sub_scope, scope)) + { + result = true; + return result; + } + if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) + { + sub_scope.Scopes.Add(scope); + result = true; + return result; + } + } + result = false; + return result; + } + public void Read(MethodSymbols symbols) + { + MethodEntry entry = this.symbol_file.GetMethodByToken(symbols.MethodToken.ToInt32()); + if (entry != null) + { + this.ReadLineNumbers(entry, symbols); + MdbReader.ReadLocalVariables(entry, symbols); + } + } + private void ReadLineNumbers(MethodEntry entry, MethodSymbols symbols) + { + LineNumberTable table = entry.GetLineNumberTable(); + LineNumberEntry[] lines = table.LineNumbers; + Collection instructions = symbols.instructions = new Collection(lines.Length); + for (int i = 0; i < lines.Length; i++) + { + LineNumberEntry line = lines[i]; + instructions.Add(new InstructionSymbol(line.Offset, new SequencePoint(this.GetDocument(entry.CompileUnit.SourceFile)) + { + StartLine = line.Row, + EndLine = line.Row + })); + } + } + private static void ReadLocalVariables(MethodEntry entry, MethodSymbols symbols) + { + LocalVariableEntry[] locals = entry.GetLocals(); + for (int i = 0; i < locals.Length; i++) + { + LocalVariableEntry local = locals[i]; + VariableDefinition variable = symbols.Variables[local.Index]; + variable.Name = local.Name; + } + } + public void Dispose() + { + this.symbol_file.Dispose(); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReaderProvider.cs b/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReaderProvider.cs new file mode 100644 index 00000000..b140e831 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.Cecil.Mdb/MdbReaderProvider.cs @@ -0,0 +1,19 @@ +using Mono.Cecil.Cil; +using Mono.CompilerServices.SymbolWriter; +using System; +using System.IO; +namespace Mono.Cecil.Mdb +{ + public class MdbReaderProvider : ISymbolReaderProvider + { + public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName) + { + return new MdbReader(MonoSymbolFile.ReadSymbolFile(module, fileName)); + } + public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) + { + return new MdbReader(MonoSymbolFile.ReadSymbolFile(module, symbolStream)); + //throw new NotImplementedException(); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/AnonymousScopeEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/AnonymousScopeEntry.cs new file mode 100644 index 00000000..422579ca --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/AnonymousScopeEntry.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +namespace Mono.CompilerServices.SymbolWriter +{ + public class AnonymousScopeEntry + { + public readonly int ID; + private List captured_vars = new List(); + private List captured_scopes = new List(); + public CapturedVariable[] CapturedVariables + { + get + { + CapturedVariable[] retval = new CapturedVariable[this.captured_vars.Count]; + this.captured_vars.CopyTo(retval, 0); + return retval; + } + } + public CapturedScope[] CapturedScopes + { + get + { + CapturedScope[] retval = new CapturedScope[this.captured_scopes.Count]; + this.captured_scopes.CopyTo(retval, 0); + return retval; + } + } + public AnonymousScopeEntry(int id) + { + this.ID = id; + } + internal AnonymousScopeEntry(MyBinaryReader reader) + { + this.ID = reader.ReadLeb128(); + int num_captured_vars = reader.ReadLeb128(); + for (int i = 0; i < num_captured_vars; i++) + { + this.captured_vars.Add(new CapturedVariable(reader)); + } + int num_captured_scopes = reader.ReadLeb128(); + for (int i = 0; i < num_captured_scopes; i++) + { + this.captured_scopes.Add(new CapturedScope(reader)); + } + } + internal void AddCapturedVariable(string name, string captured_name, CapturedVariable.CapturedKind kind) + { + this.captured_vars.Add(new CapturedVariable(name, captured_name, kind)); + } + internal void AddCapturedScope(int scope, string captured_name) + { + this.captured_scopes.Add(new CapturedScope(scope, captured_name)); + } + //internal void Write(MyBinaryWriter bw) + //{ + // bw.WriteLeb128(this.ID); + // bw.WriteLeb128(this.captured_vars.Count); + // foreach (CapturedVariable cv in this.captured_vars) + // { + // cv.Write(bw); + // } + // bw.WriteLeb128(this.captured_scopes.Count); + // foreach (CapturedScope cs in this.captured_scopes) + // { + // cs.Write(bw); + // } + //} + public override string ToString() + { + return string.Format("[AnonymousScope {0}]", this.ID); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedScope.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedScope.cs new file mode 100644 index 00000000..1669d3e7 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedScope.cs @@ -0,0 +1,28 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public struct CapturedScope + { + public readonly int Scope; + public readonly string CapturedName; + public CapturedScope(int scope, string captured_name) + { + this.Scope = scope; + this.CapturedName = captured_name; + } + internal CapturedScope(MyBinaryReader reader) + { + this.Scope = reader.ReadLeb128(); + this.CapturedName = reader.ReadString(); + } + //internal void Write(MyBinaryWriter bw) + //{ + // bw.WriteLeb128(this.Scope); + // bw.Write(this.CapturedName); + //} + public override string ToString() + { + return string.Format("[CapturedScope {0}:{1}]", this.Scope, this.CapturedName); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedVariable.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedVariable.cs new file mode 100644 index 00000000..3740f114 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CapturedVariable.cs @@ -0,0 +1,38 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public struct CapturedVariable + { + public enum CapturedKind : byte + { + Local, + Parameter, + This + } + public readonly string Name; + public readonly string CapturedName; + public readonly CapturedVariable.CapturedKind Kind; + public CapturedVariable(string name, string captured_name, CapturedVariable.CapturedKind kind) + { + this.Name = name; + this.CapturedName = captured_name; + this.Kind = kind; + } + internal CapturedVariable(MyBinaryReader reader) + { + this.Name = reader.ReadString(); + this.CapturedName = reader.ReadString(); + this.Kind = (CapturedVariable.CapturedKind)reader.ReadByte(); + } + //internal void Write(MyBinaryWriter bw) + //{ + // bw.Write(this.Name); + // bw.Write(this.CapturedName); + // bw.Write((byte)this.Kind); + //} + public override string ToString() + { + return string.Format("[CapturedVariable {0}:{1}:{2}]", this.Name, this.CapturedName, this.Kind); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CodeBlockEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CodeBlockEntry.cs new file mode 100644 index 00000000..91f51d9c --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CodeBlockEntry.cs @@ -0,0 +1,62 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public class CodeBlockEntry + { + public enum Type + { + Lexical = 1, + CompilerGenerated, + IteratorBody, + IteratorDispatcher + } + public int Index; + public int Parent; + public CodeBlockEntry.Type BlockType; + public int StartOffset; + public int EndOffset; + public CodeBlockEntry(int index, int parent, CodeBlockEntry.Type type, int start_offset) + { + this.Index = index; + this.Parent = parent; + this.BlockType = type; + this.StartOffset = start_offset; + } + internal CodeBlockEntry(int index, MyBinaryReader reader) + { + this.Index = index; + int type_flag = reader.ReadLeb128(); + this.BlockType = (CodeBlockEntry.Type)(type_flag & 63); + this.Parent = reader.ReadLeb128(); + this.StartOffset = reader.ReadLeb128(); + this.EndOffset = reader.ReadLeb128(); + if ((type_flag & 64) != 0) + { + int data_size = (int)reader.ReadInt16(); + reader.BaseStream.Position += (long)data_size; + } + } + public void Close(int end_offset) + { + this.EndOffset = end_offset; + } + //internal void Write(MyBinaryWriter bw) + //{ + // bw.WriteLeb128((int)this.BlockType); + // bw.WriteLeb128(this.Parent); + // bw.WriteLeb128(this.StartOffset); + // bw.WriteLeb128(this.EndOffset); + //} + public override string ToString() + { + return string.Format("[CodeBlock {0}:{1}:{2}:{3}:{4}]", new object[] + { + this.Index, + this.Parent, + this.BlockType, + this.StartOffset, + this.EndOffset + }); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CompileUnitEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CompileUnitEntry.cs new file mode 100644 index 00000000..1c150817 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/CompileUnitEntry.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.IO; +namespace Mono.CompilerServices.SymbolWriter +{ + public class CompileUnitEntry : ICompileUnit + { + public readonly int Index; + private int DataOffset; + private MonoSymbolFile file; + private SourceFileEntry source; + private List include_files; + private List namespaces; + private bool creating; + public static int Size + { + get + { + return 8; + } + } + CompileUnitEntry ICompileUnit.Entry + { + get + { + return this; + } + } + public SourceFileEntry SourceFile + { + get + { + SourceFileEntry result; + if (this.creating) + { + result = this.source; + } + else + { + this.ReadData(); + result = this.source; + } + return result; + } + } + public NamespaceEntry[] Namespaces + { + get + { + this.ReadData(); + NamespaceEntry[] retval = new NamespaceEntry[this.namespaces.Count]; + this.namespaces.CopyTo(retval, 0); + return retval; + } + } + public SourceFileEntry[] IncludeFiles + { + get + { + this.ReadData(); + SourceFileEntry[] result; + if (this.include_files == null) + { + result = new SourceFileEntry[0]; + } + else + { + SourceFileEntry[] retval = new SourceFileEntry[this.include_files.Count]; + this.include_files.CopyTo(retval, 0); + result = retval; + } + return result; + } + } + public CompileUnitEntry(MonoSymbolFile file, SourceFileEntry source) + { + this.file = file; + this.source = source; + this.Index = file.AddCompileUnit(this); + this.creating = true; + this.namespaces = new List(); + } + public void AddFile(SourceFileEntry file) + { + if (!this.creating) + { + throw new InvalidOperationException(); + } + if (this.include_files == null) + { + this.include_files = new List(); + } + this.include_files.Add(file); + } + public int DefineNamespace(string name, string[] using_clauses, int parent) + { + if (!this.creating) + { + throw new InvalidOperationException(); + } + int index = this.file.GetNextNamespaceIndex(); + NamespaceEntry ns = new NamespaceEntry(name, index, using_clauses, parent); + this.namespaces.Add(ns); + return index; + } + //internal void WriteData(MyBinaryWriter bw) + //{ + // this.DataOffset = (int)bw.BaseStream.Position; + // bw.WriteLeb128(this.source.Index); + // int count_includes = (this.include_files != null) ? this.include_files.Count : 0; + // bw.WriteLeb128(count_includes); + // if (this.include_files != null) + // { + // foreach (SourceFileEntry entry in this.include_files) + // { + // bw.WriteLeb128(entry.Index); + // } + // } + // bw.WriteLeb128(this.namespaces.Count); + // foreach (NamespaceEntry ns in this.namespaces) + // { + // ns.Write(this.file, bw); + // } + //} + //internal void Write(BinaryWriter bw) + //{ + // bw.Write(this.Index); + // bw.Write(this.DataOffset); + //} + internal CompileUnitEntry(MonoSymbolFile file, MyBinaryReader reader) + { + this.file = file; + this.Index = reader.ReadInt32(); + this.DataOffset = reader.ReadInt32(); + } + private void ReadData() + { + if (this.creating) + { + throw new InvalidOperationException(); + } + lock (this.file) + { + if (this.namespaces == null) + { + MyBinaryReader reader = this.file.BinaryReader; + int old_pos = (int)reader.BaseStream.Position; + reader.BaseStream.Position = (long)this.DataOffset; + int source_idx = reader.ReadLeb128(); + this.source = this.file.GetSourceFile(source_idx); + int count_includes = reader.ReadLeb128(); + if (count_includes > 0) + { + this.include_files = new List(); + for (int i = 0; i < count_includes; i++) + { + this.include_files.Add(this.file.GetSourceFile(reader.ReadLeb128())); + } + } + int count_ns = reader.ReadLeb128(); + this.namespaces = new List(); + for (int i = 0; i < count_ns; i++) + { + this.namespaces.Add(new NamespaceEntry(this.file, reader)); + } + reader.BaseStream.Position = (long)old_pos; + } + } + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ICompileUnit.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ICompileUnit.cs new file mode 100644 index 00000000..ea35a71e --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ICompileUnit.cs @@ -0,0 +1,11 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public interface ICompileUnit + { + CompileUnitEntry Entry + { + get; + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/IMethodDef.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/IMethodDef.cs new file mode 100644 index 00000000..60999589 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/IMethodDef.cs @@ -0,0 +1,15 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public interface IMethodDef + { + string Name + { + get; + } + int Token + { + get; + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ISourceFile.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ISourceFile.cs new file mode 100644 index 00000000..ee0b6f77 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ISourceFile.cs @@ -0,0 +1,11 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public interface ISourceFile + { + SourceFileEntry Entry + { + get; + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberEntry.cs new file mode 100644 index 00000000..2144cc7f --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberEntry.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +namespace Mono.CompilerServices.SymbolWriter +{ + public class LineNumberEntry + { + private class OffsetComparerClass : IComparer + { + public int Compare(LineNumberEntry l1, LineNumberEntry l2) + { + int result; + if (l1.Offset < l2.Offset) + { + result = -1; + } + else + { + if (l1.Offset > l2.Offset) + { + result = 1; + } + else + { + result = 0; + } + } + return result; + } + } + private class RowComparerClass : IComparer + { + public int Compare(LineNumberEntry l1, LineNumberEntry l2) + { + int result; + if (l1.Row < l2.Row) + { + result = -1; + } + else + { + if (l1.Row > l2.Row) + { + result = 1; + } + else + { + result = 0; + } + } + return result; + } + } + public readonly int Row; + public readonly int File; + public readonly int Offset; + public readonly bool IsHidden; + public static LineNumberEntry Null = new LineNumberEntry(0, 0, 0); + public static readonly IComparer OffsetComparer = new LineNumberEntry.OffsetComparerClass(); + public static readonly IComparer RowComparer = new LineNumberEntry.RowComparerClass(); + public LineNumberEntry(int file, int row, int offset) : this(file, row, offset, false) + { + } + public LineNumberEntry(int file, int row, int offset, bool is_hidden) + { + this.File = file; + this.Row = row; + this.Offset = offset; + this.IsHidden = is_hidden; + } + public override string ToString() + { + return string.Format("[Line {0}:{1}:{2}]", this.File, this.Row, this.Offset); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberTable.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberTable.cs new file mode 100644 index 00000000..2a3b56d5 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LineNumberTable.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections.Generic; +namespace Mono.CompilerServices.SymbolWriter +{ + public class LineNumberTable + { + public const int Default_LineBase = -1; + public const int Default_LineRange = 8; + public const byte Default_OpcodeBase = 9; + public const bool SuppressDuplicates = true; + public const byte DW_LNS_copy = 1; + public const byte DW_LNS_advance_pc = 2; + public const byte DW_LNS_advance_line = 3; + public const byte DW_LNS_set_file = 4; + public const byte DW_LNS_const_add_pc = 8; + public const byte DW_LNE_end_sequence = 1; + public const byte DW_LNE_MONO_negate_is_hidden = 64; + internal const byte DW_LNE_MONO__extensions_start = 64; + internal const byte DW_LNE_MONO__extensions_end = 127; + protected LineNumberEntry[] _line_numbers; + public readonly int LineBase; + public readonly int LineRange; + public readonly byte OpcodeBase; + public readonly int MaxAddressIncrement; + public LineNumberEntry[] LineNumbers + { + get + { + return this._line_numbers; + } + } + protected LineNumberTable(MonoSymbolFile file) + { + this.LineBase = file.OffsetTable.LineNumberTable_LineBase; + this.LineRange = file.OffsetTable.LineNumberTable_LineRange; + this.OpcodeBase = (byte)file.OffsetTable.LineNumberTable_OpcodeBase; + this.MaxAddressIncrement = (int)(255 - this.OpcodeBase) / this.LineRange; + } + internal LineNumberTable(MonoSymbolFile file, LineNumberEntry[] lines) : this(file) + { + this._line_numbers = lines; + } + //internal void Write(MonoSymbolFile file, MyBinaryWriter bw) + //{ + // int start = (int)bw.BaseStream.Position; + // bool last_is_hidden = false; + // int last_line = 1; + // int last_offset = 0; + // int last_file = 1; + // int i = 0; + // while (i < this.LineNumbers.Length) + // { + // int line_inc = this.LineNumbers[i].Row - last_line; + // int offset_inc = this.LineNumbers[i].Offset - last_offset; + // if (i + 1 >= this.LineNumbers.Length) + // { + // goto IL_84; + // } + // if (!this.LineNumbers[i + 1].Equals(this.LineNumbers[i])) + // { + // goto IL_84; + // } + // IL_207: + // i++; + // continue; + // IL_84: + // if (this.LineNumbers[i].File != last_file) + // { + // bw.Write(4); + // bw.WriteLeb128(this.LineNumbers[i].File); + // last_file = this.LineNumbers[i].File; + // } + // if (this.LineNumbers[i].IsHidden != last_is_hidden) + // { + // bw.Write(0); + // bw.Write(1); + // bw.Write(64); + // last_is_hidden = this.LineNumbers[i].IsHidden; + // } + // if (offset_inc >= this.MaxAddressIncrement) + // { + // if (offset_inc < 2 * this.MaxAddressIncrement) + // { + // bw.Write(8); + // offset_inc -= this.MaxAddressIncrement; + // } + // else + // { + // bw.Write(2); + // bw.WriteLeb128(offset_inc); + // offset_inc = 0; + // } + // } + // if (line_inc < this.LineBase || line_inc >= this.LineBase + this.LineRange) + // { + // bw.Write(3); + // bw.WriteLeb128(line_inc); + // if (offset_inc != 0) + // { + // bw.Write(2); + // bw.WriteLeb128(offset_inc); + // } + // bw.Write(1); + // } + // else + // { + // byte opcode = (byte)(line_inc - this.LineBase + this.LineRange * offset_inc + (int)this.OpcodeBase); + // bw.Write(opcode); + // } + // last_line = this.LineNumbers[i].Row; + // last_offset = this.LineNumbers[i].Offset; + // goto IL_207; + // } + // bw.Write(0); + // bw.Write(1); + // bw.Write(1); + // file.ExtendedLineNumberSize += (int)bw.BaseStream.Position - start; + //} + internal static LineNumberTable Read(MonoSymbolFile file, MyBinaryReader br) + { + LineNumberTable lnt = new LineNumberTable(file); + lnt.DoRead(file, br); + return lnt; + } + private void DoRead(MonoSymbolFile file, MyBinaryReader br) + { + List lines = new List(); + bool is_hidden = false; + bool modified = false; + int stm_line = 1; + int stm_offset = 0; + int stm_file = 1; + byte opcode; + while (true) + { + opcode = br.ReadByte(); + if (opcode == 0) + { + byte size = br.ReadByte(); + long end_pos = br.BaseStream.Position + (long)((ulong)size); + opcode = br.ReadByte(); + if (opcode == 1) + { + break; + } + if (opcode == 64) + { + is_hidden = !is_hidden; + modified = true; + } + else + { + if (opcode < 64 || opcode > 127) + { + goto IL_B8; + } + } + br.BaseStream.Position = end_pos; + } + else + { + if (opcode < this.OpcodeBase) + { + switch (opcode) + { + case 1: + lines.Add(new LineNumberEntry(stm_file, stm_line, stm_offset, is_hidden)); + modified = false; + continue; + case 2: + stm_offset += br.ReadLeb128(); + modified = true; + continue; + case 3: + stm_line += br.ReadLeb128(); + modified = true; + continue; + case 4: + stm_file = br.ReadLeb128(); + modified = true; + continue; + case 8: + stm_offset += this.MaxAddressIncrement; + modified = true; + continue; + } + goto Block_8; + } + opcode -= this.OpcodeBase; + stm_offset += (int)opcode / this.LineRange; + stm_line += this.LineBase + (int)opcode % this.LineRange; + lines.Add(new LineNumberEntry(stm_file, stm_line, stm_offset, is_hidden)); + modified = false; + } + } + if (modified) + { + lines.Add(new LineNumberEntry(stm_file, stm_line, stm_offset, is_hidden)); + } + this._line_numbers = new LineNumberEntry[lines.Count]; + lines.CopyTo(this._line_numbers, 0); + return; + IL_B8: + throw new MonoSymbolFileException("Unknown extended opcode {0:x} in LNT ({1})", new object[] + { + opcode, + file.FileName + }); + Block_8: + throw new MonoSymbolFileException("Unknown standard opcode {0:x} in LNT", new object[] + { + opcode + }); + } + public bool GetMethodBounds(out LineNumberEntry start, out LineNumberEntry end) + { + bool result; + if (this._line_numbers.Length > 1) + { + start = this._line_numbers[0]; + end = this._line_numbers[this._line_numbers.Length - 1]; + result = true; + } + else + { + start = LineNumberEntry.Null; + end = LineNumberEntry.Null; + result = false; + } + return result; + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LocalVariableEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LocalVariableEntry.cs new file mode 100644 index 00000000..56cc8223 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/LocalVariableEntry.cs @@ -0,0 +1,32 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public struct LocalVariableEntry + { + public readonly int Index; + public readonly string Name; + public readonly int BlockIndex; + public LocalVariableEntry(int index, string name, int block) + { + this.Index = index; + this.Name = name; + this.BlockIndex = block; + } + internal LocalVariableEntry(MonoSymbolFile file, MyBinaryReader reader) + { + this.Index = reader.ReadLeb128(); + this.Name = reader.ReadString(); + this.BlockIndex = reader.ReadLeb128(); + } + //internal void Write(MonoSymbolFile file, MyBinaryWriter bw) + //{ + // bw.WriteLeb128(this.Index); + // bw.Write(this.Name); + // bw.WriteLeb128(this.BlockIndex); + //} + public override string ToString() + { + return string.Format("[LocalVariable {0}:{1}:{2}]", this.Name, this.Index, this.BlockIndex - 1); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MethodEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MethodEntry.cs new file mode 100644 index 00000000..c0e876e8 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MethodEntry.cs @@ -0,0 +1,385 @@ +using System; +using System.Collections.Generic; +namespace Mono.CompilerServices.SymbolWriter +{ + public class MethodEntry : IComparable + { + [Flags] + public enum Flags + { + LocalNamesAmbiguous = 1 + } + public const int Size = 12; + public readonly int CompileUnitIndex; + public readonly int Token; + public readonly int NamespaceID; + private int DataOffset; + private int LocalVariableTableOffset; + private int LineNumberTableOffset; + private int CodeBlockTableOffset; + private int ScopeVariableTableOffset; + private int RealNameOffset; + private MethodEntry.Flags flags; + private int index; + public readonly CompileUnitEntry CompileUnit; + private LocalVariableEntry[] locals; + private CodeBlockEntry[] code_blocks; + private ScopeVariable[] scope_vars; + private LineNumberTable lnt; + private string real_name; + public readonly MonoSymbolFile SymbolFile; + public MethodEntry.Flags MethodFlags + { + get + { + return this.flags; + } + } + public int Index + { + get + { + return this.index; + } + set + { + this.index = value; + } + } + internal MethodEntry(MonoSymbolFile file, MyBinaryReader reader, int index) + { + this.SymbolFile = file; + this.index = index; + this.Token = reader.ReadInt32(); + this.DataOffset = reader.ReadInt32(); + this.LineNumberTableOffset = reader.ReadInt32(); + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = (long)this.DataOffset; + this.CompileUnitIndex = reader.ReadLeb128(); + this.LocalVariableTableOffset = reader.ReadLeb128(); + this.NamespaceID = reader.ReadLeb128(); + this.CodeBlockTableOffset = reader.ReadLeb128(); + this.ScopeVariableTableOffset = reader.ReadLeb128(); + this.RealNameOffset = reader.ReadLeb128(); + this.flags = (MethodEntry.Flags)reader.ReadLeb128(); + reader.BaseStream.Position = old_pos; + this.CompileUnit = file.GetCompileUnit(this.CompileUnitIndex); + } + internal MethodEntry(MonoSymbolFile file, CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id) + { + this.SymbolFile = file; + this.real_name = real_name; + this.locals = locals; + this.code_blocks = code_blocks; + this.scope_vars = scope_vars; + this.flags = flags; + this.index = -1; + this.Token = token; + this.CompileUnitIndex = comp_unit.Index; + this.CompileUnit = comp_unit; + this.NamespaceID = namespace_id; + this.CheckLineNumberTable(lines); + this.lnt = new LineNumberTable(file, lines); + file.NumLineNumbers += lines.Length; + int num_locals = (locals != null) ? locals.Length : 0; + if (num_locals <= 32) + { + for (int i = 0; i < num_locals; i++) + { + string nm = locals[i].Name; + for (int j = i + 1; j < num_locals; j++) + { + if (locals[j].Name == nm) + { + flags |= MethodEntry.Flags.LocalNamesAmbiguous; + goto IL_108; + } + } + } + IL_108:; + } + else + { + Dictionary local_names = new Dictionary(); + for (int k = 0; k < locals.Length; k++) + { + LocalVariableEntry local = locals[k]; + if (local_names.ContainsKey(local.Name)) + { + flags |= MethodEntry.Flags.LocalNamesAmbiguous; + break; + } + local_names.Add(local.Name, local); + } + } + } + private void CheckLineNumberTable(LineNumberEntry[] line_numbers) + { + int last_offset = -1; + int last_row = -1; + if (line_numbers != null) + { + for (int i = 0; i < line_numbers.Length; i++) + { + LineNumberEntry line = line_numbers[i]; + if (line.Equals(LineNumberEntry.Null)) + { + throw new MonoSymbolFileException(); + } + if (line.Offset < last_offset) + { + throw new MonoSymbolFileException(); + } + if (line.Offset > last_offset) + { + last_row = line.Row; + last_offset = line.Offset; + } + else + { + if (line.Row > last_row) + { + last_row = line.Row; + } + } + } + } + } + //internal void Write(MyBinaryWriter bw) + //{ + // if (this.index <= 0 || this.DataOffset == 0) + // { + // throw new InvalidOperationException(); + // } + // bw.Write(this.Token); + // bw.Write(this.DataOffset); + // bw.Write(this.LineNumberTableOffset); + //} + //internal void WriteData(MonoSymbolFile file, MyBinaryWriter bw) + //{ + // if (this.index <= 0) + // { + // throw new InvalidOperationException(); + // } + // this.LocalVariableTableOffset = (int)bw.BaseStream.Position; + // int num_locals = (this.locals != null) ? this.locals.Length : 0; + // bw.WriteLeb128(num_locals); + // for (int i = 0; i < num_locals; i++) + // { + // this.locals[i].Write(file, bw); + // } + // file.LocalCount += num_locals; + // this.CodeBlockTableOffset = (int)bw.BaseStream.Position; + // int num_code_blocks = (this.code_blocks != null) ? this.code_blocks.Length : 0; + // bw.WriteLeb128(num_code_blocks); + // for (int i = 0; i < num_code_blocks; i++) + // { + // this.code_blocks[i].Write(bw); + // } + // this.ScopeVariableTableOffset = (int)bw.BaseStream.Position; + // int num_scope_vars = (this.scope_vars != null) ? this.scope_vars.Length : 0; + // bw.WriteLeb128(num_scope_vars); + // for (int i = 0; i < num_scope_vars; i++) + // { + // this.scope_vars[i].Write(bw); + // } + // if (this.real_name != null) + // { + // this.RealNameOffset = (int)bw.BaseStream.Position; + // bw.Write(this.real_name); + // } + // this.LineNumberTableOffset = (int)bw.BaseStream.Position; + // this.lnt.Write(file, bw); + // this.DataOffset = (int)bw.BaseStream.Position; + // bw.WriteLeb128(this.CompileUnitIndex); + // bw.WriteLeb128(this.LocalVariableTableOffset); + // bw.WriteLeb128(this.NamespaceID); + // bw.WriteLeb128(this.CodeBlockTableOffset); + // bw.WriteLeb128(this.ScopeVariableTableOffset); + // bw.WriteLeb128(this.RealNameOffset); + // bw.WriteLeb128((int)this.flags); + //} + public LineNumberTable GetLineNumberTable() + { + LineNumberTable result; + lock (this.SymbolFile) + { + if (this.lnt != null) + { + result = this.lnt; + } + else + { + if (this.LineNumberTableOffset == 0) + { + result = null; + } + else + { + MyBinaryReader reader = this.SymbolFile.BinaryReader; + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = (long)this.LineNumberTableOffset; + this.lnt = LineNumberTable.Read(this.SymbolFile, reader); + reader.BaseStream.Position = old_pos; + result = this.lnt; + } + } + } + return result; + } + public LocalVariableEntry[] GetLocals() + { + LocalVariableEntry[] result; + lock (this.SymbolFile) + { + if (this.locals != null) + { + result = this.locals; + } + else + { + if (this.LocalVariableTableOffset == 0) + { + result = null; + } + else + { + MyBinaryReader reader = this.SymbolFile.BinaryReader; + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = (long)this.LocalVariableTableOffset; + int num_locals = reader.ReadLeb128(); + this.locals = new LocalVariableEntry[num_locals]; + for (int i = 0; i < num_locals; i++) + { + this.locals[i] = new LocalVariableEntry(this.SymbolFile, reader); + } + reader.BaseStream.Position = old_pos; + result = this.locals; + } + } + } + return result; + } + public CodeBlockEntry[] GetCodeBlocks() + { + CodeBlockEntry[] result; + lock (this.SymbolFile) + { + if (this.code_blocks != null) + { + result = this.code_blocks; + } + else + { + if (this.CodeBlockTableOffset == 0) + { + result = null; + } + else + { + MyBinaryReader reader = this.SymbolFile.BinaryReader; + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = (long)this.CodeBlockTableOffset; + int num_code_blocks = reader.ReadLeb128(); + this.code_blocks = new CodeBlockEntry[num_code_blocks]; + for (int i = 0; i < num_code_blocks; i++) + { + this.code_blocks[i] = new CodeBlockEntry(i, reader); + } + reader.BaseStream.Position = old_pos; + result = this.code_blocks; + } + } + } + return result; + } + public ScopeVariable[] GetScopeVariables() + { + ScopeVariable[] result; + lock (this.SymbolFile) + { + if (this.scope_vars != null) + { + result = this.scope_vars; + } + else + { + if (this.ScopeVariableTableOffset == 0) + { + result = null; + } + else + { + MyBinaryReader reader = this.SymbolFile.BinaryReader; + long old_pos = reader.BaseStream.Position; + reader.BaseStream.Position = (long)this.ScopeVariableTableOffset; + int num_scope_vars = reader.ReadLeb128(); + this.scope_vars = new ScopeVariable[num_scope_vars]; + for (int i = 0; i < num_scope_vars; i++) + { + this.scope_vars[i] = new ScopeVariable(reader); + } + reader.BaseStream.Position = old_pos; + result = this.scope_vars; + } + } + } + return result; + } + public string GetRealName() + { + string result; + lock (this.SymbolFile) + { + if (this.real_name != null) + { + result = this.real_name; + } + else + { + if (this.RealNameOffset == 0) + { + result = null; + } + else + { + this.real_name = this.SymbolFile.BinaryReader.ReadString(this.RealNameOffset); + result = this.real_name; + } + } + } + return result; + } + public int CompareTo(object obj) + { + MethodEntry method = (MethodEntry)obj; + int result; + if (method.Token < this.Token) + { + result = 1; + } + else + { + if (method.Token > this.Token) + { + result = -1; + } + else + { + result = 0; + } + } + return result; + } + public override string ToString() + { + return string.Format("[Method {0}:{1:x}:{2}:{3}]", new object[] + { + this.index, + this.Token, + this.CompileUnitIndex, + this.CompileUnit + }); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs new file mode 100644 index 00000000..2204cace --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs @@ -0,0 +1,635 @@ +using Mono.Cecil; +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; +namespace Mono.CompilerServices.SymbolWriter +{ + public class MonoSymbolFile : IDisposable + { + private List methods = new List(); + private List sources = new List(); + private List comp_units = new List(); + private Dictionary type_hash = new Dictionary(); + private Dictionary anonymous_scopes; + private OffsetTable ot; + private int last_type_index; + private int last_method_index; + private int last_namespace_index; + public readonly string FileName = ""; + public readonly int MajorVersion = 50; + public readonly int MinorVersion = 0; + public int NumLineNumbers; + private MyBinaryReader reader; + private Dictionary source_file_hash; + private Dictionary compile_unit_hash; + private List method_list; + private Dictionary method_token_hash; + private Dictionary source_name_hash; + private Guid guid; + internal int LineNumberCount = 0; + internal int LocalCount = 0; + internal int StringSize = 0; + internal int LineNumberSize = 0; + internal int ExtendedLineNumberSize = 0; + public int CompileUnitCount + { + get + { + return this.ot.CompileUnitCount; + } + } + public int SourceCount + { + get + { + return this.ot.SourceCount; + } + } + public int MethodCount + { + get + { + return this.ot.MethodCount; + } + } + public int TypeCount + { + get + { + return this.ot.TypeCount; + } + } + public int AnonymousScopeCount + { + get + { + return this.ot.AnonymousScopeCount; + } + } + public int NamespaceCount + { + get + { + return this.last_namespace_index; + } + } + public Guid Guid + { + get + { + return this.guid; + } + } + public OffsetTable OffsetTable + { + get + { + return this.ot; + } + } + public SourceFileEntry[] Sources + { + get + { + if (this.reader == null) + { + throw new InvalidOperationException(); + } + SourceFileEntry[] retval = new SourceFileEntry[this.SourceCount]; + for (int i = 0; i < this.SourceCount; i++) + { + retval[i] = this.GetSourceFile(i + 1); + } + return retval; + } + } + public CompileUnitEntry[] CompileUnits + { + get + { + if (this.reader == null) + { + throw new InvalidOperationException(); + } + CompileUnitEntry[] retval = new CompileUnitEntry[this.CompileUnitCount]; + for (int i = 0; i < this.CompileUnitCount; i++) + { + retval[i] = this.GetCompileUnit(i + 1); + } + return retval; + } + } + public MethodEntry[] Methods + { + get + { + if (this.reader == null) + { + throw new InvalidOperationException(); + } + bool flag = false; + MethodEntry[] result; + + this.read_methods(); + MethodEntry[] retval = new MethodEntry[this.MethodCount]; + this.method_list.CopyTo(retval, 0); + result = retval; + + return result; + } + } + internal MyBinaryReader BinaryReader + { + get + { + if (this.reader == null) + { + throw new InvalidOperationException(); + } + return this.reader; + } + } + internal MonoSymbolFile() + { + this.ot = new OffsetTable(); + } + internal int AddSource(SourceFileEntry source) + { + this.sources.Add(source); + return this.sources.Count; + } + internal int AddCompileUnit(CompileUnitEntry entry) + { + this.comp_units.Add(entry); + return this.comp_units.Count; + } + internal int DefineType(Type type) + { + int index; + int result; + if (this.type_hash.TryGetValue(type, out index)) + { + result = index; + } + else + { + index = ++this.last_type_index; + this.type_hash.Add(type, index); + result = index; + } + return result; + } + internal void AddMethod(MethodEntry entry) + { + this.methods.Add(entry); + } + public MethodEntry DefineMethod(CompileUnitEntry comp_unit, int token, ScopeVariable[] scope_vars, LocalVariableEntry[] locals, LineNumberEntry[] lines, CodeBlockEntry[] code_blocks, string real_name, MethodEntry.Flags flags, int namespace_id) + { + if (this.reader != null) + { + throw new InvalidOperationException(); + } + MethodEntry method = new MethodEntry(this, comp_unit, token, scope_vars, locals, lines, code_blocks, real_name, flags, namespace_id); + this.AddMethod(method); + return method; + } + internal void DefineAnonymousScope(int id) + { + if (this.reader != null) + { + throw new InvalidOperationException(); + } + if (this.anonymous_scopes == null) + { + this.anonymous_scopes = new Dictionary(); + } + this.anonymous_scopes.Add(id, new AnonymousScopeEntry(id)); + } + internal void DefineCapturedVariable(int scope_id, string name, string captured_name, CapturedVariable.CapturedKind kind) + { + if (this.reader != null) + { + throw new InvalidOperationException(); + } + AnonymousScopeEntry scope = this.anonymous_scopes[scope_id]; + scope.AddCapturedVariable(name, captured_name, kind); + } + internal void DefineCapturedScope(int scope_id, int id, string captured_name) + { + if (this.reader != null) + { + throw new InvalidOperationException(); + } + AnonymousScopeEntry scope = this.anonymous_scopes[scope_id]; + scope.AddCapturedScope(id, captured_name); + } + internal int GetNextTypeIndex() + { + return ++this.last_type_index; + } + internal int GetNextMethodIndex() + { + return ++this.last_method_index; + } + internal int GetNextNamespaceIndex() + { + return ++this.last_namespace_index; + } + //private void Write(MyBinaryWriter bw, Guid guid) + //{ + // bw.Write(5037318119232611860L); + // bw.Write(this.MajorVersion); + // bw.Write(this.MinorVersion); + // bw.Write(guid.ToByteArray()); + // long offset_table_offset = bw.BaseStream.Position; + // this.ot.Write(bw, this.MajorVersion, this.MinorVersion); + // this.methods.Sort(); + // for (int i = 0; i < this.methods.Count; i++) + // { + // this.methods[i].Index = i + 1; + // } + // this.ot.DataSectionOffset = (int)bw.BaseStream.Position; + // foreach (SourceFileEntry source in this.sources) + // { + // //SourceFileEntry source; + // source.WriteData(bw); + // } + // foreach (CompileUnitEntry comp_unit in this.comp_units) + // { + // comp_unit.WriteData(bw); + // } + // foreach (MethodEntry method in this.methods) + // { + // method.WriteData(this, bw); + // } + // this.ot.DataSectionSize = (int)bw.BaseStream.Position - this.ot.DataSectionOffset; + // this.ot.MethodTableOffset = (int)bw.BaseStream.Position; + // for (int i = 0; i < this.methods.Count; i++) + // { + // MethodEntry entry = this.methods[i]; + // entry.Write(bw); + // } + // this.ot.MethodTableSize = (int)bw.BaseStream.Position - this.ot.MethodTableOffset; + // this.ot.SourceTableOffset = (int)bw.BaseStream.Position; + // for (int i = 0; i < this.sources.Count; i++) + // { + // SourceFileEntry source = this.sources[i]; + // source.Write(bw); + // } + // this.ot.SourceTableSize = (int)bw.BaseStream.Position - this.ot.SourceTableOffset; + // this.ot.CompileUnitTableOffset = (int)bw.BaseStream.Position; + // for (int i = 0; i < this.comp_units.Count; i++) + // { + // CompileUnitEntry unit = this.comp_units[i]; + // unit.Write(bw); + // } + // this.ot.CompileUnitTableSize = (int)bw.BaseStream.Position - this.ot.CompileUnitTableOffset; + // this.ot.AnonymousScopeCount = ((this.anonymous_scopes != null) ? this.anonymous_scopes.Count : 0); + // this.ot.AnonymousScopeTableOffset = (int)bw.BaseStream.Position; + // if (this.anonymous_scopes != null) + // { + // foreach (AnonymousScopeEntry scope in this.anonymous_scopes.Values) + // { + // scope.Write(bw); + // } + // } + // this.ot.AnonymousScopeTableSize = (int)bw.BaseStream.Position - this.ot.AnonymousScopeTableOffset; + // this.ot.TypeCount = this.last_type_index; + // this.ot.MethodCount = this.methods.Count; + // this.ot.SourceCount = this.sources.Count; + // this.ot.CompileUnitCount = this.comp_units.Count; + // this.ot.TotalFileSize = (int)bw.BaseStream.Position; + // bw.Seek((int)offset_table_offset, SeekOrigin.Begin); + // this.ot.Write(bw, this.MajorVersion, this.MinorVersion); + // bw.Seek(0, SeekOrigin.End); + //} + //public void CreateSymbolFile(Guid guid, FileStream fs) + //{ + // if (this.reader != null) + // { + // throw new InvalidOperationException(); + // } + // this.Write(new MyBinaryWriter(fs), guid); + //} + private MonoSymbolFile(System.IO.Stream stream) + { + //this.FileName = filename; + //FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read); + this.reader = new MyBinaryReader(stream); + try + { + long magic = this.reader.ReadInt64(); + int major_version = this.reader.ReadInt32(); + int minor_version = this.reader.ReadInt32(); + if (magic != 5037318119232611860L) + { + throw new MonoSymbolFileException("Symbol file `{0}' is not a valid Mono symbol file", new object[] + { + //filename + }); + } + if (major_version != 50) + { + throw new MonoSymbolFileException("Symbol file `{0}' has version {1}, but expected {2}", new object[] + { + //filename, + major_version, + 50 + }); + } + if (minor_version != 0) + { + throw new MonoSymbolFileException("Symbol file `{0}' has version {1}.{2}, but expected {3}.{4}", new object[] + { + //filename, + major_version, + minor_version, + 50, + 0 + }); + } + this.MajorVersion = major_version; + this.MinorVersion = minor_version; + this.guid = new Guid(this.reader.ReadBytes(16)); + this.ot = new OffsetTable(this.reader, major_version, minor_version); + } + catch + { + throw new MonoSymbolFileException("Cannot read symbol file `{0}'", new object[] + { + //filename + }); + } + this.source_file_hash = new Dictionary(); + this.compile_unit_hash = new Dictionary(); + } + private MonoSymbolFile(string filename) + { + this.FileName = filename; + FileStream stream = new FileStream(filename, FileMode.Open, FileAccess.Read); + this.reader = new MyBinaryReader(stream); + try + { + long magic = this.reader.ReadInt64(); + int major_version = this.reader.ReadInt32(); + int minor_version = this.reader.ReadInt32(); + if (magic != 5037318119232611860L) + { + throw new MonoSymbolFileException("Symbol file `{0}' is not a valid Mono symbol file", new object[] + { + filename + }); + } + if (major_version != 50) + { + throw new MonoSymbolFileException("Symbol file `{0}' has version {1}, but expected {2}", new object[] + { + filename, + major_version, + 50 + }); + } + if (minor_version != 0) + { + throw new MonoSymbolFileException("Symbol file `{0}' has version {1}.{2}, but expected {3}.{4}", new object[] + { + filename, + major_version, + minor_version, + 50, + 0 + }); + } + this.MajorVersion = major_version; + this.MinorVersion = minor_version; + this.guid = new Guid(this.reader.ReadBytes(16)); + this.ot = new OffsetTable(this.reader, major_version, minor_version); + } + catch + { + throw new MonoSymbolFileException("Cannot read symbol file `{0}'", new object[] + { + filename + }); + } + this.source_file_hash = new Dictionary(); + this.compile_unit_hash = new Dictionary(); + } + private void CheckGuidMatch(Guid other, string filename, string assembly) + { + if (other == this.guid) + { + return; + } + throw new MonoSymbolFileException("Symbol file `{0}' does not match assembly `{1}'", new object[] + { + filename, + assembly + }); + } + protected MonoSymbolFile(string filename, ModuleDefinition module) + : this(filename) + { + if (module != null) + { + this.CheckGuidMatch(module.Mvid, filename, module.FullyQualifiedName); + } + } + protected MonoSymbolFile(System.IO.Stream stream, ModuleDefinition module) + : this(stream) + { + if (module != null) + { + //this.CheckGuidMatch(module.Mvid, filename, module.FullyQualifiedName); + } + } + public static MonoSymbolFile ReadSymbolFile(ModuleDefinition module) + { + return MonoSymbolFile.ReadSymbolFile(module, module.FullyQualifiedName); + } + public static MonoSymbolFile ReadSymbolFile(ModuleDefinition module, string filename) + { + string name = filename + ".mdb"; + return new MonoSymbolFile(name, module); + } + public static MonoSymbolFile ReadSymbolFile(ModuleDefinition module, System.IO.Stream stream) + { + return new MonoSymbolFile(stream, module); + } + public static MonoSymbolFile ReadSymbolFile(string mdbFilename) + { + return new MonoSymbolFile(mdbFilename); + } + public SourceFileEntry GetSourceFile(int index) + { + if (index < 1 || index > this.ot.SourceCount) + { + throw new ArgumentException(); + } + if (this.reader == null) + { + throw new InvalidOperationException(); + } + SourceFileEntry result; + + SourceFileEntry source; + if (this.source_file_hash.TryGetValue(index, out source)) + { + result = source; + } + else + { + long old_pos = this.reader.BaseStream.Position; + this.reader.BaseStream.Position = (long)(this.ot.SourceTableOffset + SourceFileEntry.Size * (index - 1)); + source = new SourceFileEntry(this, this.reader); + this.source_file_hash.Add(index, source); + this.reader.BaseStream.Position = old_pos; + result = source; + } + + return result; + } + public CompileUnitEntry GetCompileUnit(int index) + { + if (index < 1 || index > this.ot.CompileUnitCount) + { + throw new ArgumentException(); + } + if (this.reader == null) + { + throw new InvalidOperationException(); + } + CompileUnitEntry result; + CompileUnitEntry unit; + if (this.compile_unit_hash.TryGetValue(index, out unit)) + { + result = unit; + } + else + { + long old_pos = this.reader.BaseStream.Position; + this.reader.BaseStream.Position = (long)(this.ot.CompileUnitTableOffset + CompileUnitEntry.Size * (index - 1)); + unit = new CompileUnitEntry(this, this.reader); + this.compile_unit_hash.Add(index, unit); + this.reader.BaseStream.Position = old_pos; + result = unit; + } + return result; + } + private void read_methods() + { + if (this.method_token_hash == null) + { + this.method_token_hash = new Dictionary(); + this.method_list = new List(); + long old_pos = this.reader.BaseStream.Position; + this.reader.BaseStream.Position = (long)this.ot.MethodTableOffset; + for (int i = 0; i < this.MethodCount; i++) + { + MethodEntry entry = new MethodEntry(this, this.reader, i + 1); + this.method_token_hash.Add(entry.Token, entry); + this.method_list.Add(entry); + } + this.reader.BaseStream.Position = old_pos; + } + } + public MethodEntry GetMethodByToken(int token) + { + if (this.reader == null) + { + throw new InvalidOperationException(); + } + MethodEntry result; + this.read_methods(); + MethodEntry me; + this.method_token_hash.TryGetValue(token, out me); + result = me; + return result; + } + public MethodEntry GetMethod(int index) + { + if (index < 1 || index > this.ot.MethodCount) + { + throw new ArgumentException(); + } + if (this.reader == null) + { + throw new InvalidOperationException(); + } + MethodEntry result; + this.read_methods(); + result = this.method_list[index - 1]; + return result; + } + public int FindSource(string file_name) + { + if (this.reader == null) + { + throw new InvalidOperationException(); + } + int result; + if (this.source_name_hash == null) + { + this.source_name_hash = new Dictionary(); + for (int i = 0; i < this.ot.SourceCount; i++) + { + SourceFileEntry source = this.GetSourceFile(i + 1); + this.source_name_hash.Add(source.FileName, i); + } + } + int value; + if (!this.source_name_hash.TryGetValue(file_name, out value)) + { + result = -1; + } + else + { + result = value; + } + return result; + } + public AnonymousScopeEntry GetAnonymousScope(int id) + { + if (this.reader == null) + { + throw new InvalidOperationException(); + } + AnonymousScopeEntry result; + if (this.anonymous_scopes != null) + { + AnonymousScopeEntry scope; + this.anonymous_scopes.TryGetValue(id, out scope); + result = scope; + } + else + { + this.anonymous_scopes = new Dictionary(); + this.reader.BaseStream.Position = (long)this.ot.AnonymousScopeTableOffset; + for (int i = 0; i < this.ot.AnonymousScopeCount; i++) + { + AnonymousScopeEntry scope = new AnonymousScopeEntry(this.reader); + this.anonymous_scopes.Add(scope.ID, scope); + } + result = this.anonymous_scopes[id]; + } + + return result; + } + public void Dispose() + { + this.Dispose(true); + } + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + if (this.reader != null) + { + this.reader.Close(); + this.reader = null; + } + } + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFileException.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFileException.cs new file mode 100644 index 00000000..f3750ab4 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFileException.cs @@ -0,0 +1,13 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public class MonoSymbolFileException : Exception + { + public MonoSymbolFileException() + { + } + public MonoSymbolFileException(string message, params object[] args) : base(string.Format(message, args)) + { + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs new file mode 100644 index 00000000..a8b38380 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs @@ -0,0 +1,182 @@ +//using System; +//using System.Collections.Generic; +//using System.IO; +//namespace Mono.CompilerServices.SymbolWriter +//{ +// public class MonoSymbolWriter +// { +// private List methods; +// private List sources; +// private List comp_units; +// protected readonly MonoSymbolFile file; +// private string filename; +// private SourceMethodBuilder current_method; +// private Stack current_method_stack = new Stack(); +// public MonoSymbolFile SymbolFile +// { +// get +// { +// return this.file; +// } +// } +// public MonoSymbolWriter(string filename) +// { +// this.methods = new List(); +// this.sources = new List(); +// this.comp_units = new List(); +// this.file = new MonoSymbolFile(); +// this.filename = filename + ".mdb"; +// } +// public void CloseNamespace() +// { +// } +// public void DefineLocalVariable(int index, string name) +// { +// if (this.current_method != null) +// { +// this.current_method.AddLocal(index, name); +// } +// } +// public void DefineCapturedLocal(int scope_id, string name, string captured_name) +// { +// this.file.DefineCapturedVariable(scope_id, name, captured_name, CapturedVariable.CapturedKind.Local); +// } +// public void DefineCapturedParameter(int scope_id, string name, string captured_name) +// { +// this.file.DefineCapturedVariable(scope_id, name, captured_name, CapturedVariable.CapturedKind.Parameter); +// } +// public void DefineCapturedThis(int scope_id, string captured_name) +// { +// this.file.DefineCapturedVariable(scope_id, "this", captured_name, CapturedVariable.CapturedKind.This); +// } +// public void DefineCapturedScope(int scope_id, int id, string captured_name) +// { +// this.file.DefineCapturedScope(scope_id, id, captured_name); +// } +// public void DefineScopeVariable(int scope, int index) +// { +// if (this.current_method != null) +// { +// this.current_method.AddScopeVariable(scope, index); +// } +// } +// public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden) +// { +// if (this.current_method != null) +// { +// this.current_method.MarkSequencePoint(offset, file, line, column, is_hidden); +// } +// } +// public SourceMethodBuilder OpenMethod(ICompileUnit file, int ns_id, IMethodDef method) +// { +// SourceMethodBuilder builder = new SourceMethodBuilder(file, ns_id, method); +// this.current_method_stack.Push(this.current_method); +// this.current_method = builder; +// this.methods.Add(this.current_method); +// return builder; +// } +// public void CloseMethod() +// { +// this.current_method = this.current_method_stack.Pop(); +// } +// public SourceFileEntry DefineDocument(string url) +// { +// SourceFileEntry entry = new SourceFileEntry(this.file, url); +// this.sources.Add(entry); +// return entry; +// } +// public SourceFileEntry DefineDocument(string url, byte[] guid, byte[] checksum) +// { +// SourceFileEntry entry = new SourceFileEntry(this.file, url, guid, checksum); +// this.sources.Add(entry); +// return entry; +// } +// public CompileUnitEntry DefineCompilationUnit(SourceFileEntry source) +// { +// CompileUnitEntry entry = new CompileUnitEntry(this.file, source); +// this.comp_units.Add(entry); +// return entry; +// } +// public int DefineNamespace(string name, CompileUnitEntry unit, string[] using_clauses, int parent) +// { +// if (unit == null || using_clauses == null) +// { +// throw new NullReferenceException(); +// } +// return unit.DefineNamespace(name, using_clauses, parent); +// } +// public int OpenScope(int start_offset) +// { +// int result; +// if (this.current_method == null) +// { +// result = 0; +// } +// else +// { +// this.current_method.StartBlock(CodeBlockEntry.Type.Lexical, start_offset); +// result = 0; +// } +// return result; +// } +// public void CloseScope(int end_offset) +// { +// if (this.current_method != null) +// { +// this.current_method.EndBlock(end_offset); +// } +// } +// public void OpenCompilerGeneratedBlock(int start_offset) +// { +// if (this.current_method != null) +// { +// this.current_method.StartBlock(CodeBlockEntry.Type.CompilerGenerated, start_offset); +// } +// } +// public void CloseCompilerGeneratedBlock(int end_offset) +// { +// if (this.current_method != null) +// { +// this.current_method.EndBlock(end_offset); +// } +// } +// public void StartIteratorBody(int start_offset) +// { +// this.current_method.StartBlock(CodeBlockEntry.Type.IteratorBody, start_offset); +// } +// public void EndIteratorBody(int end_offset) +// { +// this.current_method.EndBlock(end_offset); +// } +// public void StartIteratorDispatcher(int start_offset) +// { +// this.current_method.StartBlock(CodeBlockEntry.Type.IteratorDispatcher, start_offset); +// } +// public void EndIteratorDispatcher(int end_offset) +// { +// this.current_method.EndBlock(end_offset); +// } +// public void DefineAnonymousScope(int id) +// { +// this.file.DefineAnonymousScope(id); +// } +// public void WriteSymbolFile(Guid guid) +// { +// foreach (SourceMethodBuilder method in this.methods) +// { +// method.DefineMethod(this.file); +// } +// try +// { +// File.Delete(this.filename); +// } +// catch +// { +// } +// using (FileStream fs = new FileStream(this.filename, FileMode.Create, FileAccess.Write)) +// { +// this.file.CreateSymbolFile(guid, fs); +// } +// } +// } +//} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryReader.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryReader.cs new file mode 100644 index 00000000..6715419c --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryReader.cs @@ -0,0 +1,23 @@ +using System; +using System.IO; +namespace Mono.CompilerServices.SymbolWriter +{ + internal class MyBinaryReader : BinaryReader + { + public MyBinaryReader(Stream stream) : base(stream) + { + } + public int ReadLeb128() + { + return base.Read7BitEncodedInt(); + } + public string ReadString(int offset) + { + long old_pos = this.BaseStream.Position; + this.BaseStream.Position = (long)offset; + string text = this.ReadString(); + this.BaseStream.Position = old_pos; + return text; + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryWriter.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryWriter.cs new file mode 100644 index 00000000..c837da81 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/MyBinaryWriter.cs @@ -0,0 +1,15 @@ +//using System; +//using System.IO; +//namespace Mono.CompilerServices.SymbolWriter +//{ +// internal class MyBinaryWriter : BinaryWriter +// { +// public MyBinaryWriter(Stream stream) : base(stream) +// { +// } +// public void WriteLeb128(int value) +// { +// base.Write7BitEncodedInt(value); +// } +// } +//} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceEntry.cs new file mode 100644 index 00000000..c2513c66 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceEntry.cs @@ -0,0 +1,47 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public struct NamespaceEntry + { + public readonly string Name; + public readonly int Index; + public readonly int Parent; + public readonly string[] UsingClauses; + public NamespaceEntry(string name, int index, string[] using_clauses, int parent) + { + this.Name = name; + this.Index = index; + this.Parent = parent; + this.UsingClauses = ((using_clauses != null) ? using_clauses : new string[0]); + } + internal NamespaceEntry(MonoSymbolFile file, MyBinaryReader reader) + { + this.Name = reader.ReadString(); + this.Index = reader.ReadLeb128(); + this.Parent = reader.ReadLeb128(); + int count = reader.ReadLeb128(); + this.UsingClauses = new string[count]; + for (int i = 0; i < count; i++) + { + this.UsingClauses[i] = reader.ReadString(); + } + } + //internal void Write(MonoSymbolFile file, MyBinaryWriter bw) + //{ + // bw.Write(this.Name); + // bw.WriteLeb128(this.Index); + // bw.WriteLeb128(this.Parent); + // bw.WriteLeb128(this.UsingClauses.Length); + // string[] usingClauses = this.UsingClauses; + // for (int i = 0; i < usingClauses.Length; i++) + // { + // string uc = usingClauses[i]; + // bw.Write(uc); + // } + //} + public override string ToString() + { + return string.Format("[Namespace {0}:{1}:{2}]", this.Name, this.Index, this.Parent); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceInfo.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceInfo.cs new file mode 100644 index 00000000..13fca6d2 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/NamespaceInfo.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections; +namespace Mono.CompilerServices.SymbolWriter +{ + internal class NamespaceInfo + { + public string Name; + public int NamespaceID; + public ArrayList UsingClauses = new ArrayList(); + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/OffsetTable.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/OffsetTable.cs new file mode 100644 index 00000000..27e86298 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/OffsetTable.cs @@ -0,0 +1,107 @@ +using System; +using System.IO; +namespace Mono.CompilerServices.SymbolWriter +{ + public class OffsetTable + { + [Flags] + public enum Flags + { + IsAspxSource = 1, + WindowsFileNames = 2 + } + public const int MajorVersion = 50; + public const int MinorVersion = 0; + public const long Magic = 5037318119232611860L; + public int TotalFileSize; + public int DataSectionOffset; + public int DataSectionSize; + public int CompileUnitCount; + public int CompileUnitTableOffset; + public int CompileUnitTableSize; + public int SourceCount; + public int SourceTableOffset; + public int SourceTableSize; + public int MethodCount; + public int MethodTableOffset; + public int MethodTableSize; + public int TypeCount; + public int AnonymousScopeCount; + public int AnonymousScopeTableOffset; + public int AnonymousScopeTableSize; + public OffsetTable.Flags FileFlags; + public int LineNumberTable_LineBase = -1; + public int LineNumberTable_LineRange = 8; + public int LineNumberTable_OpcodeBase = 9; + internal OffsetTable() + { + int platform = (int)Environment.OSVersion.Platform; + if (platform != 4 && platform != 128) + { + this.FileFlags |= OffsetTable.Flags.WindowsFileNames; + } + } + internal OffsetTable(BinaryReader reader, int major_version, int minor_version) + { + this.TotalFileSize = reader.ReadInt32(); + this.DataSectionOffset = reader.ReadInt32(); + this.DataSectionSize = reader.ReadInt32(); + this.CompileUnitCount = reader.ReadInt32(); + this.CompileUnitTableOffset = reader.ReadInt32(); + this.CompileUnitTableSize = reader.ReadInt32(); + this.SourceCount = reader.ReadInt32(); + this.SourceTableOffset = reader.ReadInt32(); + this.SourceTableSize = reader.ReadInt32(); + this.MethodCount = reader.ReadInt32(); + this.MethodTableOffset = reader.ReadInt32(); + this.MethodTableSize = reader.ReadInt32(); + this.TypeCount = reader.ReadInt32(); + this.AnonymousScopeCount = reader.ReadInt32(); + this.AnonymousScopeTableOffset = reader.ReadInt32(); + this.AnonymousScopeTableSize = reader.ReadInt32(); + this.LineNumberTable_LineBase = reader.ReadInt32(); + this.LineNumberTable_LineRange = reader.ReadInt32(); + this.LineNumberTable_OpcodeBase = reader.ReadInt32(); + this.FileFlags = (OffsetTable.Flags)reader.ReadInt32(); + } + internal void Write(BinaryWriter bw, int major_version, int minor_version) + { + bw.Write(this.TotalFileSize); + bw.Write(this.DataSectionOffset); + bw.Write(this.DataSectionSize); + bw.Write(this.CompileUnitCount); + bw.Write(this.CompileUnitTableOffset); + bw.Write(this.CompileUnitTableSize); + bw.Write(this.SourceCount); + bw.Write(this.SourceTableOffset); + bw.Write(this.SourceTableSize); + bw.Write(this.MethodCount); + bw.Write(this.MethodTableOffset); + bw.Write(this.MethodTableSize); + bw.Write(this.TypeCount); + bw.Write(this.AnonymousScopeCount); + bw.Write(this.AnonymousScopeTableOffset); + bw.Write(this.AnonymousScopeTableSize); + bw.Write(this.LineNumberTable_LineBase); + bw.Write(this.LineNumberTable_LineRange); + bw.Write(this.LineNumberTable_OpcodeBase); + bw.Write((int)this.FileFlags); + } + public override string ToString() + { + return string.Format("OffsetTable [{0} - {1}:{2} - {3}:{4}:{5} - {6}:{7}:{8} - {9}]", new object[] + { + this.TotalFileSize, + this.DataSectionOffset, + this.DataSectionSize, + this.SourceCount, + this.SourceTableOffset, + this.SourceTableSize, + this.MethodCount, + this.MethodTableOffset, + this.MethodTableSize, + this.TypeCount + }); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ScopeVariable.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ScopeVariable.cs new file mode 100644 index 00000000..e3eedb1a --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/ScopeVariable.cs @@ -0,0 +1,28 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + public struct ScopeVariable + { + public readonly int Scope; + public readonly int Index; + public ScopeVariable(int scope, int index) + { + this.Scope = scope; + this.Index = index; + } + internal ScopeVariable(MyBinaryReader reader) + { + this.Scope = reader.ReadLeb128(); + this.Index = reader.ReadLeb128(); + } + //internal void Write(MyBinaryWriter bw) + //{ + // bw.WriteLeb128(this.Scope); + // bw.WriteLeb128(this.Index); + //} + public override string ToString() + { + return string.Format("[ScopeVariable {0}:{1}]", this.Scope, this.Index); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceFileEntry.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceFileEntry.cs new file mode 100644 index 00000000..ab45bf5b --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceFileEntry.cs @@ -0,0 +1,131 @@ +using System; +using System.IO; +using System.Security.Cryptography; +namespace Mono.CompilerServices.SymbolWriter +{ + public class SourceFileEntry + { + public readonly int Index; + private int DataOffset; + private MonoSymbolFile file; + private string file_name; + private byte[] guid; + private byte[] hash; + private bool creating; + private bool auto_generated; + public static int Size + { + get + { + return 8; + } + } + public string FileName + { + get + { + return this.file_name; + } + } + public bool AutoGenerated + { + get + { + return this.auto_generated; + } + } + public SourceFileEntry(MonoSymbolFile file, string file_name) + { + this.file = file; + this.file_name = file_name; + this.Index = file.AddSource(this); + this.creating = true; + } + public SourceFileEntry(MonoSymbolFile file, string file_name, byte[] guid, byte[] checksum) : this(file, file_name) + { + this.guid = guid; + this.hash = checksum; + } + //internal void WriteData(MyBinaryWriter bw) + //{ + // this.DataOffset = (int)bw.BaseStream.Position; + // bw.Write(this.file_name); + // if (this.guid == null) + // { + // this.guid = Guid.NewGuid().ToByteArray(); + // try + // { + // using (FileStream fs = new FileStream(this.file_name, FileMode.Open, FileAccess.Read)) + // { + // MD5 md5 = MD5.Create(); + // this.hash = md5.ComputeHash(fs); + // } + // } + // catch + // { + // this.hash = new byte[16]; + // } + // } + // bw.Write(this.guid); + // bw.Write(this.hash); + // bw.Write(this.auto_generated ? 1 : 0); + //} + //internal void Write(BinaryWriter bw) + //{ + // bw.Write(this.Index); + // bw.Write(this.DataOffset); + //} + internal SourceFileEntry(MonoSymbolFile file, MyBinaryReader reader) + { + this.file = file; + this.Index = reader.ReadInt32(); + this.DataOffset = reader.ReadInt32(); + int old_pos = (int)reader.BaseStream.Position; + reader.BaseStream.Position = (long)this.DataOffset; + this.file_name = reader.ReadString(); + this.guid = reader.ReadBytes(16); + this.hash = reader.ReadBytes(16); + this.auto_generated = (reader.ReadByte() == 1); + reader.BaseStream.Position = (long)old_pos; + } + public void SetAutoGenerated() + { + if (!this.creating) + { + throw new InvalidOperationException(); + } + this.auto_generated = true; + this.file.OffsetTable.FileFlags |= OffsetTable.Flags.IsAspxSource; + } + public bool CheckChecksum() + { + bool result; + try + { + using (FileStream fs = new FileStream(this.file_name, FileMode.Open)) + { + MD5 md5 = MD5.Create(); + byte[] data = md5.ComputeHash(fs); + for (int i = 0; i < 16; i++) + { + if (data[i] != this.hash[i]) + { + result = false; + return result; + } + } + result = true; + } + } + catch + { + result = false; + } + return result; + } + public override string ToString() + { + return string.Format("SourceFileEntry ({0}:{1})", this.Index, this.DataOffset); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs new file mode 100644 index 00000000..8a8a0dff --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +namespace Mono.CompilerServices.SymbolWriter +{ + public class SourceMethodBuilder + { + private List _locals; + private List _blocks; + private List _scope_vars; + private Stack _block_stack; + private string _real_name; + private IMethodDef _method; + private ICompileUnit _comp_unit; + private int _ns_id; + private LineNumberEntry[] method_lines; + private int method_lines_pos = 0; + public CodeBlockEntry[] Blocks + { + get + { + CodeBlockEntry[] result; + if (this._blocks == null) + { + result = new CodeBlockEntry[0]; + } + else + { + CodeBlockEntry[] retval = new CodeBlockEntry[this._blocks.Count]; + this._blocks.CopyTo(retval, 0); + result = retval; + } + return result; + } + } + public CodeBlockEntry CurrentBlock + { + get + { + CodeBlockEntry result; + if (this._block_stack != null && this._block_stack.Count > 0) + { + result = this._block_stack.Peek(); + } + else + { + result = null; + } + return result; + } + } + public LocalVariableEntry[] Locals + { + get + { + LocalVariableEntry[] result; + if (this._locals == null) + { + result = new LocalVariableEntry[0]; + } + else + { + LocalVariableEntry[] retval = new LocalVariableEntry[this._locals.Count]; + this._locals.CopyTo(retval, 0); + result = retval; + } + return result; + } + } + public ScopeVariable[] ScopeVariables + { + get + { + ScopeVariable[] result; + if (this._scope_vars == null) + { + result = new ScopeVariable[0]; + } + else + { + ScopeVariable[] retval = new ScopeVariable[this._scope_vars.Count]; + this._scope_vars.CopyTo(retval); + result = retval; + } + return result; + } + } + public string RealMethodName + { + get + { + return this._real_name; + } + } + public ICompileUnit SourceFile + { + get + { + return this._comp_unit; + } + } + public IMethodDef Method + { + get + { + return this._method; + } + } + public SourceMethodBuilder(ICompileUnit comp_unit, int ns_id, IMethodDef method) + { + this._comp_unit = comp_unit; + this._method = method; + this._ns_id = ns_id; + this.method_lines = new LineNumberEntry[32]; + } + public void MarkSequencePoint(int offset, SourceFileEntry file, int line, int column, bool is_hidden) + { + if (this.method_lines_pos == this.method_lines.Length) + { + LineNumberEntry[] tmp = this.method_lines; + this.method_lines = new LineNumberEntry[this.method_lines.Length * 2]; + Array.Copy(tmp, this.method_lines, this.method_lines_pos); + } + int file_idx = (file != null) ? file.Index : 0; + this.method_lines[this.method_lines_pos++] = new LineNumberEntry(file_idx, line, offset, is_hidden); + } + public void StartBlock(CodeBlockEntry.Type type, int start_offset) + { + if (this._block_stack == null) + { + this._block_stack = new Stack(); + } + if (this._blocks == null) + { + this._blocks = new List(); + } + int parent = (this.CurrentBlock != null) ? this.CurrentBlock.Index : -1; + CodeBlockEntry block = new CodeBlockEntry(this._blocks.Count + 1, parent, type, start_offset); + this._block_stack.Push(block); + this._blocks.Add(block); + } + public void EndBlock(int end_offset) + { + CodeBlockEntry block = this._block_stack.Pop(); + block.Close(end_offset); + } + public void AddLocal(int index, string name) + { + if (this._locals == null) + { + this._locals = new List(); + } + int block_idx = (this.CurrentBlock != null) ? this.CurrentBlock.Index : 0; + this._locals.Add(new LocalVariableEntry(index, name, block_idx)); + } + public void AddScopeVariable(int scope, int index) + { + if (this._scope_vars == null) + { + this._scope_vars = new List(); + } + this._scope_vars.Add(new ScopeVariable(scope, index)); + } + public void SetRealMethodName(string name) + { + this._real_name = name; + } + public void DefineMethod(MonoSymbolFile file) + { + LineNumberEntry[] lines = new LineNumberEntry[this.method_lines_pos]; + Array.Copy(this.method_lines, lines, this.method_lines_pos); + MethodEntry entry = new MethodEntry(file, this._comp_unit.Entry, this._method.Token, this.ScopeVariables, this.Locals, lines, this.Blocks, this.RealMethodName, (MethodEntry.Flags)0, this._ns_id); + file.AddMethod(entry); + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodImpl.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodImpl.cs new file mode 100644 index 00000000..cdfc8667 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodImpl.cs @@ -0,0 +1,37 @@ +using System; +namespace Mono.CompilerServices.SymbolWriter +{ + internal class SourceMethodImpl : IMethodDef + { + private string name; + private int token; + private int namespaceID; + public string Name + { + get + { + return this.name; + } + } + public int NamespaceID + { + get + { + return this.namespaceID; + } + } + public int Token + { + get + { + return this.token; + } + } + public SourceMethodImpl(string name, int token, int namespaceID) + { + this.name = name; + this.token = token; + this.namespaceID = namespaceID; + } + } +} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolDocumentWriterImpl.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolDocumentWriterImpl.cs new file mode 100644 index 00000000..1c22cb89 --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolDocumentWriterImpl.cs @@ -0,0 +1,33 @@ +//using System; +//using System.Diagnostics.SymbolStore; +//namespace Mono.CompilerServices.SymbolWriter +//{ +// internal class SymbolDocumentWriterImpl : ISymbolDocumentWriter, ISourceFile, ICompileUnit +// { +// private CompileUnitEntry comp_unit; +// SourceFileEntry ISourceFile.Entry +// { +// get +// { +// return this.comp_unit.SourceFile; +// } +// } +// public CompileUnitEntry Entry +// { +// get +// { +// return this.comp_unit; +// } +// } +// public SymbolDocumentWriterImpl(CompileUnitEntry comp_unit) +// { +// this.comp_unit = comp_unit; +// } +// public void SetCheckSum(Guid algorithmId, byte[] checkSum) +// { +// } +// public void SetSource(byte[] source) +// { +// } +// } +//} diff --git a/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs new file mode 100644 index 00000000..d489c4cb --- /dev/null +++ b/Mono.Cecil.Mdb/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs @@ -0,0 +1,162 @@ +//using System; +//using System.Collections; +//using System.Diagnostics.SymbolStore; +//using System.Reflection; +//using System.Text; +//namespace Mono.CompilerServices.SymbolWriter +//{ +// public class SymbolWriterImpl : ISymbolWriter +// { +// private MonoSymbolWriter msw; +// private int nextLocalIndex; +// private int currentToken; +// private string methodName; +// private Stack namespaceStack = new Stack(); +// private bool methodOpened; +// private Hashtable documents = new Hashtable(); +// private Guid guid; +// public SymbolWriterImpl(Guid guid) +// { +// this.guid = guid; +// } +// public void Close() +// { +// this.msw.WriteSymbolFile(this.guid); +// } +// public void CloseMethod() +// { +// if (this.methodOpened) +// { +// this.methodOpened = false; +// this.nextLocalIndex = 0; +// this.msw.CloseMethod(); +// } +// } +// public void CloseNamespace() +// { +// this.namespaceStack.Pop(); +// this.msw.CloseNamespace(); +// } +// public void CloseScope(int endOffset) +// { +// this.msw.CloseScope(endOffset); +// } +// public ISymbolDocumentWriter DefineDocument(string url, Guid language, Guid languageVendor, Guid documentType) +// { +// SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl)this.documents[url]; +// if (doc == null) +// { +// SourceFileEntry entry = this.msw.DefineDocument(url); +// CompileUnitEntry comp_unit = this.msw.DefineCompilationUnit(entry); +// doc = new SymbolDocumentWriterImpl(comp_unit); +// this.documents[url] = doc; +// } +// return doc; +// } +// public void DefineField(SymbolToken parent, string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) +// { +// } +// public void DefineGlobalVariable(string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3) +// { +// } +// public void DefineLocalVariable(string name, FieldAttributes attributes, byte[] signature, SymAddressKind addrKind, int addr1, int addr2, int addr3, int startOffset, int endOffset) +// { +// this.msw.DefineLocalVariable(this.nextLocalIndex++, name); +// } +// public void DefineParameter(string name, ParameterAttributes attributes, int sequence, SymAddressKind addrKind, int addr1, int addr2, int addr3) +// { +// } +// public void DefineSequencePoints(ISymbolDocumentWriter document, int[] offsets, int[] lines, int[] columns, int[] endLines, int[] endColumns) +// { +// SymbolDocumentWriterImpl doc = (SymbolDocumentWriterImpl)document; +// SourceFileEntry file = (doc != null) ? doc.Entry.SourceFile : null; +// for (int i = 0; i < offsets.Length; i++) +// { +// if (i <= 0 || offsets[i] != offsets[i - 1] || lines[i] != lines[i - 1] || columns[i] != columns[i - 1]) +// { +// this.msw.MarkSequencePoint(offsets[i], file, lines[i], columns[i], false); +// } +// } +// } +// public void Initialize(IntPtr emitter, string filename, bool fFullBuild) +// { +// this.msw = new MonoSymbolWriter(filename); +// } +// public void OpenMethod(SymbolToken method) +// { +// this.currentToken = method.GetToken(); +// } +// public void OpenNamespace(string name) +// { +// NamespaceInfo i = new NamespaceInfo(); +// i.NamespaceID = -1; +// i.Name = name; +// this.namespaceStack.Push(i); +// } +// public int OpenScope(int startOffset) +// { +// return this.msw.OpenScope(startOffset); +// } +// public void SetMethodSourceRange(ISymbolDocumentWriter startDoc, int startLine, int startColumn, ISymbolDocumentWriter endDoc, int endLine, int endColumn) +// { +// int nsId = this.GetCurrentNamespace(startDoc); +// SourceMethodImpl sm = new SourceMethodImpl(this.methodName, this.currentToken, nsId); +// this.msw.OpenMethod(((ICompileUnit)startDoc).Entry, nsId, sm); +// this.methodOpened = true; +// } +// public void SetScopeRange(int scopeID, int startOffset, int endOffset) +// { +// } +// public void SetSymAttribute(SymbolToken parent, string name, byte[] data) +// { +// if (name == "__name") +// { +// this.methodName = Encoding.UTF8.GetString(data); +// } +// } +// public void SetUnderlyingWriter(IntPtr underlyingWriter) +// { +// } +// public void SetUserEntryPoint(SymbolToken entryMethod) +// { +// } +// public void UsingNamespace(string fullName) +// { +// if (this.namespaceStack.Count == 0) +// { +// this.OpenNamespace(""); +// } +// NamespaceInfo ni = (NamespaceInfo)this.namespaceStack.Peek(); +// if (ni.NamespaceID != -1) +// { +// NamespaceInfo old = ni; +// this.CloseNamespace(); +// this.OpenNamespace(old.Name); +// ni = (NamespaceInfo)this.namespaceStack.Peek(); +// ni.UsingClauses = old.UsingClauses; +// } +// ni.UsingClauses.Add(fullName); +// } +// private int GetCurrentNamespace(ISymbolDocumentWriter doc) +// { +// if (this.namespaceStack.Count == 0) +// { +// this.OpenNamespace(""); +// } +// NamespaceInfo ni = (NamespaceInfo)this.namespaceStack.Peek(); +// if (ni.NamespaceID == -1) +// { +// string[] usings = (string[])ni.UsingClauses.ToArray(typeof(string)); +// int parentId = 0; +// if (this.namespaceStack.Count > 1) +// { +// this.namespaceStack.Pop(); +// parentId = ((NamespaceInfo)this.namespaceStack.Peek()).NamespaceID; +// this.namespaceStack.Push(ni); +// } +// ni.NamespaceID = this.msw.DefineNamespace(ni.Name, ((ICompileUnit)doc).Entry, usings, parentId); +// } +// return ni.NamespaceID; +// } +// } +//} diff --git a/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj b/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj new file mode 100644 index 00000000..6c4ebc33 --- /dev/null +++ b/Mono.Cecil.Pdb/Mono.Cecil.Pdb.csproj @@ -0,0 +1,87 @@ + + + + + Debug + AnyCPU + {CEA7A85F-2523-4AD0-8296-6E8E0A2E6DF7} + Library + Properties + Mono.Cecil.Pdb + Mono.Cecil.Pdb + v2.0 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {d3785d8b-4d85-4546-8763-47fc848c13e0} + Mono.Cecil.20 + + + + + \ No newline at end of file diff --git a/Mono.Cecil.Pdb/Properties/AssemblyInfo.cs b/Mono.Cecil.Pdb/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..aa929945 --- /dev/null +++ b/Mono.Cecil.Pdb/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过以下 +// 特性集控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Mono.Cecil.Pdb")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Mono.Cecil.Pdb")] +[assembly: AssemblyCopyright("Copyright © 2015")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 使此程序集中的类型 +// 对 COM 组件不可见。 如果需要从 COM 访问此程序集中的类型, +// 则将该类型上的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("37439f61-a9af-46e6-8389-746e2ceda89a")] + +// 程序集的版本信息由下面四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值, +// 方法是按如下所示使用“*”: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitAccess.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitAccess.cs new file mode 100644 index 00000000..e8e77b0b --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitAccess.cs @@ -0,0 +1,249 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.IO; +using System.Text; + +namespace Microsoft.Cci.Pdb { + internal class BitAccess { + + internal BitAccess(int capacity) { + this.buffer = new byte[capacity]; + } + + internal byte[] Buffer { + get { return buffer; } + } + private byte[] buffer; + + internal void FillBuffer(Stream stream, int capacity) { + MinCapacity(capacity); + stream.Read(buffer, 0, capacity); + offset = 0; + } + + internal void Append(Stream stream, int count) { + int newCapacity = offset + count; + if (buffer.Length < newCapacity) { + byte[] newBuffer = new byte[newCapacity]; + Array.Copy(buffer, newBuffer, buffer.Length); + buffer = newBuffer; + } + stream.Read(buffer, offset, count); + offset += count; + } + + internal int Position { + get { return offset; } + set { offset = value; } + } + private int offset; + + //internal void WriteBuffer(Stream stream, int count) { + // stream.Write(buffer, 0, count); + //} + + internal void MinCapacity(int capacity) { + if (buffer.Length < capacity) { + buffer = new byte[capacity]; + } + offset = 0; + } + + internal void Align(int alignment) { + while ((offset % alignment) != 0) { + offset++; + } + } + + //internal void WriteInt32(int value) { + // buffer[offset + 0] = (byte)value; + // buffer[offset + 1] = (byte)(value >> 8); + // buffer[offset + 2] = (byte)(value >> 16); + // buffer[offset + 3] = (byte)(value >> 24); + // offset += 4; + //} + + //internal void WriteInt32(int[] values) { + // for (int i = 0; i < values.Length; i++) { + // WriteInt32(values[i]); + // } + //} + + //internal void WriteBytes(byte[] bytes) { + // for (int i = 0; i < bytes.Length; i++) { + // buffer[offset++] = bytes[i]; + // } + //} + + internal void ReadInt16(out short value) { + value = (short)((buffer[offset + 0] & 0xFF) | + (buffer[offset + 1] << 8)); + offset += 2; + } + + internal void ReadInt8(out sbyte value) { + value = (sbyte)buffer[offset]; + offset += 1; + } + + internal void ReadInt32(out int value) { + value = (int)((buffer[offset + 0] & 0xFF) | + (buffer[offset + 1] << 8) | + (buffer[offset + 2] << 16) | + (buffer[offset + 3] << 24)); + offset += 4; + } + + internal void ReadInt64(out long value) { + value = (long)(((ulong)buffer[offset + 0] & 0xFF) | + ((ulong)buffer[offset + 1] << 8) | + ((ulong)buffer[offset + 2] << 16) | + ((ulong)buffer[offset + 3] << 24) | + ((ulong)buffer[offset + 4] << 32) | + ((ulong)buffer[offset + 5] << 40) | + ((ulong)buffer[offset + 6] << 48) | + ((ulong)buffer[offset + 7] << 56)); + offset += 8; + } + + internal void ReadUInt16(out ushort value) { + value = (ushort)((buffer[offset + 0] & 0xFF) | + (buffer[offset + 1] << 8)); + offset += 2; + } + + internal void ReadUInt8(out byte value) { + value = (byte)((buffer[offset + 0] & 0xFF)); + offset += 1; + } + + internal void ReadUInt32(out uint value) { + value = (uint)((buffer[offset + 0] & 0xFF) | + (buffer[offset + 1] << 8) | + (buffer[offset + 2] << 16) | + (buffer[offset + 3] << 24)); + offset += 4; + } + + internal void ReadUInt64(out ulong value) { + value = (ulong)(((ulong)buffer[offset + 0] & 0xFF) | + ((ulong)buffer[offset + 1] << 8) | + ((ulong)buffer[offset + 2] << 16) | + ((ulong)buffer[offset + 3] << 24) | + ((ulong)buffer[offset + 4] << 32) | + ((ulong)buffer[offset + 5] << 40) | + ((ulong)buffer[offset + 6] << 48) | + ((ulong)buffer[offset + 7] << 56)); + offset += 8; + } + + internal void ReadInt32(int[] values) { + for (int i = 0; i < values.Length; i++) { + ReadInt32(out values[i]); + } + } + + internal void ReadUInt32(uint[] values) { + for (int i = 0; i < values.Length; i++) { + ReadUInt32(out values[i]); + } + } + + internal void ReadBytes(byte[] bytes) { + for (int i = 0; i < bytes.Length; i++) { + bytes[i] = buffer[offset++]; + } + } + + internal float ReadFloat() { + float result = BitConverter.ToSingle(buffer, offset); + offset += 4; + return result; + } + + internal double ReadDouble() { + double result = BitConverter.ToDouble(buffer, offset); + offset += 8; + return result; + } + + internal decimal ReadDecimal() { + int[] bits = new int[4]; + this.ReadInt32(bits); + return new decimal(bits[2], bits[3], bits[1], bits[0] < 0, (byte)((bits[0] & 0x00FF0000) >> 16)); + } + + internal void ReadBString(out string value) { + ushort len; + this.ReadUInt16(out len); + value = Encoding.UTF8.GetString(buffer, offset, len); + offset += len; + } + + internal void ReadCString(out string value) { + int len = 0; + while (offset + len < buffer.Length && buffer[offset + len] != 0) { + len++; + } + value = Encoding.UTF8.GetString(buffer, offset, len); + offset += len + 1; + } + + internal void SkipCString(out string value) { + int len = 0; + while (offset + len < buffer.Length && buffer[offset + len] != 0) { + len++; + } + offset += len + 1; + value= null; + } + + internal void ReadGuid(out Guid guid) { + uint a; + ushort b; + ushort c; + byte d; + byte e; + byte f; + byte g; + byte h; + byte i; + byte j; + byte k; + + ReadUInt32(out a); + ReadUInt16(out b); + ReadUInt16(out c); + ReadUInt8(out d); + ReadUInt8(out e); + ReadUInt8(out f); + ReadUInt8(out g); + ReadUInt8(out h); + ReadUInt8(out i); + ReadUInt8(out j); + ReadUInt8(out k); + + guid = new Guid(a, b, c, d, e, f, g, h, i, j, k); + } + + internal string ReadString() { + int len = 0; + while (offset + len < buffer.Length && buffer[offset + len] != 0) { + len+=2; + } + string result = Encoding.Unicode.GetString(buffer, offset, len); + offset += len + 2; + return result; + } + + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitSet.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitSet.cs new file mode 100644 index 00000000..67191317 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/BitSet.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal struct BitSet { + internal BitSet(BitAccess bits) { + bits.ReadInt32(out size); // 0..3 : Number of words + words = new uint[size]; + bits.ReadUInt32(words); + } + + //internal BitSet(int size) { + // this.size = size; + // words = new uint[size]; + //} + + internal bool IsSet(int index) { + int word = index / 32; + if (word >= this.size) return false; + return ((words[word] & GetBit(index)) != 0); + } + + //internal void Set(int index) { + // int word = index / 32; + // if (word >= this.size) return; + // words[word] |= GetBit(index); + //} + + //internal void Clear(int index) { + // int word = index / 32; + // if (word >= this.size) return; + // words[word] &= ~GetBit(index); + //} + + private static uint GetBit(int index) { + return ((uint)1 << (index % 32)); + } + + //private static uint ReverseBits(uint value) { + // uint o = 0; + // for (int i = 0; i < 32; i++) { + // o = (o << 1) | (value & 1); + // value >>= 1; + // } + // return o; + //} + + internal bool IsEmpty { + get { return size == 0; } + } + + //internal bool GetWord(int index, out uint word) { + // if (index < size) { + // word = ReverseBits(words[index]); + // return true; + // } + // word = 0; + // return false; + //} + + private int size; + private uint[] words; + } + +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/CvInfo.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/CvInfo.cs new file mode 100644 index 00000000..49c51ce1 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/CvInfo.cs @@ -0,0 +1,2435 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +// +// File: CvInfo.cs +// +// Generic CodeView information definitions +// +// Structures, constants, etc. for accessing and interpreting +// CodeView information. +// +// The master copy of this file resides in the langapi project (in C++). +// All Microsoft projects are required to use the master copy without +// modification. Modification of the master version or a copy +// without consultation with all parties concerned is extremely +// risky. +// +// When this file is modified, the corresponding documentation file +// omfdeb.doc in the langapi project must be updated. +// +// This is a read-only copy of the C++ file converted to C#. +// +using System; + +namespace Microsoft.Cci.Pdb { + internal struct FLOAT10 { + internal byte Data_0; + internal byte Data_1; + internal byte Data_2; + internal byte Data_3; + internal byte Data_4; + internal byte Data_5; + internal byte Data_6; + internal byte Data_7; + internal byte Data_8; + internal byte Data_9; + }; + + internal enum CV_SIGNATURE { + C6=0, // Actual signature is >64K + C7=1, // First explicit signature + C11=2, // C11 (vc5.x) 32-bit types + C13=4, // C13 (vc7.x) zero terminated names + RESERVERD=5, // All signatures from 5 to 64K are reserved + }; + + // CodeView Symbol and Type OMF type information is broken up into two + // ranges. Type indices less than 0x1000 describe type information + // that is frequently used. Type indices above 0x1000 are used to + // describe more complex features such as functions, arrays and + // structures. + // + + // Primitive types have predefined meaning that is encoded in the + // values of the various bit fields in the value. + // + // A CodeView primitive type is defined as: + // + // 1 1 + // 1 089 7654 3 210 + // r mode type r sub + // + // Where + // mode is the pointer mode + // type is a type indicator + // sub is a subtype enumeration + // r is a reserved field + // + // See Microsoft Symbol and Type OMF (Version 4.0) for more + // information. + // + + // pointer mode enumeration values + + internal enum CV_prmode { + CV_TM_DIRECT=0, // mode is not a pointer + CV_TM_NPTR32=4, // mode is a 32 bit near pointer + CV_TM_NPTR64=6, // mode is a 64 bit near pointer + CV_TM_NPTR128=7, // mode is a 128 bit near pointer + }; + + // type enumeration values + + internal enum CV_type { + CV_SPECIAL=0x00, // special type size values + CV_SIGNED=0x01, // signed integral size values + CV_UNSIGNED=0x02, // unsigned integral size values + CV_BOOLEAN=0x03, // Boolean size values + CV_REAL=0x04, // real number size values + CV_COMPLEX=0x05, // complex number size values + CV_SPECIAL2=0x06, // second set of special types + CV_INT=0x07, // integral (int) values + CV_CVRESERVED=0x0f, + }; + + // subtype enumeration values for CV_SPECIAL + + internal enum CV_special { + CV_SP_NOTYPE=0x00, + CV_SP_ABS=0x01, + CV_SP_SEGMENT=0x02, + CV_SP_VOID=0x03, + CV_SP_CURRENCY=0x04, + CV_SP_NBASICSTR=0x05, + CV_SP_FBASICSTR=0x06, + CV_SP_NOTTRANS=0x07, + CV_SP_HRESULT=0x08, + }; + + // subtype enumeration values for CV_SPECIAL2 + + internal enum CV_special2 { + CV_S2_BIT=0x00, + CV_S2_PASCHAR=0x01, // Pascal CHAR + }; + + // subtype enumeration values for CV_SIGNED, CV_UNSIGNED and CV_BOOLEAN + + internal enum CV_integral { + CV_IN_1BYTE=0x00, + CV_IN_2BYTE=0x01, + CV_IN_4BYTE=0x02, + CV_IN_8BYTE=0x03, + CV_IN_16BYTE=0x04, + }; + + // subtype enumeration values for CV_REAL and CV_COMPLEX + + internal enum CV_real { + CV_RC_REAL32=0x00, + CV_RC_REAL64=0x01, + CV_RC_REAL80=0x02, + CV_RC_REAL128=0x03, + }; + + // subtype enumeration values for CV_INT (really int) + + internal enum CV_int { + CV_RI_CHAR=0x00, + CV_RI_INT1=0x00, + CV_RI_WCHAR=0x01, + CV_RI_UINT1=0x01, + CV_RI_INT2=0x02, + CV_RI_UINT2=0x03, + CV_RI_INT4=0x04, + CV_RI_UINT4=0x05, + CV_RI_INT8=0x06, + CV_RI_UINT8=0x07, + CV_RI_INT16=0x08, + CV_RI_UINT16=0x09, + }; + + internal struct CV_PRIMITIVE_TYPE { + const uint CV_MMASK = 0x700; // mode mask + const uint CV_TMASK = 0x0f0; // type mask + const uint CV_SMASK = 0x00f; // subtype mask + + const int CV_MSHIFT = 8; // primitive mode right shift count + const int CV_TSHIFT = 4; // primitive type right shift count + const int CV_SSHIFT = 0; // primitive subtype right shift count + + // function to extract primitive mode, type and size + + //internal static CV_prmode CV_MODE(TYPE_ENUM typ) { + // return (CV_prmode)((((uint)typ) & CV_MMASK) >> CV_MSHIFT); + //} + + //internal static CV_type CV_TYPE(TYPE_ENUM typ) { + // return (CV_type)((((uint)typ) & CV_TMASK) >> CV_TSHIFT); + //} + + //internal static uint CV_SUBT(TYPE_ENUM typ) { + // return ((((uint)typ) & CV_SMASK) >> CV_SSHIFT); + //} + + // functions to check the type of a primitive + + //internal static bool CV_TYP_IS_DIRECT(TYPE_ENUM typ) { + // return (CV_MODE(typ) == CV_prmode.CV_TM_DIRECT); + //} + + //internal static bool CV_TYP_IS_PTR(TYPE_ENUM typ) { + // return (CV_MODE(typ) != CV_prmode.CV_TM_DIRECT); + //} + + //internal static bool CV_TYP_IS_SIGNED(TYPE_ENUM typ) { + // return + // (((CV_TYPE(typ) == CV_type.CV_SIGNED) && CV_TYP_IS_DIRECT(typ)) || + // (typ == TYPE_ENUM.T_INT1) || + // (typ == TYPE_ENUM.T_INT2) || + // (typ == TYPE_ENUM.T_INT4) || + // (typ == TYPE_ENUM.T_INT8) || + // (typ == TYPE_ENUM.T_INT16) || + // (typ == TYPE_ENUM.T_RCHAR)); + //} + + //internal static bool CV_TYP_IS_UNSIGNED(TYPE_ENUM typ) { + // return (((CV_TYPE(typ) == CV_type.CV_UNSIGNED) && CV_TYP_IS_DIRECT(typ)) || + // (typ == TYPE_ENUM.T_UINT1) || + // (typ == TYPE_ENUM.T_UINT2) || + // (typ == TYPE_ENUM.T_UINT4) || + // (typ == TYPE_ENUM.T_UINT8) || + // (typ == TYPE_ENUM.T_UINT16)); + //} + + //internal static bool CV_TYP_IS_REAL(TYPE_ENUM typ) { + // return ((CV_TYPE(typ) == CV_type.CV_REAL) && CV_TYP_IS_DIRECT(typ)); + //} + + const uint CV_FIRST_NONPRIM = 0x1000; + + //internal static bool CV_IS_PRIMITIVE(TYPE_ENUM typ) { + // return ((uint)(typ) < CV_FIRST_NONPRIM); + //} + + //internal static bool CV_TYP_IS_COMPLEX(TYPE_ENUM typ) { + // return ((CV_TYPE(typ) == CV_type.CV_COMPLEX) && CV_TYP_IS_DIRECT(typ)); + //} + + //internal static bool CV_IS_INTERNAL_PTR(TYPE_ENUM typ) { + // return (CV_IS_PRIMITIVE(typ) && + // CV_TYPE(typ) == CV_type.CV_CVRESERVED && + // CV_TYP_IS_PTR(typ)); + //} + } + + // selected values for type_index - for a more complete definition, see + // Microsoft Symbol and Type OMF document + + // Special Types + + internal enum TYPE_ENUM { + // Special Types + + T_NOTYPE=0x0000, // uncharacterized type (no type) + T_ABS=0x0001, // absolute symbol + T_SEGMENT=0x0002, // segment type + T_VOID=0x0003, // void + T_HRESULT=0x0008, // OLE/COM HRESULT + T_32PHRESULT=0x0408, // OLE/COM HRESULT __ptr32// + T_64PHRESULT=0x0608, // OLE/COM HRESULT __ptr64// + T_PVOID=0x0103, // near pointer to void + T_PFVOID=0x0203, // far pointer to void + T_PHVOID=0x0303, // huge pointer to void + T_32PVOID=0x0403, // 32 bit pointer to void + T_64PVOID=0x0603, // 64 bit pointer to void + T_CURRENCY=0x0004, // BASIC 8 byte currency value + T_NOTTRANS=0x0007, // type not translated by cvpack + T_BIT=0x0060, // bit + T_PASCHAR=0x0061, // Pascal CHAR + + // Character types + + T_CHAR=0x0010, // 8 bit signed + T_32PCHAR=0x0410, // 32 bit pointer to 8 bit signed + T_64PCHAR=0x0610, // 64 bit pointer to 8 bit signed + + T_UCHAR=0x0020, // 8 bit unsigned + T_32PUCHAR=0x0420, // 32 bit pointer to 8 bit unsigned + T_64PUCHAR=0x0620, // 64 bit pointer to 8 bit unsigned + + // really a character types + + T_RCHAR=0x0070, // really a char + T_32PRCHAR=0x0470, // 32 bit pointer to a real char + T_64PRCHAR=0x0670, // 64 bit pointer to a real char + + // really a wide character types + + T_WCHAR=0x0071, // wide char + T_32PWCHAR=0x0471, // 32 bit pointer to a wide char + T_64PWCHAR=0x0671, // 64 bit pointer to a wide char + + // 8 bit int types + + T_INT1=0x0068, // 8 bit signed int + T_32PINT1=0x0468, // 32 bit pointer to 8 bit signed int + T_64PINT1=0x0668, // 64 bit pointer to 8 bit signed int + + T_UINT1=0x0069, // 8 bit unsigned int + T_32PUINT1=0x0469, // 32 bit pointer to 8 bit unsigned int + T_64PUINT1=0x0669, // 64 bit pointer to 8 bit unsigned int + + // 16 bit short types + + T_SHORT=0x0011, // 16 bit signed + T_32PSHORT=0x0411, // 32 bit pointer to 16 bit signed + T_64PSHORT=0x0611, // 64 bit pointer to 16 bit signed + + T_USHORT=0x0021, // 16 bit unsigned + T_32PUSHORT=0x0421, // 32 bit pointer to 16 bit unsigned + T_64PUSHORT=0x0621, // 64 bit pointer to 16 bit unsigned + + // 16 bit int types + + T_INT2=0x0072, // 16 bit signed int + T_32PINT2=0x0472, // 32 bit pointer to 16 bit signed int + T_64PINT2=0x0672, // 64 bit pointer to 16 bit signed int + + T_UINT2=0x0073, // 16 bit unsigned int + T_32PUINT2=0x0473, // 32 bit pointer to 16 bit unsigned int + T_64PUINT2=0x0673, // 64 bit pointer to 16 bit unsigned int + + // 32 bit long types + + T_LONG=0x0012, // 32 bit signed + T_ULONG=0x0022, // 32 bit unsigned + T_32PLONG=0x0412, // 32 bit pointer to 32 bit signed + T_32PULONG=0x0422, // 32 bit pointer to 32 bit unsigned + T_64PLONG=0x0612, // 64 bit pointer to 32 bit signed + T_64PULONG=0x0622, // 64 bit pointer to 32 bit unsigned + + // 32 bit int types + + T_INT4=0x0074, // 32 bit signed int + T_32PINT4=0x0474, // 32 bit pointer to 32 bit signed int + T_64PINT4=0x0674, // 64 bit pointer to 32 bit signed int + + T_UINT4=0x0075, // 32 bit unsigned int + T_32PUINT4=0x0475, // 32 bit pointer to 32 bit unsigned int + T_64PUINT4=0x0675, // 64 bit pointer to 32 bit unsigned int + + // 64 bit quad types + + T_QUAD=0x0013, // 64 bit signed + T_32PQUAD=0x0413, // 32 bit pointer to 64 bit signed + T_64PQUAD=0x0613, // 64 bit pointer to 64 bit signed + + T_UQUAD=0x0023, // 64 bit unsigned + T_32PUQUAD=0x0423, // 32 bit pointer to 64 bit unsigned + T_64PUQUAD=0x0623, // 64 bit pointer to 64 bit unsigned + + // 64 bit int types + + T_INT8=0x0076, // 64 bit signed int + T_32PINT8=0x0476, // 32 bit pointer to 64 bit signed int + T_64PINT8=0x0676, // 64 bit pointer to 64 bit signed int + + T_UINT8=0x0077, // 64 bit unsigned int + T_32PUINT8=0x0477, // 32 bit pointer to 64 bit unsigned int + T_64PUINT8=0x0677, // 64 bit pointer to 64 bit unsigned int + + // 128 bit octet types + + T_OCT=0x0014, // 128 bit signed + T_32POCT=0x0414, // 32 bit pointer to 128 bit signed + T_64POCT=0x0614, // 64 bit pointer to 128 bit signed + + T_UOCT=0x0024, // 128 bit unsigned + T_32PUOCT=0x0424, // 32 bit pointer to 128 bit unsigned + T_64PUOCT=0x0624, // 64 bit pointer to 128 bit unsigned + + // 128 bit int types + + T_INT16=0x0078, // 128 bit signed int + T_32PINT16=0x0478, // 32 bit pointer to 128 bit signed int + T_64PINT16=0x0678, // 64 bit pointer to 128 bit signed int + + T_UINT16=0x0079, // 128 bit unsigned int + T_32PUINT16=0x0479, // 32 bit pointer to 128 bit unsigned int + T_64PUINT16=0x0679, // 64 bit pointer to 128 bit unsigned int + + // 32 bit real types + + T_REAL32=0x0040, // 32 bit real + T_32PREAL32=0x0440, // 32 bit pointer to 32 bit real + T_64PREAL32=0x0640, // 64 bit pointer to 32 bit real + + // 64 bit real types + + T_REAL64=0x0041, // 64 bit real + T_32PREAL64=0x0441, // 32 bit pointer to 64 bit real + T_64PREAL64=0x0641, // 64 bit pointer to 64 bit real + + // 80 bit real types + + T_REAL80=0x0042, // 80 bit real + T_32PREAL80=0x0442, // 32 bit pointer to 80 bit real + T_64PREAL80=0x0642, // 64 bit pointer to 80 bit real + + // 128 bit real types + + T_REAL128=0x0043, // 128 bit real + T_32PREAL128=0x0443, // 32 bit pointer to 128 bit real + T_64PREAL128=0x0643, // 64 bit pointer to 128 bit real + + // 32 bit complex types + + T_CPLX32=0x0050, // 32 bit complex + T_32PCPLX32=0x0450, // 32 bit pointer to 32 bit complex + T_64PCPLX32=0x0650, // 64 bit pointer to 32 bit complex + + // 64 bit complex types + + T_CPLX64=0x0051, // 64 bit complex + T_32PCPLX64=0x0451, // 32 bit pointer to 64 bit complex + T_64PCPLX64=0x0651, // 64 bit pointer to 64 bit complex + + // 80 bit complex types + + T_CPLX80=0x0052, // 80 bit complex + T_32PCPLX80=0x0452, // 32 bit pointer to 80 bit complex + T_64PCPLX80=0x0652, // 64 bit pointer to 80 bit complex + + // 128 bit complex types + + T_CPLX128=0x0053, // 128 bit complex + T_32PCPLX128=0x0453, // 32 bit pointer to 128 bit complex + T_64PCPLX128=0x0653, // 64 bit pointer to 128 bit complex + + // boolean types + + T_BOOL08=0x0030, // 8 bit boolean + T_32PBOOL08=0x0430, // 32 bit pointer to 8 bit boolean + T_64PBOOL08=0x0630, // 64 bit pointer to 8 bit boolean + + T_BOOL16=0x0031, // 16 bit boolean + T_32PBOOL16=0x0431, // 32 bit pointer to 18 bit boolean + T_64PBOOL16=0x0631, // 64 bit pointer to 18 bit boolean + + T_BOOL32=0x0032, // 32 bit boolean + T_32PBOOL32=0x0432, // 32 bit pointer to 32 bit boolean + T_64PBOOL32=0x0632, // 64 bit pointer to 32 bit boolean + + T_BOOL64=0x0033, // 64 bit boolean + T_32PBOOL64=0x0433, // 32 bit pointer to 64 bit boolean + T_64PBOOL64=0x0633, // 64 bit pointer to 64 bit boolean + }; + + // No leaf index can have a value of 0x0000. The leaf indices are + // separated into ranges depending upon the use of the type record. + // The second range is for the type records that are directly referenced + // in symbols. The first range is for type records that are not + // referenced by symbols but instead are referenced by other type + // records. All type records must have a starting leaf index in these + // first two ranges. The third range of leaf indices are used to build + // up complex lists such as the field list of a class type record. No + // type record can begin with one of the leaf indices. The fourth ranges + // of type indices are used to represent numeric data in a symbol or + // type record. These leaf indices are greater than 0x8000. At the + // point that type or symbol processor is expecting a numeric field, the + // next two bytes in the type record are examined. If the value is less + // than 0x8000, then the two bytes contain the numeric value. If the + // value is greater than 0x8000, then the data follows the leaf index in + // a format specified by the leaf index. The final range of leaf indices + // are used to force alignment of subfields within a complex type record.. + // + + internal enum LEAF { + // leaf indices starting records but referenced from symbol records + + LF_VTSHAPE=0x000a, + LF_COBOL1=0x000c, + LF_LABEL=0x000e, + LF_NULL=0x000f, + LF_NOTTRAN=0x0010, + LF_ENDPRECOMP=0x0014, // not referenced from symbol + LF_TYPESERVER_ST=0x0016, // not referenced from symbol + + // leaf indices starting records but referenced only from type records + + LF_LIST=0x0203, + LF_REFSYM=0x020c, + + LF_ENUMERATE_ST=0x0403, + + // 32-bit type index versions of leaves, all have the 0x1000 bit set + // + LF_TI16_MAX=0x1000, + + LF_MODIFIER=0x1001, + LF_POINTER=0x1002, + LF_ARRAY_ST=0x1003, + LF_CLASS_ST=0x1004, + LF_STRUCTURE_ST=0x1005, + LF_UNION_ST=0x1006, + LF_ENUM_ST=0x1007, + LF_PROCEDURE=0x1008, + LF_MFUNCTION=0x1009, + LF_COBOL0=0x100a, + LF_BARRAY=0x100b, + LF_DIMARRAY_ST=0x100c, + LF_VFTPATH=0x100d, + LF_PRECOMP_ST=0x100e, // not referenced from symbol + LF_OEM=0x100f, // oem definable type string + LF_ALIAS_ST=0x1010, // alias (typedef) type + LF_OEM2=0x1011, // oem definable type string + + // leaf indices starting records but referenced only from type records + + LF_SKIP=0x1200, + LF_ARGLIST=0x1201, + LF_DEFARG_ST=0x1202, + LF_FIELDLIST=0x1203, + LF_DERIVED=0x1204, + LF_BITFIELD=0x1205, + LF_METHODLIST=0x1206, + LF_DIMCONU=0x1207, + LF_DIMCONLU=0x1208, + LF_DIMVARU=0x1209, + LF_DIMVARLU=0x120a, + + LF_BCLASS=0x1400, + LF_VBCLASS=0x1401, + LF_IVBCLASS=0x1402, + LF_FRIENDFCN_ST=0x1403, + LF_INDEX=0x1404, + LF_MEMBER_ST=0x1405, + LF_STMEMBER_ST=0x1406, + LF_METHOD_ST=0x1407, + LF_NESTTYPE_ST=0x1408, + LF_VFUNCTAB=0x1409, + LF_FRIENDCLS=0x140a, + LF_ONEMETHOD_ST=0x140b, + LF_VFUNCOFF=0x140c, + LF_NESTTYPEEX_ST=0x140d, + LF_MEMBERMODIFY_ST=0x140e, + LF_MANAGED_ST=0x140f, + + // Types w/ SZ names + + LF_ST_MAX=0x1500, + + LF_TYPESERVER=0x1501, // not referenced from symbol + LF_ENUMERATE=0x1502, + LF_ARRAY=0x1503, + LF_CLASS=0x1504, + LF_STRUCTURE=0x1505, + LF_UNION=0x1506, + LF_ENUM=0x1507, + LF_DIMARRAY=0x1508, + LF_PRECOMP=0x1509, // not referenced from symbol + LF_ALIAS=0x150a, // alias (typedef) type + LF_DEFARG=0x150b, + LF_FRIENDFCN=0x150c, + LF_MEMBER=0x150d, + LF_STMEMBER=0x150e, + LF_METHOD=0x150f, + LF_NESTTYPE=0x1510, + LF_ONEMETHOD=0x1511, + LF_NESTTYPEEX=0x1512, + LF_MEMBERMODIFY=0x1513, + LF_MANAGED=0x1514, + LF_TYPESERVER2=0x1515, + + LF_NUMERIC=0x8000, + LF_CHAR=0x8000, + LF_SHORT=0x8001, + LF_USHORT=0x8002, + LF_LONG=0x8003, + LF_ULONG=0x8004, + LF_REAL32=0x8005, + LF_REAL64=0x8006, + LF_REAL80=0x8007, + LF_REAL128=0x8008, + LF_QUADWORD=0x8009, + LF_UQUADWORD=0x800a, + LF_COMPLEX32=0x800c, + LF_COMPLEX64=0x800d, + LF_COMPLEX80=0x800e, + LF_COMPLEX128=0x800f, + LF_VARSTRING=0x8010, + + LF_OCTWORD=0x8017, + LF_UOCTWORD=0x8018, + + LF_DECIMAL=0x8019, + LF_DATE=0x801a, + LF_UTF8STRING=0x801b, + + LF_PAD0=0xf0, + LF_PAD1=0xf1, + LF_PAD2=0xf2, + LF_PAD3=0xf3, + LF_PAD4=0xf4, + LF_PAD5=0xf5, + LF_PAD6=0xf6, + LF_PAD7=0xf7, + LF_PAD8=0xf8, + LF_PAD9=0xf9, + LF_PAD10=0xfa, + LF_PAD11=0xfb, + LF_PAD12=0xfc, + LF_PAD13=0xfd, + LF_PAD14=0xfe, + LF_PAD15=0xff, + + }; + + // end of leaf indices + + // Type enum for pointer records + // Pointers can be one of the following types + + internal enum CV_ptrtype { + CV_PTR_BASE_SEG=0x03, // based on segment + CV_PTR_BASE_VAL=0x04, // based on value of base + CV_PTR_BASE_SEGVAL=0x05, // based on segment value of base + CV_PTR_BASE_ADDR=0x06, // based on address of base + CV_PTR_BASE_SEGADDR=0x07, // based on segment address of base + CV_PTR_BASE_TYPE=0x08, // based on type + CV_PTR_BASE_SELF=0x09, // based on self + CV_PTR_NEAR32=0x0a, // 32 bit pointer + CV_PTR_64=0x0c, // 64 bit pointer + CV_PTR_UNUSEDPTR=0x0d // first unused pointer type + }; + + // Mode enum for pointers + // Pointers can have one of the following modes + + internal enum CV_ptrmode { + CV_PTR_MODE_PTR=0x00, // "normal" pointer + CV_PTR_MODE_REF=0x01, // reference + CV_PTR_MODE_PMEM=0x02, // pointer to data member + CV_PTR_MODE_PMFUNC=0x03, // pointer to member function + CV_PTR_MODE_RESERVED=0x04 // first unused pointer mode + }; + + // enumeration for pointer-to-member types + + internal enum CV_pmtype { + CV_PMTYPE_Undef=0x00, // not specified (pre VC8) + CV_PMTYPE_D_Single=0x01, // member data, single inheritance + CV_PMTYPE_D_Multiple=0x02, // member data, multiple inheritance + CV_PMTYPE_D_Virtual=0x03, // member data, virtual inheritance + CV_PMTYPE_D_General=0x04, // member data, most general + CV_PMTYPE_F_Single=0x05, // member function, single inheritance + CV_PMTYPE_F_Multiple=0x06, // member function, multiple inheritance + CV_PMTYPE_F_Virtual=0x07, // member function, virtual inheritance + CV_PMTYPE_F_General=0x08, // member function, most general + }; + + // enumeration for method properties + + internal enum CV_methodprop { + CV_MTvanilla=0x00, + CV_MTvirtual=0x01, + CV_MTstatic=0x02, + CV_MTfriend=0x03, + CV_MTintro=0x04, + CV_MTpurevirt=0x05, + CV_MTpureintro=0x06 + }; + + // enumeration for virtual shape table entries + + internal enum CV_VTS_desc { + CV_VTS_near=0x00, + CV_VTS_far=0x01, + CV_VTS_thin=0x02, + CV_VTS_outer=0x03, + CV_VTS_meta=0x04, + CV_VTS_near32=0x05, + CV_VTS_far32=0x06, + CV_VTS_unused=0x07 + }; + + // enumeration for LF_LABEL address modes + + internal enum CV_LABEL_TYPE { + CV_LABEL_NEAR=0, // near return + CV_LABEL_FAR=4 // far return + }; + + // enumeration for LF_MODIFIER values + + [Flags] + internal enum CV_modifier : ushort { + MOD_const=0x0001, + MOD_volatile=0x0002, + MOD_unaligned=0x0004, + }; + + // bit field structure describing class/struct/union/enum properties + + [Flags] + internal enum CV_prop : ushort { + packed=0x0001, // true if structure is packed + ctor=0x0002, // true if constructors or destructors present + ovlops=0x0004, // true if overloaded operators present + isnested=0x0008, // true if this is a nested class + cnested=0x0010, // true if this class contains nested types + opassign=0x0020, // true if overloaded assignment (=) + opcast=0x0040, // true if casting methods + fwdref=0x0080, // true if forward reference (incomplete defn) + scoped=0x0100, // scoped definition + } + + // class field attribute + + [Flags] + internal enum CV_fldattr { + access=0x0003, // access protection CV_access_t + mprop=0x001c, // method properties CV_methodprop_t + pseudo=0x0020, // compiler generated fcn and does not exist + noinherit=0x0040, // true if class cannot be inherited + noconstruct=0x0080, // true if class cannot be constructed + compgenx=0x0100, // compiler generated fcn and does exist + } + + // Structures to access to the type records + + internal struct TYPTYPE { + internal ushort len; + internal ushort leaf; + // byte data[]; + + // char *NextType (char * pType) { + // return (pType + ((TYPTYPE *)pType)->len + sizeof(ushort)); + // } + }; // general types record + + // memory representation of pointer to member. These representations are + // indexed by the enumeration above in the LF_POINTER record + + // representation of a 32 bit pointer to data for a class with + // or without virtual functions and no virtual bases + + internal struct CV_PDMR32_NVVFCN { + internal int mdisp; // displacement to data (NULL = 0x80000000) + }; + + // representation of a 32 bit pointer to data for a class + // with virtual bases + + internal struct CV_PDMR32_VBASE { + internal int mdisp; // displacement to data + internal int pdisp; // this pointer displacement + internal int vdisp; // vbase table displacement + // NULL = (,,0xffffffff) + }; + + // representation of a 32 bit pointer to member function for a + // class with no virtual bases and a single address point + + internal struct CV_PMFR32_NVSA { + internal uint off; // near address of function (NULL = 0L) + }; + + // representation of a 32 bit pointer to member function for a + // class with no virtual bases and multiple address points + + internal struct CV_PMFR32_NVMA { + internal uint off; // near address of function (NULL = 0L,x) + internal int disp; + }; + + // representation of a 32 bit pointer to member function for a + // class with virtual bases + + internal struct CV_PMFR32_VBASE { + internal uint off; // near address of function (NULL = 0L,x,x,x) + internal int mdisp; // displacement to data + internal int pdisp; // this pointer displacement + internal int vdisp; // vbase table displacement + }; + + ////////////////////////////////////////////////////////////////////////////// + // + // The following type records are basically variant records of the + // above structure. The "ushort leaf" of the above structure and + // the "ushort leaf" of the following type definitions are the same + // symbol. + // + + // Notes on alignment + // Alignment of the fields in most of the type records is done on the + // basis of the TYPTYPE record base. That is why in most of the lf* + // records that the type is located on what appears to + // be a offset mod 4 == 2 boundary. The exception to this rule are those + // records that are in a list (lfFieldList, lfMethodList), which are + // aligned to their own bases since they don't have the length field + // + + // Type record for LF_MODIFIER + + internal struct LeafModifier { + // internal ushort leaf; // LF_MODIFIER [TYPTYPE] + internal uint type; // (type index) modified type + internal CV_modifier attr; // modifier attribute modifier_t + }; + + // type record for LF_POINTER + + [Flags] + internal enum LeafPointerAttr : uint { + ptrtype=0x0000001f, // ordinal specifying pointer type (CV_ptrtype) + ptrmode=0x000000e0, // ordinal specifying pointer mode (CV_ptrmode) + isflat32=0x00000100, // true if 0:32 pointer + isvolatile=0x00000200, // TRUE if volatile pointer + isconst=0x00000400, // TRUE if const pointer + isunaligned=0x00000800, // TRUE if unaligned pointer + isrestrict=0x00001000, // TRUE if restricted pointer (allow agressive opts) + }; + + internal struct LeafPointer { + internal struct LeafPointerBody { + // internal ushort leaf; // LF_POINTER [TYPTYPE] + internal uint utype; // (type index) type index of the underlying type + internal LeafPointerAttr attr; + }; +#if false + union { + internal struct { + uint pmclass; // (type index) index of containing class for pointer to member + ushort pmenum; // enumeration specifying pm format (CV_pmtype) + }; + ushort bseg; // base segment if PTR_BASE_SEG + byte[] Sym; // copy of base symbol record (including length) + internal struct { + uint index; // (type index) type index if CV_PTR_BASE_TYPE + string name; // name of base type + } btype; + } pbase; +#endif + } + + // type record for LF_ARRAY + + internal struct LeafArray { + // internal ushort leaf; // LF_ARRAY [TYPTYPE] + internal uint elemtype; // (type index) type index of element type + internal uint idxtype; // (type index) type index of indexing type + internal byte[] data; // variable length data specifying size in bytes + internal string name; + }; + + // type record for LF_CLASS, LF_STRUCTURE + + internal struct LeafClass { + // internal ushort leaf; // LF_CLASS, LF_STRUCT [TYPTYPE] + internal ushort count; // count of number of elements in class + internal ushort property; // (CV_prop_t) property attribute field (prop_t) + internal uint field; // (type index) type index of LF_FIELD descriptor list + internal uint derived; // (type index) type index of derived from list if not zero + internal uint vshape; // (type index) type index of vshape table for this class + internal byte[] data; // data describing length of structure in bytes + internal string name; + }; + + // type record for LF_UNION + + internal struct LeafUnion { + // internal ushort leaf; // LF_UNION [TYPTYPE] + internal ushort count; // count of number of elements in class + internal ushort property; // (CV_prop_t) property attribute field + internal uint field; // (type index) type index of LF_FIELD descriptor list + internal byte[] data; // variable length data describing length of + internal string name; + }; + + // type record for LF_ALIAS + + internal struct LeafAlias { + // internal ushort leaf; // LF_ALIAS [TYPTYPE] + internal uint utype; // (type index) underlying type + internal string name; // alias name + }; + + // type record for LF_MANAGED + + internal struct LeafManaged { + // internal ushort leaf; // LF_MANAGED [TYPTYPE] + internal string name; // utf8, zero terminated managed type name + }; + + // type record for LF_ENUM + + internal struct LeafEnum { + // internal ushort leaf; // LF_ENUM [TYPTYPE] + internal ushort count; // count of number of elements in class + internal ushort property; // (CV_propt_t) property attribute field + internal uint utype; // (type index) underlying type of the enum + internal uint field; // (type index) type index of LF_FIELD descriptor list + internal string name; // length prefixed name of enum + }; + + // Type record for LF_PROCEDURE + + internal struct LeafProc { + // internal ushort leaf; // LF_PROCEDURE [TYPTYPE] + internal uint rvtype; // (type index) type index of return value + internal byte calltype; // calling convention (CV_call_t) + internal byte reserved; // reserved for future use + internal ushort parmcount; // number of parameters + internal uint arglist; // (type index) type index of argument list + }; + + // Type record for member function + + internal struct LeafMFunc { + // internal ushort leaf; // LF_MFUNCTION [TYPTYPE] + internal uint rvtype; // (type index) type index of return value + internal uint classtype; // (type index) type index of containing class + internal uint thistype; // (type index) type index of this pointer (model specific) + internal byte calltype; // calling convention (call_t) + internal byte reserved; // reserved for future use + internal ushort parmcount; // number of parameters + internal uint arglist; // (type index) type index of argument list + internal int thisadjust; // this adjuster (long because pad required anyway) + }; + + // type record for virtual function table shape + + internal struct LeafVTShape { + // internal ushort leaf; // LF_VTSHAPE [TYPTYPE] + internal ushort count; // number of entries in vfunctable + internal byte[] desc; // 4 bit (CV_VTS_desc) descriptors + }; + + // type record for cobol0 + + internal struct LeafCobol0 { + // internal ushort leaf; // LF_COBOL0 [TYPTYPE] + internal uint type; // (type index) parent type record index + internal byte[] data; + }; + + // type record for cobol1 + + internal struct LeafCobol1 { + // internal ushort leaf; // LF_COBOL1 [TYPTYPE] + internal byte[] data; + }; + + // type record for basic array + + internal struct LeafBArray { + // internal ushort leaf; // LF_BARRAY [TYPTYPE] + internal uint utype; // (type index) type index of underlying type + }; + + // type record for assembler labels + + internal struct LeafLabel { + // internal ushort leaf; // LF_LABEL [TYPTYPE] + internal ushort mode; // addressing mode of label + }; + + // type record for dimensioned arrays + + internal struct LeafDimArray { + // internal ushort leaf; // LF_DIMARRAY [TYPTYPE] + internal uint utype; // (type index) underlying type of the array + internal uint diminfo; // (type index) dimension information + internal string name; // length prefixed name + }; + + // type record describing path to virtual function table + + internal struct LeafVFTPath { + // internal ushort leaf; // LF_VFTPATH [TYPTYPE] + internal uint count; // count of number of bases in path + internal uint[] bases; // (type index) bases from root to leaf + }; + + // type record describing inclusion of precompiled types + + internal struct LeafPreComp { + // internal ushort leaf; // LF_PRECOMP [TYPTYPE] + internal uint start; // starting type index included + internal uint count; // number of types in inclusion + internal uint signature; // signature + internal string name; // length prefixed name of included type file + }; + + // type record describing end of precompiled types that can be + // included by another file + + internal struct LeafEndPreComp { + // internal ushort leaf; // LF_ENDPRECOMP [TYPTYPE] + internal uint signature; // signature + }; + + // type record for OEM definable type strings + + internal struct LeafOEM { + // internal ushort leaf; // LF_OEM [TYPTYPE] + internal ushort cvOEM; // MS assigned OEM identified + internal ushort recOEM; // OEM assigned type identifier + internal uint count; // count of type indices to follow + internal uint[] index; // (type index) array of type indices followed + // by OEM defined data + }; + + internal enum OEM_ID { + OEM_MS_FORTRAN90=0xF090, + OEM_ODI=0x0010, + OEM_THOMSON_SOFTWARE=0x5453, + OEM_ODI_REC_BASELIST=0x0000, + }; + + internal struct LeafOEM2 { + // internal ushort leaf; // LF_OEM2 [TYPTYPE] + internal Guid idOem; // an oem ID (Guid) + internal uint count; // count of type indices to follow + internal uint[] index; // (type index) array of type indices followed + // by OEM defined data + }; + + // type record describing using of a type server + + internal struct LeafTypeServer { + // internal ushort leaf; // LF_TYPESERVER [TYPTYPE] + internal uint signature; // signature + internal uint age; // age of database used by this module + internal string name; // length prefixed name of PDB + }; + + // type record describing using of a type server with v7 (GUID) signatures + + internal struct LeafTypeServer2 { + // internal ushort leaf; // LF_TYPESERVER2 [TYPTYPE] + internal Guid sig70; // guid signature + internal uint age; // age of database used by this module + internal string name; // length prefixed name of PDB + }; + + // description of type records that can be referenced from + // type records referenced by symbols + + // type record for skip record + + internal struct LeafSkip { + // internal ushort leaf; // LF_SKIP [TYPTYPE] + internal uint type; // (type index) next valid index + internal byte[] data; // pad data + }; + + // argument list leaf + + internal struct LeafArgList { + // internal ushort leaf; // LF_ARGLIST [TYPTYPE] + internal uint count; // number of arguments + internal uint[] arg; // (type index) number of arguments + }; + + // derived class list leaf + + internal struct LeafDerived { + // internal ushort leaf; // LF_DERIVED [TYPTYPE] + internal uint count; // number of arguments + internal uint[] drvdcls; // (type index) type indices of derived classes + }; + + // leaf for default arguments + + internal struct LeafDefArg { + // internal ushort leaf; // LF_DEFARG [TYPTYPE] + internal uint type; // (type index) type of resulting expression + internal byte[] expr; // length prefixed expression string + }; + + // list leaf + // This list should no longer be used because the utilities cannot + // verify the contents of the list without knowing what type of list + // it is. New specific leaf indices should be used instead. + + internal struct LeafList { + // internal ushort leaf; // LF_LIST [TYPTYPE] + internal byte[] data; // data format specified by indexing type + }; + + // field list leaf + // This is the header leaf for a complex list of class and structure + // subfields. + + internal struct LeafFieldList { + // internal ushort leaf; // LF_FIELDLIST [TYPTYPE] + internal char[] data; // field list sub lists + }; + + // type record for non-static methods and friends in overloaded method list + + internal struct mlMethod { + internal ushort attr; // (CV_fldattr_t) method attribute + internal ushort pad0; // internal padding, must be 0 + internal uint index; // (type index) index to type record for procedure + internal uint[] vbaseoff; // offset in vfunctable if intro virtual + }; + + internal struct LeafMethodList { + // internal ushort leaf; // LF_METHODLIST [TYPTYPE] + internal byte[] mList; // really a mlMethod type + }; + + // type record for LF_BITFIELD + + internal struct LeafBitfield { + // internal ushort leaf; // LF_BITFIELD [TYPTYPE] + internal uint type; // (type index) type of bitfield + internal byte length; + internal byte position; + }; + + // type record for dimensioned array with constant bounds + + internal struct LeafDimCon { + // internal ushort leaf; // LF_DIMCONU or LF_DIMCONLU [TYPTYPE] + internal uint typ; // (type index) type of index + internal ushort rank; // number of dimensions + internal byte[] dim; // array of dimension information with + // either upper bounds or lower/upper bound + }; + + // type record for dimensioned array with variable bounds + + internal struct LeafDimVar { + // internal ushort leaf; // LF_DIMVARU or LF_DIMVARLU [TYPTYPE] + internal uint rank; // number of dimensions + internal uint typ; // (type index) type of index + internal uint[] dim; // (type index) array of type indices for either + // variable upper bound or variable + // lower/upper bound. The count of type + // indices is rank or rank*2 depending on + // whether it is LFDIMVARU or LF_DIMVARLU. + // The referenced types must be + // LF_REFSYM or T_VOID + }; + + // type record for referenced symbol + + internal struct LeafRefSym { + // internal ushort leaf; // LF_REFSYM [TYPTYPE] + internal byte[] Sym; // copy of referenced symbol record + // (including length) + }; + + // the following are numeric leaves. They are used to indicate the + // size of the following variable length data. When the numeric + // data is a single byte less than 0x8000, then the data is output + // directly. If the data is more the 0x8000 or is a negative value, + // then the data is preceeded by the proper index. + // + + // signed character leaf + + internal struct LeafChar { + // internal ushort leaf; // LF_CHAR [TYPTYPE] + internal sbyte val; // signed 8-bit value + }; + + // signed short leaf + + internal struct LeafShort { + // internal ushort leaf; // LF_SHORT [TYPTYPE] + internal short val; // signed 16-bit value + }; + + // ushort leaf + + internal struct LeafUShort { + // internal ushort leaf; // LF_ushort [TYPTYPE] + internal ushort val; // unsigned 16-bit value + }; + + // signed (32-bit) long leaf + + internal struct LeafLong { + // internal ushort leaf; // LF_LONG [TYPTYPE] + internal int val; // signed 32-bit value + }; + + // uint leaf + + internal struct LeafULong { + // internal ushort leaf; // LF_ULONG [TYPTYPE] + internal uint val; // unsigned 32-bit value + }; + + // signed quad leaf + + internal struct LeafQuad { + // internal ushort leaf; // LF_QUAD [TYPTYPE] + internal long val; // signed 64-bit value + }; + + // unsigned quad leaf + + internal struct LeafUQuad { + // internal ushort leaf; // LF_UQUAD [TYPTYPE] + internal ulong val; // unsigned 64-bit value + }; + + // signed int128 leaf + + internal struct LeafOct { + // internal ushort leaf; // LF_OCT [TYPTYPE] + internal ulong val0; + internal ulong val1; // signed 128-bit value + }; + + // unsigned int128 leaf + + internal struct LeafUOct { + // internal ushort leaf; // LF_UOCT [TYPTYPE] + internal ulong val0; + internal ulong val1; // unsigned 128-bit value + }; + + // real 32-bit leaf + + internal struct LeafReal32 { + // internal ushort leaf; // LF_REAL32 [TYPTYPE] + internal float val; // 32-bit real value + }; + + // real 64-bit leaf + + internal struct LeafReal64 { + // internal ushort leaf; // LF_REAL64 [TYPTYPE] + internal double val; // 64-bit real value + }; + + // real 80-bit leaf + + internal struct LeafReal80 { + // internal ushort leaf; // LF_REAL80 [TYPTYPE] + internal FLOAT10 val; // real 80-bit value + }; + + // real 128-bit leaf + + internal struct LeafReal128 { + // internal ushort leaf; // LF_REAL128 [TYPTYPE] + internal ulong val0; + internal ulong val1; // real 128-bit value + }; + + // complex 32-bit leaf + + internal struct LeafCmplx32 { + // internal ushort leaf; // LF_COMPLEX32 [TYPTYPE] + internal float val_real; // real component + internal float val_imag; // imaginary component + }; + + // complex 64-bit leaf + + internal struct LeafCmplx64 { + // internal ushort leaf; // LF_COMPLEX64 [TYPTYPE] + internal double val_real; // real component + internal double val_imag; // imaginary component + }; + + // complex 80-bit leaf + + internal struct LeafCmplx80 { + // internal ushort leaf; // LF_COMPLEX80 [TYPTYPE] + internal FLOAT10 val_real; // real component + internal FLOAT10 val_imag; // imaginary component + }; + + // complex 128-bit leaf + + internal struct LeafCmplx128 { + // internal ushort leaf; // LF_COMPLEX128 [TYPTYPE] + internal ulong val0_real; + internal ulong val1_real; // real component + internal ulong val0_imag; + internal ulong val1_imag; // imaginary component + }; + + // variable length numeric field + + internal struct LeafVarString { + // internal ushort leaf; // LF_VARSTRING [TYPTYPE] + internal ushort len; // length of value in bytes + internal byte[] value; // value + }; + + // index leaf - contains type index of another leaf + // a major use of this leaf is to allow the compilers to emit a + // long complex list (LF_FIELD) in smaller pieces. + + internal struct LeafIndex { + // internal ushort leaf; // LF_INDEX [TYPTYPE] + internal ushort pad0; // internal padding, must be 0 + internal uint index; // (type index) type index of referenced leaf + }; + + // subfield record for base class field + + internal struct LeafBClass { + // internal ushort leaf; // LF_BCLASS [TYPTYPE] + internal ushort attr; // (CV_fldattr_t) attribute + internal uint index; // (type index) type index of base class + internal byte[] offset; // variable length offset of base within class + }; + + // subfield record for direct and indirect virtual base class field + + internal struct LeafVBClass { + // internal ushort leaf; // LF_VBCLASS | LV_IVBCLASS [TYPTYPE] + internal ushort attr; // (CV_fldattr_t) attribute + internal uint index; // (type index) type index of direct virtual base class + internal uint vbptr; // (type index) type index of virtual base pointer + internal byte[] vbpoff; // virtual base pointer offset from address point + // followed by virtual base offset from vbtable + }; + + // subfield record for friend class + + internal struct LeafFriendCls { + // internal ushort leaf; // LF_FRIENDCLS [TYPTYPE] + internal ushort pad0; // internal padding, must be 0 + internal uint index; // (type index) index to type record of friend class + }; + + // subfield record for friend function + + internal struct LeafFriendFcn { + // internal ushort leaf; // LF_FRIENDFCN [TYPTYPE] + internal ushort pad0; // internal padding, must be 0 + internal uint index; // (type index) index to type record of friend function + internal string name; // name of friend function + }; + + // subfield record for non-static data members + + internal struct LeafMember { + // internal ushort leaf; // LF_MEMBER [TYPTYPE] + internal ushort attr; // (CV_fldattr_t)attribute mask + internal uint index; // (type index) index of type record for field + internal byte[] offset; // variable length offset of field + internal string name; // length prefixed name of field + }; + + // type record for static data members + + internal struct LeafSTMember { + // internal ushort leaf; // LF_STMEMBER [TYPTYPE] + internal ushort attr; // (CV_fldattr_t) attribute mask + internal uint index; // (type index) index of type record for field + internal string name; // length prefixed name of field + }; + + // subfield record for virtual function table pointer + + internal struct LeafVFuncTab { + // internal ushort leaf; // LF_VFUNCTAB [TYPTYPE] + internal ushort pad0; // internal padding, must be 0 + internal uint type; // (type index) type index of pointer + }; + + // subfield record for virtual function table pointer with offset + + internal struct LeafVFuncOff { + // internal ushort leaf; // LF_VFUNCOFF [TYPTYPE] + internal ushort pad0; // internal padding, must be 0. + internal uint type; // (type index) type index of pointer + internal int offset; // offset of virtual function table pointer + }; + + // subfield record for overloaded method list + + internal struct LeafMethod { + // internal ushort leaf; // LF_METHOD [TYPTYPE] + internal ushort count; // number of occurrences of function + internal uint mList; // (type index) index to LF_METHODLIST record + internal string name; // length prefixed name of method + }; + + // subfield record for nonoverloaded method + + internal struct LeafOneMethod { + // internal ushort leaf; // LF_ONEMETHOD [TYPTYPE] + internal ushort attr; // (CV_fldattr_t) method attribute + internal uint index; // (type index) index to type record for procedure + internal uint[] vbaseoff; // offset in vfunctable if intro virtual + internal string name; + }; + + // subfield record for enumerate + + internal struct LeafEnumerate { + // internal ushort leaf; // LF_ENUMERATE [TYPTYPE] + internal ushort attr; // (CV_fldattr_t) access + internal byte[] value; // variable length value field + internal string name; + }; + + // type record for nested (scoped) type definition + + internal struct LeafNestType { + // internal ushort leaf; // LF_NESTTYPE [TYPTYPE] + internal ushort pad0; // internal padding, must be 0 + internal uint index; // (type index) index of nested type definition + internal string name; // length prefixed type name + }; + + // type record for nested (scoped) type definition, with attributes + // new records for vC v5.0, no need to have 16-bit ti versions. + + internal struct LeafNestTypeEx { + // internal ushort leaf; // LF_NESTTYPEEX [TYPTYPE] + internal ushort attr; // (CV_fldattr_t) member access + internal uint index; // (type index) index of nested type definition + internal string name; // length prefixed type name + }; + + // type record for modifications to members + + internal struct LeafMemberModify { + // internal ushort leaf; // LF_MEMBERMODIFY [TYPTYPE] + internal ushort attr; // (CV_fldattr_t) the new attributes + internal uint index; // (type index) index of base class type definition + internal string name; // length prefixed member name + }; + + // type record for pad leaf + + internal struct LeafPad { + internal byte leaf; + }; + + // Symbol definitions + + internal enum SYM { + S_END=0x0006, // Block, procedure, "with" or thunk end + S_OEM=0x0404, // OEM defined symbol + + S_REGISTER_ST=0x1001, // Register variable + S_CONSTANT_ST=0x1002, // constant symbol + S_UDT_ST=0x1003, // User defined type + S_COBOLUDT_ST=0x1004, // special UDT for cobol that does not symbol pack + S_MANYREG_ST=0x1005, // multiple register variable + S_BPREL32_ST=0x1006, // BP-relative + S_LDATA32_ST=0x1007, // Module-local symbol + S_GDATA32_ST=0x1008, // Global data symbol + S_PUB32_ST=0x1009, // a internal symbol (CV internal reserved) + S_LPROC32_ST=0x100a, // Local procedure start + S_GPROC32_ST=0x100b, // Global procedure start + S_VFTABLE32=0x100c, // address of virtual function table + S_REGREL32_ST=0x100d, // register relative address + S_LTHREAD32_ST=0x100e, // local thread storage + S_GTHREAD32_ST=0x100f, // global thread storage + + S_LPROCMIPS_ST=0x1010, // Local procedure start + S_GPROCMIPS_ST=0x1011, // Global procedure start + + // new symbol records for edit and continue information + + S_FRAMEPROC=0x1012, // extra frame and proc information + S_COMPILE2_ST=0x1013, // extended compile flags and info + + // new symbols necessary for 16-bit enumerates of IA64 registers + // and IA64 specific symbols + + S_MANYREG2_ST=0x1014, // multiple register variable + S_LPROCIA64_ST=0x1015, // Local procedure start (IA64) + S_GPROCIA64_ST=0x1016, // Global procedure start (IA64) + + // Local symbols for IL + S_LOCALSLOT_ST=0x1017, // local IL sym with field for local slot index + S_PARAMSLOT_ST=0x1018, // local IL sym with field for parameter slot index + + S_ANNOTATION=0x1019, // Annotation string literals + + // symbols to support managed code debugging + S_GMANPROC_ST=0x101a, // Global proc + S_LMANPROC_ST=0x101b, // Local proc + S_RESERVED1=0x101c, // reserved + S_RESERVED2=0x101d, // reserved + S_RESERVED3=0x101e, // reserved + S_RESERVED4=0x101f, // reserved + S_LMANDATA_ST=0x1020, + S_GMANDATA_ST=0x1021, + S_MANFRAMEREL_ST=0x1022, + S_MANREGISTER_ST=0x1023, + S_MANSLOT_ST=0x1024, + S_MANMANYREG_ST=0x1025, + S_MANREGREL_ST=0x1026, + S_MANMANYREG2_ST=0x1027, + S_MANTYPREF=0x1028, // Index for type referenced by name from metadata + S_UNAMESPACE_ST=0x1029, // Using namespace + + // Symbols w/ SZ name fields. All name fields contain utf8 encoded strings. + S_ST_MAX=0x1100, // starting point for SZ name symbols + + S_OBJNAME=0x1101, // path to object file name + S_THUNK32=0x1102, // Thunk Start + S_BLOCK32=0x1103, // block start + S_WITH32=0x1104, // with start + S_LABEL32=0x1105, // code label + S_REGISTER=0x1106, // Register variable + S_CONSTANT=0x1107, // constant symbol + S_UDT=0x1108, // User defined type + S_COBOLUDT=0x1109, // special UDT for cobol that does not symbol pack + S_MANYREG=0x110a, // multiple register variable + S_BPREL32=0x110b, // BP-relative + S_LDATA32=0x110c, // Module-local symbol + S_GDATA32=0x110d, // Global data symbol + S_PUB32=0x110e, // a internal symbol (CV internal reserved) + S_LPROC32=0x110f, // Local procedure start + S_GPROC32=0x1110, // Global procedure start + S_REGREL32=0x1111, // register relative address + S_LTHREAD32=0x1112, // local thread storage + S_GTHREAD32=0x1113, // global thread storage + + S_LPROCMIPS=0x1114, // Local procedure start + S_GPROCMIPS=0x1115, // Global procedure start + S_COMPILE2=0x1116, // extended compile flags and info + S_MANYREG2=0x1117, // multiple register variable + S_LPROCIA64=0x1118, // Local procedure start (IA64) + S_GPROCIA64=0x1119, // Global procedure start (IA64) + S_LOCALSLOT=0x111a, // local IL sym with field for local slot index + S_SLOT=S_LOCALSLOT, // alias for LOCALSLOT + S_PARAMSLOT=0x111b, // local IL sym with field for parameter slot index + + // symbols to support managed code debugging + S_LMANDATA=0x111c, + S_GMANDATA=0x111d, + S_MANFRAMEREL=0x111e, + S_MANREGISTER=0x111f, + S_MANSLOT=0x1120, + S_MANMANYREG=0x1121, + S_MANREGREL=0x1122, + S_MANMANYREG2=0x1123, + S_UNAMESPACE=0x1124, // Using namespace + + // ref symbols with name fields + S_PROCREF=0x1125, // Reference to a procedure + S_DATAREF=0x1126, // Reference to data + S_LPROCREF=0x1127, // Local Reference to a procedure + S_ANNOTATIONREF=0x1128, // Reference to an S_ANNOTATION symbol + S_TOKENREF=0x1129, // Reference to one of the many MANPROCSYM's + + // continuation of managed symbols + S_GMANPROC=0x112a, // Global proc + S_LMANPROC=0x112b, // Local proc + + // short, light-weight thunks + S_TRAMPOLINE=0x112c, // trampoline thunks + S_MANCONSTANT=0x112d, // constants with metadata type info + + // native attributed local/parms + S_ATTR_FRAMEREL=0x112e, // relative to virtual frame ptr + S_ATTR_REGISTER=0x112f, // stored in a register + S_ATTR_REGREL=0x1130, // relative to register (alternate frame ptr) + S_ATTR_MANYREG=0x1131, // stored in >1 register + + // Separated code (from the compiler) support + S_SEPCODE=0x1132, + + S_LOCAL=0x1133, // defines a local symbol in optimized code + S_DEFRANGE=0x1134, // defines a single range of addresses in which symbol can be evaluated + S_DEFRANGE2=0x1135, // defines ranges of addresses in which symbol can be evaluated + + S_SECTION=0x1136, // A COFF section in a PE executable + S_COFFGROUP=0x1137, // A COFF group + S_EXPORT=0x1138, // A export + + S_CALLSITEINFO=0x1139, // Indirect call site information + S_FRAMECOOKIE=0x113a, // Security cookie information + + S_DISCARDED=0x113b, // Discarded by LINK /OPT:REF (experimental, see richards) + + S_RECTYPE_MAX, // one greater than last + S_RECTYPE_LAST=S_RECTYPE_MAX - 1, + + }; + + // enum describing compile flag ambient data model + + internal enum CV_CFL_DATA { + CV_CFL_DNEAR=0x00, + CV_CFL_DFAR=0x01, + CV_CFL_DHUGE=0x02 + }; + + // enum describing compile flag ambiant code model + + internal enum CV_CFL_CODE { + CV_CFL_CNEAR=0x00, + CV_CFL_CFAR=0x01, + CV_CFL_CHUGE=0x02 + }; + + // enum describing compile flag target floating point package + + internal enum CV_CFL_FPKG { + CV_CFL_NDP=0x00, + CV_CFL_EMU=0x01, + CV_CFL_ALT=0x02 + }; + + // enum describing function return method + + [Flags] + internal enum CV_PROCFLAGS : byte { + CV_PFLAG_NOFPO=0x01, // frame pointer present + CV_PFLAG_INT=0x02, // interrupt return + CV_PFLAG_FAR=0x04, // far return + CV_PFLAG_NEVER=0x08, // function does not return + CV_PFLAG_NOTREACHED=0x10, // label isn't fallen into + CV_PFLAG_CUST_CALL=0x20, // custom calling convention + CV_PFLAG_NOINLINE=0x40, // function marked as noinline + CV_PFLAG_OPTDBGINFO=0x80, // function has debug information for optimized code + }; + + // Extended proc flags + // + internal struct CV_EXPROCFLAGS { + internal byte flags; // (CV_PROCFLAGS) + internal byte reserved; // must be zero + }; + + // local variable flags + [Flags] + internal enum CV_LVARFLAGS : ushort { + fIsParam=0x0001, // variable is a parameter + fAddrTaken=0x0002, // address is taken + fCompGenx=0x0004, // variable is compiler generated + fIsAggregate=0x0008, // the symbol is splitted in temporaries, + // which are treated by compiler as + // independent entities + fIsAggregated=0x0010, // Counterpart of fIsAggregate - tells + // that it is a part of a fIsAggregate symbol + fIsAliased=0x0020, // variable has multiple simultaneous lifetimes + fIsAlias=0x0040, // represents one of the multiple simultaneous lifetimes + }; + + // represents an address range, used for optimized code debug info + internal struct CV_lvar_addr_range { // defines a range of addresses + internal uint offStart; + internal ushort isectStart; + internal uint cbRange; + }; + + // enum describing function data return method + + internal enum CV_GENERIC_STYLE { + CV_GENERIC_VOID=0x00, // void return type + CV_GENERIC_REG=0x01, // return data is in registers + CV_GENERIC_ICAN=0x02, // indirect caller allocated near + CV_GENERIC_ICAF=0x03, // indirect caller allocated far + CV_GENERIC_IRAN=0x04, // indirect returnee allocated near + CV_GENERIC_IRAF=0x05, // indirect returnee allocated far + CV_GENERIC_UNUSED=0x06 // first unused + }; + + [Flags] + internal enum CV_GENERIC_FLAG : ushort { + cstyle=0x0001, // true push varargs right to left + rsclean=0x0002, // true if returnee stack cleanup + }; + + // flag bitfields for separated code attributes + + [Flags] + internal enum CV_SEPCODEFLAGS : uint { + fIsLexicalScope=0x00000001, // S_SEPCODE doubles as lexical scope + fReturnsToParent=0x00000002, // code frag returns to parent + }; + + // Generic layout for symbol records + + internal struct SYMTYPE { + internal ushort reclen; // Record length + internal ushort rectyp; // Record type + // byte data[CV_ZEROLEN]; + // SYMTYPE *NextSym (SYMTYPE * pSym) { + // return (SYMTYPE *) ((char *)pSym + pSym->reclen + sizeof(ushort)); + // } + }; + + // non-model specific symbol types + + internal struct RegSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_REGISTER + internal uint typind; // (type index) Type index or Metadata token + internal ushort reg; // register enumerate + internal string name; // Length-prefixed name + }; + + internal struct AttrRegSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANREGISTER | S_ATTR_REGISTER + internal uint typind; // (type index) Type index or Metadata token + internal uint offCod; // first code address where var is live + internal ushort segCod; + internal ushort flags; // (CV_LVARFLAGS)local var flags + internal ushort reg; // register enumerate + internal string name; // Length-prefixed name + }; + + internal struct ManyRegSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANYREG + internal uint typind; // (type index) Type index or metadata token + internal byte count; // count of number of registers + internal byte[] reg; // count register enumerates, most-sig first + internal string name; // length-prefixed name. + }; + + internal struct ManyRegSym2 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANYREG2 + internal uint typind; // (type index) Type index or metadata token + internal ushort count; // count of number of registers, + internal ushort[] reg; // count register enumerates, most-sig first + internal string name; // length-prefixed name. + }; + + internal struct AttrManyRegSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANMANYREG + internal uint typind; // (type index) Type index or metadata token + internal uint offCod; // first code address where var is live + internal ushort segCod; + internal ushort flags; // (CV_LVARFLAGS)local var flags + internal byte count; // count of number of registers + internal byte[] reg; // count register enumerates, most-sig first + internal string name; // utf-8 encoded zero terminate name + }; + + internal struct AttrManyRegSym2 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANMANYREG2 | S_ATTR_MANYREG + internal uint typind; // (type index) Type index or metadata token + internal uint offCod; // first code address where var is live + internal ushort segCod; + internal ushort flags; // (CV_LVARFLAGS)local var flags + internal ushort count; // count of number of registers + internal ushort[] reg; // count register enumerates, most-sig first + internal string name; // utf-8 encoded zero terminate name + }; + + internal struct ConstSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_CONSTANT or S_MANCONSTANT + internal uint typind; // (type index) Type index (containing enum if enumerate) or metadata token + internal ushort value; // numeric leaf containing value + internal string name; // Length-prefixed name + }; + + internal struct UdtSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_UDT | S_COBOLUDT + internal uint typind; // (type index) Type index + internal string name; // Length-prefixed name + }; + + internal struct ManyTypRef { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANTYPREF + internal uint typind; // (type index) Type index + }; + + internal struct SearchSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_SSEARCH + internal uint startsym; // offset of the procedure + internal ushort seg; // segment of symbol + }; + + [Flags] + internal enum CFLAGSYM_FLAGS : ushort { + pcode=0x0001, // true if pcode present + floatprec=0x0006, // floating precision + floatpkg=0x0018, // float package + ambdata=0x00e0, // ambient data model + ambcode=0x0700, // ambient code model + mode32=0x0800, // true if compiled 32 bit mode + }; + + internal struct CFlagSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_COMPILE + internal byte machine; // target processor + internal byte language; // language index + internal ushort flags; // (CFLAGSYM_FLAGS) + internal string ver; // Length-prefixed compiler version string + }; + + [Flags] + internal enum COMPILESYM_FLAGS : uint { + iLanguage=0x000000ff, // language index + fEC=0x00000100, // compiled for E/C + fNoDbgInfo=0x00000200, // not compiled with debug info + fLTCG=0x00000400, // compiled with LTCG + fNoDataAlign=0x00000800, // compiled with -Bzalign + fManagedPresent=0x00001000, // managed code/data present + fSecurityChecks=0x00002000, // compiled with /GS + fHotPatch=0x00004000, // compiled with /hotpatch + fCVTCIL=0x00008000, // converted with CVTCIL + fMSILModule=0x00010000, // MSIL netmodule + }; + + internal struct CompileSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_COMPILE2 + internal uint flags; // (COMPILESYM_FLAGS) + internal ushort machine; // target processor + internal ushort verFEMajor; // front end major version # + internal ushort verFEMinor; // front end minor version # + internal ushort verFEBuild; // front end build version # + internal ushort verMajor; // back end major version # + internal ushort verMinor; // back end minor version # + internal ushort verBuild; // back end build version # + internal string verSt; // Length-prefixed compiler version string, followed + internal string[] verArgs; // block of zero terminated strings, ended by double-zero. + }; + + internal struct ObjNameSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_OBJNAME + internal uint signature; // signature + internal string name; // Length-prefixed name + }; + + internal struct EndArgSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_ENDARG + }; + + internal struct ReturnSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_RETURN + internal CV_GENERIC_FLAG flags; // flags + internal byte style; // CV_GENERIC_STYLE return style + // followed by return method data + }; + + internal struct EntryThisSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_ENTRYTHIS + internal byte thissym; // symbol describing this pointer on entry + }; + + internal struct BpRelSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_BPREL32 + internal int off; // BP-relative offset + internal uint typind; // (type index) Type index or Metadata token + internal string name; // Length-prefixed name + }; + + internal struct FrameRelSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANFRAMEREL | S_ATTR_FRAMEREL + internal int off; // Frame relative offset + internal uint typind; // (type index) Type index or Metadata token + internal uint offCod; // first code address where var is live + internal ushort segCod; + internal ushort flags; // (CV_LVARFLAGS)local var flags + internal string name; // Length-prefixed name + }; + + internal struct SlotSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_LOCALSLOT or S_PARAMSLOT + internal uint index; // slot index + internal uint typind; // (type index) Type index or Metadata token + internal string name; // Length-prefixed name + }; + + internal struct AttrSlotSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANSLOT + internal uint index; // slot index + internal uint typind; // (type index) Type index or Metadata token + internal uint offCod; // first code address where var is live + internal ushort segCod; + internal ushort flags; // (CV_LVARFLAGS)local var flags + internal string name; // Length-prefixed name + + }; + + internal struct AnnotationSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_ANNOTATION + internal uint off; + internal ushort seg; + internal ushort csz; // Count of zero terminated annotation strings + internal string[] rgsz; // Sequence of zero terminated annotation strings + }; + + internal struct DatasSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_LDATA32, S_GDATA32 or S_PUB32, S_LMANDATA, S_GMANDATA + internal uint typind; // (type index) Type index, or Metadata token if a managed symbol + internal uint off; + internal ushort seg; + internal string name; // Length-prefixed name + }; + + [Flags] + internal enum CV_PUBSYMFLAGS : uint { + fNone=0, + fCode=0x00000001, // set if internal symbol refers to a code address + fFunction=0x00000002, // set if internal symbol is a function + fManaged=0x00000004, // set if managed code (native or IL) + fMSIL=0x00000008, // set if managed IL code + }; + + internal struct PubSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_PUB32 + internal uint flags; // (CV_PUBSYMFLAGS) + internal uint off; + internal ushort seg; + internal string name; // Length-prefixed name + }; + + internal struct ProcSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_GPROC32 or S_LPROC32 + internal uint parent; // pointer to the parent + internal uint end; // pointer to this blocks end + internal uint next; // pointer to next symbol + internal uint len; // Proc length + internal uint dbgStart; // Debug start offset + internal uint dbgEnd; // Debug end offset + internal uint typind; // (type index) Type index + internal uint off; + internal ushort seg; + internal byte flags; // (CV_PROCFLAGS) Proc flags + internal string name; // Length-prefixed name + }; + + internal struct ManProcSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_GMANPROC, S_LMANPROC, S_GMANPROCIA64 or S_LMANPROCIA64 + internal uint parent; // pointer to the parent + internal uint end; // pointer to this blocks end + internal uint next; // pointer to next symbol + internal uint len; // Proc length + internal uint dbgStart; // Debug start offset + internal uint dbgEnd; // Debug end offset + internal uint token; // COM+ metadata token for method + internal uint off; + internal ushort seg; + internal byte flags; // (CV_PROCFLAGS) Proc flags + internal ushort retReg; // Register return value is in (may not be used for all archs) + internal string name; // optional name field + }; + + internal struct ManProcSymMips { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_GMANPROCMIPS or S_LMANPROCMIPS + internal uint parent; // pointer to the parent + internal uint end; // pointer to this blocks end + internal uint next; // pointer to next symbol + internal uint len; // Proc length + internal uint dbgStart; // Debug start offset + internal uint dbgEnd; // Debug end offset + internal uint regSave; // int register save mask + internal uint fpSave; // fp register save mask + internal uint intOff; // int register save offset + internal uint fpOff; // fp register save offset + internal uint token; // COM+ token type + internal uint off; + internal ushort seg; + internal byte retReg; // Register return value is in + internal byte frameReg; // Frame pointer register + internal string name; // optional name field + }; + + internal struct ThunkSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_THUNK32 + internal uint parent; // pointer to the parent + internal uint end; // pointer to this blocks end + internal uint next; // pointer to next symbol + internal uint off; + internal ushort seg; + internal ushort len; // length of thunk + internal byte ord; // THUNK_ORDINAL specifying type of thunk + internal string name; // Length-prefixed name + internal byte[] variant; // variant portion of thunk + }; + + internal enum TRAMP { // Trampoline subtype + trampIncremental, // incremental thunks + trampBranchIsland, // Branch island thunks + }; + + internal struct TrampolineSym { // Trampoline thunk symbol + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_TRAMPOLINE + internal ushort trampType; // trampoline sym subtype + internal ushort cbThunk; // size of the thunk + internal uint offThunk; // offset of the thunk + internal uint offTarget; // offset of the target of the thunk + internal ushort sectThunk; // section index of the thunk + internal ushort sectTarget; // section index of the target of the thunk + }; + + internal struct LabelSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_LABEL32 + internal uint off; + internal ushort seg; + internal byte flags; // (CV_PROCFLAGS) flags + internal string name; // Length-prefixed name + }; + + internal struct BlockSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_BLOCK32 + internal uint parent; // pointer to the parent + internal uint end; // pointer to this blocks end + internal uint len; // Block length + internal uint off; // Offset in code segment + internal ushort seg; // segment of label + internal string name; // Length-prefixed name + }; + + internal struct WithSym32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_WITH32 + internal uint parent; // pointer to the parent + internal uint end; // pointer to this blocks end + internal uint len; // Block length + internal uint off; // Offset in code segment + internal ushort seg; // segment of label + internal string expr; // Length-prefixed expression string + }; + + internal struct VpathSym32 { + // internal ushort reclen; // record length + // internal ushort rectyp; // S_VFTABLE32 + internal uint root; // (type index) type index of the root of path + internal uint path; // (type index) type index of the path record + internal uint off; // offset of virtual function table + internal ushort seg; // segment of virtual function table + }; + + internal struct RegRel32 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_REGREL32 + internal uint off; // offset of symbol + internal uint typind; // (type index) Type index or metadata token + internal ushort reg; // register index for symbol + internal string name; // Length-prefixed name + }; + + internal struct AttrRegRel { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_MANREGREL | S_ATTR_REGREL + internal uint off; // offset of symbol + internal uint typind; // (type index) Type index or metadata token + internal ushort reg; // register index for symbol + internal uint offCod; // first code address where var is live + internal ushort segCod; + internal ushort flags; // (CV_LVARFLAGS)local var flags + internal string name; // Length-prefixed name + }; + + internal struct ThreadSym32 { + // internal ushort reclen; // record length + // internal ushort rectyp; // S_LTHREAD32 | S_GTHREAD32 + internal uint typind; // (type index) type index + internal uint off; // offset into thread storage + internal ushort seg; // segment of thread storage + internal string name; // length prefixed name + }; + + internal struct Slink32 { + // internal ushort reclen; // record length + // internal ushort rectyp; // S_SLINK32 + internal uint framesize; // frame size of parent procedure + internal int off; // signed offset where the static link was saved relative to the value of reg + internal ushort reg; + }; + + internal struct ProcSymMips { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_GPROCMIPS or S_LPROCMIPS + internal uint parent; // pointer to the parent + internal uint end; // pointer to this blocks end + internal uint next; // pointer to next symbol + internal uint len; // Proc length + internal uint dbgStart; // Debug start offset + internal uint dbgEnd; // Debug end offset + internal uint regSave; // int register save mask + internal uint fpSave; // fp register save mask + internal uint intOff; // int register save offset + internal uint fpOff; // fp register save offset + internal uint typind; // (type index) Type index + internal uint off; // Symbol offset + internal ushort seg; // Symbol segment + internal byte retReg; // Register return value is in + internal byte frameReg; // Frame pointer register + internal string name; // Length-prefixed name + }; + + internal struct ProcSymIa64 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_GPROCIA64 or S_LPROCIA64 + internal uint parent; // pointer to the parent + internal uint end; // pointer to this blocks end + internal uint next; // pointer to next symbol + internal uint len; // Proc length + internal uint dbgStart; // Debug start offset + internal uint dbgEnd; // Debug end offset + internal uint typind; // (type index) Type index + internal uint off; // Symbol offset + internal ushort seg; // Symbol segment + internal ushort retReg; // Register return value is in + internal byte flags; // (CV_PROCFLAGS) Proc flags + internal string name; // Length-prefixed name + }; + + internal struct RefSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_PROCREF_ST, S_DATAREF_ST, or S_LPROCREF_ST + internal uint sumName; // SUC of the name + internal uint ibSym; // Offset of actual symbol in $$Symbols + internal ushort imod; // Module containing the actual symbol + internal ushort usFill; // align this record + }; + + internal struct RefSym2 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_PROCREF, S_DATAREF, or S_LPROCREF + internal uint sumName; // SUC of the name + internal uint ibSym; // Offset of actual symbol in $$Symbols + internal ushort imod; // Module containing the actual symbol + internal string name; // hidden name made a first class member + }; + + internal struct AlignSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_ALIGN + }; + + internal struct OemSymbol { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_OEM + internal Guid idOem; // an oem ID (GUID) + internal uint typind; // (type index) Type index + internal byte[] rgl; // user data, force 4-byte alignment + }; + + [Flags] + internal enum FRAMEPROCSYM_FLAGS : uint { + fHasAlloca=0x00000001, // function uses _alloca() + fHasSetJmp=0x00000002, // function uses setjmp() + fHasLongJmp=0x00000004, // function uses longjmp() + fHasInlAsm=0x00000008, // function uses inline asm + fHasEH=0x00000010, // function has EH states + fInlSpec=0x00000020, // function was speced as inline + fHasSEH=0x00000040, // function has SEH + fNaked=0x00000080, // function is __declspec(naked) + fSecurityChecks=0x00000100, // function has buffer security check introduced by /GS. + fAsyncEH=0x00000200, // function compiled with /EHa + fGSNoStackOrdering=0x00000400, // function has /GS buffer checks, but stack ordering couldn't be done + fWasInlined=0x00000800, // function was inlined within another function + }; + + internal struct FrameProcSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_FRAMEPROC + internal uint cbFrame; // count of bytes of total frame of procedure + internal uint cbPad; // count of bytes of padding in the frame + internal uint offPad; // offset (rel to frame) to where padding starts + internal uint cbSaveRegs; // count of bytes of callee save registers + internal uint offExHdlr; // offset of exception handler + internal ushort secExHdlr; // section id of exception handler + internal uint flags; // (FRAMEPROCSYM_FLAGS) + } + + internal struct UnamespaceSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_UNAMESPACE + internal string name; // name + }; + + internal struct SepCodSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_SEPCODE + internal uint parent; // pointer to the parent + internal uint end; // pointer to this block's end + internal uint length; // count of bytes of this block + internal uint scf; // (CV_SEPCODEFLAGS) flags + internal uint off; // sec:off of the separated code + internal uint offParent; // secParent:offParent of the enclosing scope + internal ushort sec; // (proc, block, or sepcode) + internal ushort secParent; + }; + + internal struct LocalSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_LOCAL + internal uint id; // id of the local + internal uint typind; // (type index) type index + internal ushort flags; // (CV_LVARFLAGS) local var flags + internal uint idParent; // This is is parent variable - fIsAggregated or fIsAlias + internal uint offParent; // Offset in parent variable - fIsAggregated + + internal uint expr; // NI of expression that this temp holds + internal uint pad0; // pad, must be zero + internal uint pad1; // pad, must be zero + + internal string name; // Name of this symbol. + } + + internal struct DefRangeSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_DEFRANGE + + internal uint id; // ID of the local symbol for which this formula holds + internal uint program; // program to evaluate the value of the symbol + + internal CV_lvar_addr_range range; // Range of addresses where this program is valid + }; + + internal struct DefRangeSym2 { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_DEFRANGE2 + + internal uint id; // ID of the local symbol for which this formula holds + internal uint program; // program to evaluate the value of the symbol + + internal ushort count; // count of CV_lvar_addr_range records following + internal CV_lvar_addr_range[] range;// Range of addresses where this program is valid + }; + + internal struct SectionSym { + // internal ushort reclen // Record length + // internal ushort rectyp; // S_SECTION + + internal ushort isec; // Section number + internal byte align; // Alignment of this section (power of 2) + internal byte bReserved; // Reserved. Must be zero. + internal uint rva; + internal uint cb; + internal uint characteristics; + internal string name; // name + }; + + internal struct CoffGroupSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_COFFGROUP + + internal uint cb; + internal uint characteristics; + internal uint off; // Symbol offset + internal ushort seg; // Symbol segment + internal string name; // name + }; + + [Flags] + internal enum EXPORTSYM_FLAGS : ushort { + fConstant=0x0001, // CONSTANT + fData=0x0002, // DATA + fPrivate=0x0004, // PRIVATE + fNoName=0x0008, // NONAME + fOrdinal=0x0010, // Ordinal was explicitly assigned + fForwarder=0x0020, // This is a forwarder + } + + internal struct ExportSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_EXPORT + + internal ushort ordinal; + internal ushort flags; // (EXPORTSYM_FLAGS) + internal string name; // name of + }; + + // + // Symbol for describing indirect calls when they are using + // a function pointer cast on some other type or temporary. + // Typical content will be an LF_POINTER to an LF_PROCEDURE + // type record that should mimic an actual variable with the + // function pointer type in question. + // + // Since the compiler can sometimes tail-merge a function call + // through a function pointer, there may be more than one + // S_CALLSITEINFO record at an address. This is similar to what + // you could do in your own code by: + // + // if (expr) + // pfn = &function1; + // else + // pfn = &function2; + // + // (*pfn)(arg list); + // + + internal struct CallsiteInfo { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_CALLSITEINFO + internal int off; // offset of call site + internal ushort ect; // section index of call site + internal ushort pad0; // alignment padding field, must be zero + internal uint typind; // (type index) type index describing function signature + }; + + // Frame cookie information + + internal enum CV_cookietype { + CV_COOKIETYPE_COPY=0, + CV_COOKIETYPE_XOR_SP, + CV_COOKIETYPE_XOR_BP, + CV_COOKIETYPE_XOR_R13, + }; + + // Symbol for describing security cookie's position and type + // (raw, xor'd with esp, xor'd with ebp). + + internal struct FrameCookie { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_FRAMECOOKIE + internal int off; // Frame relative offset + internal ushort reg; // Register index + internal int cookietype; // (CV_cookietype) Type of the cookie + internal byte flags; // Flags describing this cookie + }; + + internal enum CV_DISCARDED : uint { + CV_DISCARDED_UNKNOWN=0, + CV_DISCARDED_NOT_SELECTED=1, + CV_DISCARDED_NOT_REFERENCED=2, + }; + + internal struct DiscardedSym { + // internal ushort reclen; // Record length [SYMTYPE] + // internal ushort rectyp; // S_DISCARDED + internal CV_DISCARDED iscarded; + internal uint fileid; // First FILEID if line number info present + internal uint linenum; // First line number + internal byte[] data; // Original record(s) with invalid indices + }; + + // + // V7 line number data types + // + + internal enum DEBUG_S_SUBSECTION_TYPE : uint { + DEBUG_S_IGNORE=0x80000000, // if this bit is set in a subsection type then ignore the subsection contents + + DEBUG_S_SYMBOLS=0xf1, + DEBUG_S_LINES=0xf2, + DEBUG_S_STRINGTABLE=0xf3, + DEBUG_S_FILECHKSMS=0xf4, + DEBUG_S_FRAMEDATA=0xf5, + }; + + // + // Line flags (data present) + // + internal enum CV_LINE_SUBSECTION_FLAGS : ushort { + CV_LINES_HAVE_COLUMNS=0x0001, + } + + internal struct CV_LineSection { + internal uint off; + internal ushort sec; + internal ushort flags; + internal uint cod; + } + + internal struct CV_SourceFile { + internal uint index; // Index to file in checksum section. + internal uint count; // Number of CV_Line records. + internal uint linsiz; // Size of CV_Line recods. + } + + [Flags] + internal enum CV_Line_Flags : uint { + linenumStart=0x00ffffff, // line where statement/expression starts + deltaLineEnd=0x7f000000, // delta to line where statement ends (optional) + fStatement=0x80000000, // true if a statement linenumber, else an expression line num + }; + + internal struct CV_Line { + internal uint offset; // Offset to start of code bytes for line number + internal uint flags; // (CV_Line_Flags) + }; + + internal struct CV_Column { + internal ushort offColumnStart; + internal ushort offColumnEnd; + }; + + // File information + + internal enum CV_FILE_CHECKSUM_TYPE : byte { + None=0, + MD5=1, + }; + + internal struct CV_FileCheckSum { + internal uint name; // Index of name in name table. + internal byte len; // Hash length + internal byte type; // Hash type + } + + [Flags] + internal enum FRAMEDATA_FLAGS : uint { + fHasSEH=0x00000001, + fHasEH=0x00000002, + fIsFunctionStart=0x00000004, + }; + + internal struct FrameData { + internal uint ulRvaStart; + internal uint cbBlock; + internal uint cbLocals; + internal uint cbParams; + internal uint cbStkMax; + internal uint frameFunc; + internal ushort cbProlog; + internal ushort cbSavedRegs; + internal uint flags; // (FRAMEDATA_FLAGS) + }; + + internal struct XFixupData { + internal ushort wType; + internal ushort wExtra; + internal uint rva; + internal uint rvaTarget; + }; + + internal enum DEBUG_S_SUBSECTION { + SYMBOLS=0xF1, + LINES=0xF2, + STRINGTABLE=0xF3, + FILECHKSMS=0xF4, + FRAMEDATA=0xF5, + } +} \ No newline at end of file diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DataStream.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DataStream.cs new file mode 100644 index 00000000..48a18516 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DataStream.cs @@ -0,0 +1,111 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.IO; + +namespace Microsoft.Cci.Pdb { + internal class DataStream { + internal DataStream() { + } + + internal DataStream(int contentSize, BitAccess bits, int count) { + this.contentSize = contentSize; + if (count > 0) { + this.pages = new int[count]; + bits.ReadInt32(this.pages); + } + } + + internal void Read(PdbReader reader, BitAccess bits) { + bits.MinCapacity(contentSize); + Read(reader, 0, bits.Buffer, 0, contentSize); + } + + internal void Read(PdbReader reader, int position, + byte[] bytes, int offset, int data) { + if (position + data > contentSize) { + throw new PdbException("DataStream can't read off end of stream. " + + "(pos={0},siz={1})", + position, data); + } + if (position == contentSize) { + return; + } + + int left = data; + int page = position / reader.pageSize; + int rema = position % reader.pageSize; + + // First get remained of first page. + if (rema != 0) { + int todo = reader.pageSize - rema; + if (todo > left) { + todo = left; + } + + reader.Seek(pages[page], rema); + reader.Read(bytes, offset, todo); + + offset += todo; + left -= todo; + page++; + } + + // Now get the remaining pages. + while (left > 0) { + int todo = reader.pageSize; + if (todo > left) { + todo = left; + } + + reader.Seek(pages[page], 0); + reader.Read(bytes, offset, todo); + + offset += todo; + left -= todo; + page++; + } + } + + //private void AddPages(int page0, int count) { + // if (pages == null) { + // pages = new int[count]; + // for (int i = 0; i < count; i++) { + // pages[i] = page0 + i; + // } + // } else { + // int[] old = pages; + // int used = old.Length; + + // pages = new int[used + count]; + // Array.Copy(old, pages, used); + // for (int i = 0; i < count; i++) { + // pages[used + i] = page0 + i; + // } + // } + //} + + //internal int Pages { + // get { return pages == null ? 0 : pages.Length; } + //} + + internal int Length { + get { return contentSize; } + } + + //internal int GetPage(int index) { + // return pages[index]; + //} + + internal int contentSize; + internal int[] pages; + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs new file mode 100644 index 00000000..588f3c13 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal struct DbiDbgHdr { + internal DbiDbgHdr(BitAccess bits) { + bits.ReadUInt16(out snFPO); + bits.ReadUInt16(out snException); + bits.ReadUInt16(out snFixup); + bits.ReadUInt16(out snOmapToSrc); + bits.ReadUInt16(out snOmapFromSrc); + bits.ReadUInt16(out snSectionHdr); + bits.ReadUInt16(out snTokenRidMap); + bits.ReadUInt16(out snXdata); + bits.ReadUInt16(out snPdata); + bits.ReadUInt16(out snNewFPO); + bits.ReadUInt16(out snSectionHdrOrig); + } + + internal ushort snFPO; // 0..1 + internal ushort snException; // 2..3 (deprecated) + internal ushort snFixup; // 4..5 + internal ushort snOmapToSrc; // 6..7 + internal ushort snOmapFromSrc; // 8..9 + internal ushort snSectionHdr; // 10..11 + internal ushort snTokenRidMap; // 12..13 + internal ushort snXdata; // 14..15 + internal ushort snPdata; // 16..17 + internal ushort snNewFPO; // 18..19 + internal ushort snSectionHdrOrig; // 20..21 + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiHeader.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiHeader.cs new file mode 100644 index 00000000..0ca79158 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiHeader.cs @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal struct DbiHeader { + internal DbiHeader(BitAccess bits) { + bits.ReadInt32(out sig); + bits.ReadInt32(out ver); + bits.ReadInt32(out age); + bits.ReadInt16(out gssymStream); + bits.ReadUInt16(out vers); + bits.ReadInt16(out pssymStream); + bits.ReadUInt16(out pdbver); + bits.ReadInt16(out symrecStream); + bits.ReadUInt16(out pdbver2); + bits.ReadInt32(out gpmodiSize); + bits.ReadInt32(out secconSize); + bits.ReadInt32(out secmapSize); + bits.ReadInt32(out filinfSize); + bits.ReadInt32(out tsmapSize); + bits.ReadInt32(out mfcIndex); + bits.ReadInt32(out dbghdrSize); + bits.ReadInt32(out ecinfoSize); + bits.ReadUInt16(out flags); + bits.ReadUInt16(out machine); + bits.ReadInt32(out reserved); + } + + internal int sig; // 0..3 + internal int ver; // 4..7 + internal int age; // 8..11 + internal short gssymStream; // 12..13 + internal ushort vers; // 14..15 + internal short pssymStream; // 16..17 + internal ushort pdbver; // 18..19 + internal short symrecStream; // 20..21 + internal ushort pdbver2; // 22..23 + internal int gpmodiSize; // 24..27 + internal int secconSize; // 28..31 + internal int secmapSize; // 32..35 + internal int filinfSize; // 36..39 + internal int tsmapSize; // 40..43 + internal int mfcIndex; // 44..47 + internal int dbghdrSize; // 48..51 + internal int ecinfoSize; // 52..55 + internal ushort flags; // 56..57 + internal ushort machine; // 58..59 + internal int reserved; // 60..63 + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs new file mode 100644 index 00000000..8ab37171 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs @@ -0,0 +1,57 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal class DbiModuleInfo { + internal DbiModuleInfo(BitAccess bits, bool readStrings) { + bits.ReadInt32(out opened); + new DbiSecCon(bits); + bits.ReadUInt16(out flags); + bits.ReadInt16(out stream); + bits.ReadInt32(out cbSyms); + bits.ReadInt32(out cbOldLines); + bits.ReadInt32(out cbLines); + bits.ReadInt16(out files); + bits.ReadInt16(out pad1); + bits.ReadUInt32(out offsets); + bits.ReadInt32(out niSource); + bits.ReadInt32(out niCompiler); + if (readStrings) { + bits.ReadCString(out moduleName); + bits.ReadCString(out objectName); + } else { + bits.SkipCString(out moduleName); + bits.SkipCString(out objectName); + } + bits.Align(4); + //if (opened != 0 || pad1 != 0) { + // throw new PdbException("Invalid DBI module. "+ + // "(opened={0}, pad={1})", opened, pad1); + //} + } + + internal int opened; // 0..3 + //internal DbiSecCon section; // 4..31 + internal ushort flags; // 32..33 + internal short stream; // 34..35 + internal int cbSyms; // 36..39 + internal int cbOldLines; // 40..43 + internal int cbLines; // 44..57 + internal short files; // 48..49 + internal short pad1; // 50..51 + internal uint offsets; + internal int niSource; + internal int niCompiler; + internal string moduleName; + internal string objectName; + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiSecCon.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiSecCon.cs new file mode 100644 index 00000000..de9fde95 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/DbiSecCon.cs @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal struct DbiSecCon { + internal DbiSecCon(BitAccess bits) { + bits.ReadInt16(out section); + bits.ReadInt16(out pad1); + bits.ReadInt32(out offset); + bits.ReadInt32(out size); + bits.ReadUInt32(out flags); + bits.ReadInt16(out module); + bits.ReadInt16(out pad2); + bits.ReadUInt32(out dataCrc); + bits.ReadUInt32(out relocCrc); + //if (pad1 != 0 || pad2 != 0) { + // throw new PdbException("Invalid DBI section. "+ + // "(pad1={0}, pad2={1})", + // pad1, pad2); + //} + } + + internal short section; // 0..1 + internal short pad1; // 2..3 + internal int offset; // 4..7 + internal int size; // 8..11 + internal uint flags; // 12..15 + internal short module; // 16..17 + internal short pad2; // 18..19 + internal uint dataCrc; // 20..23 + internal uint relocCrc; // 24..27 + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/IntHashTable.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/IntHashTable.cs new file mode 100644 index 00000000..42489ad5 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/IntHashTable.cs @@ -0,0 +1,583 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.Collections; + +namespace Microsoft.Cci.Pdb { + // The IntHashTable class represents a dictionary of associated keys and + // values with constant lookup time. + // + // Objects used as keys in a hashtable must implement the GetHashCode + // and Equals methods (or they can rely on the default implementations + // inherited from Object if key equality is simply reference + // equality). Furthermore, the GetHashCode and Equals methods of + // a key object must produce the same results given the same parameters + // for the entire time the key is present in the hashtable. In practical + // terms, this means that key objects should be immutable, at least for + // the time they are used as keys in a hashtable. + // + // When entries are added to a hashtable, they are placed into + // buckets based on the hashcode of their keys. Subsequent lookups of + // keys will use the hashcode of the keys to only search a particular + // bucket, thus substantially reducing the number of key comparisons + // required to find an entry. A hashtable's maximum load factor, which + // can be specified when the hashtable is instantiated, determines the + // maximum ratio of hashtable entries to hashtable buckets. Smaller load + // factors cause faster average lookup times at the cost of increased + // memory consumption. The default maximum load factor of 1.0 generally + // provides the best balance between speed and size. As entries are added + // to a hashtable, the hashtable's actual load factor increases, and when + // the actual load factor reaches the maximum load factor value, the + // number of buckets in the hashtable is automatically increased by + // approximately a factor of two (to be precise, the number of hashtable + // buckets is increased to the smallest prime number that is larger than + // twice the current number of hashtable buckets). + // + // Each object provides their own hash function, accessed by calling + // GetHashCode(). However, one can write their own object + // implementing IHashCodeProvider and pass it to a constructor on + // the IntHashTable. That hash function would be used for all objects in + // the table. + // + // This IntHashTable is implemented to support multiple concurrent readers + // and one concurrent writer without using any synchronization primitives. + // All read methods essentially must protect themselves from a resize + // occuring while they are running. This was done by enforcing an + // ordering on inserts & removes, as well as removing some member variables + // and special casing the expand code to work in a temporary array instead + // of the live bucket array. All inserts must set a bucket's value and + // key before setting the hash code & collision field. + // + // By Brian Grunkemeyer, algorithm by Patrick Dussud. + // Version 1.30 2/20/2000 + //| + internal class IntHashTable {//: IEnumerable { + /* + Implementation Notes: + + This IntHashTable uses double hashing. There are hashsize buckets in + the table, and each bucket can contain 0 or 1 element. We a bit to + mark whether there's been a collision when we inserted multiple + elements (ie, an inserted item was hashed at least a second time and + we probed this bucket, but it was already in use). Using the + collision bit, we can terminate lookups & removes for elements that + aren't in the hash table more quickly. We steal the most + significant bit from the hash code to store the collision bit. + + Our hash function is of the following form: + + h(key, n) = h1(key) + n*h2(key) + + where n is the number of times we've hit a collided bucket and + rehashed (on this particular lookup). Here are our hash functions: + + h1(key) = GetHash(key); // default implementation calls key.GetHashCode(); + h2(key) = 1 + (((h1(key) >> 5) + 1) % (hashsize - 1)); + + The h1 can return any number. h2 must return a number between 1 and + hashsize - 1 that is relatively prime to hashsize (not a problem if + hashsize is prime). (Knuth's Art of Computer Programming, Vol. 3, + p. 528-9) + + If this is true, then we are guaranteed to visit every bucket in + exactly hashsize probes, since the least common multiple of hashsize + and h2(key) will be hashsize * h2(key). ( This is the first number + where adding h2 to h1 mod hashsize will be 0 and we will search the + same bucket twice). + + We previously used a different h2(key, n) that was not constant. + That is a horrifically bad idea, unless you can prove that series + will never produce any identical numbers that overlap when you mod + them by hashsize, for all subranges from i to i+hashsize, for all i. + It's not worth investigating, since there was no clear benefit from + using that hash function, and it was broken. + + For efficiency reasons, we've implemented this by storing h1 and h2 + in a temporary, and setting a variable called seed equal to h1. We + do a probe, and if we collided, we simply add h2 to seed each time + through the loop. + + A good test for h2() is to subclass IntHashTable, provide your own + implementation of GetHash() that returns a constant, then add many + items to the hash table. Make sure Count equals the number of items + you inserted. + + -- Brian Grunkemeyer, 10/28/1999 + */ + + // A typical resize algorithm would pick the smallest prime number in this array + // that is larger than twice the previous capacity. + // Suppose our Hashtable currently has capacity x and enough elements are added + // such that a resize needs to occur. Resizing first computes 2x then finds the + // first prime in the table greater than 2x, i.e. if primes are ordered + // p_1, p_2, ? p_i,? it finds p_n such that p_n-1 < 2x < p_n. + // Doubling is important for preserving the asymptotic complexity of the + // hashtable operations such as add. Having a prime guarantees that double + // hashing does not lead to infinite loops. IE, your hash function will be + // h1(key) + i*h2(key), 0 <= i < size. h2 and the size must be relatively prime. + private static readonly int[] primes = { + 3, 7, 11, 17, 23, 29, 37, 47, 59, 71, 89, 107, 131, 163, 197, 239, 293, 353, 431, 521, 631, 761, 919, + 1103, 1327, 1597, 1931, 2333, 2801, 3371, 4049, 4861, 5839, 7013, 8419, 10103, 12143, 14591, + 17519, 21023, 25229, 30293, 36353, 43627, 52361, 62851, 75431, 90523, 108631, 130363, 156437, + 187751, 225307, 270371, 324449, 389357, 467237, 560689, 672827, 807403, 968897, 1162687, 1395263, + 1674319, 2009191, 2411033, 2893249, 3471899, 4166287, 4999559, 5999471, 7199369}; + + private static int GetPrime(int minSize) { + if (minSize < 0) { + throw new ArgumentException("Arg_HTCapacityOverflow"); + } + for (int i = 0; i < primes.Length; i++) { + int size = primes[i]; + if (size >= minSize) { + return size; + } + } + throw new ArgumentException("Arg_HTCapacityOverflow"); + } + + // Deleted entries have their key set to buckets + + // The hash table data. + // This cannot be serialised + private struct bucket { + internal int key; + internal int hash_coll; // Store hash code; sign bit means there was a collision. + internal Object val; + } + + private bucket[] buckets; + + // The total number of entries in the hash table. + private int count; + + // The total number of collision bits set in the hashtable + private int occupancy; + + private int loadsize; + private int loadFactorPerc; // 100 = 1.0 + + private int version; + + // Constructs a new hashtable. The hashtable is created with an initial + // capacity of zero and a load factor of 1.0. + //| + internal IntHashTable() + : this(0, 100) { + } + + //// Constructs a new hashtable with the given initial capacity and a load + //// factor of 1.0. The capacity argument serves as an indication of + //// the number of entries the hashtable will contain. When this number (or + //// an approximation) is known, specifying it in the constructor can + //// eliminate a number of resizing operations that would otherwise be + //// performed when elements are added to the hashtable. + //// + ////| + //internal IntHashTable(int capacity) + // : this(capacity, 100) { + //} + + // Constructs a new hashtable with the given initial capacity and load + // factor. The capacity argument serves as an indication of the + // number of entries the hashtable will contain. When this number (or an + // approximation) is known, specifying it in the constructor can eliminate + // a number of resizing operations that would otherwise be performed when + // elements are added to the hashtable. The loadFactorPerc argument + // indicates the maximum ratio of hashtable entries to hashtable buckets. + // Smaller load factors cause faster average lookup times at the cost of + // increased memory consumption. A load factor of 1.0 generally provides + // the best balance between speed and size. + // + //| + internal IntHashTable(int capacity, int loadFactorPerc) { + if (capacity < 0) + throw new ArgumentOutOfRangeException("capacity", "ArgumentOutOfRange_NeedNonNegNum"); + if (!(loadFactorPerc >= 10 && loadFactorPerc <= 100)) + throw new ArgumentOutOfRangeException("loadFactorPerc", String.Format("ArgumentOutOfRange_IntHashTableLoadFactor", 10, 100)); + + // Based on perf work, .72 is the optimal load factor for this table. + this.loadFactorPerc = (loadFactorPerc * 72) / 100; + + int hashsize = GetPrime((int)(capacity / this.loadFactorPerc)); + buckets = new bucket[hashsize]; + + loadsize = (int)(this.loadFactorPerc * hashsize) / 100; + if (loadsize >= hashsize) + loadsize = hashsize-1; + } + + // Computes the hash function: H(key, i) = h1(key) + i*h2(key, hashSize). + // The out parameter seed is h1(key), while the out parameter + // incr is h2(key, hashSize). Callers of this function should + // add incr each time through a loop. + private static uint InitHash(int key, int hashsize, out uint seed, out uint incr) { + // Hashcode must be positive. Also, we must not use the sign bit, since + // that is used for the collision bit. + uint hashcode = (uint)key & 0x7FFFFFFF; + seed = (uint)hashcode; + // Restriction: incr MUST be between 1 and hashsize - 1, inclusive for + // the modular arithmetic to work correctly. This guarantees you'll + // visit every bucket in the table exactly once within hashsize + // iterations. Violate this and it'll cause obscure bugs forever. + // If you change this calculation for h2(key), update putEntry too! + incr = (uint)(1 + (((seed >> 5) + 1) % ((uint)hashsize - 1))); + return hashcode; + } + + // Adds an entry with the given key and value to this hashtable. An + // ArgumentException is thrown if the key is null or if the key is already + // present in the hashtable. + // + //| + internal void Add(int key, Object value) { + Insert(key, value, true); + } + + //// Removes all entries from this hashtable. + ////| + //internal void Clear() { + // if (count == 0) + // return; + + // for (int i = 0; i < buckets.Length; i++) { + // buckets[i].hash_coll = 0; + // buckets[i].key = -1; + // buckets[i].val = null; + // } + + // count = 0; + // occupancy = 0; + //} + + // Checks if this hashtable contains an entry with the given key. This is + // an O(1) operation. + // + //| + //internal bool Contains(int key) { + // if (key < 0) { + // throw new ArgumentException("Argument_KeyLessThanZero"); + // } + + // uint seed; + // uint incr; + // // Take a snapshot of buckets, in case another thread resizes table + // bucket[] lbuckets = buckets; + // uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr); + // int ntry = 0; + + // bucket b; + // do { + // int bucketNumber = (int)(seed % (uint)lbuckets.Length); + // b = lbuckets[bucketNumber]; + // if (b.val == null) { + // return false; + // } + // if (((b.hash_coll & 0x7FFFFFFF) == hashcode) && b.key == key) { + // return true; + // } + // seed += incr; + // } while (b.hash_coll < 0 && ++ntry < lbuckets.Length); + // return false; + //} + + // Returns the value associated with the given key. If an entry with the + // given key is not found, the returned value is null. + // + //| + internal Object this[int key] { + get { + if (key < 0) { + throw new ArgumentException("Argument_KeyLessThanZero"); + } + uint seed; + uint incr; + // Take a snapshot of buckets, in case another thread does a resize + bucket[] lbuckets = buckets; + uint hashcode = InitHash(key, lbuckets.Length, out seed, out incr); + int ntry = 0; + + bucket b; + do { + int bucketNumber = (int)(seed % (uint)lbuckets.Length); + b = lbuckets[bucketNumber]; + if (b.val == null) { + return null; + } + if (((b.hash_coll & 0x7FFFFFFF) == hashcode) && key == b.key) { + return b.val; + } + seed += incr; + } while (b.hash_coll < 0 && ++ntry < lbuckets.Length); + return null; + } + //set { + // Insert(key, value, false); + //} + } + + // Increases the bucket count of this hashtable. This method is called from + // the Insert method when the actual load factor of the hashtable reaches + // the upper limit specified when the hashtable was constructed. The number + // of buckets in the hashtable is increased to the smallest prime number + // that is larger than twice the current number of buckets, and the entries + // in the hashtable are redistributed into the new buckets using the cached + // hashcodes. + private void expand() { + rehash(GetPrime(1+buckets.Length*2)); + } + + // We occationally need to rehash the table to clean up the collision bits. + private void rehash() { + rehash(buckets.Length); + } + + private void rehash(int newsize) { + + // reset occupancy + occupancy=0; + + // Don't replace any internal state until we've finished adding to the + // new bucket[]. This serves two purposes: + // 1) Allow concurrent readers to see valid hashtable contents + // at all times + // 2) Protect against an OutOfMemoryException while allocating this + // new bucket[]. + bucket[] newBuckets = new bucket[newsize]; + + // rehash table into new buckets + int nb; + for (nb = 0; nb < buckets.Length; nb++) { + bucket oldb = buckets[nb]; + if (oldb.val != null) { + putEntry(newBuckets, oldb.key, oldb.val, oldb.hash_coll & 0x7FFFFFFF); + } + } + + // New bucket[] is good to go - replace buckets and other internal state. + version++; + buckets = newBuckets; + loadsize = (int)(loadFactorPerc * newsize) / 100; + + if (loadsize >= newsize) { + loadsize = newsize-1; + } + + return; + } + + // Returns an enumerator for this hashtable. + // If modifications made to the hashtable while an enumeration is + // in progress, the MoveNext and Current methods of the + // enumerator will throw an exception. + // + //| + //IEnumerator IEnumerable.GetEnumerator() { + // return new IntHashTableEnumerator(this); + //} + + // Internal method to compare two keys. + // + // Inserts an entry into this hashtable. This method is called from the Set + // and Add methods. If the add parameter is true and the given key already + // exists in the hashtable, an exception is thrown. + private void Insert(int key, Object nvalue, bool add) { + if (key < 0) { + throw new ArgumentException("Argument_KeyLessThanZero"); + } + if (nvalue == null) { + throw new ArgumentNullException("nvalue", "ArgumentNull_Value"); + } + if (count >= loadsize) { + expand(); + } else if (occupancy > loadsize && count > 100) { + rehash(); + } + + uint seed; + uint incr; + // Assume we only have one thread writing concurrently. Modify + // buckets to contain new data, as long as we insert in the right order. + uint hashcode = InitHash(key, buckets.Length, out seed, out incr); + int ntry = 0; + int emptySlotNumber = -1; // We use the empty slot number to cache the first empty slot. We chose to reuse slots + // create by remove that have the collision bit set over using up new slots. + + do { + int bucketNumber = (int)(seed % (uint)buckets.Length); + + // Set emptySlot number to current bucket if it is the first available bucket that we have seen + // that once contained an entry and also has had a collision. + // We need to search this entire collision chain because we have to ensure that there are no + // duplicate entries in the table. + + // Insert the key/value pair into this bucket if this bucket is empty and has never contained an entry + // OR + // This bucket once contained an entry but there has never been a collision + if (buckets[bucketNumber].val == null) { + // If we have found an available bucket that has never had a collision, but we've seen an available + // bucket in the past that has the collision bit set, use the previous bucket instead + if (emptySlotNumber != -1) { // Reuse slot + bucketNumber = emptySlotNumber; + } + + // We pretty much have to insert in this order. Don't set hash + // code until the value & key are set appropriately. + buckets[bucketNumber].val = nvalue; + buckets[bucketNumber].key = key; + buckets[bucketNumber].hash_coll |= (int)hashcode; + count++; + version++; + return; + } + + // The current bucket is in use + // OR + // it is available, but has had the collision bit set and we have already found an available bucket + if (((buckets[bucketNumber].hash_coll & 0x7FFFFFFF) == hashcode) && + key == buckets[bucketNumber].key) { + if (add) { + throw new ArgumentException("Argument_AddingDuplicate__" + buckets[bucketNumber].key); + } + buckets[bucketNumber].val = nvalue; + version++; + return; + } + + // The current bucket is full, and we have therefore collided. We need to set the collision bit + // UNLESS + // we have remembered an available slot previously. + if (emptySlotNumber == -1) {// We don't need to set the collision bit here since we already have an empty slot + if (buckets[bucketNumber].hash_coll >= 0) { + buckets[bucketNumber].hash_coll |= unchecked((int)0x80000000); + occupancy++; + } + } + seed += incr; + } while (++ntry < buckets.Length); + + // This code is here if and only if there were no buckets without a collision bit set in the entire table + if (emptySlotNumber != -1) { + // We pretty much have to insert in this order. Don't set hash + // code until the value & key are set appropriately. + buckets[emptySlotNumber].val = nvalue; + buckets[emptySlotNumber].key = key; + buckets[emptySlotNumber].hash_coll |= (int)hashcode; + count++; + version++; + return; + + } + + // If you see this assert, make sure load factor & count are reasonable. + // Then verify that our double hash function (h2, described at top of file) + // meets the requirements described above. You should never see this assert. + throw new InvalidOperationException("InvalidOperation_HashInsertFailed"); + } + + private void putEntry(bucket[] newBuckets, int key, Object nvalue, int hashcode) { + uint seed = (uint)hashcode; + uint incr = (uint)(1 + (((seed >> 5) + 1) % ((uint)newBuckets.Length - 1))); + + do { + int bucketNumber = (int)(seed % (uint)newBuckets.Length); + + if ((newBuckets[bucketNumber].val == null)) { + newBuckets[bucketNumber].val = nvalue; + newBuckets[bucketNumber].key = key; + newBuckets[bucketNumber].hash_coll |= hashcode; + return; + } + + if (newBuckets[bucketNumber].hash_coll >= 0) { + newBuckets[bucketNumber].hash_coll |= unchecked((int)0x80000000); + occupancy++; + } + seed += incr; + } while (true); + } + + // Returns the number of associations in this hashtable. + // + //| + //internal int Count { + // get { return count; } + //} + + // Implements an enumerator for a hashtable. The enumerator uses the + // internal version number of the hashtabke to ensure that no modifications + // are made to the hashtable while an enumeration is in progress. + //private class IntHashTableEnumerator : IEnumerator { + // private IntHashTable hashtable; + // private int bucket; + // private int version; + // private bool current; + // //private int currentKey; + // private Object currentValue; + + // internal IntHashTableEnumerator(IntHashTable hashtable) { + // this.hashtable = hashtable; + // bucket = hashtable.buckets.Length; + // version = hashtable.version; + // } + + // public bool MoveNext() { + // if (version != hashtable.version) + // throw new InvalidOperationException("InvalidOperation_EnumFailedVersion"); + // while (bucket > 0) { + // bucket--; + // Object val = hashtable.buckets[bucket].val; + // if (val != null) { + // //currentKey = hashtable.buckets[bucket].key; + // currentValue = val; + // current = true; + // return true; + // } + // } + // current = false; + // return false; + // } + + // //internal int Key { + // // get { + // // if (current == false) + // // throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen"); + // // return currentKey; + // // } + // //} + + // public Object Current { + // get { + // if (current == false) + // throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen"); + // return currentValue; + // } + // } + + // //public Object Value { + // // get { + // // if (version != hashtable.version) + // // throw new InvalidOperationException("InvalidOperation_EnumFailedVersion"); + // // if (current == false) + // // throw new InvalidOperationException("InvalidOperation_EnumOpCantHappen"); + // // return currentValue; + // // } + // //} + + // public void Reset() { + // if (version != hashtable.version) throw new InvalidOperationException("InvalidOperation_EnumFailedVersion"); + // current = false; + // bucket = hashtable.buckets.Length; + // //currentKey = -1; + // currentValue = null; + // } + //} + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/Interfaces.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/Interfaces.cs new file mode 100644 index 00000000..82561fbc --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/Interfaces.cs @@ -0,0 +1,77 @@ +using System; +using System.Collections.Generic; + +namespace Microsoft.Cci { + + /// + /// A range of CLR IL operations that comprise a lexical scope, specified as an IL offset and a length. + /// + public interface ILocalScope { + /// + /// The offset of the first operation in the scope. + /// + uint Offset { get; } + + /// + /// The length of the scope. Offset+Length equals the offset of the first operation outside the scope, or equals the method body length. + /// + uint Length { get; } + } + + /// + /// A description of the lexical scope in which a namespace type has been nested. This scope is tied to a particular + /// method body, so that partial types can be accommodated. + /// + public interface INamespaceScope { + + /// + /// Zero or more used namespaces. These correspond to using clauses in C#. + /// + IEnumerable UsedNamespaces { get; } + + } + + + /// + /// A namespace that is used (imported) inside a namespace scope. + /// + public interface IUsedNamespace { + /// + /// An alias for a namespace. For example the "x" of "using x = y.z;" in C#. Empty if no alias is present. + /// + IName Alias { get; } + + /// + /// The name of a namepace that has been aliased. For example the "y.z" of "using x = y.z;" or "using y.z" in C#. + /// + IName NamespaceName { get; } + } + + /// + /// The name of an entity. Typically name instances come from a common pool. Within the pool no two distinct instances will have the same Value or UniqueKey. + /// + public interface IName { + /// + /// An integer that is unique within the pool from which the name instance has been allocated. Useful as a hashtable key. + /// + int UniqueKey { + get; + //^ ensures result > 0; + } + + /// + /// An integer that is unique within the pool from which the name instance has been allocated. Useful as a hashtable key. + /// All name instances in the pool that have the same string value when ignoring the case of the characters in the string + /// will have the same key value. + /// + int UniqueKeyIgnoringCase { + get; + //^ ensures result > 0; + } + + /// + /// The string value corresponding to this name. + /// + string Value { get; } + } +} \ No newline at end of file diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/MsfDirectory.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/MsfDirectory.cs new file mode 100644 index 00000000..a6669b5b --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/MsfDirectory.cs @@ -0,0 +1,58 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal class MsfDirectory { + internal MsfDirectory(PdbReader reader, PdbFileHeader head, BitAccess bits) { + int pages = reader.PagesFromSize(head.directorySize); + + // 0..n in page of directory pages. + bits.MinCapacity(head.directorySize); + int directoryRootPages = head.directoryRoot.Length; + int pagesPerPage = head.pageSize / 4; + int pagesToGo = pages; + for (int i = 0; i < directoryRootPages; i++) { + int pagesInThisPage = pagesToGo <= pagesPerPage ? pagesToGo : pagesPerPage; + reader.Seek(head.directoryRoot[i], 0); + bits.Append(reader.reader, pagesInThisPage * 4); + pagesToGo -= pagesInThisPage; + } + bits.Position = 0; + + DataStream stream = new DataStream(head.directorySize, bits, pages); + bits.MinCapacity(head.directorySize); + stream.Read(reader, bits); + + // 0..3 in directory pages + int count; + bits.ReadInt32(out count); + + // 4..n + int[] sizes = new int[count]; + bits.ReadInt32(sizes); + + // n..m + streams = new DataStream[count]; + for (int i = 0; i < count; i++) { + if (sizes[i] <= 0) { + streams[i] = new DataStream(); + } else { + streams[i] = new DataStream(sizes[i], bits, + reader.PagesFromSize(sizes[i])); + } + } + } + + internal DataStream[] streams; + } + +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbConstant.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbConstant.cs new file mode 100644 index 00000000..434841b0 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbConstant.cs @@ -0,0 +1,89 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.Runtime.InteropServices; + +namespace Microsoft.Cci.Pdb { + internal class PdbConstant { + internal string name; + internal uint token; + internal object value; + + internal PdbConstant(BitAccess bits) { + bits.ReadUInt32(out this.token); + byte tag1; + bits.ReadUInt8(out tag1); + byte tag2; + bits.ReadUInt8(out tag2); + if (tag2 == 0) { + this.value = tag1; + } else if (tag2 == 0x80) { + switch (tag1) { + case 0x00: //sbyte + sbyte sb; + bits.ReadInt8(out sb); + this.value = sb; + break; + case 0x01: //short + short s; + bits.ReadInt16(out s); + this.value = s; + break; + case 0x02: //ushort + ushort us; + bits.ReadUInt16(out us); + this.value = us; + break; + case 0x03: //int + int i; + bits.ReadInt32(out i); + this.value = i; + break; + case 0x04: //uint + uint ui; + bits.ReadUInt32(out ui); + this.value = ui; + break; + case 0x05: //float + this.value = bits.ReadFloat(); + break; + case 0x06: //double + this.value = bits.ReadDouble(); + break; + case 0x09: //long + long sl; + bits.ReadInt64(out sl); + this.value = sl; + break; + case 0x0a: //ulong + ulong ul; + bits.ReadUInt64(out ul); + this.value = ul; + break; + case 0x10: //string + string str; + bits.ReadBString(out str); + this.value = str; + break; + case 0x19: //decimal + this.value = bits.ReadDecimal(); + break; + default: + //TODO: error + break; + } + } else { + //TODO: error + } + bits.ReadCString(out name); + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbDebugException.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbDebugException.cs new file mode 100644 index 00000000..d7f8f0fd --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbDebugException.cs @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.IO; + +namespace Microsoft.Cci.Pdb { + internal class PdbDebugException : IOException { + internal PdbDebugException(String format, params object[] args) + : base(String.Format(format, args)) { + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbException.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbException.cs new file mode 100644 index 00000000..38d1d563 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbException.cs @@ -0,0 +1,20 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.IO; + +namespace Microsoft.Cci.Pdb { + internal class PdbException : IOException { + internal PdbException(String format, params object[] args) + : base(String.Format(format, args)) { + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFile.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFile.cs new file mode 100644 index 00000000..9e560281 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFile.cs @@ -0,0 +1,439 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Diagnostics.SymbolStore; + +namespace Microsoft.Cci.Pdb { + internal class PdbFile { + private PdbFile() // This class can't be instantiated. + { + } + + static void LoadGuidStream(BitAccess bits, out Guid doctype, out Guid language, out Guid vendor) { + bits.ReadGuid(out language); + bits.ReadGuid(out vendor); + bits.ReadGuid(out doctype); + } + + static Dictionary LoadNameIndex(BitAccess bits, out int age, out Guid guid) { + Dictionary result = new Dictionary(); + int ver; + int sig; + bits.ReadInt32(out ver); // 0..3 Version + bits.ReadInt32(out sig); // 4..7 Signature + bits.ReadInt32(out age); // 8..11 Age + bits.ReadGuid(out guid); // 12..27 GUID + + //if (ver != 20000404) { + // throw new PdbDebugException("Unsupported PDB Stream version {0}", ver); + //} + + // Read string buffer. + int buf; + bits.ReadInt32(out buf); // 28..31 Bytes of Strings + + int beg = bits.Position; + int nxt = bits.Position + buf; + + bits.Position = nxt; + + // Read map index. + int cnt; // n+0..3 hash size. + int max; // n+4..7 maximum ni. + + bits.ReadInt32(out cnt); + bits.ReadInt32(out max); + + BitSet present = new BitSet(bits); + BitSet deleted = new BitSet(bits); + if (!deleted.IsEmpty) { + throw new PdbDebugException("Unsupported PDB deleted bitset is not empty."); + } + + int j = 0; + for (int i = 0; i < max; i++) { + if (present.IsSet(i)) { + int ns; + int ni; + bits.ReadInt32(out ns); + bits.ReadInt32(out ni); + + string name; + int saved = bits.Position; + bits.Position = beg + ns; + bits.ReadCString(out name); + bits.Position = saved; + + result.Add(name.ToUpperInvariant(), ni); + j++; + } + } + if (j != cnt) { + throw new PdbDebugException("Count mismatch. ({0} != {1})", j, cnt); + } + return result; + } + + static IntHashTable LoadNameStream(BitAccess bits) { + IntHashTable ht = new IntHashTable(); + + uint sig; + int ver; + bits.ReadUInt32(out sig); // 0..3 Signature + bits.ReadInt32(out ver); // 4..7 Version + + // Read (or skip) string buffer. + int buf; + bits.ReadInt32(out buf); // 8..11 Bytes of Strings + + if (sig != 0xeffeeffe || ver != 1) { + throw new PdbDebugException("Unsupported Name Stream version. "+ + "(sig={0:x8}, ver={1})", + sig, ver); + } + int beg = bits.Position; + int nxt = bits.Position + buf; + bits.Position = nxt; + + // Read hash table. + int siz; + bits.ReadInt32(out siz); // n+0..3 Number of hash buckets. + nxt = bits.Position; + + for (int i = 0; i < siz; i++) { + int ni; + string name; + + bits.ReadInt32(out ni); + + if (ni != 0) { + int saved = bits.Position; + bits.Position = beg + ni; + bits.ReadCString(out name); + bits.Position = saved; + + ht.Add(ni, name); + } + } + bits.Position = nxt; + + return ht; + } + + private static PdbFunction match = new PdbFunction(); + + private static int FindFunction(PdbFunction[] funcs, ushort sec, uint off) { + match.segment = sec; + match.address = off; + + return Array.BinarySearch(funcs, match, PdbFunction.byAddress); + } + + static void LoadManagedLines(PdbFunction[] funcs, + IntHashTable names, + BitAccess bits, + MsfDirectory dir, + Dictionary nameIndex, + PdbReader reader, + uint limit) { + Array.Sort(funcs, PdbFunction.byAddressAndToken); + IntHashTable checks = new IntHashTable(); + + // Read the files first + int begin = bits.Position; + while (bits.Position < limit) { + int sig; + int siz; + bits.ReadInt32(out sig); + bits.ReadInt32(out siz); + int place = bits.Position; + int endSym = bits.Position + siz; + + switch ((DEBUG_S_SUBSECTION)sig) { + case DEBUG_S_SUBSECTION.FILECHKSMS: + while (bits.Position < endSym) { + CV_FileCheckSum chk; + + int ni = bits.Position - place; + bits.ReadUInt32(out chk.name); + bits.ReadUInt8(out chk.len); + bits.ReadUInt8(out chk.type); + + string name = (string)names[(int)chk.name]; + int guidStream; + Guid doctypeGuid = SymDocumentType.Text; + Guid languageGuid = Guid.Empty; + Guid vendorGuid = Guid.Empty; + if (nameIndex.TryGetValue("/SRC/FILES/"+name.ToUpperInvariant(), out guidStream)) { + var guidBits = new BitAccess(0x100); + dir.streams[guidStream].Read(reader, guidBits); + LoadGuidStream(guidBits, out doctypeGuid, out languageGuid, out vendorGuid); + } + + PdbSource src = new PdbSource(/*(uint)ni,*/ name, doctypeGuid, languageGuid, vendorGuid); + checks.Add(ni, src); + bits.Position += chk.len; + bits.Align(4); + } + bits.Position = endSym; + break; + + default: + bits.Position = endSym; + break; + } + } + + // Read the lines next. + bits.Position = begin; + while (bits.Position < limit) { + int sig; + int siz; + bits.ReadInt32(out sig); + bits.ReadInt32(out siz); + int endSym = bits.Position + siz; + + switch ((DEBUG_S_SUBSECTION)sig) { + case DEBUG_S_SUBSECTION.LINES: { + CV_LineSection sec; + + bits.ReadUInt32(out sec.off); + bits.ReadUInt16(out sec.sec); + bits.ReadUInt16(out sec.flags); + bits.ReadUInt32(out sec.cod); + int funcIndex = FindFunction(funcs, sec.sec, sec.off); + if (funcIndex < 0) break; + var func = funcs[funcIndex]; + if (func.lines == null) { + while (funcIndex > 0) { + var f = funcs[funcIndex-1]; + if (f.lines != null || f.segment != sec.sec || f.address != sec.off) break; + func = f; + funcIndex--; + } + } else { + while (funcIndex < funcs.Length-1 && func.lines != null) { + var f = funcs[funcIndex+1]; + if (f.segment != sec.sec || f.address != sec.off) break; + func = f; + funcIndex++; + } + } + if (func.lines != null) break; + + // Count the line blocks. + int begSym = bits.Position; + int blocks = 0; + while (bits.Position < endSym) { + CV_SourceFile file; + bits.ReadUInt32(out file.index); + bits.ReadUInt32(out file.count); + bits.ReadUInt32(out file.linsiz); // Size of payload. + int linsiz = (int)file.count * (8 + ((sec.flags & 1) != 0 ? 4 : 0)); + bits.Position += linsiz; + blocks++; + } + + func.lines = new PdbLines[blocks]; + int block = 0; + + bits.Position = begSym; + while (bits.Position < endSym) { + CV_SourceFile file; + bits.ReadUInt32(out file.index); + bits.ReadUInt32(out file.count); + bits.ReadUInt32(out file.linsiz); // Size of payload. + + PdbSource src = (PdbSource)checks[(int)file.index]; + PdbLines tmp = new PdbLines(src, file.count); + func.lines[block++] = tmp; + PdbLine[] lines = tmp.lines; + + int plin = bits.Position; + int pcol = bits.Position + 8 * (int)file.count; + + for (int i = 0; i < file.count; i++) { + CV_Line line; + CV_Column column = new CV_Column(); + + bits.Position = plin + 8 * i; + bits.ReadUInt32(out line.offset); + bits.ReadUInt32(out line.flags); + + uint lineBegin = line.flags & (uint)CV_Line_Flags.linenumStart; + uint delta = (line.flags & (uint)CV_Line_Flags.deltaLineEnd) >> 24; + //bool statement = ((line.flags & (uint)CV_Line_Flags.fStatement) == 0); + if ((sec.flags & 1) != 0) { + bits.Position = pcol + 4 * i; + bits.ReadUInt16(out column.offColumnStart); + bits.ReadUInt16(out column.offColumnEnd); + } + + lines[i] = new PdbLine(line.offset, + lineBegin, + column.offColumnStart, + lineBegin+delta, + column.offColumnEnd); + } + } + break; + } + } + bits.Position = endSym; + } + } + + static void LoadFuncsFromDbiModule(BitAccess bits, + DbiModuleInfo info, + IntHashTable names, + ArrayList funcList, + bool readStrings, + MsfDirectory dir, + Dictionary nameIndex, + PdbReader reader) { + PdbFunction[] funcs = null; + + bits.Position = 0; + int sig; + bits.ReadInt32(out sig); + if (sig != 4) { + throw new PdbDebugException("Invalid signature. (sig={0})", sig); + } + + bits.Position = 4; + // Console.WriteLine("{0}:", info.moduleName); + funcs = PdbFunction.LoadManagedFunctions(/*info.moduleName,*/ + bits, (uint)info.cbSyms, + readStrings); + if (funcs != null) { + bits.Position = info.cbSyms + info.cbOldLines; + LoadManagedLines(funcs, names, bits, dir, nameIndex, reader, + (uint)(info.cbSyms + info.cbOldLines + info.cbLines)); + + for (int i = 0; i < funcs.Length; i++) { + funcList.Add(funcs[i]); + } + } + } + + static void LoadDbiStream(BitAccess bits, + out DbiModuleInfo[] modules, + out DbiDbgHdr header, + bool readStrings) { + DbiHeader dh = new DbiHeader(bits); + header = new DbiDbgHdr(); + + //if (dh.sig != -1 || dh.ver != 19990903) { + // throw new PdbException("Unsupported DBI Stream version, sig={0}, ver={1}", + // dh.sig, dh.ver); + //} + + // Read gpmod section. + ArrayList modList = new ArrayList(); + int end = bits.Position + dh.gpmodiSize; + while (bits.Position < end) { + DbiModuleInfo mod = new DbiModuleInfo(bits, readStrings); + modList.Add(mod); + } + if (bits.Position != end) { + throw new PdbDebugException("Error reading DBI stream, pos={0} != {1}", + bits.Position, end); + } + + if (modList.Count > 0) { + modules = (DbiModuleInfo[])modList.ToArray(typeof(DbiModuleInfo)); + } else { + modules = null; + } + + // Skip the Section Contribution substream. + bits.Position += dh.secconSize; + + // Skip the Section Map substream. + bits.Position += dh.secmapSize; + + // Skip the File Info substream. + bits.Position += dh.filinfSize; + + // Skip the TSM substream. + bits.Position += dh.tsmapSize; + + // Skip the EC substream. + bits.Position += dh.ecinfoSize; + + // Read the optional header. + end = bits.Position + dh.dbghdrSize; + if (dh.dbghdrSize > 0) { + header = new DbiDbgHdr(bits); + } + bits.Position = end; + } + + internal static PdbFunction[] LoadFunctions(Stream read, bool readAllStrings, out int age, out Guid guid) { + BitAccess bits = new BitAccess(512 * 1024); + return LoadFunctions(read, bits, readAllStrings, out age, out guid); + } + + internal static PdbFunction[] LoadFunctions(Stream read, BitAccess bits, bool readAllStrings, out int age, out Guid guid) { + PdbFileHeader head = new PdbFileHeader(read, bits); + PdbReader reader = new PdbReader(read, head.pageSize); + MsfDirectory dir = new MsfDirectory(reader, head, bits); + DbiModuleInfo[] modules = null; + DbiDbgHdr header; + + dir.streams[1].Read(reader, bits); + Dictionary nameIndex = LoadNameIndex(bits, out age, out guid); + int nameStream; + if (!nameIndex.TryGetValue("/NAMES", out nameStream)) { + throw new PdbException("No `name' stream"); + } + + dir.streams[nameStream].Read(reader, bits); + IntHashTable names = LoadNameStream(bits); + + dir.streams[3].Read(reader, bits); + LoadDbiStream(bits, out modules, out header, readAllStrings); + + ArrayList funcList = new ArrayList(); + + if (modules != null) { + for (int m = 0; m < modules.Length; m++) { + if (modules[m].stream > 0) { + dir.streams[modules[m].stream].Read(reader, bits); + LoadFuncsFromDbiModule(bits, modules[m], names, funcList, + readAllStrings, dir, nameIndex, reader); + } + } + } + + PdbFunction[] funcs = (PdbFunction[])funcList.ToArray(typeof(PdbFunction)); + + // After reading the functions, apply the token remapping table if it exists. + if (header.snTokenRidMap != 0 && header.snTokenRidMap != 0xffff) { + dir.streams[header.snTokenRidMap].Read(reader, bits); + uint[] ridMap = new uint[dir.streams[header.snTokenRidMap].Length / 4]; + bits.ReadUInt32(ridMap); + + foreach (PdbFunction func in funcs) { + func.token = 0x06000000 | ridMap[func.token & 0xffffff]; + } + } + + // + Array.Sort(funcs, PdbFunction.byAddressAndToken); + //Array.Sort(funcs, PdbFunction.byToken); + return funcs; + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs new file mode 100644 index 00000000..e1f56dbe --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs @@ -0,0 +1,90 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.IO; +using System.Text; + +namespace Microsoft.Cci.Pdb { + internal class PdbFileHeader { + //internal PdbFileHeader(int pageSize) { + // this.magic = new byte[32] { + // 0x4D, 0x69, 0x63, 0x72, 0x6F, 0x73, 0x6F, 0x66, // "Microsof" + // 0x74, 0x20, 0x43, 0x2F, 0x43, 0x2B, 0x2B, 0x20, // "t C/C++ " + // 0x4D, 0x53, 0x46, 0x20, 0x37, 0x2E, 0x30, 0x30, // "MSF 7.00" + // 0x0D, 0x0A, 0x1A, 0x44, 0x53, 0x00, 0x00, 0x00 // "^^^DS^^^" + // }; + // this.pageSize = pageSize; + //} + + internal PdbFileHeader(Stream reader, BitAccess bits) { + bits.MinCapacity(56); + reader.Seek(0, SeekOrigin.Begin); + bits.FillBuffer(reader, 52); + + this.magic = new byte[32]; + bits.ReadBytes(this.magic); // 0..31 + bits.ReadInt32(out this.pageSize); // 32..35 + bits.ReadInt32(out this.freePageMap); // 36..39 + bits.ReadInt32(out this.pagesUsed); // 40..43 + bits.ReadInt32(out this.directorySize); // 44..47 + bits.ReadInt32(out this.zero); // 48..51 + + int directoryPages = ((((directorySize + pageSize - 1) / pageSize) * 4) + pageSize - 1) / pageSize; + this.directoryRoot = new int[directoryPages]; + bits.FillBuffer(reader, directoryPages * 4); + bits.ReadInt32(this.directoryRoot); + } + + //internal string Magic { + // get { return StringFromBytesUTF8(magic); } + //} + + //internal void Write(Stream writer, BitAccess bits) { + // bits.MinCapacity(pageSize); + // bits.WriteBytes(magic); // 0..31 + // bits.WriteInt32(pageSize); // 32..35 + // bits.WriteInt32(freePageMap); // 36..39 + // bits.WriteInt32(pagesUsed); // 40..43 + // bits.WriteInt32(directorySize); // 44..47 + // bits.WriteInt32(zero); // 48..51 + // bits.WriteInt32(directoryRoot); // 52..55 + + // writer.Seek(0, SeekOrigin.Begin); + // bits.WriteBuffer(writer, pageSize); + //} + + //////////////////////////////////////////////////// Helper Functions. + // + //internal static string StringFromBytesUTF8(byte[] bytes) { + // return StringFromBytesUTF8(bytes, 0, bytes.Length); + //} + + //internal static string StringFromBytesUTF8(byte[] bytes, int offset, int length) { + // for (int i = 0; i < length; i++) { + // if (bytes[offset + i] < ' ') { + // length = i; + // } + // } + // return Encoding.UTF8.GetString(bytes, offset, length); + //} + + ////////////////////////////////////////////////////////////// Fields. + // + internal readonly byte[] magic; + internal readonly int pageSize; + internal int freePageMap; + internal int pagesUsed; + internal int directorySize; + internal readonly int zero; + internal int[] directoryRoot; + } + +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFunction.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFunction.cs new file mode 100644 index 00000000..4f2e806e --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbFunction.cs @@ -0,0 +1,519 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.Collections; +using System.Collections.Generic; + +namespace Microsoft.Cci.Pdb +{ + internal class PdbFunction + { + static internal readonly Guid msilMetaData = new Guid(0xc6ea3fc9, 0x59b3, 0x49d6, 0xbc, 0x25, + 0x09, 0x02, 0xbb, 0xab, 0xb4, 0x60); + static internal readonly IComparer byAddress = new PdbFunctionsByAddress(); + static internal readonly IComparer byAddressAndToken = new PdbFunctionsByAddressAndToken(); + //static internal readonly IComparer byToken = new PdbFunctionsByToken(); + + internal uint token; + internal uint slotToken; + //internal string name; + //internal string module; + //internal ushort flags; + + internal uint segment; + internal uint address; + //internal uint length; + + //internal byte[] metadata; + internal PdbScope[] scopes; + internal PdbSlot[] slots; + internal PdbConstant[] constants; + internal string[] usedNamespaces; + internal PdbLines[] lines; + internal ushort[]/*?*/ usingCounts; + internal IEnumerable/*?*/ namespaceScopes; + internal string/*?*/ iteratorClass; + internal List/*?*/ iteratorScopes; + + private static string StripNamespace(string module) + { + int li = module.LastIndexOf('.'); + if (li > 0) + { + return module.Substring(li + 1); + } + return module; + } + + + internal static PdbFunction[] LoadManagedFunctions(/*string module,*/ + BitAccess bits, uint limit, + bool readStrings) + { + //string mod = StripNamespace(module); + int begin = bits.Position; + int count = 0; + + while (bits.Position < limit) + { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.Position = star; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) + { + case SYM.S_GMANPROC: + case SYM.S_LMANPROC: + ManProcSym proc; + bits.ReadUInt32(out proc.parent); + bits.ReadUInt32(out proc.end); + bits.Position = (int)proc.end; + count++; + break; + + case SYM.S_END: + bits.Position = stop; + break; + + default: + //Console.WriteLine("{0,6}: {1:x2} {2}", + // bits.Position, rec, (SYM)rec); + bits.Position = stop; + break; + } + } + if (count == 0) + { + return null; + } + + bits.Position = begin; + PdbFunction[] funcs = new PdbFunction[count]; + int func = 0; + + while (bits.Position < limit) + { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) + { + + case SYM.S_GMANPROC: + case SYM.S_LMANPROC: + ManProcSym proc; + //int offset = bits.Position; + + bits.ReadUInt32(out proc.parent); + bits.ReadUInt32(out proc.end); + bits.ReadUInt32(out proc.next); + bits.ReadUInt32(out proc.len); + bits.ReadUInt32(out proc.dbgStart); + bits.ReadUInt32(out proc.dbgEnd); + bits.ReadUInt32(out proc.token); + bits.ReadUInt32(out proc.off); + bits.ReadUInt16(out proc.seg); + bits.ReadUInt8(out proc.flags); + bits.ReadUInt16(out proc.retReg); + if (readStrings) + { + bits.ReadCString(out proc.name); + } + else + { + bits.SkipCString(out proc.name); + } + //Console.WriteLine("token={0:X8} [{1}::{2}]", proc.token, module, proc.name); + + bits.Position = stop; + funcs[func++] = new PdbFunction(/*module,*/ proc, bits); + break; + + default: + { + //throw new PdbDebugException("Unknown SYMREC {0}", (SYM)rec); + bits.Position = stop; + break; + } + } + } + return funcs; + } + + internal static void CountScopesAndSlots(BitAccess bits, uint limit, + out int constants, out int scopes, out int slots, out int usedNamespaces) + { + int pos = bits.Position; + BlockSym32 block; + constants = 0; + slots = 0; + scopes = 0; + usedNamespaces = 0; + + while (bits.Position < limit) + { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.Position = star; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) + { + case SYM.S_BLOCK32: + { + bits.ReadUInt32(out block.parent); + bits.ReadUInt32(out block.end); + + scopes++; + bits.Position = (int)block.end; + break; + } + + case SYM.S_MANSLOT: + slots++; + bits.Position = stop; + break; + + case SYM.S_UNAMESPACE: + usedNamespaces++; + bits.Position = stop; + break; + + case SYM.S_MANCONSTANT: + constants++; + bits.Position = stop; + break; + + default: + bits.Position = stop; + break; + } + } + bits.Position = pos; + } + + internal PdbFunction() + { + } + + internal PdbFunction(/*string module, */ManProcSym proc, BitAccess bits) + { + this.token = proc.token; + //this.module = module; + //this.name = proc.name; + //this.flags = proc.flags; + this.segment = proc.seg; + this.address = proc.off; + //this.length = proc.len; + + if (proc.seg != 1) + { + throw new PdbDebugException("Segment is {0}, not 1.", proc.seg); + } + if (proc.parent != 0 || proc.next != 0) + { + throw new PdbDebugException("Warning parent={0}, next={1}", + proc.parent, proc.next); + } + //if (proc.dbgStart != 0 || proc.dbgEnd != 0) { + // throw new PdbDebugException("Warning DBG start={0}, end={1}", + // proc.dbgStart, proc.dbgEnd); + //} + + int constantCount; + int scopeCount; + int slotCount; + int usedNamespacesCount; + CountScopesAndSlots(bits, proc.end, out constantCount, out scopeCount, out slotCount, out usedNamespacesCount); + int scope = constantCount > 0 || slotCount > 0 || usedNamespacesCount > 0 ? 1 : 0; + int slot = 0; + int constant = 0; + int usedNs = 0; + scopes = new PdbScope[scopeCount + scope]; + slots = new PdbSlot[slotCount]; + constants = new PdbConstant[constantCount]; + usedNamespaces = new string[usedNamespacesCount]; + + if (scope > 0) + scopes[0] = new PdbScope(this.address, proc.len, slots, constants, usedNamespaces); + + while (bits.Position < proc.end) + { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.Position = star; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) + { + case SYM.S_OEM: + { // 0x0404 + OemSymbol oem; + + bits.ReadGuid(out oem.idOem); + bits.ReadUInt32(out oem.typind); + // internal byte[] rgl; // user data, force 4-byte alignment + + if (oem.idOem == msilMetaData) + { + string name = bits.ReadString(); + if (name == "MD2") + { + byte version; + bits.ReadUInt8(out version); + if (version == 4) + { + byte count; + bits.ReadUInt8(out count); + bits.Align(4); + while (count-- > 0) + this.ReadCustomMetadata(bits); + } + } + bits.Position = stop; + break; + } + else + { + throw new PdbDebugException("OEM section: guid={0} ti={1}", + oem.idOem, oem.typind); + // bits.Position = stop; + } + } + + case SYM.S_BLOCK32: + { + BlockSym32 block = new BlockSym32(); + + bits.ReadUInt32(out block.parent); + bits.ReadUInt32(out block.end); + bits.ReadUInt32(out block.len); + bits.ReadUInt32(out block.off); + bits.ReadUInt16(out block.seg); + bits.SkipCString(out block.name); + bits.Position = stop; + + scopes[scope++] = new PdbScope(this.address, block, bits, out slotToken); + bits.Position = (int)block.end; + break; + } + + case SYM.S_MANSLOT: + uint typind; + slots[slot++] = new PdbSlot(bits, out typind); + bits.Position = stop; + break; + + case SYM.S_MANCONSTANT: + constants[constant++] = new PdbConstant(bits); + bits.Position = stop; + break; + + case SYM.S_UNAMESPACE: + bits.ReadCString(out usedNamespaces[usedNs++]); + bits.Position = stop; + break; + + case SYM.S_END: + bits.Position = stop; + break; + + default: + { + //throw new PdbDebugException("Unknown SYM: {0}", (SYM)rec); + bits.Position = stop; + break; + } + } + } + + if (bits.Position != proc.end) + { + throw new PdbDebugException("Not at S_END"); + } + + ushort esiz; + ushort erec; + bits.ReadUInt16(out esiz); + bits.ReadUInt16(out erec); + + if (erec != (ushort)SYM.S_END) + { + throw new PdbDebugException("Missing S_END"); + } + } + + private void ReadCustomMetadata(BitAccess bits) + { + int savedPosition = bits.Position; + byte version; + bits.ReadUInt8(out version); + if (version != 4) + { + throw new PdbDebugException("Unknown custom metadata item version: {0}", version); + } + byte kind; + bits.ReadUInt8(out kind); + bits.Align(4); + uint numberOfBytesInItem; + bits.ReadUInt32(out numberOfBytesInItem); + switch (kind) + { + case 0: this.ReadUsingInfo(bits); break; + case 1: break; // this.ReadForwardInfo(bits); break; + case 2: break; // this.ReadForwardedToModuleInfo(bits); break; + case 3: this.ReadIteratorLocals(bits); break; + case 4: this.ReadForwardIterator(bits); break; + case 6: break; //vs2015 thing + case 7: break; //vs2015 thing + default: + throw new PdbDebugException("Unknown custom metadata item kind: {0}", kind); + } + bits.Position = savedPosition + (int)numberOfBytesInItem; + } + + private void ReadForwardIterator(BitAccess bits) + { + this.iteratorClass = bits.ReadString(); + } + + private void ReadIteratorLocals(BitAccess bits) + { + uint numberOfLocals; + bits.ReadUInt32(out numberOfLocals); + this.iteratorScopes = new List((int)numberOfLocals); + while (numberOfLocals-- > 0) + { + uint ilStartOffset; + uint ilEndOffset; + bits.ReadUInt32(out ilStartOffset); + bits.ReadUInt32(out ilEndOffset); + this.iteratorScopes.Add(new PdbIteratorScope(ilStartOffset, ilEndOffset - ilStartOffset)); + } + } + + //private void ReadForwardedToModuleInfo(BitAccess bits) { + //} + + //private void ReadForwardInfo(BitAccess bits) { + //} + + private void ReadUsingInfo(BitAccess bits) + { + ushort numberOfNamespaces; + bits.ReadUInt16(out numberOfNamespaces); + this.usingCounts = new ushort[numberOfNamespaces]; + for (ushort i = 0; i < numberOfNamespaces; i++) + { + bits.ReadUInt16(out this.usingCounts[i]); + } + } + + internal class PdbFunctionsByAddress : IComparer + { + public int Compare(Object x, Object y) + { + PdbFunction fx = (PdbFunction)x; + PdbFunction fy = (PdbFunction)y; + + if (fx.segment < fy.segment) + { + return -1; + } + else if (fx.segment > fy.segment) + { + return 1; + } + else if (fx.address < fy.address) + { + return -1; + } + else if (fx.address > fy.address) + { + return 1; + } + else + { + return 0; + } + } + } + + internal class PdbFunctionsByAddressAndToken : IComparer + { + public int Compare(Object x, Object y) + { + PdbFunction fx = (PdbFunction)x; + PdbFunction fy = (PdbFunction)y; + + if (fx.segment < fy.segment) + { + return -1; + } + else if (fx.segment > fy.segment) + { + return 1; + } + else if (fx.address < fy.address) + { + return -1; + } + else if (fx.address > fy.address) + { + return 1; + } + else + { + if (fx.token < fy.token) + return -1; + else if (fx.token > fy.token) + return 1; + else + return 0; + } + } + } + + //internal class PdbFunctionsByToken : IComparer { + // public int Compare(Object x, Object y) { + // PdbFunction fx = (PdbFunction)x; + // PdbFunction fy = (PdbFunction)y; + + // if (fx.token < fy.token) { + // return -1; + // } else if (fx.token > fy.token) { + // return 1; + // } else { + // return 0; + // } + // } + + //} + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLine.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLine.cs new file mode 100644 index 00000000..f6fe3a9d --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLine.cs @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal struct PdbLine { + internal uint offset; + internal uint lineBegin; + internal uint lineEnd; + internal ushort colBegin; + internal ushort colEnd; + + internal PdbLine(uint offset, uint lineBegin, ushort colBegin, uint lineEnd, ushort colEnd) { + this.offset = offset; + this.lineBegin = lineBegin; + this.colBegin = colBegin; + this.lineEnd = lineEnd; + this.colEnd = colEnd; + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLines.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLines.cs new file mode 100644 index 00000000..382638b7 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbLines.cs @@ -0,0 +1,23 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal class PdbLines { + internal PdbSource file; + internal PdbLine[] lines; + + internal PdbLines(PdbSource file, uint count) { + this.file = file; + this.lines = new PdbLine[count]; + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbReader.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbReader.cs new file mode 100644 index 00000000..edfd9263 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbReader.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; +using System.IO; + +namespace Microsoft.Cci.Pdb { + internal class PdbReader { + internal PdbReader(Stream reader, int pageSize) { + this.pageSize = pageSize; + this.reader = reader; + } + + internal void Seek(int page, int offset) { + reader.Seek(page * pageSize + offset, SeekOrigin.Begin); + } + + internal void Read(byte[] bytes, int offset, int count) { + reader.Read(bytes, offset, count); + } + + internal int PagesFromSize(int size) { + return (size + pageSize - 1) / (pageSize); + } + + //internal int PageSize { + // get { return pageSize; } + //} + + internal readonly int pageSize; + internal readonly Stream reader; + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbScope.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbScope.cs new file mode 100644 index 00000000..c46220b8 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbScope.cs @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal class PdbScope { + internal PdbConstant[] constants; + internal PdbSlot[] slots; + internal PdbScope[] scopes; + internal string[] usedNamespaces; + + //internal uint segment; + internal uint address; + internal uint offset; + internal uint length; + + internal PdbScope(uint address, uint length, PdbSlot[] slots, PdbConstant[] constants, string[] usedNamespaces) { + this.constants = constants; + this.slots = slots; + this.scopes = new PdbScope[0]; + this.usedNamespaces = usedNamespaces; + this.address = address; + this.offset = 0; + this.length = length; + } + + internal PdbScope(uint funcOffset, BlockSym32 block, BitAccess bits, out uint typind) { + //this.segment = block.seg; + this.address = block.off; + this.offset = block.off - funcOffset; + this.length = block.len; + typind = 0; + + int constantCount; + int scopeCount; + int slotCount; + int namespaceCount; + PdbFunction.CountScopesAndSlots(bits, block.end, out constantCount, out scopeCount, out slotCount, out namespaceCount); + constants = new PdbConstant[constantCount]; + scopes = new PdbScope[scopeCount]; + slots = new PdbSlot[slotCount]; + usedNamespaces = new string[namespaceCount]; + int constant = 0; + int scope = 0; + int slot = 0; + int usedNs = 0; + + while (bits.Position < block.end) { + ushort siz; + ushort rec; + + bits.ReadUInt16(out siz); + int star = bits.Position; + int stop = bits.Position + siz; + bits.Position = star; + bits.ReadUInt16(out rec); + + switch ((SYM)rec) { + case SYM.S_BLOCK32: { + BlockSym32 sub = new BlockSym32(); + + bits.ReadUInt32(out sub.parent); + bits.ReadUInt32(out sub.end); + bits.ReadUInt32(out sub.len); + bits.ReadUInt32(out sub.off); + bits.ReadUInt16(out sub.seg); + bits.SkipCString(out sub.name); + + bits.Position = stop; + scopes[scope++] = new PdbScope(funcOffset, sub, bits, out typind); + break; + } + + case SYM.S_MANSLOT: + slots[slot++] = new PdbSlot(bits, out typind); + bits.Position = stop; + break; + + case SYM.S_UNAMESPACE: + bits.ReadCString(out usedNamespaces[usedNs++]); + bits.Position = stop; + break; + + case SYM.S_END: + bits.Position = stop; + break; + + case SYM.S_MANCONSTANT: + constants[constant++] = new PdbConstant(bits); + bits.Position = stop; + break; + + default: + //throw new PdbException("Unknown SYM in scope {0}", (SYM)rec); + bits.Position = stop; + break; + } + } + + if (bits.Position != block.end) { + throw new Exception("Not at S_END"); + } + + ushort esiz; + ushort erec; + bits.ReadUInt16(out esiz); + bits.ReadUInt16(out erec); + + if (erec != (ushort)SYM.S_END) { + throw new Exception("Missing S_END"); + } + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSlot.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSlot.cs new file mode 100644 index 00000000..0dc89ad4 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSlot.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal class PdbSlot { + internal uint slot; + internal string name; + internal ushort flags; + //internal uint segment; + //internal uint address; + + internal PdbSlot(BitAccess bits, out uint typind) { + AttrSlotSym slot; + + bits.ReadUInt32(out slot.index); + bits.ReadUInt32(out slot.typind); + bits.ReadUInt32(out slot.offCod); + bits.ReadUInt16(out slot.segCod); + bits.ReadUInt16(out slot.flags); + bits.ReadCString(out slot.name); + + this.slot = slot.index; + this.name = slot.name; + this.flags = slot.flags; + //this.segment = slot.segCod; + //this.address = slot.offCod; + + typind = slot.typind; + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSource.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSource.cs new file mode 100644 index 00000000..ac40f851 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/PdbSource.cs @@ -0,0 +1,29 @@ +//----------------------------------------------------------------------------- +// +// Copyright (c) Microsoft. All rights reserved. +// This code is licensed under the Microsoft Public License. +// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF +// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY +// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR +// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT. +// +//----------------------------------------------------------------------------- +using System; + +namespace Microsoft.Cci.Pdb { + internal class PdbSource { + //internal uint index; + internal string name; + internal Guid doctype; + internal Guid language; + internal Guid vendor; + + internal PdbSource(/*uint index, */string name, Guid doctype, Guid language, Guid vendor) { + //this.index = index; + this.name = name; + this.doctype = doctype; + this.language = language; + this.vendor = vendor; + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs new file mode 100644 index 00000000..db3f291b --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs @@ -0,0 +1,33 @@ +//----------------------------------------------------------------------------- +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +//----------------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.IO; +using Microsoft.Cci; +using Microsoft.Cci.Pdb; +using System.Text; +using System.Diagnostics.SymbolStore; + +namespace Microsoft.Cci { + + internal sealed class PdbIteratorScope : ILocalScope { + + internal PdbIteratorScope(uint offset, uint length) { + this.offset = offset; + this.length = length; + } + + public uint Offset { + get { return this.offset; } + } + uint offset; + + public uint Length { + get { return this.length; } + } + uint length; + } +} \ No newline at end of file diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs new file mode 100644 index 00000000..f98eec5a --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs @@ -0,0 +1,28 @@ +// ISymUnmanagedDocumentWriter.cs +// +// Author: +// Juerg Billeter (j@bitron.ch) +// +// (C) 2008 Juerg Billeter +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System.Runtime.InteropServices; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs new file mode 100644 index 00000000..9b14c210 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs @@ -0,0 +1,34 @@ +// +// ISymUnmanagedWriter2.cs +// +// Author: +// Juerg Billeter (j@bitron.ch) +// +// (C) 2008 Juerg Billeter +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Diagnostics.SymbolStore; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; + +using Mono.Cecil.Cil; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs new file mode 100644 index 00000000..7cf9c5d2 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs @@ -0,0 +1,4 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Text; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbHelper.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbHelper.cs new file mode 100644 index 00000000..c6286355 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbHelper.cs @@ -0,0 +1,212 @@ +// +// PdbHelper.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.IO; + +using Mono.Cecil.Cil; + +namespace Mono.Cecil.Pdb +{ + + class PdbHelper + { + + + + public static string GetPdbFileName(string assemblyFileName) + { + return Path.ChangeExtension(assemblyFileName, ".pdb"); + } + } + + public class PdbReaderProvider : ISymbolReaderProvider + { + + public ISymbolReader GetSymbolReader(ModuleDefinition module, string fileName) + { + return new PdbReader(File.OpenRead(PdbHelper.GetPdbFileName(fileName))); + } + + public ISymbolReader GetSymbolReader(ModuleDefinition module, Stream symbolStream) + { + return new PdbReader(symbolStream); + } + } + + + public class GuidCompare : IEqualityComparer + { + + public bool Equals(Guid x, Guid y) + { + return x == y; + } + + public int GetHashCode(Guid obj) + { + return obj.GetHashCode(); + } + } + public class DocumentLanguageCompare : IEqualityComparer + { + + + public bool Equals(DocumentLanguage x, DocumentLanguage y) + { + return x == y; + } + + public int GetHashCode(DocumentLanguage obj) + { + return obj.GetHashCode(); + } + } + public class uintCompare : IEqualityComparer + { + public bool Equals(uint x, uint y) + { + return x == y; + } + + public int GetHashCode(uint obj) + { + return obj.GetHashCode(); + } + } + + static class GuidMapping + { + + static readonly Dictionary guid_language = new Dictionary(new GuidCompare()); + static readonly Dictionary language_guid = new Dictionary(new DocumentLanguageCompare()); + + static GuidMapping() + { + AddMapping(DocumentLanguage.C, new Guid(0x63a08714, 0xfc37, 0x11d2, 0x90, 0x4c, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); + AddMapping(DocumentLanguage.Cpp, new Guid(0x3a12d0b7, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); + AddMapping(DocumentLanguage.CSharp, new Guid(0x3f5162f8, 0x07c6, 0x11d3, 0x90, 0x53, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); + AddMapping(DocumentLanguage.Basic, new Guid(0x3a12d0b8, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); + AddMapping(DocumentLanguage.Java, new Guid(0x3a12d0b4, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); + AddMapping(DocumentLanguage.Cobol, new Guid(0xaf046cd1, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); + AddMapping(DocumentLanguage.Pascal, new Guid(0xaf046cd2, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); + AddMapping(DocumentLanguage.Cil, new Guid(0xaf046cd3, 0xd0e1, 0x11d2, 0x97, 0x7c, 0x0, 0xa0, 0xc9, 0xb4, 0xd5, 0xc)); + AddMapping(DocumentLanguage.JScript, new Guid(0x3a12d0b6, 0xc26c, 0x11d0, 0xb4, 0x42, 0x0, 0xa0, 0x24, 0x4a, 0x1d, 0xd2)); + AddMapping(DocumentLanguage.Smc, new Guid(0xd9b9f7b, 0x6611, 0x11d3, 0xbd, 0x2a, 0x0, 0x0, 0xf8, 0x8, 0x49, 0xbd)); + AddMapping(DocumentLanguage.MCpp, new Guid(0x4b35fde8, 0x07c6, 0x11d3, 0x90, 0x53, 0x0, 0xc0, 0x4f, 0xa3, 0x02, 0xa1)); + //AddMapping(DocumentLanguage.FSharp, new Guid(0xab4f38c9, 0xb6e6, 0x43ba, 0xbe, 0x3b, 0x58, 0x08, 0x0b, 0x2c, 0xcc, 0xe3)); + } + + static void AddMapping(DocumentLanguage language, Guid guid) + { + guid_language.Add(guid, language); + language_guid.Add(language, guid); + } + + static readonly Guid type_text = new Guid(0x5a869d0b, 0x6611, 0x11d3, 0xbd, 0x2a, 0x00, 0x00, 0xf8, 0x08, 0x49, 0xbd); + + public static DocumentType ToType(Guid guid) + { + if (guid == type_text) + return DocumentType.Text; + + return DocumentType.Other; + } + + public static Guid ToGuid(DocumentType type) + { + if (type == DocumentType.Text) + return type_text; + + return new Guid(); + } + + static readonly Guid hash_md5 = new Guid(0x406ea660, 0x64cf, 0x4c82, 0xb6, 0xf0, 0x42, 0xd4, 0x81, 0x72, 0xa7, 0x99); + static readonly Guid hash_sha1 = new Guid(0xff1816ec, 0xaa5e, 0x4d10, 0x87, 0xf7, 0x6f, 0x49, 0x63, 0x83, 0x34, 0x60); + + public static DocumentHashAlgorithm ToHashAlgorithm(Guid guid) + { + if (guid == hash_md5) + return DocumentHashAlgorithm.MD5; + + if (guid == hash_sha1) + return DocumentHashAlgorithm.SHA1; + + return DocumentHashAlgorithm.None; + } + + public static Guid ToGuid(DocumentHashAlgorithm hash_algo) + { + if (hash_algo == DocumentHashAlgorithm.MD5) + return hash_md5; + + if (hash_algo == DocumentHashAlgorithm.SHA1) + return hash_sha1; + + return new Guid(); + } + + public static DocumentLanguage ToLanguage(Guid guid) + { + DocumentLanguage language; + if (!guid_language.TryGetValue(guid, out language)) + return DocumentLanguage.Other; + + return language; + } + + public static Guid ToGuid(DocumentLanguage language) + { + Guid guid; + if (!language_guid.TryGetValue(language, out guid)) + return new Guid(); + + return guid; + } + + static readonly Guid vendor_ms = new Guid(0x994b45c4, 0xe6e9, 0x11d2, 0x90, 0x3f, 0x00, 0xc0, 0x4f, 0xa3, 0x02, 0xa1); + + public static DocumentLanguageVendor ToVendor(Guid guid) + { + if (guid == vendor_ms) + return DocumentLanguageVendor.Microsoft; + + return DocumentLanguageVendor.Other; + } + + public static Guid ToGuid(DocumentLanguageVendor vendor) + { + if (vendor == DocumentLanguageVendor.Microsoft) + return vendor_ms; + + return new Guid(); + } + } +} + diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbReader.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbReader.cs new file mode 100644 index 00000000..1449e1da --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbReader.cs @@ -0,0 +1,286 @@ +// +// PdbReader.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.IO; + +using Microsoft.Cci.Pdb; + +using Mono.Cecil.Cil; + +namespace Mono.Cecil.Pdb +{ + + public class PdbReader : ISymbolReader + { + + int age; + Guid guid; + + readonly Stream pdb_file; + readonly Dictionary documents = new Dictionary(); + readonly Dictionary functions = new Dictionary(new uintCompare()); + + internal PdbReader(Stream file) + { + this.pdb_file = file; + } + + /* + uint Magic = 0x53445352; + Guid Signature; + uint Age; + string FileName; + */ + + public bool ProcessDebugHeader(ImageDebugDirectory directory, byte[] header) + { + if (header.Length < 24) + return false; + + var magic = ReadInt32(header, 0); + if (magic != 0x53445352) + return false; + + var guid_bytes = new byte[16]; + Buffer.BlockCopy(header, 4, guid_bytes, 0, 16); + + this.guid = new Guid(guid_bytes); + this.age = ReadInt32(header, 20); + + return PopulateFunctions(); + } + + static int ReadInt32(byte[] bytes, int start) + { + return (bytes[start] + | (bytes[start + 1] << 8) + | (bytes[start + 2] << 16) + | (bytes[start + 3] << 24)); + } + + bool PopulateFunctions() + { + using (pdb_file) + { + int age; + Guid guid; + var funcs = PdbFile.LoadFunctions(pdb_file, true, out age, out guid); + + if (this.age != 0 && this.guid != guid) + return false; + + foreach (PdbFunction function in funcs) + functions.Add(function.token, function); + } + + return true; + } + + public void Read(MethodBody body, InstructionMapper mapper) + { + var method_token = body.Method.MetadataToken; + + PdbFunction function; + if (!functions.TryGetValue(method_token.ToUInt32(), out function)) + return; + + ReadSequencePoints(function, mapper); + ReadScopeAndLocals(function.scopes, null, body, mapper); + } + + static void ReadScopeAndLocals(PdbScope[] scopes, Scope parent, MethodBody body, InstructionMapper mapper) + { + foreach (PdbScope scope in scopes) + ReadScopeAndLocals(scope, parent, body, mapper); + + CreateRootScope(body); + } + + static void CreateRootScope(MethodBody body) + { + if (!body.HasVariables) + return; + + var instructions = body.Instructions; + + var root = new Scope(); + root.Start = instructions[0]; + root.End = instructions[instructions.Count - 1]; + + var variables = body.Variables; + for (int i = 0; i < variables.Count; i++) + root.Variables.Add(variables[i]); + + body.Scope = root; + } + + static void ReadScopeAndLocals(PdbScope scope, Scope parent, MethodBody body, InstructionMapper mapper) + { + //Scope s = new Scope (); + //s.Start = GetInstruction (body, instructions, (int) scope.address); + //s.End = GetInstruction (body, instructions, (int) scope.length - 1); + + //if (parent != null) + // parent.Scopes.Add (s); + //else + // body.Scopes.Add (s); + + if (scope == null) + return; + + foreach (PdbSlot slot in scope.slots) + { + int index = (int)slot.slot; + if (index < 0 || index >= body.Variables.Count) + continue; + + VariableDefinition variable = body.Variables[index]; + variable.Name = slot.name; + + //s.Variables.Add (variable); + } + + ReadScopeAndLocals(scope.scopes, null /* s */, body, mapper); + } + + void ReadSequencePoints(PdbFunction function, InstructionMapper mapper) + { + if (function.lines == null) + return; + + foreach (PdbLines lines in function.lines) + ReadLines(lines, mapper); + } + + void ReadLines(PdbLines lines, InstructionMapper mapper) + { + var document = GetDocument(lines.file); + + foreach (var line in lines.lines) + ReadLine(line, document, mapper); + } + + static void ReadLine(PdbLine line, Document document, InstructionMapper mapper) + { + var instruction = mapper((int)line.offset); + if (instruction == null) + return; + + var sequence_point = new SequencePoint(document); + sequence_point.StartLine = (int)line.lineBegin; + sequence_point.StartColumn = (int)line.colBegin; + sequence_point.EndLine = (int)line.lineEnd; + sequence_point.EndColumn = (int)line.colEnd; + + instruction.SequencePoint = sequence_point; + } + + Document GetDocument(PdbSource source) + { + string name = source.name; + Document document; + if (documents.TryGetValue(name, out document)) + return document; + + document = new Document(name) + { + Language = GuidMapping.ToLanguage(source.language), + LanguageVendor = GuidMapping.ToVendor(source.vendor), + Type = GuidMapping.ToType(source.doctype), + }; + documents.Add(name, document); + return document; + } + + public void Read(MethodSymbols symbols) + { + PdbFunction function; + if (!functions.TryGetValue(symbols.MethodToken.ToUInt32(), out function)) + return; + + ReadSequencePoints(function, symbols); + ReadLocals(function.scopes, symbols); + } + + void ReadLocals(PdbScope[] scopes, MethodSymbols symbols) + { + foreach (var scope in scopes) + ReadLocals(scope, symbols); + } + + void ReadLocals(PdbScope scope, MethodSymbols symbols) + { + if (scope == null) + return; + + foreach (var slot in scope.slots) + { + int index = (int)slot.slot; + if (index < 0 || index >= symbols.Variables.Count) + continue; + + var variable = symbols.Variables[index]; + variable.Name = slot.name; + } + + ReadLocals(scope.scopes, symbols); + } + + void ReadSequencePoints(PdbFunction function, MethodSymbols symbols) + { + if (function.lines == null) + return; + + foreach (PdbLines lines in function.lines) + ReadLines(lines, symbols); + } + + void ReadLines(PdbLines lines, MethodSymbols symbols) + { + for (int i = 0; i < lines.lines.Length; i++) + { + var line = lines.lines[i]; + + symbols.Instructions.Add(new InstructionSymbol((int)line.offset, new SequencePoint(GetDocument(lines.file)) + { + StartLine = (int)line.lineBegin, + StartColumn = (int)line.colBegin, + EndLine = (int)line.lineEnd, + EndColumn = (int)line.colEnd, + })); + } + } + + public void Dispose() + { + pdb_file.Close(); + } + } +} diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbWriter.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbWriter.cs new file mode 100644 index 00000000..d11a8638 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/PdbWriter.cs @@ -0,0 +1,34 @@ +// +// PdbWriter.cs +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2011 Jb Evain +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics.SymbolStore; + +using Mono.Cecil.Cil; +using Mono.Collections.Generic; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs new file mode 100644 index 00000000..db6cb437 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs @@ -0,0 +1,29 @@ +// +// SymDocumentWriter.cs +// +// Author: +// Juerg Billeter (j@bitron.ch) +// +// (C) 2008 Juerg Billeter +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; diff --git a/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymWriter.cs b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymWriter.cs new file mode 100644 index 00000000..306af962 --- /dev/null +++ b/Mono.Cecil.Pdb/pdb/Mono.Cecil.Pdb/SymWriter.cs @@ -0,0 +1,37 @@ +// +// SymWriter.cs +// +// Author: +// Juerg Billeter (j@bitron.ch) +// +// (C) 2008 Juerg Billeter +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.Diagnostics.SymbolStore; +using System.Runtime.InteropServices; + +using Mono.Cecil.Cil; +using Mono.Collections.Generic; + +