From 3d974637671de8876a33b49948453d61379b2a58 Mon Sep 17 00:00:00 2001 From: HCoderDev Date: Sat, 27 Jan 2024 16:38:43 +0530 Subject: [PATCH] Testing --- ArchUnit.sln | 38 +- .../ArchUnitNET.MSTestV2.csproj | 2 +- ArchUnitNET.NUnit/ArchUnitNET.NUnit.csproj | 2 +- ArchUnitNET.xUnit/ArchUnitNET.xUnit.csproj | 2 +- ArchUnitNET/ArchUnitNET.csproj | 25 +- .../Implementation/AssemblyDefinition.cs | 9 + .../Implementation/ModuleDefinition.cs | 10 + ArchUnitNet.Reflect/Mono.Cecil.Reflect.csproj | 15 + SampleTest/GlobalUsings.cs | 1 + SampleTest/SampleTest.csproj | 25 + SampleTest/UnitTest1.cs | 22 + Test/DefectsDataTable.cs | 26 + Test/Test.csproj | 11 + TestAssembly/TestAssembly.csproj | 2 +- cecil-master/.editorconfig | 23 + cecil-master/.gitattributes | 8 + cecil-master/.github/FUNDING.yml | 1 + cecil-master/.github/workflows/main.yml | 35 + cecil-master/.gitignore | 18 + cecil-master/Directory.Build.props | 30 + cecil-master/LICENSE.txt | 21 + cecil-master/Mono.Cecil.Cil/Code.cs | 234 + cecil-master/Mono.Cecil.Cil/CodeReader.cs | 666 +++ cecil-master/Mono.Cecil.Cil/CodeWriter.cs | 654 +++ cecil-master/Mono.Cecil.Cil/Document.cs | 123 + .../Mono.Cecil.Cil/ExceptionHandler.cs | 71 + cecil-master/Mono.Cecil.Cil/ILProcessor.cs | 292 ++ cecil-master/Mono.Cecil.Cil/Instruction.cs | 302 ++ cecil-master/Mono.Cecil.Cil/MethodBody.cs | 495 +++ cecil-master/Mono.Cecil.Cil/OpCode.cs | 439 ++ cecil-master/Mono.Cecil.Cil/OpCodes.cs | 894 ++++ cecil-master/Mono.Cecil.Cil/PortablePdb.cs | 681 +++ cecil-master/Mono.Cecil.Cil/SequencePoint.cs | 76 + cecil-master/Mono.Cecil.Cil/Symbols.cs | 1228 ++++++ .../Mono.Cecil.Cil/VariableDefinition.cs | 29 + .../Mono.Cecil.Cil/VariableReference.cs | 42 + cecil-master/Mono.Cecil.Metadata/BlobHeap.cs | 54 + cecil-master/Mono.Cecil.Metadata/Buffers.cs | 517 +++ .../Mono.Cecil.Metadata/CodedIndex.cs | 29 + .../Mono.Cecil.Metadata/ElementType.cs | 55 + cecil-master/Mono.Cecil.Metadata/GuidHeap.cs | 36 + cecil-master/Mono.Cecil.Metadata/Heap.cs | 24 + .../Mono.Cecil.Metadata/MetadataToken.cs | 94 + cecil-master/Mono.Cecil.Metadata/PdbHeap.cs | 34 + cecil-master/Mono.Cecil.Metadata/Row.cs | 152 + .../Mono.Cecil.Metadata/StringHeap.cs | 60 + cecil-master/Mono.Cecil.Metadata/TableHeap.cs | 104 + cecil-master/Mono.Cecil.Metadata/TokenType.cs | 49 + .../Mono.Cecil.Metadata/UserStringHeap.cs | 36 + cecil-master/Mono.Cecil.Metadata/Utilities.cs | 650 +++ .../Mono.Cecil.PE/BinaryStreamReader.cs | 54 + .../Mono.Cecil.PE/BinaryStreamWriter.cs | 89 + cecil-master/Mono.Cecil.PE/ByteBuffer.cs | 336 ++ .../ByteBufferEqualityComparer.cs | 48 + cecil-master/Mono.Cecil.PE/DataDirectory.cs | 32 + cecil-master/Mono.Cecil.PE/Image.cs | 171 + cecil-master/Mono.Cecil.PE/ImageReader.cs | 797 ++++ cecil-master/Mono.Cecil.PE/ImageWriter.cs | 866 ++++ cecil-master/Mono.Cecil.PE/Section.cs | 24 + cecil-master/Mono.Cecil.PE/TextMap.cs | 129 + cecil-master/Mono.Cecil.Tests.props | 16 + cecil-master/Mono.Cecil.csproj | 18 + cecil-master/Mono.Cecil.nunit | 9 + cecil-master/Mono.Cecil.nuspec | 42 + cecil-master/Mono.Cecil.sln | 67 + cecil-master/Mono.Cecil/ArrayType.cs | 145 + cecil-master/Mono.Cecil/AssemblyDefinition.cs | 189 + cecil-master/Mono.Cecil/AssemblyFlags.cs | 24 + .../Mono.Cecil/AssemblyHashAlgorithm.cs | 22 + cecil-master/Mono.Cecil/AssemblyInfo.cs | 22 + .../Mono.Cecil/AssemblyLinkedResource.cs | 39 + .../Mono.Cecil/AssemblyNameDefinition.cs | 32 + .../Mono.Cecil/AssemblyNameReference.cs | 269 ++ cecil-master/Mono.Cecil/AssemblyReader.cs | 3883 +++++++++++++++++ cecil-master/Mono.Cecil/AssemblyWriter.cs | 3377 ++++++++++++++ .../Mono.Cecil/BaseAssemblyResolver.cs | 407 ++ cecil-master/Mono.Cecil/CallSite.cs | 106 + cecil-master/Mono.Cecil/Consts.cs | 5 + cecil-master/Mono.Cecil/CustomAttribute.cs | 220 + .../Mono.Cecil/DefaultAssemblyResolver.cs | 61 + cecil-master/Mono.Cecil/EmbeddedResource.cs | 98 + cecil-master/Mono.Cecil/EventAttributes.cs | 21 + cecil-master/Mono.Cecil/EventDefinition.cs | 156 + cecil-master/Mono.Cecil/EventReference.cs | 42 + cecil-master/Mono.Cecil/ExportedType.cs | 240 + cecil-master/Mono.Cecil/FieldAttributes.cs | 41 + cecil-master/Mono.Cecil/FieldDefinition.cs | 282 ++ cecil-master/Mono.Cecil/FieldReference.cs | 68 + cecil-master/Mono.Cecil/FileAttributes.cs | 17 + .../Mono.Cecil/FunctionPointerType.cs | 111 + .../Mono.Cecil/GenericInstanceMethod.cs | 78 + .../Mono.Cecil/GenericInstanceType.cs | 76 + cecil-master/Mono.Cecil/GenericParameter.cs | 362 ++ .../Mono.Cecil/GenericParameterAttributes.cs | 27 + .../Mono.Cecil/GenericParameterResolver.cs | 175 + cecil-master/Mono.Cecil/IConstantProvider.cs | 44 + .../Mono.Cecil/ICustomAttributeProvider.cs | 45 + cecil-master/Mono.Cecil/IGenericInstance.cs | 48 + .../Mono.Cecil/IGenericParameterProvider.cs | 58 + .../Mono.Cecil/IMarshalInfoProvider.cs | 38 + cecil-master/Mono.Cecil/IMemberDefinition.cs | 82 + cecil-master/Mono.Cecil/IMetadataScope.cs | 23 + .../Mono.Cecil/IMetadataTokenProvider.cs | 17 + cecil-master/Mono.Cecil/IMethodSignature.cs | 57 + cecil-master/Mono.Cecil/Import.cs | 812 ++++ cecil-master/Mono.Cecil/LinkedResource.cs | 42 + .../Mono.Cecil/ManifestResourceAttributes.cs | 21 + cecil-master/Mono.Cecil/MarshalInfo.cs | 153 + .../Mono.Cecil/MemberDefinitionCollection.cs | 74 + cecil-master/Mono.Cecil/MemberReference.cs | 102 + cecil-master/Mono.Cecil/MetadataResolver.cs | 442 ++ cecil-master/Mono.Cecil/MetadataSystem.cs | 382 ++ cecil-master/Mono.Cecil/MethodAttributes.cs | 48 + .../Mono.Cecil/MethodCallingConvention.cs | 23 + cecil-master/Mono.Cecil/MethodDefinition.cs | 564 +++ .../Mono.Cecil/MethodImplAttributes.cs | 37 + cecil-master/Mono.Cecil/MethodReference.cs | 202 + .../Mono.Cecil/MethodReferenceComparer.cs | 143 + cecil-master/Mono.Cecil/MethodReturnType.cs | 98 + .../Mono.Cecil/MethodSemanticsAttributes.cs | 25 + .../Mono.Cecil/MethodSpecification.cs | 84 + cecil-master/Mono.Cecil/Modifiers.cs | 112 + cecil-master/Mono.Cecil/ModuleDefinition.cs | 1353 ++++++ cecil-master/Mono.Cecil/ModuleKind.cs | 55 + cecil-master/Mono.Cecil/ModuleReference.cs | 49 + cecil-master/Mono.Cecil/NativeType.cs | 55 + cecil-master/Mono.Cecil/PInvokeAttributes.cs | 44 + cecil-master/Mono.Cecil/PInvokeInfo.cs | 120 + .../Mono.Cecil/ParameterAttributes.cs | 27 + .../Mono.Cecil/ParameterDefinition.cs | 146 + .../ParameterDefinitionCollection.cs | 62 + cecil-master/Mono.Cecil/ParameterReference.cs | 57 + cecil-master/Mono.Cecil/PinnedType.cs | 35 + cecil-master/Mono.Cecil/PointerType.cs | 43 + cecil-master/Mono.Cecil/PropertyAttributes.cs | 23 + cecil-master/Mono.Cecil/PropertyDefinition.cs | 245 ++ cecil-master/Mono.Cecil/PropertyReference.cs | 45 + cecil-master/Mono.Cecil/ReferenceType.cs | 43 + cecil-master/Mono.Cecil/Resource.cs | 58 + .../Mono.Cecil/SecurityDeclaration.cs | 201 + cecil-master/Mono.Cecil/SentinelType.cs | 35 + cecil-master/Mono.Cecil/TargetRuntime.cs | 19 + cecil-master/Mono.Cecil/Treatments.cs | 61 + cecil-master/Mono.Cecil/TypeAttributes.cs | 63 + cecil-master/Mono.Cecil/TypeComparisonMode.cs | 12 + cecil-master/Mono.Cecil/TypeDefinition.cs | 620 +++ .../Mono.Cecil/TypeDefinitionCollection.cs | 100 + cecil-master/Mono.Cecil/TypeParser.cs | 532 +++ cecil-master/Mono.Cecil/TypeReference.cs | 352 ++ .../TypeReferenceEqualityComparer.cs | 253 ++ cecil-master/Mono.Cecil/TypeResolver.cs | 220 + cecil-master/Mono.Cecil/TypeSpecification.cs | 68 + cecil-master/Mono.Cecil/TypeSystem.cs | 331 ++ cecil-master/Mono.Cecil/VariantType.cs | 37 + .../Mono.Cecil/WindowsRuntimeProjections.cs | 971 +++++ .../Mono.Collections.Generic/Collection.cs | 418 ++ .../ReadOnlyCollection.cs | 101 + .../CryptoConvert.cs | 290 ++ .../CryptoService.cs | 204 + cecil-master/Mono/Disposable.cs | 45 + cecil-master/Mono/Empty.cs | 62 + cecil-master/Mono/MergeSort.cs | 66 + cecil-master/ProjectInfo.cs | 20 + cecil-master/README.md | 15 + cecil-master/Test/Mono.Cecil.Tests.csproj | 29 + .../Test/Mono.Cecil.Tests/AssemblyInfo.cs | 6 + .../Test/Mono.Cecil.Tests/AssemblyTests.cs | 109 + .../Test/Mono.Cecil.Tests/BaseTestFixture.cs | 357 ++ .../Mono.Cecil.Tests/CompilationService.cs | 385 ++ .../Mono.Cecil.Tests/CustomAttributesTests.cs | 852 ++++ .../Test/Mono.Cecil.Tests/EventTests.cs | 79 + .../Test/Mono.Cecil.Tests/Extensions.cs | 93 + .../Test/Mono.Cecil.Tests/FieldTests.cs | 425 ++ .../Test/Mono.Cecil.Tests/Formatter.cs | 193 + .../Test/Mono.Cecil.Tests/ILProcessorTests.cs | 586 +++ .../Test/Mono.Cecil.Tests/ImageReadTests.cs | 275 ++ .../Test/Mono.Cecil.Tests/ImportCecilTests.cs | 368 ++ .../Mono.Cecil.Tests/ImportReflectionTests.cs | 428 ++ ...oadAssemblyDefinitionForTestsBaseSimple.cs | 16 + .../Test/Mono.Cecil.Tests/MethodBodyTests.cs | 453 ++ .../MethodReferenceComparerTests.cs | 135 + .../Test/Mono.Cecil.Tests/MethodTests.cs | 374 ++ .../Test/Mono.Cecil.Tests/ModuleTests.cs | 355 ++ .../Test/Mono.Cecil.Tests/NestedTypesTests.cs | 91 + .../Test/Mono.Cecil.Tests/ParameterTests.cs | 274 ++ .../Test/Mono.Cecil.Tests/PortablePdbTests.cs | 1152 +++++ .../Test/Mono.Cecil.Tests/PropertyTests.cs | 128 + .../Test/Mono.Cecil.Tests/ResolveTests.cs | 333 ++ .../SecurityDeclarationTests.cs | 298 ++ .../Test/Mono.Cecil.Tests/SymbolTests.cs | 141 + .../Mono.Cecil.Tests/TypeDefinitionUtils.cs | 41 + .../Test/Mono.Cecil.Tests/TypeParserTests.cs | 397 ++ .../TypeReferenceComparisonTests.cs | 84 + .../Test/Mono.Cecil.Tests/TypeTests.cs | 285 ++ .../Test/Mono.Cecil.Tests/VariableTests.cs | 185 + .../WindowsRuntimeAssemblyResolver.cs | 97 + .../WindowsRuntimeProjectionsTests.cs | 339 ++ .../Resources/assemblies/Deterministic.dll | Bin 0 -> 3072 bytes .../EmbeddedCompressedPdbTarget.exe | Bin 0 -> 11264 bytes .../assemblies/EmbeddedPdbChecksumLib.dll | Bin 0 -> 9728 bytes .../assemblies/EmbeddedPdbDeterministic.dll | Bin 0 -> 3584 bytes .../assemblies/EmbeddedPdbTarget.exe | Bin 0 -> 11264 bytes .../Test/Resources/assemblies/EmptyPdb.dll | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/EmptyPdb.pdb | Bin 0 -> 232 bytes .../assemblies/ExternalPdbDeterministic.dll | Bin 0 -> 3072 bytes .../assemblies/ExternalPdbDeterministic.pdb | Bin 0 -> 452 bytes .../Test/Resources/assemblies/FSharp.Core.dll | Bin 0 -> 1636016 bytes .../assemblies/GenericAttributes.dll | Bin 0 -> 5120 bytes .../GenericParameterConstraintAttributes.dll | Bin 0 -> 4608 bytes .../Test/Resources/assemblies/Issue697.dll | Bin 0 -> 6656 bytes .../Resources/assemblies/Issue697.dll.mdb | Bin 0 -> 1233 bytes .../assemblies/LocallyScopedConstantArray.dll | Bin 0 -> 4096 bytes .../assemblies/LocallyScopedConstantArray.pdb | Bin 0 -> 700 bytes .../Resources/assemblies/ManagedWinmd.winmd | Bin 0 -> 10240 bytes .../Resources/assemblies/Mono.Android.dll | Bin 0 -> 24482304 bytes .../Resources/assemblies/Mono.Android.pdb | Bin 0 -> 12635132 bytes .../Resources/assemblies/NativeWinmd.winmd | Bin 0 -> 4608 bytes .../Test/Resources/assemblies/NullConst.dll | Bin 0 -> 5120 bytes .../Test/Resources/assemblies/NullConst.pdb | Bin 0 -> 10424 bytes .../Resources/assemblies/PdbChecksumLib.dll | Bin 0 -> 4096 bytes .../Resources/assemblies/PdbChecksumLib.pdb | Bin 0 -> 9576 bytes .../Test/Resources/assemblies/PdbTarget.exe | Bin 0 -> 10240 bytes .../Test/Resources/assemblies/PdbTarget.pdb | Bin 0 -> 1692 bytes .../assemblies/PortableClassLibrary.dll | Bin 0 -> 5632 bytes .../assemblies/ReproConstGenericInst.dll | Bin 0 -> 4608 bytes .../assemblies/ReproConstGenericInst.pdb | Bin 0 -> 9564 bytes .../assemblies/RetargetableExample.dll | Bin 0 -> 3072 bytes .../Test/Resources/assemblies/SQLite-net.dll | Bin 0 -> 71168 bytes .../Resources/assemblies/SQLite-net.dll.mdb | Bin 0 -> 22513 bytes .../assemblies/System.Private.Xml.dll | Bin 0 -> 8422792 bytes .../assemblies/System.Private.Xml.pdb | Bin 0 -> 1284024 bytes .../Resources/assemblies/System.Runtime.dll | Bin 0 -> 22128 bytes .../Test/Resources/assemblies/TargetLib.dll | Bin 0 -> 4096 bytes .../Test/Resources/assemblies/TargetLib.pdb | Bin 0 -> 420 bytes .../assemblies/anycpu32bitpreferred.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/boxedoptarg.dll | Bin 0 -> 3072 bytes .../Test/Resources/assemblies/bug-185.dll | Bin 0 -> 5120 bytes .../Test/Resources/assemblies/catch.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/cecil.dll | Bin 0 -> 344064 bytes .../Test/Resources/assemblies/cecil.pdb | Bin 0 -> 182680 bytes .../Test/Resources/assemblies/cppcli.dll | Bin 0 -> 50176 bytes .../Test/Resources/assemblies/cscgpbug.dll | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/decsec-att.dll | Bin 0 -> 4096 bytes .../Test/Resources/assemblies/decsec-xml.dll | Bin 0 -> 5120 bytes .../Test/Resources/assemblies/decsec1-xml.dll | Bin 0 -> 4096 bytes .../Resources/assemblies/delay-signed.dll | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/embedcs.exe | Bin 0 -> 4096 bytes .../Test/Resources/assemblies/embedcs.pdb | Bin 0 -> 924 bytes .../Resources/assemblies/empty-decsec-att.dll | Bin 0 -> 3584 bytes .../Resources/assemblies/empty-str-const.exe | Bin 0 -> 4096 bytes .../Resources/assemblies/empty-str-const.pdb | Bin 0 -> 2668 bytes .../Test/Resources/assemblies/foo.dll | Bin 0 -> 3072 bytes .../Test/Resources/assemblies/fptr.exe | Bin 0 -> 2048 bytes .../Test/Resources/assemblies/gifaceref.exe | Bin 0 -> 5120 bytes .../Resources/assemblies/hello.anycpu.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/hello.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/hello.ia64.exe | Bin 0 -> 3072 bytes .../assemblies/hello.textonly.x64.exe | Bin 0 -> 1548 bytes .../Test/Resources/assemblies/hello.x64.exe | Bin 0 -> 3072 bytes .../Test/Resources/assemblies/hello.x86.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/hello1.exe | Bin 0 -> 3072 bytes .../Test/Resources/assemblies/hello2.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/hellow.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/iterator.exe | Bin 0 -> 5632 bytes .../Test/Resources/assemblies/libhello.dll | Bin 0 -> 3072 bytes .../Test/Resources/assemblies/libmdb.dll | Bin 0 -> 3072 bytes .../Test/Resources/assemblies/libmdb.dll.mdb | Bin 0 -> 238 bytes .../Test/Resources/assemblies/libpdb.dll | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/libpdb.pdb | Bin 0 -> 11776 bytes .../Test/Resources/assemblies/libres.dll | Bin 0 -> 3072 bytes .../Test/Resources/assemblies/line.exe | Bin 0 -> 4096 bytes .../Test/Resources/assemblies/line.pdb | Bin 0 -> 340 bytes .../Test/Resources/assemblies/marshal.dll | Bin 0 -> 3584 bytes .../Resources/assemblies/mdb-mismatch.dll | Bin 0 -> 3072 bytes .../Resources/assemblies/mdb-mismatch.dll.mdb | Bin 0 -> 238 bytes .../Test/Resources/assemblies/metro.exe | Bin 0 -> 15872 bytes .../Test/Resources/assemblies/mma.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/moda.netmodule | Bin 0 -> 2048 bytes .../Test/Resources/assemblies/modb.netmodule | Bin 0 -> 2048 bytes .../Test/Resources/assemblies/mylib.dll | Bin 0 -> 4608 bytes .../Test/Resources/assemblies/mylib.pdb | Bin 0 -> 416 bytes .../Test/Resources/assemblies/net471.exe | Bin 0 -> 4608 bytes .../Test/Resources/assemblies/noblob.dll | Bin 0 -> 3072 bytes .../assemblies/nullable-constant.exe | Bin 0 -> 3584 bytes .../assemblies/nullable-parameter.dll | Bin 0 -> 3072 bytes .../Resources/assemblies/ordered-attrs.exe | Bin 0 -> 4608 bytes .../Resources/assemblies/pdb-mismatch.dll | Bin 0 -> 4096 bytes .../Resources/assemblies/pdb-mismatch.pdb | Bin 0 -> 420 bytes .../Test/Resources/assemblies/pinvoke.exe | Bin 0 -> 4096 bytes .../Resources/assemblies/self-ref-typeref.dll | Bin 0 -> 5120 bytes .../Test/Resources/assemblies/switch.exe | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/text_file.txt | 1 + .../Test/Resources/assemblies/varargs.exe | Bin 0 -> 2048 bytes .../Test/Resources/assemblies/winrtcomp.winmd | Bin 0 -> 5120 bytes .../Test/Resources/assemblies/wp7.dll | Bin 0 -> 10752 bytes .../Test/Resources/assemblies/xattr.dll | Bin 0 -> 3584 bytes .../Test/Resources/assemblies/xattr.pdb | Bin 0 -> 420 bytes .../Test/Resources/cs/CustomAttributes.cs | 199 + cecil-master/Test/Resources/cs/Events.cs | 8 + cecil-master/Test/Resources/cs/Fields.cs | 41 + cecil-master/Test/Resources/cs/Generics.cs | 121 + cecil-master/Test/Resources/cs/Interfaces.cs | 22 + cecil-master/Test/Resources/cs/Layouts.cs | 16 + cecil-master/Test/Resources/cs/Methods.cs | 21 + cecil-master/Test/Resources/cs/NestedTypes.cs | 16 + cecil-master/Test/Resources/cs/Properties.cs | 18 + .../Test/Resources/il/FieldRVAAlignment.il | 85 + cecil-master/Test/Resources/il/branch-out.il | 34 + .../Test/Resources/il/ca-empty-blob.il | 21 + .../Test/Resources/il/ca-iface-impl.il | 35 + .../Test/Resources/il/explicitthis.il | 113 + cecil-master/Test/Resources/il/hello.il | 84 + cecil-master/Test/Resources/il/methodspecs.il | 43 + cecil-master/Test/Resources/il/others.il | 106 + .../Test/Resources/il/privatescope.il | 77 + cecil-master/Test/Resources/il/types.il | 46 + cecil-master/cecil.snk | Bin 0 -> 596 bytes cecil-master/rocks/Mono.Cecil.Rocks.csproj | 15 + .../rocks/Mono.Cecil.Rocks/AssemblyInfo.cs | 16 + .../rocks/Mono.Cecil.Rocks/DocCommentId.cs | 348 ++ .../rocks/Mono.Cecil.Rocks/Functional.cs | 41 + .../rocks/Mono.Cecil.Rocks/ILParser.cs | 229 + .../rocks/Mono.Cecil.Rocks/MethodBodyRocks.cs | 412 ++ .../Mono.Cecil.Rocks/MethodDefinitionRocks.cs | 72 + .../Mono.Cecil.Rocks/ModuleDefinitionRocks.cs | 32 + .../ParameterReferenceRocks.cs | 11 + .../SecurityDeclarationRocks.cs | 156 + .../Mono.Cecil.Rocks/TypeDefinitionRocks.cs | 65 + .../Mono.Cecil.Rocks/TypeReferenceRocks.cs | 89 + .../rocks/Test/Mono.Cecil.Rocks.Tests.csproj | 23 + .../Mono.Cecil.Tests/DocCommentIdTests.cs | 382 ++ .../MethodDefinitionRocksTests.cs | 66 + .../ModuleDefinitionRocksTests.cs | 29 + .../SecurityDeclarationRocksTests.cs | 66 + .../TypeDefinitionRocksTests.cs | 97 + .../TypeReferenceRocksTests.cs | 124 + .../Test/Resources/assemblies/decsec-att.dll | Bin 0 -> 4096 bytes .../Test/Resources/assemblies/decsec-xml.dll | Bin 0 -> 5120 bytes cecil-master/rocks/Test/Resources/cs/Types.cs | 14 + .../symbols/mdb/Mono.Cecil.Mdb.csproj | 16 + .../mdb/Mono.Cecil.Mdb/AssemblyInfo.cs | 16 + .../symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs | 207 + .../symbols/mdb/Mono.Cecil.Mdb/MdbWriter.cs | 219 + .../MonoSymbolFile.cs | 643 +++ .../MonoSymbolTable.cs | 1446 ++++++ .../MonoSymbolWriter.cs | 238 + .../SourceMethodBuilder.cs | 246 ++ .../SymbolWriterImpl.cs | 352 ++ .../mdb/Test/Mono.Cecil.Mdb.Tests.csproj | 23 + .../mdb/Test/Mono.Cecil.Tests/MdbTests.cs | 100 + .../assemblies/BreakpointTest.Portable.dll | Bin 0 -> 6144 bytes .../BreakpointTest.Portable.dll.mdb | Bin 0 -> 865 bytes .../Test/Resources/assemblies/mscorlib.dll | Bin 0 -> 4021248 bytes .../Resources/assemblies/mscorlib.dll.mdb | Bin 0 -> 1763801 bytes .../Test/Resources/assemblies/simplemdb.exe | Bin 0 -> 3072 bytes .../Resources/assemblies/simplemdb.exe.mdb | Bin 0 -> 369 bytes .../pdb/Microsoft.Cci.Pdb/.editorconfig | 3 + .../pdb/Microsoft.Cci.Pdb/BitAccess.cs | 253 ++ .../symbols/pdb/Microsoft.Cci.Pdb/BitSet.cs | 67 + .../symbols/pdb/Microsoft.Cci.Pdb/CvInfo.cs | 2409 ++++++++++ .../pdb/Microsoft.Cci.Pdb/DataStream.cs | 104 + .../pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs | 34 + .../pdb/Microsoft.Cci.Pdb/DbiHeader.cs | 52 + .../pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs | 50 + .../pdb/Microsoft.Cci.Pdb/DbiSecCon.cs | 35 + .../pdb/Microsoft.Cci.Pdb/IntHashTable.cs | 576 +++ .../pdb/Microsoft.Cci.Pdb/Interfaces.cs | 77 + .../symbols/pdb/Microsoft.Cci.Pdb/LICENSE | 21 + .../pdb/Microsoft.Cci.Pdb/MsfDirectory.cs | 51 + .../pdb/Microsoft.Cci.Pdb/PdbConstant.cs | 89 + .../Microsoft.Cci.Pdb/PdbDebugException.cs | 13 + .../pdb/Microsoft.Cci.Pdb/PdbException.cs | 13 + .../symbols/pdb/Microsoft.Cci.Pdb/PdbFile.cs | 582 +++ .../pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs | 96 + .../pdb/Microsoft.Cci.Pdb/PdbFunction.cs | 542 +++ .../symbols/pdb/Microsoft.Cci.Pdb/PdbInfo.cs | 43 + .../symbols/pdb/Microsoft.Cci.Pdb/PdbLine.cs | 22 + .../symbols/pdb/Microsoft.Cci.Pdb/PdbLines.cs | 16 + .../pdb/Microsoft.Cci.Pdb/PdbReader.cs | 33 + .../symbols/pdb/Microsoft.Cci.Pdb/PdbScope.cs | 120 + .../symbols/pdb/Microsoft.Cci.Pdb/PdbSlot.cs | 42 + .../pdb/Microsoft.Cci.Pdb/PdbSource.cs | 26 + .../pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs | 26 + .../SourceLocationProvider.cs | 29 + .../symbols/pdb/Mono.Cecil.Pdb.csproj | 17 + .../pdb/Mono.Cecil.Pdb/AssemblyInfo.cs | 16 + .../ISymUnmanagedDocumentWriter.cs | 21 + .../Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs | 86 + .../pdb/Mono.Cecil.Pdb/ModuleMetadata.cs | 803 ++++ .../pdb/Mono.Cecil.Pdb/NativePdbReader.cs | 363 ++ .../pdb/Mono.Cecil.Pdb/NativePdbWriter.cs | 372 ++ .../symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs | 127 + .../pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs | 38 + .../symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs | 156 + .../pdb/Test/Mono.Cecil.Pdb.Tests.csproj | 23 + .../pdb/Test/Mono.Cecil.Tests/PdbTests.cs | 489 +++ .../pdb/Test/Resources/assemblies/AVbTest.exe | Bin 0 -> 9216 bytes .../pdb/Test/Resources/assemblies/AVbTest.pdb | Bin 0 -> 24064 bytes .../Test/Resources/assemblies/CecilTest.exe | Bin 0 -> 4608 bytes .../Test/Resources/assemblies/CecilTest.pdb | Bin 0 -> 11776 bytes .../Test/Resources/assemblies/ComplexPdb.cs | 71 + .../Test/Resources/assemblies/ComplexPdb.dll | Bin 0 -> 7680 bytes .../Test/Resources/assemblies/ComplexPdb.pdb | Bin 0 -> 15872 bytes .../assemblies/EmptyRootNamespace.dll | Bin 0 -> 7168 bytes .../assemblies/EmptyRootNamespace.pdb | Bin 0 -> 19968 bytes .../Test/Resources/assemblies/FSharp.Core.dll | Bin 0 -> 898904 bytes .../Resources/assemblies/MixedNativeCLI.exe | Bin 0 -> 34816 bytes .../assemblies/MixedNativeCLI.exe.metagen | 5 + .../Resources/assemblies/MixedNativeCLI.pdb | Bin 0 -> 847872 bytes .../Test/Resources/assemblies/PdbTarget.exe | Bin 0 -> 10240 bytes .../Test/Resources/assemblies/PdbTarget.pdb | Bin 0 -> 1692 bytes .../Test/Resources/assemblies/VBConsApp.exe | Bin 0 -> 15360 bytes .../Test/Resources/assemblies/VBConsApp.pdb | Bin 0 -> 36352 bytes .../Resources/assemblies/empty-iterator.dll | Bin 0 -> 4608 bytes .../Resources/assemblies/empty-iterator.pdb | Bin 0 -> 11776 bytes .../pdb/Test/Resources/assemblies/fsapp.exe | Bin 0 -> 5120 bytes .../pdb/Test/Resources/assemblies/fsapp.pdb | Bin 0 -> 11776 bytes .../Resources/assemblies/longtypename.dll | Bin 0 -> 4096 bytes .../Resources/assemblies/longtypename.pdb | Bin 0 -> 11776 bytes .../pdb/Test/Resources/assemblies/test.exe | Bin 0 -> 4096 bytes .../pdb/Test/Resources/assemblies/test.pdb | Bin 0 -> 11776 bytes 421 files changed, 57327 insertions(+), 18 deletions(-) create mode 100644 ArchUnitNet.Reflect/Implementation/AssemblyDefinition.cs create mode 100644 ArchUnitNet.Reflect/Implementation/ModuleDefinition.cs create mode 100644 ArchUnitNet.Reflect/Mono.Cecil.Reflect.csproj create mode 100644 SampleTest/GlobalUsings.cs create mode 100644 SampleTest/SampleTest.csproj create mode 100644 SampleTest/UnitTest1.cs create mode 100644 Test/DefectsDataTable.cs create mode 100644 Test/Test.csproj create mode 100644 cecil-master/.editorconfig create mode 100644 cecil-master/.gitattributes create mode 100644 cecil-master/.github/FUNDING.yml create mode 100644 cecil-master/.github/workflows/main.yml create mode 100644 cecil-master/.gitignore create mode 100644 cecil-master/Directory.Build.props create mode 100644 cecil-master/LICENSE.txt create mode 100644 cecil-master/Mono.Cecil.Cil/Code.cs create mode 100644 cecil-master/Mono.Cecil.Cil/CodeReader.cs create mode 100644 cecil-master/Mono.Cecil.Cil/CodeWriter.cs create mode 100644 cecil-master/Mono.Cecil.Cil/Document.cs create mode 100644 cecil-master/Mono.Cecil.Cil/ExceptionHandler.cs create mode 100644 cecil-master/Mono.Cecil.Cil/ILProcessor.cs create mode 100644 cecil-master/Mono.Cecil.Cil/Instruction.cs create mode 100644 cecil-master/Mono.Cecil.Cil/MethodBody.cs create mode 100644 cecil-master/Mono.Cecil.Cil/OpCode.cs create mode 100644 cecil-master/Mono.Cecil.Cil/OpCodes.cs create mode 100644 cecil-master/Mono.Cecil.Cil/PortablePdb.cs create mode 100644 cecil-master/Mono.Cecil.Cil/SequencePoint.cs create mode 100644 cecil-master/Mono.Cecil.Cil/Symbols.cs create mode 100644 cecil-master/Mono.Cecil.Cil/VariableDefinition.cs create mode 100644 cecil-master/Mono.Cecil.Cil/VariableReference.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/BlobHeap.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/Buffers.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/CodedIndex.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/ElementType.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/GuidHeap.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/Heap.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/MetadataToken.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/PdbHeap.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/Row.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/StringHeap.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/TableHeap.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/TokenType.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/UserStringHeap.cs create mode 100644 cecil-master/Mono.Cecil.Metadata/Utilities.cs create mode 100644 cecil-master/Mono.Cecil.PE/BinaryStreamReader.cs create mode 100644 cecil-master/Mono.Cecil.PE/BinaryStreamWriter.cs create mode 100644 cecil-master/Mono.Cecil.PE/ByteBuffer.cs create mode 100644 cecil-master/Mono.Cecil.PE/ByteBufferEqualityComparer.cs create mode 100644 cecil-master/Mono.Cecil.PE/DataDirectory.cs create mode 100644 cecil-master/Mono.Cecil.PE/Image.cs create mode 100644 cecil-master/Mono.Cecil.PE/ImageReader.cs create mode 100644 cecil-master/Mono.Cecil.PE/ImageWriter.cs create mode 100644 cecil-master/Mono.Cecil.PE/Section.cs create mode 100644 cecil-master/Mono.Cecil.PE/TextMap.cs create mode 100644 cecil-master/Mono.Cecil.Tests.props create mode 100644 cecil-master/Mono.Cecil.csproj create mode 100644 cecil-master/Mono.Cecil.nunit create mode 100644 cecil-master/Mono.Cecil.nuspec create mode 100644 cecil-master/Mono.Cecil.sln create mode 100644 cecil-master/Mono.Cecil/ArrayType.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyDefinition.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyFlags.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyHashAlgorithm.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyInfo.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyLinkedResource.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyNameDefinition.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyNameReference.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyReader.cs create mode 100644 cecil-master/Mono.Cecil/AssemblyWriter.cs create mode 100644 cecil-master/Mono.Cecil/BaseAssemblyResolver.cs create mode 100644 cecil-master/Mono.Cecil/CallSite.cs create mode 100644 cecil-master/Mono.Cecil/Consts.cs create mode 100644 cecil-master/Mono.Cecil/CustomAttribute.cs create mode 100644 cecil-master/Mono.Cecil/DefaultAssemblyResolver.cs create mode 100644 cecil-master/Mono.Cecil/EmbeddedResource.cs create mode 100644 cecil-master/Mono.Cecil/EventAttributes.cs create mode 100644 cecil-master/Mono.Cecil/EventDefinition.cs create mode 100644 cecil-master/Mono.Cecil/EventReference.cs create mode 100644 cecil-master/Mono.Cecil/ExportedType.cs create mode 100644 cecil-master/Mono.Cecil/FieldAttributes.cs create mode 100644 cecil-master/Mono.Cecil/FieldDefinition.cs create mode 100644 cecil-master/Mono.Cecil/FieldReference.cs create mode 100644 cecil-master/Mono.Cecil/FileAttributes.cs create mode 100644 cecil-master/Mono.Cecil/FunctionPointerType.cs create mode 100644 cecil-master/Mono.Cecil/GenericInstanceMethod.cs create mode 100644 cecil-master/Mono.Cecil/GenericInstanceType.cs create mode 100644 cecil-master/Mono.Cecil/GenericParameter.cs create mode 100644 cecil-master/Mono.Cecil/GenericParameterAttributes.cs create mode 100644 cecil-master/Mono.Cecil/GenericParameterResolver.cs create mode 100644 cecil-master/Mono.Cecil/IConstantProvider.cs create mode 100644 cecil-master/Mono.Cecil/ICustomAttributeProvider.cs create mode 100644 cecil-master/Mono.Cecil/IGenericInstance.cs create mode 100644 cecil-master/Mono.Cecil/IGenericParameterProvider.cs create mode 100644 cecil-master/Mono.Cecil/IMarshalInfoProvider.cs create mode 100644 cecil-master/Mono.Cecil/IMemberDefinition.cs create mode 100644 cecil-master/Mono.Cecil/IMetadataScope.cs create mode 100644 cecil-master/Mono.Cecil/IMetadataTokenProvider.cs create mode 100644 cecil-master/Mono.Cecil/IMethodSignature.cs create mode 100644 cecil-master/Mono.Cecil/Import.cs create mode 100644 cecil-master/Mono.Cecil/LinkedResource.cs create mode 100644 cecil-master/Mono.Cecil/ManifestResourceAttributes.cs create mode 100644 cecil-master/Mono.Cecil/MarshalInfo.cs create mode 100644 cecil-master/Mono.Cecil/MemberDefinitionCollection.cs create mode 100644 cecil-master/Mono.Cecil/MemberReference.cs create mode 100644 cecil-master/Mono.Cecil/MetadataResolver.cs create mode 100644 cecil-master/Mono.Cecil/MetadataSystem.cs create mode 100644 cecil-master/Mono.Cecil/MethodAttributes.cs create mode 100644 cecil-master/Mono.Cecil/MethodCallingConvention.cs create mode 100644 cecil-master/Mono.Cecil/MethodDefinition.cs create mode 100644 cecil-master/Mono.Cecil/MethodImplAttributes.cs create mode 100644 cecil-master/Mono.Cecil/MethodReference.cs create mode 100644 cecil-master/Mono.Cecil/MethodReferenceComparer.cs create mode 100644 cecil-master/Mono.Cecil/MethodReturnType.cs create mode 100644 cecil-master/Mono.Cecil/MethodSemanticsAttributes.cs create mode 100644 cecil-master/Mono.Cecil/MethodSpecification.cs create mode 100644 cecil-master/Mono.Cecil/Modifiers.cs create mode 100644 cecil-master/Mono.Cecil/ModuleDefinition.cs create mode 100644 cecil-master/Mono.Cecil/ModuleKind.cs create mode 100644 cecil-master/Mono.Cecil/ModuleReference.cs create mode 100644 cecil-master/Mono.Cecil/NativeType.cs create mode 100644 cecil-master/Mono.Cecil/PInvokeAttributes.cs create mode 100644 cecil-master/Mono.Cecil/PInvokeInfo.cs create mode 100644 cecil-master/Mono.Cecil/ParameterAttributes.cs create mode 100644 cecil-master/Mono.Cecil/ParameterDefinition.cs create mode 100644 cecil-master/Mono.Cecil/ParameterDefinitionCollection.cs create mode 100644 cecil-master/Mono.Cecil/ParameterReference.cs create mode 100644 cecil-master/Mono.Cecil/PinnedType.cs create mode 100644 cecil-master/Mono.Cecil/PointerType.cs create mode 100644 cecil-master/Mono.Cecil/PropertyAttributes.cs create mode 100644 cecil-master/Mono.Cecil/PropertyDefinition.cs create mode 100644 cecil-master/Mono.Cecil/PropertyReference.cs create mode 100644 cecil-master/Mono.Cecil/ReferenceType.cs create mode 100644 cecil-master/Mono.Cecil/Resource.cs create mode 100644 cecil-master/Mono.Cecil/SecurityDeclaration.cs create mode 100644 cecil-master/Mono.Cecil/SentinelType.cs create mode 100644 cecil-master/Mono.Cecil/TargetRuntime.cs create mode 100644 cecil-master/Mono.Cecil/Treatments.cs create mode 100644 cecil-master/Mono.Cecil/TypeAttributes.cs create mode 100644 cecil-master/Mono.Cecil/TypeComparisonMode.cs create mode 100644 cecil-master/Mono.Cecil/TypeDefinition.cs create mode 100644 cecil-master/Mono.Cecil/TypeDefinitionCollection.cs create mode 100644 cecil-master/Mono.Cecil/TypeParser.cs create mode 100644 cecil-master/Mono.Cecil/TypeReference.cs create mode 100644 cecil-master/Mono.Cecil/TypeReferenceEqualityComparer.cs create mode 100644 cecil-master/Mono.Cecil/TypeResolver.cs create mode 100644 cecil-master/Mono.Cecil/TypeSpecification.cs create mode 100644 cecil-master/Mono.Cecil/TypeSystem.cs create mode 100644 cecil-master/Mono.Cecil/VariantType.cs create mode 100644 cecil-master/Mono.Cecil/WindowsRuntimeProjections.cs create mode 100644 cecil-master/Mono.Collections.Generic/Collection.cs create mode 100644 cecil-master/Mono.Collections.Generic/ReadOnlyCollection.cs create mode 100644 cecil-master/Mono.Security.Cryptography/CryptoConvert.cs create mode 100644 cecil-master/Mono.Security.Cryptography/CryptoService.cs create mode 100644 cecil-master/Mono/Disposable.cs create mode 100644 cecil-master/Mono/Empty.cs create mode 100644 cecil-master/Mono/MergeSort.cs create mode 100644 cecil-master/ProjectInfo.cs create mode 100644 cecil-master/README.md create mode 100644 cecil-master/Test/Mono.Cecil.Tests.csproj create mode 100644 cecil-master/Test/Mono.Cecil.Tests/AssemblyInfo.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/AssemblyTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/BaseTestFixture.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/CompilationService.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/CustomAttributesTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/EventTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/Extensions.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/FieldTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/Formatter.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/ILProcessorTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/ImageReadTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/ImportCecilTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/ImportReflectionTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/LoadAssemblyDefinitionForTestsBaseSimple.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/MethodBodyTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/MethodReferenceComparerTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/MethodTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/ModuleTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/NestedTypesTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/ParameterTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/PortablePdbTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/PropertyTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/ResolveTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/SymbolTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/TypeDefinitionUtils.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/TypeParserTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/TypeReferenceComparisonTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/TypeTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/VariableTests.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs create mode 100644 cecil-master/Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs create mode 100644 cecil-master/Test/Resources/assemblies/Deterministic.dll create mode 100644 cecil-master/Test/Resources/assemblies/EmbeddedCompressedPdbTarget.exe create mode 100644 cecil-master/Test/Resources/assemblies/EmbeddedPdbChecksumLib.dll create mode 100644 cecil-master/Test/Resources/assemblies/EmbeddedPdbDeterministic.dll create mode 100644 cecil-master/Test/Resources/assemblies/EmbeddedPdbTarget.exe create mode 100644 cecil-master/Test/Resources/assemblies/EmptyPdb.dll create mode 100644 cecil-master/Test/Resources/assemblies/EmptyPdb.pdb create mode 100644 cecil-master/Test/Resources/assemblies/ExternalPdbDeterministic.dll create mode 100644 cecil-master/Test/Resources/assemblies/ExternalPdbDeterministic.pdb create mode 100644 cecil-master/Test/Resources/assemblies/FSharp.Core.dll create mode 100644 cecil-master/Test/Resources/assemblies/GenericAttributes.dll create mode 100644 cecil-master/Test/Resources/assemblies/GenericParameterConstraintAttributes.dll create mode 100644 cecil-master/Test/Resources/assemblies/Issue697.dll create mode 100644 cecil-master/Test/Resources/assemblies/Issue697.dll.mdb create mode 100644 cecil-master/Test/Resources/assemblies/LocallyScopedConstantArray.dll create mode 100644 cecil-master/Test/Resources/assemblies/LocallyScopedConstantArray.pdb create mode 100644 cecil-master/Test/Resources/assemblies/ManagedWinmd.winmd create mode 100644 cecil-master/Test/Resources/assemblies/Mono.Android.dll create mode 100644 cecil-master/Test/Resources/assemblies/Mono.Android.pdb create mode 100644 cecil-master/Test/Resources/assemblies/NativeWinmd.winmd create mode 100644 cecil-master/Test/Resources/assemblies/NullConst.dll create mode 100644 cecil-master/Test/Resources/assemblies/NullConst.pdb create mode 100644 cecil-master/Test/Resources/assemblies/PdbChecksumLib.dll create mode 100644 cecil-master/Test/Resources/assemblies/PdbChecksumLib.pdb create mode 100644 cecil-master/Test/Resources/assemblies/PdbTarget.exe create mode 100644 cecil-master/Test/Resources/assemblies/PdbTarget.pdb create mode 100644 cecil-master/Test/Resources/assemblies/PortableClassLibrary.dll create mode 100644 cecil-master/Test/Resources/assemblies/ReproConstGenericInst.dll create mode 100644 cecil-master/Test/Resources/assemblies/ReproConstGenericInst.pdb create mode 100644 cecil-master/Test/Resources/assemblies/RetargetableExample.dll create mode 100644 cecil-master/Test/Resources/assemblies/SQLite-net.dll create mode 100644 cecil-master/Test/Resources/assemblies/SQLite-net.dll.mdb create mode 100644 cecil-master/Test/Resources/assemblies/System.Private.Xml.dll create mode 100644 cecil-master/Test/Resources/assemblies/System.Private.Xml.pdb create mode 100644 cecil-master/Test/Resources/assemblies/System.Runtime.dll create mode 100644 cecil-master/Test/Resources/assemblies/TargetLib.dll create mode 100644 cecil-master/Test/Resources/assemblies/TargetLib.pdb create mode 100644 cecil-master/Test/Resources/assemblies/anycpu32bitpreferred.exe create mode 100644 cecil-master/Test/Resources/assemblies/boxedoptarg.dll create mode 100644 cecil-master/Test/Resources/assemblies/bug-185.dll create mode 100644 cecil-master/Test/Resources/assemblies/catch.exe create mode 100644 cecil-master/Test/Resources/assemblies/cecil.dll create mode 100644 cecil-master/Test/Resources/assemblies/cecil.pdb create mode 100644 cecil-master/Test/Resources/assemblies/cppcli.dll create mode 100644 cecil-master/Test/Resources/assemblies/cscgpbug.dll create mode 100644 cecil-master/Test/Resources/assemblies/decsec-att.dll create mode 100644 cecil-master/Test/Resources/assemblies/decsec-xml.dll create mode 100644 cecil-master/Test/Resources/assemblies/decsec1-xml.dll create mode 100644 cecil-master/Test/Resources/assemblies/delay-signed.dll create mode 100644 cecil-master/Test/Resources/assemblies/embedcs.exe create mode 100644 cecil-master/Test/Resources/assemblies/embedcs.pdb create mode 100644 cecil-master/Test/Resources/assemblies/empty-decsec-att.dll create mode 100644 cecil-master/Test/Resources/assemblies/empty-str-const.exe create mode 100644 cecil-master/Test/Resources/assemblies/empty-str-const.pdb create mode 100644 cecil-master/Test/Resources/assemblies/foo.dll create mode 100644 cecil-master/Test/Resources/assemblies/fptr.exe create mode 100644 cecil-master/Test/Resources/assemblies/gifaceref.exe create mode 100644 cecil-master/Test/Resources/assemblies/hello.anycpu.exe create mode 100644 cecil-master/Test/Resources/assemblies/hello.exe create mode 100644 cecil-master/Test/Resources/assemblies/hello.ia64.exe create mode 100644 cecil-master/Test/Resources/assemblies/hello.textonly.x64.exe create mode 100644 cecil-master/Test/Resources/assemblies/hello.x64.exe create mode 100644 cecil-master/Test/Resources/assemblies/hello.x86.exe create mode 100644 cecil-master/Test/Resources/assemblies/hello1.exe create mode 100644 cecil-master/Test/Resources/assemblies/hello2.exe create mode 100644 cecil-master/Test/Resources/assemblies/hellow.exe create mode 100644 cecil-master/Test/Resources/assemblies/iterator.exe create mode 100644 cecil-master/Test/Resources/assemblies/libhello.dll create mode 100644 cecil-master/Test/Resources/assemblies/libmdb.dll create mode 100644 cecil-master/Test/Resources/assemblies/libmdb.dll.mdb create mode 100644 cecil-master/Test/Resources/assemblies/libpdb.dll create mode 100644 cecil-master/Test/Resources/assemblies/libpdb.pdb create mode 100644 cecil-master/Test/Resources/assemblies/libres.dll create mode 100644 cecil-master/Test/Resources/assemblies/line.exe create mode 100644 cecil-master/Test/Resources/assemblies/line.pdb create mode 100644 cecil-master/Test/Resources/assemblies/marshal.dll create mode 100644 cecil-master/Test/Resources/assemblies/mdb-mismatch.dll create mode 100644 cecil-master/Test/Resources/assemblies/mdb-mismatch.dll.mdb create mode 100644 cecil-master/Test/Resources/assemblies/metro.exe create mode 100644 cecil-master/Test/Resources/assemblies/mma.exe create mode 100644 cecil-master/Test/Resources/assemblies/moda.netmodule create mode 100644 cecil-master/Test/Resources/assemblies/modb.netmodule create mode 100644 cecil-master/Test/Resources/assemblies/mylib.dll create mode 100644 cecil-master/Test/Resources/assemblies/mylib.pdb create mode 100644 cecil-master/Test/Resources/assemblies/net471.exe create mode 100644 cecil-master/Test/Resources/assemblies/noblob.dll create mode 100644 cecil-master/Test/Resources/assemblies/nullable-constant.exe create mode 100644 cecil-master/Test/Resources/assemblies/nullable-parameter.dll create mode 100644 cecil-master/Test/Resources/assemblies/ordered-attrs.exe create mode 100644 cecil-master/Test/Resources/assemblies/pdb-mismatch.dll create mode 100644 cecil-master/Test/Resources/assemblies/pdb-mismatch.pdb create mode 100644 cecil-master/Test/Resources/assemblies/pinvoke.exe create mode 100644 cecil-master/Test/Resources/assemblies/self-ref-typeref.dll create mode 100644 cecil-master/Test/Resources/assemblies/switch.exe create mode 100644 cecil-master/Test/Resources/assemblies/text_file.txt create mode 100644 cecil-master/Test/Resources/assemblies/varargs.exe create mode 100644 cecil-master/Test/Resources/assemblies/winrtcomp.winmd create mode 100644 cecil-master/Test/Resources/assemblies/wp7.dll create mode 100644 cecil-master/Test/Resources/assemblies/xattr.dll create mode 100644 cecil-master/Test/Resources/assemblies/xattr.pdb create mode 100644 cecil-master/Test/Resources/cs/CustomAttributes.cs create mode 100644 cecil-master/Test/Resources/cs/Events.cs create mode 100644 cecil-master/Test/Resources/cs/Fields.cs create mode 100644 cecil-master/Test/Resources/cs/Generics.cs create mode 100644 cecil-master/Test/Resources/cs/Interfaces.cs create mode 100644 cecil-master/Test/Resources/cs/Layouts.cs create mode 100644 cecil-master/Test/Resources/cs/Methods.cs create mode 100644 cecil-master/Test/Resources/cs/NestedTypes.cs create mode 100644 cecil-master/Test/Resources/cs/Properties.cs create mode 100644 cecil-master/Test/Resources/il/FieldRVAAlignment.il create mode 100644 cecil-master/Test/Resources/il/branch-out.il create mode 100644 cecil-master/Test/Resources/il/ca-empty-blob.il create mode 100644 cecil-master/Test/Resources/il/ca-iface-impl.il create mode 100644 cecil-master/Test/Resources/il/explicitthis.il create mode 100644 cecil-master/Test/Resources/il/hello.il create mode 100644 cecil-master/Test/Resources/il/methodspecs.il create mode 100644 cecil-master/Test/Resources/il/others.il create mode 100644 cecil-master/Test/Resources/il/privatescope.il create mode 100644 cecil-master/Test/Resources/il/types.il create mode 100644 cecil-master/cecil.snk create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks.csproj create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/AssemblyInfo.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/DocCommentId.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/Functional.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/ILParser.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/MethodBodyRocks.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/MethodDefinitionRocks.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/ModuleDefinitionRocks.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/ParameterReferenceRocks.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/SecurityDeclarationRocks.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/TypeDefinitionRocks.cs create mode 100644 cecil-master/rocks/Mono.Cecil.Rocks/TypeReferenceRocks.cs create mode 100644 cecil-master/rocks/Test/Mono.Cecil.Rocks.Tests.csproj create mode 100644 cecil-master/rocks/Test/Mono.Cecil.Tests/DocCommentIdTests.cs create mode 100644 cecil-master/rocks/Test/Mono.Cecil.Tests/MethodDefinitionRocksTests.cs create mode 100644 cecil-master/rocks/Test/Mono.Cecil.Tests/ModuleDefinitionRocksTests.cs create mode 100644 cecil-master/rocks/Test/Mono.Cecil.Tests/SecurityDeclarationRocksTests.cs create mode 100644 cecil-master/rocks/Test/Mono.Cecil.Tests/TypeDefinitionRocksTests.cs create mode 100644 cecil-master/rocks/Test/Mono.Cecil.Tests/TypeReferenceRocksTests.cs create mode 100644 cecil-master/rocks/Test/Resources/assemblies/decsec-att.dll create mode 100644 cecil-master/rocks/Test/Resources/assemblies/decsec-xml.dll create mode 100644 cecil-master/rocks/Test/Resources/cs/Types.cs create mode 100644 cecil-master/symbols/mdb/Mono.Cecil.Mdb.csproj create mode 100644 cecil-master/symbols/mdb/Mono.Cecil.Mdb/AssemblyInfo.cs create mode 100644 cecil-master/symbols/mdb/Mono.Cecil.Mdb/MdbReader.cs create mode 100644 cecil-master/symbols/mdb/Mono.Cecil.Mdb/MdbWriter.cs create mode 100644 cecil-master/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs create mode 100644 cecil-master/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs create mode 100644 cecil-master/symbols/mdb/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs create mode 100644 cecil-master/symbols/mdb/Mono.CompilerServices.SymbolWriter/SourceMethodBuilder.cs create mode 100644 cecil-master/symbols/mdb/Mono.CompilerServices.SymbolWriter/SymbolWriterImpl.cs create mode 100644 cecil-master/symbols/mdb/Test/Mono.Cecil.Mdb.Tests.csproj create mode 100644 cecil-master/symbols/mdb/Test/Mono.Cecil.Tests/MdbTests.cs create mode 100644 cecil-master/symbols/mdb/Test/Resources/assemblies/BreakpointTest.Portable.dll create mode 100644 cecil-master/symbols/mdb/Test/Resources/assemblies/BreakpointTest.Portable.dll.mdb create mode 100644 cecil-master/symbols/mdb/Test/Resources/assemblies/mscorlib.dll create mode 100644 cecil-master/symbols/mdb/Test/Resources/assemblies/mscorlib.dll.mdb create mode 100644 cecil-master/symbols/mdb/Test/Resources/assemblies/simplemdb.exe create mode 100644 cecil-master/symbols/mdb/Test/Resources/assemblies/simplemdb.exe.mdb create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/.editorconfig create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/BitAccess.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/BitSet.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/CvInfo.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/DataStream.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/DbiDbgHdr.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/DbiHeader.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/DbiModuleInfo.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/DbiSecCon.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/IntHashTable.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/Interfaces.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/LICENSE create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/MsfDirectory.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbConstant.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbDebugException.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbException.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbFile.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbFileHeader.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbFunction.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbInfo.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbLine.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbLines.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbReader.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbScope.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbSlot.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbSource.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/PdbTokenLine.cs create mode 100644 cecil-master/symbols/pdb/Microsoft.Cci.Pdb/SourceLocationProvider.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb.csproj create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/AssemblyInfo.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/ISymUnmanagedDocumentWriter.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/ISymUnmanagedWriter2.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/ModuleMetadata.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/NativePdbReader.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/NativePdbWriter.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/PdbHelper.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/SymDocumentWriter.cs create mode 100644 cecil-master/symbols/pdb/Mono.Cecil.Pdb/SymWriter.cs create mode 100644 cecil-master/symbols/pdb/Test/Mono.Cecil.Pdb.Tests.csproj create mode 100644 cecil-master/symbols/pdb/Test/Mono.Cecil.Tests/PdbTests.cs create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/AVbTest.exe create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/AVbTest.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/CecilTest.exe create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/CecilTest.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/ComplexPdb.cs create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/ComplexPdb.dll create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/ComplexPdb.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/EmptyRootNamespace.dll create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/EmptyRootNamespace.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/FSharp.Core.dll create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/MixedNativeCLI.exe create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/MixedNativeCLI.exe.metagen create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/MixedNativeCLI.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/PdbTarget.exe create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/PdbTarget.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/VBConsApp.exe create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/VBConsApp.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/empty-iterator.dll create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/empty-iterator.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/fsapp.exe create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/fsapp.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/longtypename.dll create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/longtypename.pdb create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/test.exe create mode 100644 cecil-master/symbols/pdb/Test/Resources/assemblies/test.pdb diff --git a/ArchUnit.sln b/ArchUnit.sln index 3b3af5240..11d239618 100644 --- a/ArchUnit.sln +++ b/ArchUnit.sln @@ -1,6 +1,7 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.26430.16 + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34322.80 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestAssembly", "TestAssembly\TestAssembly.csproj", "{7DEF5F34-AB86-457B-819D-5E7387B3FF87}" EndProject @@ -16,9 +17,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchUnitNET.NUnit", "ArchUn EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchUnitNET.NUnitTests", "ArchUnitNET.NUnitTests\ArchUnitNET.NUnitTests.csproj", "{D2AB683F-0A64-491E-9C56-EE98588C493C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchUnitNET.MSTestV2", "ArchUnitNET.MSTestV2\ArchUnitNET.MSTestV2.csproj", "{3D057987-358A-41C6-AF55-6490FCA5875F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchUnitNET.MSTestV2", "ArchUnitNET.MSTestV2\ArchUnitNET.MSTestV2.csproj", "{3D057987-358A-41C6-AF55-6490FCA5875F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArchUnitNET.MSTestV2Tests", "ArchUnitNET.MSTestV2Tests\ArchUnitNET.MSTestV2Tests.csproj", "{6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchUnitNET.MSTestV2Tests", "ArchUnitNET.MSTestV2Tests\ArchUnitNET.MSTestV2Tests.csproj", "{6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil", "cecil-master\Mono.Cecil.csproj", "{7F718811-A5EE-4CDA-899E-DE27B515958C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil.Reflect", "ArchUnitNet.Reflect\Mono.Cecil.Reflect.csproj", "{0E3B9BEB-4022-43E3-81F7-152E84ADBB14}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{52B2170E-3C69-4DB1-9571-968BEE82C972}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SampleTest", "SampleTest\SampleTest.csproj", "{C608CC12-A59B-40C7-ADDC-EB150D4C344C}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -62,8 +71,27 @@ Global {6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}.Debug|Any CPU.Build.0 = Debug|Any CPU {6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}.Release|Any CPU.ActiveCfg = Release|Any CPU {6D6B6EFE-DA0B-4C4D-B710-FA658F0C68CF}.Release|Any CPU.Build.0 = Release|Any CPU + {7F718811-A5EE-4CDA-899E-DE27B515958C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F718811-A5EE-4CDA-899E-DE27B515958C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F718811-A5EE-4CDA-899E-DE27B515958C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F718811-A5EE-4CDA-899E-DE27B515958C}.Release|Any CPU.Build.0 = Release|Any CPU + {0E3B9BEB-4022-43E3-81F7-152E84ADBB14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E3B9BEB-4022-43E3-81F7-152E84ADBB14}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E3B9BEB-4022-43E3-81F7-152E84ADBB14}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E3B9BEB-4022-43E3-81F7-152E84ADBB14}.Release|Any CPU.Build.0 = Release|Any CPU + {52B2170E-3C69-4DB1-9571-968BEE82C972}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {52B2170E-3C69-4DB1-9571-968BEE82C972}.Debug|Any CPU.Build.0 = Debug|Any CPU + {52B2170E-3C69-4DB1-9571-968BEE82C972}.Release|Any CPU.ActiveCfg = Release|Any CPU + {52B2170E-3C69-4DB1-9571-968BEE82C972}.Release|Any CPU.Build.0 = Release|Any CPU + {C608CC12-A59B-40C7-ADDC-EB150D4C344C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C608CC12-A59B-40C7-ADDC-EB150D4C344C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C608CC12-A59B-40C7-ADDC-EB150D4C344C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C608CC12-A59B-40C7-ADDC-EB150D4C344C}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {74FB825E-09C7-484D-8EBB-C42E195505A9} + EndGlobalSection EndGlobal diff --git a/ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj b/ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj index 8c3c4cc7e..7f45522ae 100644 --- a/ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj +++ b/ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0 true ArchUnit C# MSTestV2 Extension Florian Gather, Fritz Brandhuber diff --git a/ArchUnitNET.NUnit/ArchUnitNET.NUnit.csproj b/ArchUnitNET.NUnit/ArchUnitNET.NUnit.csproj index 73b8f6b88..4c4dcae2e 100644 --- a/ArchUnitNET.NUnit/ArchUnitNET.NUnit.csproj +++ b/ArchUnitNET.NUnit/ArchUnitNET.NUnit.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0 true ArchUnit C# NUnit Extension Florian Gather, Fritz Brandhuber diff --git a/ArchUnitNET.xUnit/ArchUnitNET.xUnit.csproj b/ArchUnitNET.xUnit/ArchUnitNET.xUnit.csproj index 11fb4d373..7723c1aef 100644 --- a/ArchUnitNET.xUnit/ArchUnitNET.xUnit.csproj +++ b/ArchUnitNET.xUnit/ArchUnitNET.xUnit.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0 true ArchUnit C# xUnit Extension Florian Gather, Fritz Brandhuber diff --git a/ArchUnitNET/ArchUnitNET.csproj b/ArchUnitNET/ArchUnitNET.csproj index 27c0e10d6..b0f9b623b 100644 --- a/ArchUnitNET/ArchUnitNET.csproj +++ b/ArchUnitNET/ArchUnitNET.csproj @@ -1,7 +1,7 @@  - netstandard2.0;net45 + netstandard2.0 true ArchUnitNET TngTech.ArchUnitNET @@ -18,18 +18,25 @@ README.md + + False + + + + + + + + + - - - - - + + + - - - + diff --git a/ArchUnitNet.Reflect/Implementation/AssemblyDefinition.cs b/ArchUnitNet.Reflect/Implementation/AssemblyDefinition.cs new file mode 100644 index 000000000..de92c1936 --- /dev/null +++ b/ArchUnitNet.Reflect/Implementation/AssemblyDefinition.cs @@ -0,0 +1,9 @@ +using System; + +namespace Mono.Cecil.Reflect +{ + public class AssemblyDefinition + { + + } +} diff --git a/ArchUnitNet.Reflect/Implementation/ModuleDefinition.cs b/ArchUnitNet.Reflect/Implementation/ModuleDefinition.cs new file mode 100644 index 000000000..4b731bd34 --- /dev/null +++ b/ArchUnitNet.Reflect/Implementation/ModuleDefinition.cs @@ -0,0 +1,10 @@ +namespace Mono.Cecil.Reflect +{ + public sealed class ModuleDefinition + { + public static ModuleDefinition ReadModule(string fileName, ReaderParameters parameters) + { + return null; + } + } +} diff --git a/ArchUnitNet.Reflect/Mono.Cecil.Reflect.csproj b/ArchUnitNet.Reflect/Mono.Cecil.Reflect.csproj new file mode 100644 index 000000000..36e6d1852 --- /dev/null +++ b/ArchUnitNet.Reflect/Mono.Cecil.Reflect.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.0 + + + + + + + + + + + diff --git a/SampleTest/GlobalUsings.cs b/SampleTest/GlobalUsings.cs new file mode 100644 index 000000000..cefced496 --- /dev/null +++ b/SampleTest/GlobalUsings.cs @@ -0,0 +1 @@ +global using NUnit.Framework; \ No newline at end of file diff --git a/SampleTest/SampleTest.csproj b/SampleTest/SampleTest.csproj new file mode 100644 index 000000000..e6479f9cc --- /dev/null +++ b/SampleTest/SampleTest.csproj @@ -0,0 +1,25 @@ + + + + net6.0 + enable + enable + + false + true + + + + + + + + + + + + + + + + diff --git a/SampleTest/UnitTest1.cs b/SampleTest/UnitTest1.cs new file mode 100644 index 000000000..755dbb4b9 --- /dev/null +++ b/SampleTest/UnitTest1.cs @@ -0,0 +1,22 @@ +using ArchUnitNET.Domain; +using ArchUnitNET.Loader; +using System.Reflection; + +namespace SampleTest +{ + public class Tests + { + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Architecture ChefArchitecture = + new ArchLoader().LoadAssemblies(System.Reflection.Assembly.Load("Test")).Build(); + Assert.Pass(); + } + } +} \ No newline at end of file diff --git a/Test/DefectsDataTable.cs b/Test/DefectsDataTable.cs new file mode 100644 index 000000000..a7cb33109 --- /dev/null +++ b/Test/DefectsDataTable.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System; +using System.ComponentModel; +using System.Data; +using System.IO; + +namespace Test +{ + public class DefectsDataTable:DataTable + { + public string Name; + string path; + IContainer container; + JsonSerializer serializer= new JsonSerializer(); + + public DefectsDataTable() + { + + } + + public void addPath(string path) + { + this.path = Path.GetFullPath(path); + } + } +} diff --git a/Test/Test.csproj b/Test/Test.csproj new file mode 100644 index 000000000..99af7d118 --- /dev/null +++ b/Test/Test.csproj @@ -0,0 +1,11 @@ + + + + net6.0 + + + + + + + diff --git a/TestAssembly/TestAssembly.csproj b/TestAssembly/TestAssembly.csproj index a451d5625..6152a255e 100644 --- a/TestAssembly/TestAssembly.csproj +++ b/TestAssembly/TestAssembly.csproj @@ -1,6 +1,6 @@  - net5.0 + net6.0 Latest false TestAssembly diff --git a/cecil-master/.editorconfig b/cecil-master/.editorconfig new file mode 100644 index 000000000..e1d9b64ea --- /dev/null +++ b/cecil-master/.editorconfig @@ -0,0 +1,23 @@ +# top-most EditorConfig file +root = true + +[*.cs] +indent_style = tab +csharp_space_between_method_declaration_name_and_open_parenthesis = true +csharp_space_between_method_call_name_and_opening_parenthesis = true +csharp_space_before_open_square_brackets = true +csharp_new_line_before_open_brace = methods +csharp_new_line_before_else = false +csharp_indent_switch_labels = false + +trim_trailing_whitespace = false + +dotnet_naming_symbols.fields_locals_and_parameters.applicable_kinds = field, local, parameter +dotnet_naming_symbols.fields_locals_and_parameters.applicable_accessibilities = * + +dotnet_naming_style.snake_case.capitalization = all_lower +dotnet_naming_style.snake_case.word_separator = _ + +dotnet_naming_rule.fields_locals_and_parameters_use_snake_case.symbols = fields_locals_and_parameters +dotnet_naming_rule.fields_locals_and_parameters_use_snake_case.style = snake_case +dotnet_naming_rule.fields_locals_and_parameters_use_snake_case.severity = suggestion diff --git a/cecil-master/.gitattributes b/cecil-master/.gitattributes new file mode 100644 index 000000000..c87ac422f --- /dev/null +++ b/cecil-master/.gitattributes @@ -0,0 +1,8 @@ +* text=auto + +.md text +.cs text + +.sln text=crlf +.*proj text=crlf +.settings text=crlf diff --git a/cecil-master/.github/FUNDING.yml b/cecil-master/.github/FUNDING.yml new file mode 100644 index 000000000..2490d7939 --- /dev/null +++ b/cecil-master/.github/FUNDING.yml @@ -0,0 +1 @@ +github: jbevain diff --git a/cecil-master/.github/workflows/main.yml b/cecil-master/.github/workflows/main.yml new file mode 100644 index 000000000..638176463 --- /dev/null +++ b/cecil-master/.github/workflows/main.yml @@ -0,0 +1,35 @@ +name: CI + +on: + push: + branches: + - master + - release/* + pull_request: + branches: + - master + - release/* + +jobs: + windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v1 + - name: Build + run: dotnet build -c Debug Mono.Cecil.sln + - name: Test + run: dotnet test --no-build -c Debug Mono.Cecil.sln + linux: + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v1 + - name: Build + run: dotnet build -c Debug Mono.Cecil.sln + - name: Test .NET Core + run: dotnet test --no-build -c Debug Mono.Cecil.sln + - name: Get NuGet + run: curl -o ./nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe + - name: Get NUnit.Console + run: mono ./nuget.exe install NUnit.Console -Version 3.9.0 -OutputDirectory ./packages + - name: Test .NET 4.0 using Mono + run: mono ./packages/NUnit.ConsoleRunner.3.9.0/tools/nunit3-console.exe ./Mono.Cecil.nunit diff --git a/cecil-master/.gitignore b/cecil-master/.gitignore new file mode 100644 index 000000000..956178e31 --- /dev/null +++ b/cecil-master/.gitignore @@ -0,0 +1,18 @@ +bin +obj +*.suo +*.iml +*.user +*.pidb +*.userprefs +*.xml +*.nupkg +**/test-results/* +*Resharper* +Mono.Cecil.sln.ide* +TestResults +project.lock.json +.vs/ +.idea/ +packages/* +nuget.exe diff --git a/cecil-master/Directory.Build.props b/cecil-master/Directory.Build.props new file mode 100644 index 000000000..85dfd1d04 --- /dev/null +++ b/cecil-master/Directory.Build.props @@ -0,0 +1,30 @@ + + + false + false + false + Debug;Release + true + true + $(MSBuildThisFileDirectory)\cecil.snk + $(DefineConstants);NET_CORE + + + + true + + + + + + + + + + + + + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), Mono.Cecil.overrides))\Mono.Cecil.overrides + + + diff --git a/cecil-master/LICENSE.txt b/cecil-master/LICENSE.txt new file mode 100644 index 000000000..afd0ae681 --- /dev/null +++ b/cecil-master/LICENSE.txt @@ -0,0 +1,21 @@ +Copyright (c) 2008 - 2015 Jb Evain +Copyright (c) 2008 - 2011 Novell, Inc. + +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. diff --git a/cecil-master/Mono.Cecil.Cil/Code.cs b/cecil-master/Mono.Cecil.Cil/Code.cs new file mode 100644 index 000000000..cd929fcc3 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/Code.cs @@ -0,0 +1,234 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil.Cil/CodeReader.cs b/cecil-master/Mono.Cecil.Cil/CodeReader.cs new file mode 100644 index 000000000..89515d688 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/CodeReader.cs @@ -0,0 +1,666 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +using Mono.Cecil.PE; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil.Cil { + + sealed class CodeReader : BinaryStreamReader { + + readonly internal MetadataReader reader; + + int start; + + MethodDefinition method; + MethodBody body; + + int Offset { + get { return Position - start; } + } + + public CodeReader (MetadataReader reader) + : base (reader.image.Stream.value) + { + this.reader = reader; + } + + public int MoveTo (MethodDefinition method) + { + this.method = method; + this.reader.context = method; + var position = this.Position; + this.Position = (int) reader.image.ResolveVirtualAddress ((uint) method.RVA); + return position; + } + + public void MoveBackTo (int position) + { + this.reader.context = null; + this.Position = position; + } + + public MethodBody ReadMethodBody (MethodDefinition method) + { + var position = MoveTo (method); + this.body = new MethodBody (method); + + ReadMethodBody (); + + MoveBackTo (position); + return this.body; + } + + public int ReadCodeSize (MethodDefinition method) + { + var position = MoveTo (method); + + var code_size = ReadCodeSize (); + + MoveBackTo (position); + return code_size; + } + + int ReadCodeSize () + { + var flags = ReadByte (); + switch (flags & 0x3) { + case 0x2: // tiny + return flags >> 2; + case 0x3: // fat + Advance (-1 + 2 + 2); // go back, 2 bytes flags, 2 bytes stack size + return (int) ReadUInt32 (); + default: + throw new InvalidOperationException (); + } + } + + void ReadMethodBody () + { + var flags = ReadByte (); + switch (flags & 0x3) { + case 0x2: // tiny + body.code_size = flags >> 2; + body.MaxStackSize = 8; + ReadCode (); + break; + case 0x3: // fat + Advance (-1); + ReadFatMethod (); + break; + default: + throw new InvalidOperationException (); + } + + var symbol_reader = reader.module.symbol_reader; + + if (symbol_reader != null && method.debug_info == null) + method.debug_info = symbol_reader.Read (method); + + if (method.debug_info != null) + ReadDebugInfo (); + } + + 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, method); + reader.position = position; + + return variables; + } + + void ReadCode () + { + start = Position; + var code_size = body.code_size; + + if (code_size < 0 || Length <= (uint) (code_size + Position)) + code_size = 0; + + var end = start + code_size; + var instructions = body.instructions = new InstructionCollection (method, (code_size + 1) / 2); + + while (Position < end) { + var offset = 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 body.GetParameter (index); + } + + public VariableDefinition GetVariable (int index) + { + return body.GetVariable (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 () + { + Advance (-1); + 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; + } + } + + public MetadataToken ReadToken () + { + return new MetadataToken (ReadUInt32 ()); + } + + void ReadDebugInfo () + { + if (method.debug_info.sequence_points != null) + ReadSequencePoints (); + + if (method.debug_info.scope != null) + ReadScope (method.debug_info.scope); + + if (method.custom_infos != null) + ReadCustomDebugInformations (method); + } + + void ReadCustomDebugInformations (MethodDefinition method) + { + var custom_infos = method.custom_infos; + + for (int i = 0; i < custom_infos.Count; i++) { + var state_machine_scope = custom_infos [i] as StateMachineScopeDebugInformation; + if (state_machine_scope != null) + ReadStateMachineScope (state_machine_scope); + + var async_method = custom_infos [i] as AsyncMethodBodyDebugInformation; + if (async_method != null) + ReadAsyncMethodBody (async_method); + } + } + + void ReadAsyncMethodBody (AsyncMethodBodyDebugInformation async_method) + { + if (async_method.catch_handler.Offset > -1) + async_method.catch_handler = new InstructionOffset (GetInstruction (async_method.catch_handler.Offset)); + + if (!async_method.yields.IsNullOrEmpty ()) + for (int i = 0; i < async_method.yields.Count; i++) + async_method.yields [i] = new InstructionOffset (GetInstruction (async_method.yields [i].Offset)); + + if (!async_method.resumes.IsNullOrEmpty ()) + for (int i = 0; i < async_method.resumes.Count; i++) + async_method.resumes [i] = new InstructionOffset (GetInstruction (async_method.resumes [i].Offset)); + } + + void ReadStateMachineScope (StateMachineScopeDebugInformation state_machine_scope) + { + if (state_machine_scope.scopes.IsNullOrEmpty ()) + return; + + foreach (var scope in state_machine_scope.scopes) { + scope.start = new InstructionOffset (GetInstruction (scope.start.Offset)); + + var end_instruction = GetInstruction (scope.end.Offset); + scope.end = end_instruction == null + ? new InstructionOffset () + : new InstructionOffset (end_instruction); + } + } + + void ReadSequencePoints () + { + var symbol = method.debug_info; + + for (int i = 0; i < symbol.sequence_points.Count; i++) { + var sequence_point = symbol.sequence_points [i]; + var instruction = GetInstruction (sequence_point.Offset); + if (instruction != null) + sequence_point.offset = new InstructionOffset (instruction); + } + } + + void ReadScopes (Collection scopes) + { + for (int i = 0; i < scopes.Count; i++) + ReadScope (scopes [i]); + } + + void ReadScope (ScopeDebugInformation scope) + { + var start_instruction = GetInstruction (scope.Start.Offset); + if (start_instruction != null) + scope.Start = new InstructionOffset (start_instruction); + + var end_instruction = GetInstruction (scope.End.Offset); + scope.End = end_instruction != null + ? new InstructionOffset (end_instruction) + : new InstructionOffset (); + + if (!scope.variables.IsNullOrEmpty ()) { + for (int i = 0; i < scope.variables.Count; i++) { + var variable_info = scope.variables [i]; + var variable = GetVariable (variable_info.Index); + if (variable != null) + variable_info.index = new VariableIndex (variable); + } + } + + if (!scope.scopes.IsNullOrEmpty ()) + ReadScopes (scope.scopes); + } + + public ByteBuffer PatchRawMethodBody (MethodDefinition method, CodeWriter writer, out int code_size, out MetadataToken local_var_token) + { + var position = MoveTo (method); + + var buffer = new ByteBuffer (); + + var flags = ReadByte (); + + switch (flags & 0x3) { + case 0x2: // tiny + buffer.WriteByte (flags); + local_var_token = MetadataToken.Zero; + code_size = flags >> 2; + PatchRawCode (buffer, code_size, writer); + break; + case 0x3: // fat + Advance (-1); + PatchRawFatMethod (buffer, writer, out code_size, out local_var_token); + break; + default: + throw new NotSupportedException (); + } + + MoveBackTo (position); + + return buffer; + } + + void PatchRawFatMethod (ByteBuffer buffer, CodeWriter writer, out int code_size, out MetadataToken local_var_token) + { + var flags = ReadUInt16 (); + buffer.WriteUInt16 (flags); + buffer.WriteUInt16 (ReadUInt16 ()); + code_size = ReadInt32 (); + buffer.WriteInt32 (code_size); + local_var_token = ReadToken (); + + if (local_var_token.RID > 0) { + var variables = ReadVariables (local_var_token); + buffer.WriteUInt32 (variables != null + ? writer.GetStandAloneSignature (variables).ToUInt32 () + : 0); + } else + buffer.WriteUInt32 (0); + + PatchRawCode (buffer, code_size, writer); + + if ((flags & 0x8) != 0) + PatchRawSection (buffer, writer.metadata); + } + + void PatchRawCode (ByteBuffer buffer, int code_size, CodeWriter writer) + { + var metadata = writer.metadata; + buffer.WriteBytes (ReadBytes (code_size)); + var end = buffer.position; + buffer.position -= code_size; + + while (buffer.position < end) { + OpCode opcode; + var il_opcode = buffer.ReadByte (); + if (il_opcode != 0xfe) { + opcode = OpCodes.OneByteOpCode [il_opcode]; + } else { + var il_opcode2 = buffer.ReadByte (); + opcode = OpCodes.TwoBytesOpCode [il_opcode2]; + } + + switch (opcode.OperandType) { + case OperandType.ShortInlineI: + case OperandType.ShortInlineBrTarget: + case OperandType.ShortInlineVar: + case OperandType.ShortInlineArg: + buffer.position += 1; + break; + case OperandType.InlineVar: + case OperandType.InlineArg: + buffer.position += 2; + break; + case OperandType.InlineBrTarget: + case OperandType.ShortInlineR: + case OperandType.InlineI: + buffer.position += 4; + break; + case OperandType.InlineI8: + case OperandType.InlineR: + buffer.position += 8; + break; + case OperandType.InlineSwitch: + var length = buffer.ReadInt32 (); + buffer.position += length * 4; + break; + case OperandType.InlineString: + var @string = GetString (new MetadataToken (buffer.ReadUInt32 ())); + buffer.position -= 4; + buffer.WriteUInt32 ( + new MetadataToken ( + TokenType.String, + metadata.user_string_heap.GetStringIndex (@string)).ToUInt32 ()); + break; + case OperandType.InlineSig: + var call_site = GetCallSite (new MetadataToken (buffer.ReadUInt32 ())); + buffer.position -= 4; + buffer.WriteUInt32 (writer.GetStandAloneSignature (call_site).ToUInt32 ()); + break; + case OperandType.InlineTok: + case OperandType.InlineType: + case OperandType.InlineMethod: + case OperandType.InlineField: + var provider = reader.LookupToken (new MetadataToken (buffer.ReadUInt32 ())); + buffer.position -= 4; + buffer.WriteUInt32 (metadata.LookupToken (provider).ToUInt32 ()); + break; + } + } + } + + void PatchRawSection (ByteBuffer buffer, MetadataBuilder metadata) + { + var position = Position; + Align (4); + buffer.WriteBytes (Position - position); + + const byte fat_format = 0x40; + const byte more_sects = 0x80; + + var flags = ReadByte (); + if ((flags & fat_format) == 0) { + buffer.WriteByte (flags); + PatchRawSmallSection (buffer, metadata); + } else + PatchRawFatSection (buffer, metadata); + + if ((flags & more_sects) != 0) + PatchRawSection (buffer, metadata); + } + + void PatchRawSmallSection (ByteBuffer buffer, MetadataBuilder metadata) + { + var length = ReadByte (); + buffer.WriteByte (length); + Advance (2); + + buffer.WriteUInt16 (0); + + var count = length / 12; + + PatchRawExceptionHandlers (buffer, metadata, count, false); + } + + void PatchRawFatSection (ByteBuffer buffer, MetadataBuilder metadata) + { + Advance (-1); + var length = ReadInt32 (); + buffer.WriteInt32 (length); + + var count = (length >> 8) / 24; + + PatchRawExceptionHandlers (buffer, metadata, count, true); + } + + void PatchRawExceptionHandlers (ByteBuffer buffer, MetadataBuilder metadata, int count, bool fat_entry) + { + const int fat_entry_size = 16; + const int small_entry_size = 6; + + for (int i = 0; i < count; i++) { + ExceptionHandlerType handler_type; + if (fat_entry) { + var type = ReadUInt32 (); + handler_type = (ExceptionHandlerType) (type & 0x7); + buffer.WriteUInt32 (type); + } else { + var type = ReadUInt16 (); + handler_type = (ExceptionHandlerType) (type & 0x7); + buffer.WriteUInt16 (type); + } + + buffer.WriteBytes (ReadBytes (fat_entry ? fat_entry_size : small_entry_size)); + + switch (handler_type) { + case ExceptionHandlerType.Catch: + var exception = reader.LookupToken (ReadToken ()); + buffer.WriteUInt32 (metadata.LookupToken (exception).ToUInt32 ()); + break; + default: + buffer.WriteUInt32 (ReadUInt32 ()); + break; + } + } + } + } +} diff --git a/cecil-master/Mono.Cecil.Cil/CodeWriter.cs b/cecil-master/Mono.Cecil.Cil/CodeWriter.cs new file mode 100644 index 000000000..0ec4cc6e2 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/CodeWriter.cs @@ -0,0 +1,654 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; + +using Mono.Collections.Generic; + +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using RVA = System.UInt32; + +namespace Mono.Cecil.Cil { + + sealed class CodeWriter : ByteBuffer { + + readonly RVA code_base; + internal readonly MetadataBuilder metadata; + readonly Dictionary standalone_signatures; + readonly Dictionary tiny_method_bodies; + + MethodBody body; + + public CodeWriter (MetadataBuilder metadata) + : base (0) + { + this.code_base = metadata.text_map.GetRVA (TextSegment.Code); + this.metadata = metadata; + this.standalone_signatures = new Dictionary (); + this.tiny_method_bodies = new Dictionary (new ByteBufferEqualityComparer ()); + } + + public RVA WriteMethodBody (MethodDefinition method) + { + RVA rva; + + if (IsUnresolved (method)) { + if (method.rva == 0) + return 0; + + rva = WriteUnresolvedMethodBody (method); + } else { + if (IsEmptyMethodBody (method.Body)) + return 0; + + rva = WriteResolvedMethodBody (method); + } + + return rva; + } + + static bool IsEmptyMethodBody (MethodBody body) + { + return body.instructions.IsNullOrEmpty () + && body.variables.IsNullOrEmpty (); + } + + static bool IsUnresolved (MethodDefinition method) + { + return method.HasBody && method.HasImage && method.body == null; + } + + RVA WriteUnresolvedMethodBody (MethodDefinition method) + { + var code_reader = metadata.module.reader.code; + + int code_size; + MetadataToken local_var_token; + var raw_body = code_reader.PatchRawMethodBody (method, this, out code_size, out local_var_token); + var fat_header = (raw_body.buffer [0] & 0x3) == 0x3; + if (fat_header) + Align (4); + + var rva = BeginMethod (); + + if (fat_header || !GetOrMapTinyMethodBody (raw_body, ref rva)) { + WriteBytes (raw_body); + } + + if (method.debug_info == null) + return rva; + + var symbol_writer = metadata.symbol_writer; + if (symbol_writer != null) { + method.debug_info.code_size = code_size; + method.debug_info.local_var_token = local_var_token; + symbol_writer.Write (method.debug_info); + } + + return rva; + } + + RVA WriteResolvedMethodBody(MethodDefinition method) + { + RVA rva; + + body = method.Body; + ComputeHeader (); + if (RequiresFatHeader ()) { + Align (4); + rva = BeginMethod (); + WriteFatHeader (); + WriteInstructions (); + + if (body.HasExceptionHandlers) + WriteExceptionHandlers (); + } else { + rva = BeginMethod (); + WriteByte ((byte) (0x2 | (body.CodeSize << 2))); // tiny + WriteInstructions (); + + var start_position = (int) (rva - code_base); + var body_size = position - start_position; + var body_bytes = new byte [body_size]; + + Array.Copy (buffer, start_position, body_bytes, 0, body_size); + + if (GetOrMapTinyMethodBody (new ByteBuffer (body_bytes), ref rva)) + position = start_position; + } + + var symbol_writer = metadata.symbol_writer; + if (symbol_writer != null && method.debug_info != null) { + method.debug_info.code_size = body.CodeSize; + method.debug_info.local_var_token = body.local_var_token; + symbol_writer.Write (method.debug_info); + } + + return rva; + } + + bool GetOrMapTinyMethodBody (ByteBuffer body, ref RVA rva) + { + RVA existing_rva; + if (tiny_method_bodies.TryGetValue (body, out existing_rva)) { + rva = existing_rva; + return true; + } + + tiny_method_bodies.Add (body, rva); + return false; + } + + void WriteFatHeader () + { + var body = this.body; + byte flags = 0x3; // fat + if (body.InitLocals) + flags |= 0x10; // init locals + if (body.HasExceptionHandlers) + flags |= 0x8; // more sections + + WriteByte (flags); + WriteByte (0x30); + WriteInt16 ((short) body.max_stack_size); + WriteInt32 (body.code_size); + body.local_var_token = body.HasVariables + ? GetStandAloneSignature (body.Variables) + : MetadataToken.Zero; + WriteMetadataToken (body.local_var_token); + } + + void WriteInstructions () + { + var instructions = body.Instructions; + var items = instructions.items; + var size = instructions.size; + + for (int i = 0; i < size; i++) { + var instruction = items [i]; + WriteOpCode (instruction.opcode); + WriteOperand (instruction); + } + } + + void WriteOpCode (OpCode opcode) + { + if (opcode.Size == 1) { + WriteByte (opcode.Op2); + } else { + WriteByte (opcode.Op1); + WriteByte (opcode.Op2); + } + } + + void WriteOperand (Instruction instruction) + { + var opcode = instruction.opcode; + var operand_type = opcode.OperandType; + if (operand_type == OperandType.InlineNone) + return; + + var operand = instruction.operand; + if (operand == null && !(operand_type == OperandType.InlineBrTarget || operand_type == OperandType.ShortInlineBrTarget)) { + throw new ArgumentException (); + } + + switch (operand_type) { + case OperandType.InlineSwitch: { + var targets = (Instruction []) operand; + WriteInt32 (targets.Length); + var diff = instruction.Offset + opcode.Size + (4 * (targets.Length + 1)); + for (int i = 0; i < targets.Length; i++) + WriteInt32 (GetTargetOffset (targets [i]) - diff); + break; + } + case OperandType.ShortInlineBrTarget: { + var target = (Instruction) operand; + var offset = target != null ? GetTargetOffset (target) : body.code_size; + WriteSByte ((sbyte) (offset - (instruction.Offset + opcode.Size + 1))); + break; + } + case OperandType.InlineBrTarget: { + var target = (Instruction) operand; + var offset = target != null ? GetTargetOffset (target) : body.code_size; + WriteInt32 (offset - (instruction.Offset + opcode.Size + 4)); + break; + } + case OperandType.ShortInlineVar: + WriteByte ((byte) GetVariableIndex ((VariableDefinition) operand)); + break; + case OperandType.ShortInlineArg: + WriteByte ((byte) GetParameterIndex ((ParameterDefinition) operand)); + break; + case OperandType.InlineVar: + WriteInt16 ((short) GetVariableIndex ((VariableDefinition) operand)); + break; + case OperandType.InlineArg: + WriteInt16 ((short) GetParameterIndex ((ParameterDefinition) operand)); + break; + case OperandType.InlineSig: + WriteMetadataToken (GetStandAloneSignature ((CallSite) operand)); + break; + case OperandType.ShortInlineI: + if (opcode == OpCodes.Ldc_I4_S) + WriteSByte ((sbyte) operand); + else + WriteByte ((byte) operand); + break; + case OperandType.InlineI: + WriteInt32 ((int) operand); + break; + case OperandType.InlineI8: + WriteInt64 ((long) operand); + break; + case OperandType.ShortInlineR: + WriteSingle ((float) operand); + break; + case OperandType.InlineR: + WriteDouble ((double) operand); + break; + case OperandType.InlineString: + WriteMetadataToken ( + new MetadataToken ( + TokenType.String, + GetUserStringIndex ((string) operand))); + break; + case OperandType.InlineType: + case OperandType.InlineField: + case OperandType.InlineMethod: + case OperandType.InlineTok: + WriteMetadataToken (metadata.LookupToken ((IMetadataTokenProvider) operand)); + break; + default: + throw new ArgumentException (); + } + } + + int GetTargetOffset (Instruction instruction) + { + if (instruction == null) { + var last = body.instructions [body.instructions.size - 1]; + return last.offset + last.GetSize (); + } + + return instruction.offset; + } + + uint GetUserStringIndex (string @string) + { + if (@string == null) + return 0; + + return metadata.user_string_heap.GetStringIndex (@string); + } + + static int GetVariableIndex (VariableDefinition variable) + { + return variable.Index; + } + + int GetParameterIndex (ParameterDefinition parameter) + { + if (body.method.HasThis) { + if (parameter == body.this_parameter) + return 0; + + return parameter.Index + 1; + } + + return parameter.Index; + } + + bool RequiresFatHeader () + { + var body = this.body; + return body.CodeSize >= 64 + || body.InitLocals + || body.HasVariables + || body.HasExceptionHandlers + || body.MaxStackSize > 8; + } + + void ComputeHeader () + { + int offset = 0; + var instructions = body.instructions; + var items = instructions.items; + var count = instructions.size; + var stack_size = 0; + var max_stack = 0; + Dictionary stack_sizes = null; + + if (body.HasExceptionHandlers) + ComputeExceptionHandlerStackSize (ref stack_sizes); + + for (int i = 0; i < count; i++) { + var instruction = items [i]; + instruction.offset = offset; + offset += instruction.GetSize (); + + ComputeStackSize (instruction, ref stack_sizes, ref stack_size, ref max_stack); + } + + body.code_size = offset; + body.max_stack_size = max_stack; + } + + void ComputeExceptionHandlerStackSize (ref Dictionary stack_sizes) + { + var exception_handlers = body.ExceptionHandlers; + + for (int i = 0; i < exception_handlers.Count; i++) { + var exception_handler = exception_handlers [i]; + + switch (exception_handler.HandlerType) { + case ExceptionHandlerType.Catch: + AddExceptionStackSize (exception_handler.HandlerStart, ref stack_sizes); + break; + case ExceptionHandlerType.Filter: + AddExceptionStackSize (exception_handler.FilterStart, ref stack_sizes); + AddExceptionStackSize (exception_handler.HandlerStart, ref stack_sizes); + break; + } + } + } + + static void AddExceptionStackSize (Instruction handler_start, ref Dictionary stack_sizes) + { + if (handler_start == null) + return; + + if (stack_sizes == null) + stack_sizes = new Dictionary (); + + stack_sizes [handler_start] = 1; + } + + static void ComputeStackSize (Instruction instruction, ref Dictionary stack_sizes, ref int stack_size, ref int max_stack) + { + int computed_size; + if (stack_sizes != null && stack_sizes.TryGetValue (instruction, out computed_size)) + stack_size = computed_size; + + max_stack = System.Math.Max (max_stack, stack_size); + ComputeStackDelta (instruction, ref stack_size); + max_stack = System.Math.Max (max_stack, stack_size); + + CopyBranchStackSize (instruction, ref stack_sizes, stack_size); + ComputeStackSize (instruction, ref stack_size); + } + + static void CopyBranchStackSize (Instruction instruction, ref Dictionary stack_sizes, int stack_size) + { + if (stack_size == 0) + return; + + switch (instruction.opcode.OperandType) { + case OperandType.ShortInlineBrTarget: + case OperandType.InlineBrTarget: + CopyBranchStackSize (ref stack_sizes, (Instruction) instruction.operand, stack_size); + break; + case OperandType.InlineSwitch: + var targets = (Instruction []) instruction.operand; + for (int i = 0; i < targets.Length; i++) + CopyBranchStackSize (ref stack_sizes, targets [i], stack_size); + break; + } + } + + static void CopyBranchStackSize (ref Dictionary stack_sizes, Instruction target, int stack_size) + { + if (stack_sizes == null) + stack_sizes = new Dictionary (); + + int branch_stack_size = stack_size; + + int computed_size; + if (stack_sizes.TryGetValue (target, out computed_size)) + branch_stack_size = System.Math.Max (branch_stack_size, computed_size); + + stack_sizes [target] = branch_stack_size; + } + + static void ComputeStackSize (Instruction instruction, ref int stack_size) + { + switch (instruction.opcode.FlowControl) { + case FlowControl.Branch: + case FlowControl.Throw: + case FlowControl.Return: + stack_size = 0; + break; + } + } + + static void ComputeStackDelta (Instruction instruction, ref int stack_size) + { + switch (instruction.opcode.FlowControl) { + case FlowControl.Call: { + var method = (IMethodSignature) instruction.operand; + // pop 'this' argument + if (method.HasImplicitThis() && instruction.opcode.Code != Code.Newobj) + stack_size--; + // pop normal arguments + if (method.HasParameters) + stack_size -= method.Parameters.Count; + // pop function pointer + if (instruction.opcode.Code == Code.Calli) + stack_size--; + // push return value + if (method.ReturnType.etype != ElementType.Void || instruction.opcode.Code == Code.Newobj) + stack_size++; + break; + } + default: + ComputePopDelta (instruction.opcode.StackBehaviourPop, ref stack_size); + ComputePushDelta (instruction.opcode.StackBehaviourPush, ref stack_size); + break; + } + } + + static void ComputePopDelta (StackBehaviour pop_behavior, ref int stack_size) + { + switch (pop_behavior) { + case StackBehaviour.Popi: + case StackBehaviour.Popref: + case StackBehaviour.Pop1: + stack_size--; + break; + case StackBehaviour.Pop1_pop1: + case StackBehaviour.Popi_pop1: + case StackBehaviour.Popi_popi: + case StackBehaviour.Popi_popi8: + case StackBehaviour.Popi_popr4: + case StackBehaviour.Popi_popr8: + case StackBehaviour.Popref_pop1: + case StackBehaviour.Popref_popi: + stack_size -= 2; + break; + case StackBehaviour.Popi_popi_popi: + case StackBehaviour.Popref_popi_popi: + case StackBehaviour.Popref_popi_popi8: + case StackBehaviour.Popref_popi_popr4: + case StackBehaviour.Popref_popi_popr8: + case StackBehaviour.Popref_popi_popref: + stack_size -= 3; + break; + case StackBehaviour.PopAll: + stack_size = 0; + break; + } + } + + static void ComputePushDelta (StackBehaviour push_behaviour, ref int stack_size) + { + switch (push_behaviour) { + case StackBehaviour.Push1: + case StackBehaviour.Pushi: + case StackBehaviour.Pushi8: + case StackBehaviour.Pushr4: + case StackBehaviour.Pushr8: + case StackBehaviour.Pushref: + stack_size++; + break; + case StackBehaviour.Push1_push1: + stack_size += 2; + break; + } + } + + void WriteExceptionHandlers () + { + Align (4); + + var handlers = body.ExceptionHandlers; + + if (handlers.Count < 0x15 && !RequiresFatSection (handlers)) + WriteSmallSection (handlers); + else + WriteFatSection (handlers); + } + + static bool RequiresFatSection (Collection handlers) + { + for (int i = 0; i < handlers.Count; i++) { + var handler = handlers [i]; + + if (IsFatRange (handler.TryStart, handler.TryEnd)) + return true; + + if (IsFatRange (handler.HandlerStart, handler.HandlerEnd)) + return true; + + if (handler.HandlerType == ExceptionHandlerType.Filter + && IsFatRange (handler.FilterStart, handler.HandlerStart)) + return true; + } + + return false; + } + + static bool IsFatRange (Instruction start, Instruction end) + { + if (start == null) + throw new ArgumentException (); + + if (end == null) + return true; + + return end.Offset - start.Offset > 255 || start.Offset > 65535; + } + + void WriteSmallSection (Collection handlers) + { + const byte eh_table = 0x1; + + WriteByte (eh_table); + WriteByte ((byte) (handlers.Count * 12 + 4)); + WriteBytes (2); + + WriteExceptionHandlers ( + handlers, + i => WriteUInt16 ((ushort) i), + i => WriteByte ((byte) i)); + } + + void WriteFatSection (Collection handlers) + { + const byte eh_table = 0x1; + const byte fat_format = 0x40; + + WriteByte (eh_table | fat_format); + + int size = handlers.Count * 24 + 4; + WriteByte ((byte) (size & 0xff)); + WriteByte ((byte) ((size >> 8) & 0xff)); + WriteByte ((byte) ((size >> 16) & 0xff)); + + WriteExceptionHandlers (handlers, WriteInt32, WriteInt32); + } + + void WriteExceptionHandlers (Collection handlers, Action write_entry, Action write_length) + { + for (int i = 0; i < handlers.Count; i++) { + var handler = handlers [i]; + + write_entry ((int) handler.HandlerType); + + write_entry (handler.TryStart.Offset); + write_length (GetTargetOffset (handler.TryEnd) - handler.TryStart.Offset); + + write_entry (handler.HandlerStart.Offset); + write_length (GetTargetOffset (handler.HandlerEnd) - handler.HandlerStart.Offset); + + WriteExceptionHandlerSpecific (handler); + } + } + + void WriteExceptionHandlerSpecific (ExceptionHandler handler) + { + switch (handler.HandlerType) { + case ExceptionHandlerType.Catch: + WriteMetadataToken (metadata.LookupToken (handler.CatchType)); + break; + case ExceptionHandlerType.Filter: + WriteInt32 (handler.FilterStart.Offset); + break; + default: + WriteInt32 (0); + break; + } + } + + public MetadataToken GetStandAloneSignature (Collection variables) + { + var signature = metadata.GetLocalVariableBlobIndex (variables); + + return GetStandAloneSignatureToken (signature); + } + + public MetadataToken GetStandAloneSignature (CallSite call_site) + { + var signature = metadata.GetCallSiteBlobIndex (call_site); + var token = GetStandAloneSignatureToken (signature); + call_site.MetadataToken = token; + return token; + } + + MetadataToken GetStandAloneSignatureToken (uint signature) + { + MetadataToken token; + if (standalone_signatures.TryGetValue (signature, out token)) + return token; + + token = new MetadataToken (TokenType.Signature, metadata.AddStandAloneSignature (signature)); + standalone_signatures.Add (signature, token); + return token; + } + + RVA BeginMethod () + { + return (RVA)(code_base + position); + } + + void WriteMetadataToken (MetadataToken token) + { + WriteUInt32 (token.ToUInt32 ()); + } + + void Align (int align) + { + align--; + WriteBytes (((position + align) & ~align) - position); + } + } +} diff --git a/cecil-master/Mono.Cecil.Cil/Document.cs b/cecil-master/Mono.Cecil.Cil/Document.cs new file mode 100644 index 000000000..03d3ec301 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/Document.cs @@ -0,0 +1,123 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil.Cil { + + public enum DocumentType { + Other, + Text, + } + + public enum DocumentHashAlgorithm { + None, + MD5, + SHA1, + SHA256, + } + + 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 : DebugInformation { + + string url; + + Guid type; + Guid hash_algorithm; + Guid language; + Guid language_vendor; + + byte [] hash; + byte [] embedded_source; + + public string Url { + get { return url; } + set { url = value; } + } + + public DocumentType Type { + get { return type.ToType (); } + set { type = value.ToGuid (); } + } + + public Guid TypeGuid { + get { return type; } + set { type = value; } + } + + public DocumentHashAlgorithm HashAlgorithm { + get { return hash_algorithm.ToHashAlgorithm (); } + set { hash_algorithm = value.ToGuid (); } + } + + public Guid HashAlgorithmGuid { + get { return hash_algorithm; } + set { hash_algorithm = value; } + } + + public DocumentLanguage Language { + get { return language.ToLanguage (); } + set { language = value.ToGuid (); } + } + + public Guid LanguageGuid { + get { return language; } + set { language = value; } + } + + public DocumentLanguageVendor LanguageVendor { + get { return language_vendor.ToVendor (); } + set { language_vendor = value.ToGuid (); } + } + + public Guid LanguageVendorGuid { + get { return language_vendor; } + set { language_vendor = value; } + } + + public byte [] Hash { + get { return hash; } + set { hash = value; } + } + + public byte[] EmbeddedSource { + get { return embedded_source; } + set { embedded_source = value; } + } + + public Document (string url) + { + this.url = url; + this.hash = Empty.Array; + this.embedded_source = Empty.Array; + this.token = new MetadataToken (TokenType.Document); + } + } +} diff --git a/cecil-master/Mono.Cecil.Cil/ExceptionHandler.cs b/cecil-master/Mono.Cecil.Cil/ExceptionHandler.cs new file mode 100644 index 000000000..6bdb1aa32 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/ExceptionHandler.cs @@ -0,0 +1,71 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil.Cil/ILProcessor.cs b/cecil-master/Mono.Cecil.Cil/ILProcessor.cs new file mode 100644 index 000000000..86e6ed754 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/ILProcessor.cs @@ -0,0 +1,292 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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, body.GetParameter (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, body.GetParameter (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 InsertAfter (int index, Instruction instruction) + { + if (index < 0 || index >= instructions.Count) + throw new ArgumentOutOfRangeException ("index"); + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + 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 Replace (int index, Instruction instruction) + { + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + InsertAfter (index, instruction); + RemoveAt (index); + } + + public void Remove (Instruction instruction) + { + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + if (!instructions.Remove (instruction)) + throw new ArgumentOutOfRangeException ("instruction"); + } + + public void RemoveAt (int index) + { + if (index < 0 || index >= instructions.Count) + throw new ArgumentOutOfRangeException ("index"); + + instructions.RemoveAt (index); + } + + public void Clear () + { + instructions.Clear (); + } + } +} diff --git a/cecil-master/Mono.Cecil.Cil/Instruction.cs b/cecil-master/Mono.Cecil.Cil/Instruction.cs new file mode 100644 index 000000000..4b5eea9ea --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/Instruction.cs @@ -0,0 +1,302 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Globalization; +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; + + 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; } + } + + 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 Instruction GetPrototype () + { + return new Instruction (opcode, 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 (Convert.ToString(operand, CultureInfo.InvariantCulture)); + 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/cecil-master/Mono.Cecil.Cil/MethodBody.cs b/cecil-master/Mono.Cecil.Cil/MethodBody.cs new file mode 100644 index 000000000..89bfc905c --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/MethodBody.cs @@ -0,0 +1,495 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Threading; + +using Mono.Collections.Generic; + +namespace Mono.Cecil.Cil { + + public sealed class MethodBody { + + 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; + + 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 { + if (instructions == null) + Interlocked.CompareExchange (ref instructions, new InstructionCollection (method), null); + + return instructions; + } + } + + public bool HasExceptionHandlers { + get { return !exceptions.IsNullOrEmpty (); } + } + + public Collection ExceptionHandlers { + get { + if (exceptions == null) + Interlocked.CompareExchange (ref exceptions, new Collection (), null); + + return exceptions; + } + } + + public bool HasVariables { + get { return !variables.IsNullOrEmpty (); } + } + + public Collection Variables { + get { + if (variables == null) + Interlocked.CompareExchange (ref variables, new VariableDefinitionCollection (this.method), null); + + return variables; + } + } + + public ParameterDefinition ThisParameter { + get { + if (method == null || method.DeclaringType == null) + throw new NotSupportedException (); + + if (!method.HasThis) + return null; + + if (this_parameter == null) + Interlocked.CompareExchange (ref this_parameter, CreateThisParameter (method), null); + + return this_parameter; + } + } + + static ParameterDefinition CreateThisParameter (MethodDefinition method) + { + var parameter_type = method.DeclaringType as TypeReference; + + if (parameter_type.HasGenericParameters) { + var instance = new GenericInstanceType (parameter_type, parameter_type.GenericParameters.Count); + for (int i = 0; i < parameter_type.GenericParameters.Count; i++) + instance.GenericArguments.Add (parameter_type.GenericParameters [i]); + + parameter_type = instance; + + } + + if (parameter_type.IsValueType || parameter_type.IsPrimitive) + parameter_type = new ByReferenceType (parameter_type); + + return new ParameterDefinition (parameter_type, method); + } + + public MethodBody (MethodDefinition method) + { + this.method = method; + } + + public ILProcessor GetILProcessor () + { + return new ILProcessor (this); + } + } + + sealed class VariableDefinitionCollection : Collection { + + readonly MethodDefinition method; + + internal VariableDefinitionCollection (MethodDefinition method) + { + this.method = method; + } + + internal VariableDefinitionCollection (MethodDefinition method, int capacity) + : base (capacity) + { + this.method = method; + } + + protected override void OnAdd (VariableDefinition item, int index) + { + item.index = index; + } + + protected override void OnInsert (VariableDefinition item, int index) + { + item.index = index; + UpdateVariableIndices (index, 1); + } + + protected override void OnSet (VariableDefinition item, int index) + { + item.index = index; + } + + protected override void OnRemove (VariableDefinition item, int index) + { + UpdateVariableIndices (index + 1, -1, item); + item.index = -1; + } + + void UpdateVariableIndices (int startIndex, int offset, VariableDefinition variableToRemove = null) + { + for (int i = startIndex; i < size; i++) + items [i].index = i + offset; + + var debug_info = method == null ? null : method.debug_info; + if (debug_info == null || debug_info.Scope == null) + return; + + foreach (var scope in debug_info.GetScopes ()) { + if (!scope.HasVariables) + continue; + + var variables = scope.Variables; + int variableDebugInfoIndexToRemove = -1; + for (int i = 0; i < variables.Count; i++) { + var variable = variables [i]; + + // If a variable is being removed detect if it has debug info counterpart, if so remove that as well. + // Note that the debug info can be either resolved (has direct reference to the VariableDefinition) + // or unresolved (has only the number index of the variable) - this needs to handle both cases. + if (variableToRemove != null && + ((variable.index.IsResolved && variable.index.ResolvedVariable == variableToRemove) || + (!variable.index.IsResolved && variable.Index == variableToRemove.Index))) { + variableDebugInfoIndexToRemove = i; + continue; + } + + // For unresolved debug info updates indeces to keep them pointing to the same variable. + if (!variable.index.IsResolved && variable.Index >= startIndex) { + variable.index = new VariableIndex (variable.Index + offset); + } + } + + if (variableDebugInfoIndexToRemove >= 0) + variables.RemoveAt (variableDebugInfoIndexToRemove); + } + } + } + + class InstructionCollection : Collection { + + readonly MethodDefinition method; + + internal InstructionCollection (MethodDefinition method) + { + this.method = method; + } + + internal InstructionCollection (MethodDefinition method, int capacity) + : base (capacity) + { + this.method = method; + } + + 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) + { + int startOffset = 0; + if (size != 0) { + var current = items [index]; + if (current == null) { + var last = items [index - 1]; + last.next = item; + item.previous = last; + return; + } + + startOffset = current.Offset; + + var previous = current.previous; + if (previous != null) { + previous.next = item; + item.previous = previous; + } + + current.previous = item; + item.next = current; + } + + UpdateDebugInformation (null, null); + } + + 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; + + UpdateDebugInformation (item, current); + } + + 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; + + RemoveSequencePoint (item); + UpdateDebugInformation (item, next ?? previous); + + item.previous = null; + item.next = null; + } + + void RemoveSequencePoint (Instruction instruction) + { + var debug_info = method.debug_info; + if (debug_info == null || !debug_info.HasSequencePoints) + return; + + var sequence_points = debug_info.sequence_points; + for (int i = 0; i < sequence_points.Count; i++) { + if (sequence_points [i].Offset == instruction.offset) { + sequence_points.RemoveAt (i); + return; + } + } + } + + void UpdateDebugInformation (Instruction removedInstruction, Instruction existingInstruction) + { + // Various bits of debug information store instruction offsets (as "pointers" to the IL) + // Instruction offset can be either resolved, in which case it + // has a reference to Instruction, or unresolved in which case it stores numerical offset (instruction offset in the body). + // Depending on where the InstructionOffset comes from (loaded from PE/PDB or constructed) it can be in either state. + // Each instruction has its own offset, which is populated on load, but never updated (this would be pretty expensive to do). + // Instructions created during the editting will typically have offset 0 (so incorrect). + // Manipulating unresolved InstructionOffsets is pretty hard (since we can't rely on correct offsets of instructions). + // On the other hand resolved InstructionOffsets are easy to maintain, since they point to instructions and thus inserting + // instructions is basically a no-op and removing instructions is as easy as changing the pointer. + // For this reason the algorithm here is: + // - First make sure that all instruction offsets are resolved - if not - resolve them + // - First time this will be relatively expensive as it will walk the entire method body to convert offsets to instruction pointers + // Within the same debug info, IL offsets are typically stored in the "right" order (sequentially per start offsets), + // so the code uses a simple one-item cache instruction<->offset to avoid walking instructions multiple times + // (that would only happen for scopes which are out of order). + // - Subsequent calls should be cheap as it will only walk all local scopes without doing anything (as it checks that they're resolved) + // - If there was an edit which adds some unresolved, the cost is proportional (the code will only resolve those) + // - Then update as necessary by manipulaitng instruction references alone + + InstructionOffsetResolver resolver = new InstructionOffsetResolver (items, removedInstruction, existingInstruction); + + if (method.debug_info != null) + UpdateLocalScope (method.debug_info.Scope, ref resolver); + + var custom_debug_infos = method.custom_infos ?? method.debug_info?.custom_infos; + if (custom_debug_infos != null) { + foreach (var custom_debug_info in custom_debug_infos) { + switch (custom_debug_info) { + case StateMachineScopeDebugInformation state_machine_scope: + UpdateStateMachineScope (state_machine_scope, ref resolver); + break; + + case AsyncMethodBodyDebugInformation async_method_body: + UpdateAsyncMethodBody (async_method_body, ref resolver); + break; + + default: + // No need to update the other debug info as they don't store instruction references + break; + } + } + } + } + + void UpdateLocalScope (ScopeDebugInformation scope, ref InstructionOffsetResolver resolver) + { + if (scope == null) + return; + + scope.Start = resolver.Resolve (scope.Start); + + if (scope.HasScopes) { + foreach (var subScope in scope.Scopes) + UpdateLocalScope (subScope, ref resolver); + } + + scope.End = resolver.Resolve (scope.End); + } + + void UpdateStateMachineScope (StateMachineScopeDebugInformation debugInfo, ref InstructionOffsetResolver resolver) + { + resolver.Restart (); + foreach (var scope in debugInfo.Scopes) { + scope.Start = resolver.Resolve (scope.Start); + scope.End = resolver.Resolve (scope.End); + } + } + + void UpdateAsyncMethodBody (AsyncMethodBodyDebugInformation debugInfo, ref InstructionOffsetResolver resolver) + { + if (!debugInfo.CatchHandler.IsResolved) { + resolver.Restart (); + debugInfo.CatchHandler = resolver.Resolve (debugInfo.CatchHandler); + } + + resolver.Restart (); + for (int i = 0; i < debugInfo.Yields.Count; i++) { + debugInfo.Yields [i] = resolver.Resolve (debugInfo.Yields [i]); + } + + resolver.Restart (); + for (int i = 0; i < debugInfo.Resumes.Count; i++) { + debugInfo.Resumes [i] = resolver.Resolve (debugInfo.Resumes [i]); + } + } + + struct InstructionOffsetResolver { + readonly Instruction [] items; + readonly Instruction removed_instruction; + readonly Instruction existing_instruction; + + int cache_offset; + int cache_index; + Instruction cache_instruction; + + public int LastOffset { get => cache_offset; } + + public InstructionOffsetResolver (Instruction[] instructions, Instruction removedInstruction, Instruction existingInstruction) + { + items = instructions; + removed_instruction = removedInstruction; + existing_instruction = existingInstruction; + cache_offset = 0; + cache_index = 0; + cache_instruction = items [0]; + } + + public void Restart () + { + cache_offset = 0; + cache_index = 0; + cache_instruction = items [0]; + } + + public InstructionOffset Resolve (InstructionOffset inputOffset) + { + var result = ResolveInstructionOffset (inputOffset); + if (!result.IsEndOfMethod && result.ResolvedInstruction == removed_instruction) + result = new InstructionOffset (existing_instruction); + + return result; + } + + InstructionOffset ResolveInstructionOffset (InstructionOffset inputOffset) + { + if (inputOffset.IsResolved) + return inputOffset; + + int offset = inputOffset.Offset; + + if (cache_offset == offset) + return new InstructionOffset (cache_instruction); + + if (cache_offset > offset) { + // This should be rare - we're resolving offset pointing to a place before the current cache position + // resolve by walking the instructions from start and don't cache the result. + int size = 0; + for (int i = 0; i < items.Length; i++) { + // The array can be larger than the actual size, in which case its padded with nulls at the end + // so when we reach null, treat it as an end of the IL. + if (items [i] == null) + return new InstructionOffset (i == 0 ? items [0] : items [i - 1]); + + if (size == offset) + return new InstructionOffset (items [i]); + + if (size > offset) + return new InstructionOffset (i == 0 ? items [0] : items [i - 1]); + + size += items [i].GetSize (); + } + + // Offset is larger than the size of the body - so it points after the end + return new InstructionOffset (); + } else { + // The offset points after the current cache position - so continue counting and update the cache + int size = cache_offset; + for (int i = cache_index; i < items.Length; i++) { + cache_index = i; + cache_offset = size; + + var item = items [i]; + + // Allow for trailing null values in the case of + // instructions.Size < instructions.Capacity + if (item == null) + return new InstructionOffset (i == 0 ? items [0] : items [i - 1]); + + cache_instruction = item; + + if (cache_offset == offset) + return new InstructionOffset (cache_instruction); + + if (cache_offset > offset) + return new InstructionOffset (i == 0 ? items [0] : items [i - 1]); + + size += item.GetSize (); + } + + return new InstructionOffset (); + } + } + } + } +} \ No newline at end of file diff --git a/cecil-master/Mono.Cecil.Cil/OpCode.cs b/cecil-master/Mono.Cecil.Cil/OpCode.cs new file mode 100644 index 000000000..81ab0e12a --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/OpCode.cs @@ -0,0 +1,439 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +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 : IEquatable { + + 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/cecil-master/Mono.Cecil.Cil/OpCodes.cs b/cecil-master/Mono.Cecil.Cil/OpCodes.cs new file mode 100644 index 000000000..ba0468d30 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/OpCodes.cs @@ -0,0 +1,894 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil.Cil/PortablePdb.cs b/cecil-master/Mono.Cecil.Cil/PortablePdb.cs new file mode 100644 index 000000000..6664bee32 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/PortablePdb.cs @@ -0,0 +1,681 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Security.Cryptography; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +namespace Mono.Cecil.Cil { + + public sealed class PortablePdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + var file = File.OpenRead (Mixin.GetPdbFileName (fileName)); + return GetSymbolReader (module, Disposable.Owned (file as Stream), file.Name); + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + return GetSymbolReader (module, Disposable.NotOwned (symbolStream), symbolStream.GetFileName ()); + } + + ISymbolReader GetSymbolReader (ModuleDefinition module, Disposable symbolStream, string fileName) + { + return new PortablePdbReader (ImageReader.ReadPortablePdb (symbolStream, fileName, out _), module); + } + } + + public sealed class PortablePdbReader : ISymbolReader { + + readonly Image image; + readonly ModuleDefinition module; + readonly MetadataReader reader; + readonly MetadataReader debug_reader; + + bool IsEmbedded { get { return reader.image == debug_reader.image; } } + + internal PortablePdbReader (Image image, ModuleDefinition module) + { + this.image = image; + this.module = module; + this.reader = module.reader; + this.debug_reader = new MetadataReader (image, module, this.reader); + } + + public ISymbolWriterProvider GetWriterProvider () + { + return new PortablePdbWriterProvider (); + } + + public bool ProcessDebugHeader (ImageDebugHeader header) + { + if (image == module.Image) + return true; + + foreach (var entry in header.Entries) { + if (!IsMatchingEntry (image.PdbHeap, entry)) + continue; + + ReadModule (); + return true; + } + + return false; + } + + static bool IsMatchingEntry (PdbHeap heap, ImageDebugHeaderEntry entry) + { + if (entry.Directory.Type != ImageDebugType.CodeView) + return false; + + var data = entry.Data; + + if (data.Length < 24) + return false; + + var magic = ReadInt32 (data, 0); + if (magic != 0x53445352) + return false; + + var buffer = new byte [16]; + Buffer.BlockCopy (data, 4, buffer, 0, 16); + + var module_guid = new Guid (buffer); + + Buffer.BlockCopy (heap.Id, 0, buffer, 0, 16); + + var pdb_guid = new Guid (buffer); + + return module_guid == pdb_guid; + } + + static int ReadInt32 (byte [] bytes, int start) + { + return (bytes [start] + | (bytes [start + 1] << 8) + | (bytes [start + 2] << 16) + | (bytes [start + 3] << 24)); + } + + void ReadModule () + { + module.custom_infos = debug_reader.GetCustomDebugInformation (module); + } + + public MethodDebugInformation Read (MethodDefinition method) + { + var info = new MethodDebugInformation (method); + ReadSequencePoints (info); + ReadScope (info); + ReadStateMachineKickOffMethod (info); + ReadCustomDebugInformations (info); + return info; + } + + void ReadSequencePoints (MethodDebugInformation method_info) + { + method_info.sequence_points = debug_reader.ReadSequencePoints (method_info.method); + } + + void ReadScope (MethodDebugInformation method_info) + { + method_info.scope = debug_reader.ReadScope (method_info.method); + } + + void ReadStateMachineKickOffMethod (MethodDebugInformation method_info) + { + method_info.kickoff_method = debug_reader.ReadStateMachineKickoffMethod (method_info.method); + } + + void ReadCustomDebugInformations (MethodDebugInformation info) + { + info.method.custom_infos = debug_reader.GetCustomDebugInformation (info.method); + } + + public void Dispose () + { + if (IsEmbedded) + return; + + image.Dispose (); + } + } + + public sealed class EmbeddedPortablePdbReaderProvider : ISymbolReaderProvider { + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + + var header = module.GetDebugHeader (); + var entry = header.GetEmbeddedPortablePdbEntry (); + if (entry == null) + throw new InvalidOperationException (); + + return new EmbeddedPortablePdbReader ( + (PortablePdbReader) new PortablePdbReaderProvider ().GetSymbolReader (module, GetPortablePdbStream (entry))); + } + + static Stream GetPortablePdbStream (ImageDebugHeaderEntry entry) + { + var compressed_stream = new MemoryStream (entry.Data); + var reader = new BinaryStreamReader (compressed_stream); + reader.ReadInt32 (); // signature + var length = reader.ReadInt32 (); + var decompressed_stream = new MemoryStream (length); + + using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true)) + deflate_stream.CopyTo (decompressed_stream); + + return decompressed_stream; + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + throw new NotSupportedException (); + } + } + + public sealed class EmbeddedPortablePdbReader : ISymbolReader + { + private readonly PortablePdbReader reader; + + internal EmbeddedPortablePdbReader (PortablePdbReader reader) + { + if (reader == null) + throw new ArgumentNullException (); + + this.reader = reader; + } + + public ISymbolWriterProvider GetWriterProvider () + { + return new EmbeddedPortablePdbWriterProvider (); + } + + public bool ProcessDebugHeader (ImageDebugHeader header) + { + return reader.ProcessDebugHeader (header); + } + + public MethodDebugInformation Read (MethodDefinition method) + { + return reader.Read (method); + } + + public void Dispose () + { + reader.Dispose (); + } + } + + public sealed class PortablePdbWriterProvider : ISymbolWriterProvider + { + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + var file = File.Open (Mixin.GetPdbFileName (fileName), FileMode.OpenOrCreate, FileAccess.ReadWrite); + return GetSymbolWriter (module, Disposable.Owned (file as Stream), Disposable.NotOwned ((Stream)null)); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + Mixin.CheckModule (module); + Mixin.CheckStream (symbolStream); + + // In order to compute the PDB checksum, the stream we're writing to needs to be able to + // seek and read as well. We can't assume this about a stream provided by the user. + // So in this case, create a memory stream to cache the PDB. + return GetSymbolWriter (module, Disposable.Owned (new MemoryStream() as Stream), Disposable.NotOwned (symbolStream)); + } + + ISymbolWriter GetSymbolWriter (ModuleDefinition module, Disposable stream, Disposable final_stream) + { + var metadata = new MetadataBuilder (module, this); + var writer = ImageWriter.CreateDebugWriter (module, metadata, stream); + + return new PortablePdbWriter (metadata, module, writer, final_stream); + } + } + + public sealed class PortablePdbWriter : ISymbolWriter { + + readonly MetadataBuilder pdb_metadata; + readonly ModuleDefinition module; + readonly ImageWriter writer; + readonly Disposable final_stream; + + MetadataBuilder module_metadata; + + internal byte [] pdb_checksum; + internal Guid pdb_id_guid; + internal uint pdb_id_stamp; + + bool IsEmbedded { get { return writer == null; } } + + internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module) + { + this.pdb_metadata = pdb_metadata; + this.module = module; + + this.module_metadata = module.metadata_builder; + + if (module_metadata != pdb_metadata) + this.pdb_metadata.metadata_builder = this.module_metadata; + + pdb_metadata.AddCustomDebugInformations (module); + } + + internal PortablePdbWriter (MetadataBuilder pdb_metadata, ModuleDefinition module, ImageWriter writer, Disposable final_stream) + : this (pdb_metadata, module) + { + this.writer = writer; + this.final_stream = final_stream; + } + + public ISymbolReaderProvider GetReaderProvider () + { + return new PortablePdbReaderProvider (); + } + + public void Write (MethodDebugInformation info) + { + CheckMethodDebugInformationTable (); + + pdb_metadata.AddMethodDebugInformation (info); + } + + public void Write () + { + if (IsEmbedded) + return; + + WritePdbFile (); + + if (final_stream.value != null) { + writer.BaseStream.Seek (0, SeekOrigin.Begin); + var buffer = new byte [8192]; + CryptoService.CopyStreamChunk (writer.BaseStream, final_stream.value, buffer, (int)writer.BaseStream.Length); + } + } + + public ImageDebugHeader GetDebugHeader () + { + if (IsEmbedded) + return new ImageDebugHeader (); + + ImageDebugHeaderEntry codeViewEntry; + { + var codeViewDirectory = new ImageDebugDirectory () { + MajorVersion = 256, + MinorVersion = 20557, + Type = ImageDebugType.CodeView, + TimeDateStamp = (int)pdb_id_stamp, + }; + + var buffer = new ByteBuffer (); + // RSDS + buffer.WriteUInt32 (0x53445352); + // Module ID + buffer.WriteBytes (pdb_id_guid.ToByteArray ()); + // PDB Age + buffer.WriteUInt32 (1); + // PDB Path + var fileName = writer.BaseStream.GetFileName (); + if (string.IsNullOrEmpty (fileName)) { + fileName = module.Assembly.Name.Name + ".pdb"; + } + buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes (fileName)); + buffer.WriteByte (0); + + var data = new byte [buffer.length]; + Buffer.BlockCopy (buffer.buffer, 0, data, 0, buffer.length); + codeViewDirectory.SizeOfData = data.Length; + + codeViewEntry = new ImageDebugHeaderEntry (codeViewDirectory, data); + } + + ImageDebugHeaderEntry pdbChecksumEntry; + { + var pdbChecksumDirectory = new ImageDebugDirectory () { + MajorVersion = 1, + MinorVersion = 0, + Type = ImageDebugType.PdbChecksum, + TimeDateStamp = 0 + }; + + var buffer = new ByteBuffer (); + // SHA256 - Algorithm name + buffer.WriteBytes (System.Text.Encoding.UTF8.GetBytes ("SHA256")); + buffer.WriteByte (0); + + // Checksum - 32 bytes + buffer.WriteBytes (pdb_checksum); + + var data = new byte [buffer.length]; + Buffer.BlockCopy (buffer.buffer, 0, data, 0, buffer.length); + pdbChecksumDirectory.SizeOfData = data.Length; + + pdbChecksumEntry = new ImageDebugHeaderEntry (pdbChecksumDirectory, data); + } + + return new ImageDebugHeader (new ImageDebugHeaderEntry [] { codeViewEntry, pdbChecksumEntry }); + } + + void CheckMethodDebugInformationTable () + { + var mdi = pdb_metadata.table_heap.GetTable (Table.MethodDebugInformation); + if (mdi.length > 0) + return; + + // The MethodDebugInformation table has the same length as the Method table + mdi.rows = new Row [module_metadata.method_rid - 1]; + mdi.length = mdi.rows.Length; + } + + public void Dispose () + { + writer.stream.Dispose (); + final_stream.Dispose (); + } + + void WritePdbFile () + { + WritePdbHeap (); + + WriteTableHeap (); + + writer.BuildMetadataTextMap (); + writer.WriteMetadataHeader (); + writer.WriteMetadata (); + + writer.Flush (); + + ComputeChecksumAndPdbId (); + + WritePdbId (); + } + + void WritePdbHeap () + { + var pdb_heap = pdb_metadata.pdb_heap; + + // PDB ID ( GUID + TimeStamp ) are left zeroed out for now. Will be filled at the end with a hash. + pdb_heap.WriteBytes (20); + + pdb_heap.WriteUInt32 (module_metadata.entry_point.ToUInt32 ()); + + var table_heap = module_metadata.table_heap; + var tables = table_heap.tables; + + ulong valid = 0; + for (int i = 0; i < tables.Length; i++) { + if (tables [i] == null || tables [i].Length == 0) + continue; + + valid |= (1UL << i); + } + + pdb_heap.WriteUInt64 (valid); + + for (int i = 0; i < tables.Length; i++) { + if (tables [i] == null || tables [i].Length == 0) + continue; + + pdb_heap.WriteUInt32 ((uint) tables [i].Length); + } + } + + void WriteTableHeap () + { + pdb_metadata.table_heap.string_offsets = pdb_metadata.string_heap.WriteStrings (); + pdb_metadata.table_heap.ComputeTableInformations (); + pdb_metadata.table_heap.WriteTableHeap (); + } + + void ComputeChecksumAndPdbId () + { + var buffer = new byte [8192]; + + // Compute the has of the entire file - PDB ID is zeroes still + writer.BaseStream.Seek (0, SeekOrigin.Begin); + var sha256 = SHA256.Create (); + using (var crypto_stream = new CryptoStream (Stream.Null, sha256, CryptoStreamMode.Write)) { + CryptoService.CopyStreamChunk (writer.BaseStream, crypto_stream, buffer, (int)writer.BaseStream.Length); + } + + pdb_checksum = sha256.Hash; + + var hashBytes = new ByteBuffer (pdb_checksum); + pdb_id_guid = new Guid (hashBytes.ReadBytes (16)); + pdb_id_stamp = hashBytes.ReadUInt32 (); + } + + void WritePdbId () + { + // PDB ID is the first 20 bytes of the PdbHeap + writer.MoveToRVA (TextSegment.PdbHeap); + writer.WriteBytes (pdb_id_guid.ToByteArray ()); + writer.WriteUInt32 (pdb_id_stamp); + } + } + + public sealed class EmbeddedPortablePdbWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + Mixin.CheckModule (module); + Mixin.CheckFileName (fileName); + + var stream = new MemoryStream (); + var pdb_writer = (PortablePdbWriter) new PortablePdbWriterProvider ().GetSymbolWriter (module, stream); + return new EmbeddedPortablePdbWriter (stream, pdb_writer); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + throw new NotSupportedException (); + } + } + + public sealed class EmbeddedPortablePdbWriter : ISymbolWriter { + + readonly Stream stream; + readonly PortablePdbWriter writer; + + internal EmbeddedPortablePdbWriter (Stream stream, PortablePdbWriter writer) + { + this.stream = stream; + this.writer = writer; + } + + public ISymbolReaderProvider GetReaderProvider () + { + return new EmbeddedPortablePdbReaderProvider (); + } + + public void Write (MethodDebugInformation info) + { + writer.Write (info); + } + + public ImageDebugHeader GetDebugHeader () + { + ImageDebugHeader pdbDebugHeader = writer.GetDebugHeader (); + + var directory = new ImageDebugDirectory { + Type = ImageDebugType.EmbeddedPortablePdb, + MajorVersion = 0x0100, + MinorVersion = 0x0100, + }; + + var data = new MemoryStream (); + + var w = new BinaryStreamWriter (data); + w.WriteByte (0x4d); + w.WriteByte (0x50); + w.WriteByte (0x44); + w.WriteByte (0x42); + + w.WriteInt32 ((int) stream.Length); + + stream.Position = 0; + + using (var compress_stream = new DeflateStream (data, CompressionMode.Compress, leaveOpen: true)) + stream.CopyTo (compress_stream); + + directory.SizeOfData = (int) data.Length; + + var debugHeaderEntries = new ImageDebugHeaderEntry [pdbDebugHeader.Entries.Length + 1]; + for (int i = 0; i < pdbDebugHeader.Entries.Length; i++) + debugHeaderEntries [i] = pdbDebugHeader.Entries [i]; + debugHeaderEntries [debugHeaderEntries.Length - 1] = new ImageDebugHeaderEntry (directory, data.ToArray ()); + + return new ImageDebugHeader (debugHeaderEntries); + } + + public void Write () + { + writer.Write (); + } + + public void Dispose () + { + writer.Dispose (); + } + } + + static class PdbGuidMapping { + + static readonly Dictionary guid_language = new Dictionary (); + static readonly Dictionary language_guid = new Dictionary (); + + static PdbGuidMapping () + { + AddMapping (DocumentLanguage.C, new Guid ("63a08714-fc37-11d2-904c-00c04fa302a1")); + AddMapping (DocumentLanguage.Cpp, new Guid ("3a12d0b7-c26c-11d0-b442-00a0244a1dd2")); + AddMapping (DocumentLanguage.CSharp, new Guid ("3f5162f8-07c6-11d3-9053-00c04fa302a1")); + AddMapping (DocumentLanguage.Basic, new Guid ("3a12d0b8-c26c-11d0-b442-00a0244a1dd2")); + AddMapping (DocumentLanguage.Java, new Guid ("3a12d0b4-c26c-11d0-b442-00a0244a1dd2")); + AddMapping (DocumentLanguage.Cobol, new Guid ("af046cd1-d0e1-11d2-977c-00a0c9b4d50c")); + AddMapping (DocumentLanguage.Pascal, new Guid ("af046cd2-d0e1-11d2-977c-00a0c9b4d50c")); + AddMapping (DocumentLanguage.Cil, new Guid ("af046cd3-d0e1-11d2-977c-00a0c9b4d50c")); + AddMapping (DocumentLanguage.JScript, new Guid ("3a12d0b6-c26c-11d0-b442-00a0244a1dd2")); + AddMapping (DocumentLanguage.Smc, new Guid ("0d9b9f7b-6611-11d3-bd2a-0000f80849bd")); + AddMapping (DocumentLanguage.MCpp, new Guid ("4b35fde8-07c6-11d3-9053-00c04fa302a1")); + AddMapping (DocumentLanguage.FSharp, new Guid ("ab4f38c9-b6e6-43ba-be3b-58080b2ccce3")); + } + + static void AddMapping (DocumentLanguage language, Guid guid) + { + guid_language.Add (guid, language); + language_guid.Add (language, guid); + } + + static readonly Guid type_text = new Guid ("5a869d0b-6611-11d3-bd2a-0000f80849bd"); + + public static DocumentType ToType (this Guid guid) + { + if (guid == type_text) + return DocumentType.Text; + + return DocumentType.Other; + } + + public static Guid ToGuid (this DocumentType type) + { + if (type == DocumentType.Text) + return type_text; + + return new Guid (); + } + + static readonly Guid hash_md5 = new Guid ("406ea660-64cf-4c82-b6f0-42d48172a799"); + static readonly Guid hash_sha1 = new Guid ("ff1816ec-aa5e-4d10-87f7-6f4963833460"); + static readonly Guid hash_sha256 = new Guid ("8829d00f-11b8-4213-878b-770e8597ac16"); + + public static DocumentHashAlgorithm ToHashAlgorithm (this Guid guid) + { + if (guid == hash_md5) + return DocumentHashAlgorithm.MD5; + + if (guid == hash_sha1) + return DocumentHashAlgorithm.SHA1; + + if (guid == hash_sha256) + return DocumentHashAlgorithm.SHA256; + + return DocumentHashAlgorithm.None; + } + + public static Guid ToGuid (this DocumentHashAlgorithm hash_algo) + { + if (hash_algo == DocumentHashAlgorithm.MD5) + return hash_md5; + + if (hash_algo == DocumentHashAlgorithm.SHA1) + return hash_sha1; + + if (hash_algo == DocumentHashAlgorithm.SHA256) + return hash_sha256; + + return new Guid (); + } + + public static DocumentLanguage ToLanguage (this Guid guid) + { + DocumentLanguage language; + if (!guid_language.TryGetValue (guid, out language)) + return DocumentLanguage.Other; + + return language; + } + + public static Guid ToGuid (this DocumentLanguage language) + { + Guid guid; + if (!language_guid.TryGetValue (language, out guid)) + return new Guid (); + + return guid; + } + + static readonly Guid vendor_ms = new Guid ("994b45c4-e6e9-11d2-903f-00c04fa302a1"); + + public static DocumentLanguageVendor ToVendor (this Guid guid) + { + if (guid == vendor_ms) + return DocumentLanguageVendor.Microsoft; + + return DocumentLanguageVendor.Other; + } + + public static Guid ToGuid (this DocumentLanguageVendor vendor) + { + if (vendor == DocumentLanguageVendor.Microsoft) + return vendor_ms; + + return new Guid (); + } + } +} diff --git a/cecil-master/Mono.Cecil.Cil/SequencePoint.cs b/cecil-master/Mono.Cecil.Cil/SequencePoint.cs new file mode 100644 index 000000000..725d307ae --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/SequencePoint.cs @@ -0,0 +1,76 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil.Cil { + + public sealed class SequencePoint { + + internal InstructionOffset offset; + Document document; + + int start_line; + int start_column; + int end_line; + int end_column; + + public int Offset { + get { return offset.Offset; } + } + + 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 bool IsHidden { + get { return start_line == 0xfeefee && start_line == end_line; } + } + + public Document Document { + get { return document; } + set { document = value; } + } + + internal SequencePoint (int offset, Document document) + { + if (document == null) + throw new ArgumentNullException ("document"); + + this.offset = new InstructionOffset (offset); + this.document = document; + } + + public SequencePoint (Instruction instruction, Document document) + { + if (document == null) + throw new ArgumentNullException ("document"); + + this.offset = new InstructionOffset (instruction); + this.document = document; + } + } +} diff --git a/cecil-master/Mono.Cecil.Cil/Symbols.cs b/cecil-master/Mono.Cecil.Cil/Symbols.cs new file mode 100644 index 000000000..744e7a82b --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/Symbols.cs @@ -0,0 +1,1228 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; +using SR = System.Reflection; + +using Mono.Collections.Generic; +using Mono.Cecil.Cil; +using Mono.Cecil.PE; + +namespace Mono.Cecil.Cil { + + [StructLayout (LayoutKind.Sequential)] + public struct ImageDebugDirectory { + public const int Size = 28; + + public int Characteristics; + public int TimeDateStamp; + public short MajorVersion; + public short MinorVersion; + public ImageDebugType Type; + public int SizeOfData; + public int AddressOfRawData; + public int PointerToRawData; + } + + public enum ImageDebugType { + CodeView = 2, + Deterministic = 16, + EmbeddedPortablePdb = 17, + PdbChecksum = 19, + } + + public sealed class ImageDebugHeader { + + readonly ImageDebugHeaderEntry [] entries; + + public bool HasEntries { + get { return !entries.IsNullOrEmpty (); } + } + + public ImageDebugHeaderEntry [] Entries { + get { return entries; } + } + + public ImageDebugHeader (ImageDebugHeaderEntry [] entries) + { + this.entries = entries ?? Empty.Array; + } + + public ImageDebugHeader () + : this (Empty.Array) + { + } + + public ImageDebugHeader (ImageDebugHeaderEntry entry) + : this (new [] { entry }) + { + } + } + + public sealed class ImageDebugHeaderEntry { + + ImageDebugDirectory directory; + readonly byte [] data; + + public ImageDebugDirectory Directory { + get { return directory; } + internal set { directory = value; } + } + + public byte [] Data { + get { return data; } + } + + public ImageDebugHeaderEntry (ImageDebugDirectory directory, byte [] data) + { + this.directory = directory; + this.data = data ?? Empty.Array; + } + } + + public sealed class ScopeDebugInformation : DebugInformation { + + internal InstructionOffset start; + internal InstructionOffset end; + internal ImportDebugInformation import; + internal Collection scopes; + internal Collection variables; + internal Collection constants; + + public InstructionOffset Start { + get { return start; } + set { start = value; } + } + + public InstructionOffset End { + get { return end; } + set { end = value; } + } + + public ImportDebugInformation Import { + get { return import; } + set { import = value; } + } + + public bool HasScopes { + get { return !scopes.IsNullOrEmpty (); } + } + + public Collection Scopes { + get { + if (scopes == null) + Interlocked.CompareExchange (ref scopes, new Collection (), null); + + return scopes; + } + } + + public bool HasVariables { + get { return !variables.IsNullOrEmpty (); } + } + + public Collection Variables { + get { + if (variables == null) + Interlocked.CompareExchange (ref variables, new Collection (), null); + + return variables; + } + } + + public bool HasConstants { + get { return !constants.IsNullOrEmpty (); } + } + + public Collection Constants { + get { + if (constants == null) + Interlocked.CompareExchange (ref constants, new Collection (), null); + + return constants; + } + } + + internal ScopeDebugInformation () + { + this.token = new MetadataToken (TokenType.LocalScope); + } + + public ScopeDebugInformation (Instruction start, Instruction end) + : this () + { + if (start == null) + throw new ArgumentNullException ("start"); + + this.start = new InstructionOffset (start); + + if (end != null) + this.end = new InstructionOffset (end); + } + + public bool TryGetName (VariableDefinition variable, out string name) + { + name = null; + if (variables == null || variables.Count == 0) + return false; + + for (int i = 0; i < variables.Count; i++) { + if (variables [i].Index == variable.Index) { + name = variables [i].Name; + return true; + } + } + + return false; + } + } + + public struct InstructionOffset { + + readonly Instruction instruction; + readonly int? offset; + + public int Offset { + get { + if (instruction != null) + return instruction.Offset; + if (offset.HasValue) + return offset.Value; + + throw new NotSupportedException (); + } + } + + public bool IsEndOfMethod { + get { return instruction == null && !offset.HasValue; } + } + + internal bool IsResolved => instruction != null || !offset.HasValue; + + internal Instruction ResolvedInstruction => instruction; + + public InstructionOffset (Instruction instruction) + { + if (instruction == null) + throw new ArgumentNullException ("instruction"); + + this.instruction = instruction; + this.offset = null; + } + + public InstructionOffset (int offset) + { + this.instruction = null; + this.offset = offset; + } + } + + [Flags] + public enum VariableAttributes : ushort { + None = 0, + DebuggerHidden = 1, + } + + public struct VariableIndex { + readonly VariableDefinition variable; + readonly int? index; + + public int Index { + get { + if (variable != null) + return variable.Index; + if (index.HasValue) + return index.Value; + + throw new NotSupportedException (); + } + } + + internal bool IsResolved => variable != null; + + internal VariableDefinition ResolvedVariable => variable; + + public VariableIndex (VariableDefinition variable) + { + if (variable == null) + throw new ArgumentNullException ("variable"); + + this.variable = variable; + this.index = null; + } + + public VariableIndex (int index) + { + this.variable = null; + this.index = index; + } + } + + public abstract class DebugInformation : ICustomDebugInformationProvider { + + internal MetadataToken token; + internal Collection custom_infos; + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + public bool HasCustomDebugInformations { + get { return !custom_infos.IsNullOrEmpty (); } + } + + public Collection CustomDebugInformations { + get { + if (custom_infos == null) + Interlocked.CompareExchange (ref custom_infos, new Collection (), null); + + return custom_infos; + } + } + + internal DebugInformation () + { + } + } + + public sealed class VariableDebugInformation : DebugInformation { + + string name; + ushort attributes; + internal VariableIndex index; + + public int Index { + get { return index.Index; } + } + + public string Name { + get { return name; } + set { name = value; } + } + + public VariableAttributes Attributes { + get { return (VariableAttributes) attributes; } + set { attributes = (ushort) value; } + } + + public bool IsDebuggerHidden { + get { return attributes.GetAttributes ((ushort) VariableAttributes.DebuggerHidden); } + set { attributes = attributes.SetAttributes ((ushort) VariableAttributes.DebuggerHidden, value); } + } + + internal VariableDebugInformation (int index, string name) + { + if (name == null) + throw new ArgumentNullException ("name"); + + this.index = new VariableIndex (index); + this.name = name; + } + + public VariableDebugInformation (VariableDefinition variable, string name) + { + if (variable == null) + throw new ArgumentNullException ("variable"); + if (name == null) + throw new ArgumentNullException ("name"); + + this.index = new VariableIndex (variable); + this.name = name; + this.token = new MetadataToken (TokenType.LocalVariable); + } + } + + public sealed class ConstantDebugInformation : DebugInformation { + + string name; + TypeReference constant_type; + object value; + + public string Name { + get { return name; } + set { name = value; } + } + + public TypeReference ConstantType { + get { return constant_type; } + set { constant_type = value; } + } + + public object Value { + get { return value; } + set { this.value = value; } + } + + public ConstantDebugInformation (string name, TypeReference constant_type, object value) + { + if (name == null) + throw new ArgumentNullException ("name"); + + this.name = name; + this.constant_type = constant_type; + this.value = value; + this.token = new MetadataToken (TokenType.LocalConstant); + } + } + + public enum ImportTargetKind : byte { + ImportNamespace = 1, + ImportNamespaceInAssembly = 2, + ImportType = 3, + ImportXmlNamespaceWithAlias = 4, + ImportAlias = 5, + DefineAssemblyAlias = 6, + DefineNamespaceAlias = 7, + DefineNamespaceInAssemblyAlias = 8, + DefineTypeAlias = 9, + } + + public sealed class ImportTarget { + + internal ImportTargetKind kind; + + internal string @namespace; + internal TypeReference type; + internal AssemblyNameReference reference; + internal string alias; + + public string Namespace { + get { return @namespace; } + set { @namespace = value; } + } + + public TypeReference Type { + get { return type; } + set { type = value; } + } + + public AssemblyNameReference AssemblyReference { + get { return reference; } + set { reference = value; } + } + + public string Alias { + get { return alias; } + set { alias = value; } + } + + public ImportTargetKind Kind { + get { return kind; } + set { kind = value; } + } + + public ImportTarget (ImportTargetKind kind) + { + this.kind = kind; + } + } + + public sealed class ImportDebugInformation : DebugInformation { + + internal ImportDebugInformation parent; + internal Collection targets; + + public bool HasTargets { + get { return !targets.IsNullOrEmpty (); } + } + + public Collection Targets { + get + { + if (targets == null) + Interlocked.CompareExchange (ref targets, new Collection (), null); + + return targets; + } + } + + public ImportDebugInformation Parent { + get { return parent; } + set { parent = value; } + } + + public ImportDebugInformation () + { + this.token = new MetadataToken (TokenType.ImportScope); + } + } + + public interface ICustomDebugInformationProvider : IMetadataTokenProvider { + bool HasCustomDebugInformations { get; } + Collection CustomDebugInformations { get; } + } + + public enum CustomDebugInformationKind { + Binary, + StateMachineScope, + DynamicVariable, + DefaultNamespace, + AsyncMethodBody, + EmbeddedSource, + SourceLink, + } + + public abstract class CustomDebugInformation : DebugInformation { + + Guid identifier; + + public Guid Identifier { + get { return identifier; } + } + + public abstract CustomDebugInformationKind Kind { get; } + + internal CustomDebugInformation (Guid identifier) + { + this.identifier = identifier; + this.token = new MetadataToken (TokenType.CustomDebugInformation); + } + } + + public sealed class BinaryCustomDebugInformation : CustomDebugInformation { + + byte [] data; + + public byte [] Data { + get { return data; } + set { data = value; } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.Binary; } + } + + public BinaryCustomDebugInformation (Guid identifier, byte [] data) + : base (identifier) + { + this.data = data; + } + } + + public sealed class AsyncMethodBodyDebugInformation : CustomDebugInformation { + + internal InstructionOffset catch_handler; + internal Collection yields; + internal Collection resumes; + internal Collection resume_methods; + + public InstructionOffset CatchHandler { + get { return catch_handler; } + set { catch_handler = value; } + } + + public Collection Yields { + get { + if (yields == null) + Interlocked.CompareExchange (ref yields, new Collection (), null); + + return yields; + } + } + + public Collection Resumes { + get { + if (resumes == null) + Interlocked.CompareExchange (ref resumes, new Collection (), null); + + return resumes; + } + } + + public Collection ResumeMethods { + get { return resume_methods ?? (resume_methods = new Collection ()); } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.AsyncMethodBody; } + } + + public static Guid KindIdentifier = new Guid ("{54FD2AC5-E925-401A-9C2A-F94F171072F8}"); + + internal AsyncMethodBodyDebugInformation (int catchHandler) + : base (KindIdentifier) + { + this.catch_handler = new InstructionOffset (catchHandler); + } + + public AsyncMethodBodyDebugInformation (Instruction catchHandler) + : base (KindIdentifier) + { + this.catch_handler = new InstructionOffset (catchHandler); + } + + public AsyncMethodBodyDebugInformation () + : base (KindIdentifier) + { + this.catch_handler = new InstructionOffset (-1); + } + } + + public sealed class StateMachineScope { + + internal InstructionOffset start; + internal InstructionOffset end; + + public InstructionOffset Start { + get { return start; } + set { start = value; } + } + + public InstructionOffset End { + get { return end; } + set { end = value; } + } + + internal StateMachineScope (int start, int end) + { + this.start = new InstructionOffset (start); + this.end = new InstructionOffset (end); + } + + public StateMachineScope (Instruction start, Instruction end) + { + this.start = new InstructionOffset (start); + this.end = end != null ? new InstructionOffset (end) : new InstructionOffset (); + } + } + + public sealed class StateMachineScopeDebugInformation : CustomDebugInformation { + + internal Collection scopes; + + public Collection Scopes { + get { return scopes ?? (scopes = new Collection ()); } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.StateMachineScope; } + } + + public static Guid KindIdentifier = new Guid ("{6DA9A61E-F8C7-4874-BE62-68BC5630DF71}"); + + public StateMachineScopeDebugInformation () + : base (KindIdentifier) + { + } + } + + public sealed class EmbeddedSourceDebugInformation : CustomDebugInformation { + + internal uint index; + internal MetadataReader debug_reader; + internal bool resolved; + internal byte [] content; + internal bool compress; + + public byte [] Content { + get { + if (!resolved) + Resolve (); + + return content; + } + set { + content = value; + resolved = true; + } + } + + public bool Compress { + get { + if (!resolved) + Resolve (); + + return compress; + } + set { + compress = value; + resolved = true; + } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.EmbeddedSource; } + } + + public static Guid KindIdentifier = new Guid ("{0E8A571B-6926-466E-B4AD-8AB04611F5FE}"); + + internal EmbeddedSourceDebugInformation (uint index, MetadataReader debug_reader) + : base (KindIdentifier) + { + this.index = index; + this.debug_reader = debug_reader; + } + + public EmbeddedSourceDebugInformation (byte [] content, bool compress) + : base (KindIdentifier) + { + this.resolved = true; + this.content = content; + this.compress = compress; + } + + internal byte [] ReadRawEmbeddedSourceDebugInformation () + { + if (debug_reader == null) + throw new InvalidOperationException (); + + return debug_reader.ReadRawEmbeddedSourceDebugInformation (index); + } + + void Resolve () + { + if (resolved) + return; + + if (debug_reader == null) + throw new InvalidOperationException (); + + var row = debug_reader.ReadEmbeddedSourceDebugInformation (index); + content = row.Col1; + compress = row.Col2; + resolved = true; + } + } + + public sealed class SourceLinkDebugInformation : CustomDebugInformation { + + internal string content; + + public string Content { + get { return content; } + set { content = value; } + } + + public override CustomDebugInformationKind Kind { + get { return CustomDebugInformationKind.SourceLink; } + } + + public static Guid KindIdentifier = new Guid ("{CC110556-A091-4D38-9FEC-25AB9A351A6A}"); + + public SourceLinkDebugInformation (string content) + : base (KindIdentifier) + { + this.content = content; + } + } + + public sealed class MethodDebugInformation : DebugInformation { + + internal MethodDefinition method; + internal Collection sequence_points; + internal ScopeDebugInformation scope; + internal MethodDefinition kickoff_method; + internal int code_size; + internal MetadataToken local_var_token; + + public MethodDefinition Method { + get { return method; } + } + + public bool HasSequencePoints { + get { return !sequence_points.IsNullOrEmpty (); } + } + + public Collection SequencePoints { + get { + if (sequence_points == null) + Interlocked.CompareExchange (ref sequence_points, new Collection (), null); + + return sequence_points; + } + } + + public ScopeDebugInformation Scope { + get { return scope; } + set { scope = value; } + } + + public MethodDefinition StateMachineKickOffMethod { + get { return kickoff_method; } + set { kickoff_method = value; } + } + + internal MethodDebugInformation (MethodDefinition method) + { + if (method == null) + throw new ArgumentNullException ("method"); + + this.method = method; + this.token = new MetadataToken (TokenType.MethodDebugInformation, method.MetadataToken.RID); + } + + public SequencePoint GetSequencePoint (Instruction instruction) + { + if (!HasSequencePoints) + return null; + + for (int i = 0; i < sequence_points.Count; i++) + if (sequence_points [i].Offset == instruction.Offset) + return sequence_points [i]; + + return null; + } + + public IDictionary GetSequencePointMapping () + { + var instruction_mapping = new Dictionary (); + if (!HasSequencePoints || !method.HasBody) + return instruction_mapping; + + var offset_mapping = new Dictionary (sequence_points.Count); + + for (int i = 0; i < sequence_points.Count; i++) { + if (!offset_mapping.ContainsKey (sequence_points [i].Offset)) + offset_mapping.Add (sequence_points [i].Offset, sequence_points [i]); + } + + var instructions = method.Body.Instructions; + + for (int i = 0; i < instructions.Count; i++) { + SequencePoint sequence_point; + if (offset_mapping.TryGetValue (instructions [i].Offset, out sequence_point)) + instruction_mapping.Add (instructions [i], sequence_point); + } + + return instruction_mapping; + } + + public IEnumerable GetScopes () + { + if (scope == null) + return Empty.Array; + + return GetScopes (new[] { scope }); + } + + static IEnumerable GetScopes (IList scopes) + { + for (int i = 0; i < scopes.Count; i++) { + var scope = scopes [i]; + + yield return scope; + + if (!scope.HasScopes) + continue; + + foreach (var sub_scope in GetScopes (scope.Scopes)) + yield return sub_scope; + } + } + + public bool TryGetName (VariableDefinition variable, out string name) + { + name = null; + + var has_name = false; + var unique_name = ""; + + foreach (var scope in GetScopes ()) { + string slot_name; + if (!scope.TryGetName (variable, out slot_name)) + continue; + + if (!has_name) { + has_name = true; + unique_name = slot_name; + continue; + } + + if (unique_name != slot_name) + return false; + } + + name = unique_name; + return has_name; + } + } + + public interface ISymbolReader : IDisposable { + + ISymbolWriterProvider GetWriterProvider (); + bool ProcessDebugHeader (ImageDebugHeader header); + MethodDebugInformation Read (MethodDefinition method); + } + + public interface ISymbolReaderProvider { + ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName); + ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream); + } + +#if !NET_CORE + [Serializable] +#endif + public sealed class SymbolsNotFoundException : FileNotFoundException { + + public SymbolsNotFoundException (string message) : base (message) + { + } + +#if !NET_CORE + SymbolsNotFoundException ( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base (info, context) + { + } +#endif + } + +#if !NET_CORE + [Serializable] +#endif + public sealed class SymbolsNotMatchingException : InvalidOperationException { + + public SymbolsNotMatchingException (string message) : base (message) + { + } + +#if !NET_CORE + SymbolsNotMatchingException ( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base (info, context) + { + } +#endif + } + + public class DefaultSymbolReaderProvider : ISymbolReaderProvider { + + readonly bool throw_if_no_symbol; + + public DefaultSymbolReaderProvider () + : this (throwIfNoSymbol: true) + { + } + + public DefaultSymbolReaderProvider (bool throwIfNoSymbol) + { + throw_if_no_symbol = throwIfNoSymbol; + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, string fileName) + { + if (module.Image.HasDebugTables ()) + return null; + + if (module.HasDebugHeader) { + var header = module.GetDebugHeader (); + var entry = header.GetEmbeddedPortablePdbEntry (); + if (entry != null) + return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, fileName); + } + + var pdb_file_name = Mixin.GetPdbFileName (fileName); + + if (File.Exists (pdb_file_name)) { + if (Mixin.IsPortablePdb (Mixin.GetPdbFileName (fileName))) + return new PortablePdbReaderProvider ().GetSymbolReader (module, fileName); + + try { + return SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, fileName); + } catch (Exception) { + // We might not include support for native pdbs. + } + } + + var mdb_file_name = Mixin.GetMdbFileName (fileName); + if (File.Exists (mdb_file_name)) { + try { + return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, fileName); + } catch (Exception) { + // We might not include support for mdbs. + } + } + + if (throw_if_no_symbol) + throw new SymbolsNotFoundException (string.Format ("No symbol found for file: {0}", fileName)); + + return null; + } + + public ISymbolReader GetSymbolReader (ModuleDefinition module, Stream symbolStream) + { + if (module.Image.HasDebugTables ()) + return null; + + if (module.HasDebugHeader) { + var header = module.GetDebugHeader (); + var entry = header.GetEmbeddedPortablePdbEntry (); + if (entry != null) + return new EmbeddedPortablePdbReaderProvider ().GetSymbolReader (module, ""); + } + + Mixin.CheckStream (symbolStream); + Mixin.CheckReadSeek (symbolStream); + + var position = symbolStream.Position; + + const int portablePdbHeader = 0x424a5342; + + var reader = new BinaryStreamReader (symbolStream); + var intHeader = reader.ReadInt32 (); + symbolStream.Position = position; + + if (intHeader == portablePdbHeader) { + return new PortablePdbReaderProvider ().GetSymbolReader (module, symbolStream); + } + + const string nativePdbHeader = "Microsoft C/C++ MSF 7.00"; + + var bytesHeader = reader.ReadBytes (nativePdbHeader.Length); + symbolStream.Position = position; + var isNativePdb = true; + + for (var i = 0; i < bytesHeader.Length; i++) { + if (bytesHeader [i] != (byte) nativePdbHeader [i]) { + isNativePdb = false; + break; + } + } + + if (isNativePdb) { + try { + return SymbolProvider.GetReaderProvider (SymbolKind.NativePdb).GetSymbolReader (module, symbolStream); + } catch (Exception) { + // We might not include support for native pdbs. + } + } + + const long mdbHeader = 0x45e82623fd7fa614; + + var longHeader = reader.ReadInt64 (); + symbolStream.Position = position; + + if (longHeader == mdbHeader) { + try { + return SymbolProvider.GetReaderProvider (SymbolKind.Mdb).GetSymbolReader (module, symbolStream); + } catch (Exception) { + // We might not include support for mdbs. + } + } + + if (throw_if_no_symbol) + throw new SymbolsNotFoundException (string.Format ("No symbols found in stream")); + + return null; + } + } + + enum SymbolKind { + NativePdb, + PortablePdb, + EmbeddedPortablePdb, + Mdb, + } + + static class SymbolProvider { + + static SR.AssemblyName GetSymbolAssemblyName (SymbolKind kind) + { + if (kind == SymbolKind.PortablePdb) + throw new ArgumentException (); + + var suffix = GetSymbolNamespace (kind); + + var cecil_name = typeof (SymbolProvider).Assembly.GetName (); + + var name = new SR.AssemblyName { + Name = cecil_name.Name + "." + suffix, + Version = cecil_name.Version, +#if NET_CORE + CultureName = cecil_name.CultureName, +#else + CultureInfo = cecil_name.CultureInfo, +#endif + }; + + name.SetPublicKeyToken (cecil_name.GetPublicKeyToken ()); + + return name; + } + + static Type GetSymbolType (SymbolKind kind, string fullname) + { + var type = Type.GetType (fullname); + if (type != null) + return type; + + var assembly_name = GetSymbolAssemblyName (kind); + + 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) { + } catch (FileLoadException) { + } + + return null; + } + + public static ISymbolReaderProvider GetReaderProvider (SymbolKind kind) + { + if (kind == SymbolKind.PortablePdb) + return new PortablePdbReaderProvider (); + if (kind == SymbolKind.EmbeddedPortablePdb) + return new EmbeddedPortablePdbReaderProvider (); + + var provider_name = GetSymbolTypeName (kind, "ReaderProvider"); + var type = GetSymbolType (kind, provider_name); + if (type == null) + throw new TypeLoadException ("Could not find symbol provider type " + provider_name); + + return (ISymbolReaderProvider) Activator.CreateInstance (type); + } + + static string GetSymbolTypeName (SymbolKind kind, string name) + { + return "Mono.Cecil" + "." + GetSymbolNamespace (kind) + "." + kind + name; + } + + static string GetSymbolNamespace (SymbolKind kind) + { + if (kind == SymbolKind.PortablePdb || kind == SymbolKind.EmbeddedPortablePdb) + return "Cil"; + if (kind == SymbolKind.NativePdb) + return "Pdb"; + if (kind == SymbolKind.Mdb) + return "Mdb"; + + throw new ArgumentException (); + } + } + + public interface ISymbolWriter : IDisposable { + + ISymbolReaderProvider GetReaderProvider (); + ImageDebugHeader GetDebugHeader (); + void Write (MethodDebugInformation info); + void Write (); + } + + public interface ISymbolWriterProvider { + + ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName); + ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream); + } + + public class DefaultSymbolWriterProvider : ISymbolWriterProvider { + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + var reader = module.SymbolReader; + if (reader == null) + throw new InvalidOperationException (); + + if (module.Image != null && module.Image.HasDebugTables ()) + return null; + + return reader.GetWriterProvider ().GetSymbolWriter (module, fileName); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + throw new NotSupportedException (); + } + } +} + +namespace Mono.Cecil { + + static partial class Mixin { + + public static ImageDebugHeaderEntry GetCodeViewEntry (this ImageDebugHeader header) + { + return GetEntry (header, ImageDebugType.CodeView); + } + + public static ImageDebugHeaderEntry GetDeterministicEntry (this ImageDebugHeader header) + { + return GetEntry (header, ImageDebugType.Deterministic); + } + + public static ImageDebugHeader AddDeterministicEntry (this ImageDebugHeader header) + { + var entry = new ImageDebugHeaderEntry (new ImageDebugDirectory { Type = ImageDebugType.Deterministic }, Empty.Array); + if (header == null) + return new ImageDebugHeader (entry); + + var entries = new ImageDebugHeaderEntry [header.Entries.Length + 1]; + Array.Copy (header.Entries, entries, header.Entries.Length); + entries [entries.Length - 1] = entry; + return new ImageDebugHeader (entries); + } + + public static ImageDebugHeaderEntry GetEmbeddedPortablePdbEntry (this ImageDebugHeader header) + { + return GetEntry (header, ImageDebugType.EmbeddedPortablePdb); + } + + public static ImageDebugHeaderEntry GetPdbChecksumEntry (this ImageDebugHeader header) + { + return GetEntry (header, ImageDebugType.PdbChecksum); + } + + private static ImageDebugHeaderEntry GetEntry (this ImageDebugHeader header, ImageDebugType type) + { + if (!header.HasEntries) + return null; + + for (var i = 0; i < header.Entries.Length; i++) { + var entry = header.Entries [i]; + if (entry.Directory.Type == type) + return entry; + } + + return null; + } + + public static string GetPdbFileName (string assemblyFileName) + { + return Path.ChangeExtension (assemblyFileName, ".pdb"); + } + + public static string GetMdbFileName (string assemblyFileName) + { + return assemblyFileName + ".mdb"; + } + + public static bool IsPortablePdb (string fileName) + { + using (var file = new FileStream (fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) + return IsPortablePdb (file); + } + + public static bool IsPortablePdb (Stream stream) + { + const uint ppdb_signature = 0x424a5342; + + if (stream.Length < 4) return false; + var position = stream.Position; + try { + var reader = new BinaryReader (stream); + return reader.ReadUInt32 () == ppdb_signature; + } finally { + stream.Position = position; + } + } + } +} diff --git a/cecil-master/Mono.Cecil.Cil/VariableDefinition.cs b/cecil-master/Mono.Cecil.Cil/VariableDefinition.cs new file mode 100644 index 000000000..bd1328464 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/VariableDefinition.cs @@ -0,0 +1,29 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Cil { + + public sealed class VariableDefinition : VariableReference { + + public bool IsPinned { + get { return variable_type.IsPinned; } + } + + public VariableDefinition (TypeReference variableType) + : base (variableType) + { + } + + public override VariableDefinition Resolve () + { + return this; + } + } +} diff --git a/cecil-master/Mono.Cecil.Cil/VariableReference.cs b/cecil-master/Mono.Cecil.Cil/VariableReference.cs new file mode 100644 index 000000000..fb12e8c14 --- /dev/null +++ b/cecil-master/Mono.Cecil.Cil/VariableReference.cs @@ -0,0 +1,42 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Cil { + + public abstract class VariableReference { + + internal int index = -1; + protected TypeReference variable_type; + + public TypeReference VariableType { + get { return variable_type; } + set { variable_type = value; } + } + + public int Index { + get { return index; } + } + + internal VariableReference (TypeReference variable_type) + { + this.variable_type = variable_type; + } + + public abstract VariableDefinition Resolve (); + + public override string ToString () + { + if (index >= 0) + return "V_" + index; + + return string.Empty; + } + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/BlobHeap.cs b/cecil-master/Mono.Cecil.Metadata/BlobHeap.cs new file mode 100644 index 000000000..574a130c9 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/BlobHeap.cs @@ -0,0 +1,54 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil.Metadata { + + sealed class BlobHeap : Heap { + + public BlobHeap (byte [] data) + : base (data) + { + } + + public byte [] Read (uint index) + { + if (index == 0 || index > this.data.Length - 1) + return Empty.Array; + + int position = (int) index; + int length = (int) data.ReadCompressedUInt32 (ref position); + + if (length > data.Length - position) + return Empty.Array; + + var buffer = new byte [length]; + + Buffer.BlockCopy (data, position, buffer, 0, length); + + return buffer; + } + + public void GetView (uint signature, out byte [] buffer, out int index, out int length) + { + if (signature == 0 || signature > data.Length - 1) { + buffer = null; + index = length = 0; + return; + } + + buffer = data; + + index = (int) signature; + length = (int) buffer.ReadCompressedUInt32 (ref index); + } + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/Buffers.cs b/cecil-master/Mono.Cecil.Metadata/Buffers.cs new file mode 100644 index 000000000..b32dd43ef --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/Buffers.cs @@ -0,0 +1,517 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.Text; + +using Mono.Cecil.PE; + +using RVA = System.UInt32; + +namespace Mono.Cecil.Metadata { + + sealed class TableHeapBuffer : HeapBuffer { + + readonly ModuleDefinition module; + readonly MetadataBuilder metadata; + + readonly internal TableInformation [] table_infos = new TableInformation [Mixin.TableCount]; + readonly internal MetadataTable [] tables = new MetadataTable [Mixin.TableCount]; + + bool large_string; + bool large_blob; + bool large_guid; + + readonly int [] coded_index_sizes = new int [Mixin.CodedIndexCount]; + readonly Func counter; + + internal uint [] string_offsets; + + public override bool IsEmpty { + get { return false; } + } + + public TableHeapBuffer (ModuleDefinition module, MetadataBuilder metadata) + : base (24) + { + this.module = module; + this.metadata = metadata; + this.counter = GetTableLength; + } + + int GetTableLength (Table table) + { + return (int) table_infos [(int) table].Length; + } + + public TTable GetTable (Table table) where TTable : MetadataTable, new () + { + var md_table = (TTable) tables [(int) table]; + if (md_table != null) + return md_table; + + md_table = new TTable (); + tables [(int) table] = md_table; + return md_table; + } + + public void WriteBySize (uint value, int size) + { + if (size == 4) + WriteUInt32 (value); + else + WriteUInt16 ((ushort) value); + } + + public void WriteBySize (uint value, bool large) + { + if (large) + WriteUInt32 (value); + else + WriteUInt16 ((ushort) value); + } + + public void WriteString (uint @string) + { + WriteBySize (string_offsets [@string], large_string); + } + + public void WriteBlob (uint blob) + { + WriteBySize (blob, large_blob); + } + + public void WriteGuid (uint guid) + { + WriteBySize (guid, large_guid); + } + + public void WriteRID (uint rid, Table table) + { + WriteBySize (rid, table_infos [(int) table].IsLarge); + } + + 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] = coded_index.GetSize (counter); + } + + public void WriteCodedRID (uint rid, CodedIndex coded_index) + { + WriteBySize (rid, GetCodedIndexSize (coded_index)); + } + + public void WriteTableHeap () + { + WriteUInt32 (0); // Reserved + WriteByte (GetTableHeapVersion ()); // MajorVersion + WriteByte (0); // MinorVersion + WriteByte (GetHeapSizes ()); // HeapSizes + WriteByte (10); // Reserved2 + WriteUInt64 (GetValid ()); // Valid + WriteUInt64 (0xc416003301fa00); // Sorted + + WriteRowCount (); + WriteTables (); + } + + void WriteRowCount () + { + for (int i = 0; i < tables.Length; i++) { + var table = tables [i]; + if (table == null || table.Length == 0) + continue; + + WriteUInt32 ((uint) table.Length); + } + } + + void WriteTables () + { + for (int i = 0; i < tables.Length; i++) { + var table = tables [i]; + if (table == null || table.Length == 0) + continue; + + table.Write (this); + } + } + + ulong GetValid () + { + ulong valid = 0; + + for (int i = 0; i < tables.Length; i++) { + var table = tables [i]; + if (table == null || table.Length == 0) + continue; + + table.Sort (); + valid |= (1UL << i); + } + + return valid; + } + + public void ComputeTableInformations () + { + if (metadata.metadata_builder != null) + ComputeTableInformations (metadata.metadata_builder.table_heap); + + ComputeTableInformations (metadata.table_heap); + } + + void ComputeTableInformations (TableHeapBuffer table_heap) + { + var tables = table_heap.tables; + for (int i = 0; i < tables.Length; i++) { + var table = tables [i]; + if (table != null && table.Length > 0) + table_infos [i].Length = (uint) table.Length; + } + } + + byte GetHeapSizes () + { + byte heap_sizes = 0; + + if (metadata.string_heap.IsLarge) { + large_string = true; + heap_sizes |= 0x01; + } + + if (metadata.guid_heap.IsLarge) { + large_guid = true; + heap_sizes |= 0x02; + } + + if (metadata.blob_heap.IsLarge) { + large_blob = true; + heap_sizes |= 0x04; + } + + return heap_sizes; + } + + byte GetTableHeapVersion () + { + switch (module.Runtime) { + case TargetRuntime.Net_1_0: + case TargetRuntime.Net_1_1: + return 1; + default: + return 2; + } + } + + public void FixupData (RVA data_rva) + { + var table = GetTable (Table.FieldRVA); + if (table.length == 0) + return; + + var field_idx_size = GetTable (Table.Field).IsLarge ? 4 : 2; + var previous = this.position; + + base.position = table.position; + for (int i = 0; i < table.length; i++) { + var rva = ReadUInt32 (); + base.position -= 4; + WriteUInt32 (rva + data_rva); + base.position += field_idx_size; + } + + base.position = previous; + } + } + + sealed class ResourceBuffer : ByteBuffer { + + public ResourceBuffer () + : base (0) + { + } + + public uint AddResource (byte [] resource) + { + var offset = (uint) this.position; + WriteInt32 (resource.Length); + WriteBytes (resource); + return offset; + } + } + + sealed class DataBuffer : ByteBuffer { + + int buffer_align = 4; + + public DataBuffer () + : base (0) + { + } + + void Align (int align) + { + align--; + // Compute the number of bytes to align the current position. + // Values of 0 will be written. + WriteBytes (((position + align) & ~align) - position); + } + + public RVA AddData (byte [] data, int align) + { + if (buffer_align < align) + buffer_align = align; + + Align (align); + var rva = (RVA) position; + WriteBytes (data); + return rva; + } + + public int BufferAlign => buffer_align; + } + + abstract class HeapBuffer : ByteBuffer { + + public bool IsLarge { + get { return base.length > 65535; } + } + + public abstract bool IsEmpty { get; } + + protected HeapBuffer (int length) + : base (length) + { + } + } + + sealed class GuidHeapBuffer : HeapBuffer { + + readonly Dictionary guids = new Dictionary (); + + public override bool IsEmpty { + get { return length == 0; } + } + + public GuidHeapBuffer () + : base (16) + { + } + + public uint GetGuidIndex (Guid guid) + { + uint index; + if (guids.TryGetValue (guid, out index)) + return index; + + index = (uint) guids.Count + 1; + WriteGuid (guid); + guids.Add (guid, index); + return index; + } + + void WriteGuid (Guid guid) + { + WriteBytes (guid.ToByteArray ()); + } + } + + class StringHeapBuffer : HeapBuffer { + + protected Dictionary strings = new Dictionary (StringComparer.Ordinal); + + public sealed override bool IsEmpty { + get { return length <= 1; } + } + + public StringHeapBuffer () + : base (1) + { + WriteByte (0); + } + + public virtual uint GetStringIndex (string @string) + { + uint index; + if (strings.TryGetValue (@string, out index)) + return index; + + index = (uint) strings.Count + 1; + strings.Add (@string, index); + return index; + } + + public uint [] WriteStrings () + { + var sorted = SortStrings (strings); + strings = null; + + // Add 1 for empty string whose index and offset are both 0 + var string_offsets = new uint [sorted.Count + 1]; + string_offsets [0] = 0; + + // Find strings that can be folded + var previous = string.Empty; + foreach (var entry in sorted) { + var @string = entry.Key; + var index = entry.Value; + var position = base.position; + + if (previous.EndsWith (@string, StringComparison.Ordinal) && !IsLowSurrogateChar (entry.Key [0])) { + // Map over the tail of prev string. Watch for null-terminator of prev string. + string_offsets [index] = (uint) (position - (Encoding.UTF8.GetByteCount (entry.Key) + 1)); + } else { + string_offsets [index] = (uint) position; + WriteString (@string); + } + + previous = entry.Key; + } + + return string_offsets; + } + + static List> SortStrings (Dictionary strings) + { + var sorted = new List> (strings); + sorted.Sort (new SuffixSort ()); + return sorted; + } + + static bool IsLowSurrogateChar (int c) + { + return unchecked((uint)(c - 0xDC00)) <= 0xDFFF - 0xDC00; + } + + protected virtual void WriteString (string @string) + { + WriteBytes (Encoding.UTF8.GetBytes (@string)); + WriteByte (0); + } + + // Sorts strings such that a string is followed immediately by all strings + // that are a suffix of it. + private class SuffixSort : IComparer> { + + public int Compare(KeyValuePair xPair, KeyValuePair yPair) + { + var x = xPair.Key; + var y = yPair.Key; + + for (int i = x.Length - 1, j = y.Length - 1; i >= 0 & j >= 0; i--, j--) { + if (x [i] < y [j]) { + return -1; + } + + if (x [i] > y [j]) { + return +1; + } + } + + return y.Length.CompareTo (x.Length); + } + } + } + + sealed class BlobHeapBuffer : HeapBuffer { + + readonly Dictionary blobs = new Dictionary (new ByteBufferEqualityComparer ()); + + public override bool IsEmpty { + get { return length <= 1; } + } + + public BlobHeapBuffer () + : base (1) + { + WriteByte (0); + } + + public uint GetBlobIndex (ByteBuffer blob) + { + uint index; + if (blobs.TryGetValue (blob, out index)) + return index; + + index = (uint) base.position; + WriteBlob (blob); + blobs.Add (blob, index); + return index; + } + + void WriteBlob (ByteBuffer blob) + { + WriteCompressedUInt32 ((uint) blob.length); + WriteBytes (blob); + } + } + + sealed class UserStringHeapBuffer : StringHeapBuffer { + + public override uint GetStringIndex (string @string) + { + uint index; + if (strings.TryGetValue (@string, out index)) + return index; + + index = (uint) base.position; + WriteString (@string); + strings.Add (@string, index); + return index; + } + + protected override void WriteString (string @string) + { + WriteCompressedUInt32 ((uint) @string.Length * 2 + 1); + + byte special = 0; + + for (int i = 0; i < @string.Length; i++) { + var @char = @string [i]; + WriteUInt16 (@char); + + if (special == 1) + continue; + + if (@char < 0x20 || @char > 0x7e) { + if (@char > 0x7e + || (@char >= 0x01 && @char <= 0x08) + || (@char >= 0x0e && @char <= 0x1f) + || @char == 0x27 + || @char == 0x2d) { + + special = 1; + } + } + } + + WriteByte (special); + } + } + + sealed class PdbHeapBuffer : HeapBuffer { + + public override bool IsEmpty { + get { return false; } + } + + public PdbHeapBuffer () + : base (0) + { + } + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/CodedIndex.cs b/cecil-master/Mono.Cecil.Metadata/CodedIndex.cs new file mode 100644 index 000000000..2026a8a7d --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/CodedIndex.cs @@ -0,0 +1,29 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Metadata { + + enum CodedIndex { + TypeDefOrRef, + HasConstant, + HasCustomAttribute, + HasFieldMarshal, + HasDeclSecurity, + MemberRefParent, + HasSemantics, + MethodDefOrRef, + MemberForwarded, + Implementation, + CustomAttributeType, + ResolutionScope, + TypeOrMethodDef, + HasCustomDebugInformation, + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/ElementType.cs b/cecil-master/Mono.Cecil.Metadata/ElementType.cs new file mode 100644 index 000000000..2190160a6 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/ElementType.cs @@ -0,0 +1,55 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil.Metadata/GuidHeap.cs b/cecil-master/Mono.Cecil.Metadata/GuidHeap.cs new file mode 100644 index 000000000..76ec9d1d1 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/GuidHeap.cs @@ -0,0 +1,36 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil.Metadata { + + sealed class GuidHeap : Heap { + + public GuidHeap (byte [] data) + : base (data) + { + } + + public Guid Read (uint index) + { + const int guid_size = 16; + + if (index == 0 || ((index - 1) + guid_size) > data.Length) + return new Guid (); + + var buffer = new byte [guid_size]; + + Buffer.BlockCopy (this.data, (int) ((index - 1) * guid_size), buffer, 0, guid_size); + + return new Guid (buffer); + } + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/Heap.cs b/cecil-master/Mono.Cecil.Metadata/Heap.cs new file mode 100644 index 000000000..6874d7963 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/Heap.cs @@ -0,0 +1,24 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Metadata { + + abstract class Heap { + + public int IndexSize; + + readonly internal byte [] data; + + protected Heap (byte [] data) + { + this.data = data; + } + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/MetadataToken.cs b/cecil-master/Mono.Cecil.Metadata/MetadataToken.cs new file mode 100644 index 000000000..a8b712e7f --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/MetadataToken.cs @@ -0,0 +1,94 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil { + + public struct MetadataToken : IEquatable { + + 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 bool Equals (MetadataToken other) + { + return other.token == 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/cecil-master/Mono.Cecil.Metadata/PdbHeap.cs b/cecil-master/Mono.Cecil.Metadata/PdbHeap.cs new file mode 100644 index 000000000..39e275ad9 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/PdbHeap.cs @@ -0,0 +1,34 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using Mono.Cecil.PE; + +using RID = System.UInt32; + +namespace Mono.Cecil.Metadata { + + sealed class PdbHeap : Heap { + + public byte [] Id; + public RID EntryPoint; + public long TypeSystemTables; + public uint [] TypeSystemTableRows; + + public PdbHeap (byte [] data) + : base (data) + { + } + + public bool HasTable (Table table) + { + return (TypeSystemTables & (1L << (int) table)) != 0; + } + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/Row.cs b/cecil-master/Mono.Cecil.Metadata/Row.cs new file mode 100644 index 000000000..0c05ebade --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/Row.cs @@ -0,0 +1,152 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System.Collections.Generic; + +namespace Mono.Cecil.Metadata { + + struct Row { + internal T1 Col1; + internal T2 Col2; + + public Row (T1 col1, T2 col2) + { + Col1 = col1; + Col2 = col2; + } + } + + struct Row { + internal T1 Col1; + internal T2 Col2; + internal T3 Col3; + + public Row (T1 col1, T2 col2, T3 col3) + { + Col1 = col1; + Col2 = col2; + Col3 = col3; + } + } + + struct 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; + } + } + + struct 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; + } + } + + struct 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; + } + } + + struct 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/cecil-master/Mono.Cecil.Metadata/StringHeap.cs b/cecil-master/Mono.Cecil.Metadata/StringHeap.cs new file mode 100644 index 000000000..4bde70e23 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/StringHeap.cs @@ -0,0 +1,60 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Mono.Cecil.Metadata { + + class StringHeap : Heap { + + readonly Dictionary strings = new Dictionary (); + + public StringHeap (byte [] data) + : base (data) + { + } + + public string Read (uint index) + { + if (index == 0) + return string.Empty; + + string @string; + if (strings.TryGetValue (index, out @string)) + return @string; + + if (index > data.Length - 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; + int start = (int) index; + + for (int i = start; ; i++) { + if (data [i] == 0) + break; + + length++; + } + + return Encoding.UTF8.GetString (data, start, length); + } + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/TableHeap.cs b/cecil-master/Mono.Cecil.Metadata/TableHeap.cs new file mode 100644 index 000000000..dee655a34 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/TableHeap.cs @@ -0,0 +1,104 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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, + + Document = 0x30, + MethodDebugInformation = 0x31, + LocalScope = 0x32, + LocalVariable = 0x33, + LocalConstant = 0x34, + ImportScope = 0x35, + StateMachineMethod = 0x36, + CustomDebugInformation = 0x37, + } + + struct TableInformation { + public uint Offset; + public uint Length; + public uint RowSize; + + public bool IsLarge { + get { return Length > ushort.MaxValue; } + } + } + + sealed class TableHeap : Heap { + + public long Valid; + public long Sorted; + + public readonly TableInformation [] Tables = new TableInformation [Mixin.TableCount]; + + public TableInformation this [Table table] { + get { return Tables [(int) table]; } + } + + public TableHeap (byte [] data) + : base (data) + { + } + + public bool HasTable (Table table) + { + return (Valid & (1L << (int) table)) != 0; + } + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/TokenType.cs b/cecil-master/Mono.Cecil.Metadata/TokenType.cs new file mode 100644 index 000000000..547f6c647 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/TokenType.cs @@ -0,0 +1,49 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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, + GenericParamConstraint = 0x2c000000, + + Document = 0x30000000, + MethodDebugInformation = 0x31000000, + LocalScope = 0x32000000, + LocalVariable = 0x33000000, + LocalConstant = 0x34000000, + ImportScope = 0x35000000, + StateMachineMethod = 0x36000000, + CustomDebugInformation = 0x37000000, + + String = 0x70000000, + } +} diff --git a/cecil-master/Mono.Cecil.Metadata/UserStringHeap.cs b/cecil-master/Mono.Cecil.Metadata/UserStringHeap.cs new file mode 100644 index 000000000..7b1b42ffa --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/UserStringHeap.cs @@ -0,0 +1,36 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil.Metadata { + + sealed class UserStringHeap : StringHeap { + + public UserStringHeap (byte [] data) + : base (data) + { + } + + protected override string ReadStringAt (uint index) + { + int start = (int) index; + + uint length = (uint) (data.ReadCompressedUInt32 (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/cecil-master/Mono.Cecil.Metadata/Utilities.cs b/cecil-master/Mono.Cecil.Metadata/Utilities.cs new file mode 100644 index 000000000..e29987251 --- /dev/null +++ b/cecil-master/Mono.Cecil.Metadata/Utilities.cs @@ -0,0 +1,650 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + static partial class Mixin { + + public const int TableCount = 58; + public const int CodedIndexCount = 14; + + public static uint ReadCompressedUInt32 (this 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 (this 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; + case 20: + token_type = TokenType.GenericParamConstraint; goto ret; + case 21: + token_type = TokenType.MethodSpec; 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; + } + case CodedIndex.HasCustomDebugInformation: + 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; + case 20: + token_type = TokenType.GenericParamConstraint; goto ret; + case 21: + token_type = TokenType.MethodSpec; goto ret; + case 22: + token_type = TokenType.Document; goto ret; + case 23: + token_type = TokenType.LocalScope; goto ret; + case 24: + token_type = TokenType.LocalVariable; goto ret; + case 25: + token_type = TokenType.LocalConstant; goto ret; + case 26: + token_type = TokenType.ImportScope; goto ret; + default: + goto exit; + } + default: + goto exit; + } + ret: + return new MetadataToken (token_type, rid); + exit: + return MetadataToken.Zero; + } + + public static uint CompressMetadataToken (this CodedIndex self, MetadataToken token) + { + uint ret = 0; + if (token.RID == 0) + return ret; + switch (self) { + case CodedIndex.TypeDefOrRef: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.TypeDef: + return ret | 0; + case TokenType.TypeRef: + return ret | 1; + case TokenType.TypeSpec: + return ret | 2; + default: + goto exit; + } + case CodedIndex.HasConstant: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.Field: + return ret | 0; + case TokenType.Param: + return ret | 1; + case TokenType.Property: + return ret | 2; + default: + goto exit; + } + case CodedIndex.HasCustomAttribute: + ret = token.RID << 5; + switch (token.TokenType) { + case TokenType.Method: + return ret | 0; + case TokenType.Field: + return ret | 1; + case TokenType.TypeRef: + return ret | 2; + case TokenType.TypeDef: + return ret | 3; + case TokenType.Param: + return ret | 4; + case TokenType.InterfaceImpl: + return ret | 5; + case TokenType.MemberRef: + return ret | 6; + case TokenType.Module: + return ret | 7; + case TokenType.Permission: + return ret | 8; + case TokenType.Property: + return ret | 9; + case TokenType.Event: + return ret | 10; + case TokenType.Signature: + return ret | 11; + case TokenType.ModuleRef: + return ret | 12; + case TokenType.TypeSpec: + return ret | 13; + case TokenType.Assembly: + return ret | 14; + case TokenType.AssemblyRef: + return ret | 15; + case TokenType.File: + return ret | 16; + case TokenType.ExportedType: + return ret | 17; + case TokenType.ManifestResource: + return ret | 18; + case TokenType.GenericParam: + return ret | 19; + case TokenType.GenericParamConstraint: + return ret | 20; + case TokenType.MethodSpec: + return ret | 21; + default: + goto exit; + } + case CodedIndex.HasFieldMarshal: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Field: + return ret | 0; + case TokenType.Param: + return ret | 1; + default: + goto exit; + } + case CodedIndex.HasDeclSecurity: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.TypeDef: + return ret | 0; + case TokenType.Method: + return ret | 1; + case TokenType.Assembly: + return ret | 2; + default: + goto exit; + } + case CodedIndex.MemberRefParent: + ret = token.RID << 3; + switch (token.TokenType) { + case TokenType.TypeDef: + return ret | 0; + case TokenType.TypeRef: + return ret | 1; + case TokenType.ModuleRef: + return ret | 2; + case TokenType.Method: + return ret | 3; + case TokenType.TypeSpec: + return ret | 4; + default: + goto exit; + } + case CodedIndex.HasSemantics: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Event: + return ret | 0; + case TokenType.Property: + return ret | 1; + default: + goto exit; + } + case CodedIndex.MethodDefOrRef: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Method: + return ret | 0; + case TokenType.MemberRef: + return ret | 1; + default: + goto exit; + } + case CodedIndex.MemberForwarded: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.Field: + return ret | 0; + case TokenType.Method: + return ret | 1; + default: + goto exit; + } + case CodedIndex.Implementation: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.File: + return ret | 0; + case TokenType.AssemblyRef: + return ret | 1; + case TokenType.ExportedType: + return ret | 2; + default: + goto exit; + } + case CodedIndex.CustomAttributeType: + ret = token.RID << 3; + switch (token.TokenType) { + case TokenType.Method: + return ret | 2; + case TokenType.MemberRef: + return ret | 3; + default: + goto exit; + } + case CodedIndex.ResolutionScope: + ret = token.RID << 2; + switch (token.TokenType) { + case TokenType.Module: + return ret | 0; + case TokenType.ModuleRef: + return ret | 1; + case TokenType.AssemblyRef: + return ret | 2; + case TokenType.TypeRef: + return ret | 3; + default: + goto exit; + } + case CodedIndex.TypeOrMethodDef: + ret = token.RID << 1; + switch (token.TokenType) { + case TokenType.TypeDef: + return ret | 0; + case TokenType.Method: + return ret | 1; + default: + goto exit; + } + case CodedIndex.HasCustomDebugInformation: + ret = token.RID << 5; + switch (token.TokenType) { + case TokenType.Method: + return ret | 0; + case TokenType.Field: + return ret | 1; + case TokenType.TypeRef: + return ret | 2; + case TokenType.TypeDef: + return ret | 3; + case TokenType.Param: + return ret | 4; + case TokenType.InterfaceImpl: + return ret | 5; + case TokenType.MemberRef: + return ret | 6; + case TokenType.Module: + return ret | 7; + case TokenType.Permission: + return ret | 8; + case TokenType.Property: + return ret | 9; + case TokenType.Event: + return ret | 10; + case TokenType.Signature: + return ret | 11; + case TokenType.ModuleRef: + return ret | 12; + case TokenType.TypeSpec: + return ret | 13; + case TokenType.Assembly: + return ret | 14; + case TokenType.AssemblyRef: + return ret | 15; + case TokenType.File: + return ret | 16; + case TokenType.ExportedType: + return ret | 17; + case TokenType.ManifestResource: + return ret | 18; + case TokenType.GenericParam: + return ret | 19; + case TokenType.GenericParamConstraint: + return ret | 20; + case TokenType.MethodSpec: + return ret | 21; + case TokenType.Document: + return ret | 22; + case TokenType.LocalScope: + return ret | 23; + case TokenType.LocalVariable: + return ret | 24; + case TokenType.LocalConstant: + return ret | 25; + case TokenType.ImportScope: + return ret | 26; + default: + goto exit; + } + default: + goto exit; + } + exit: + throw new ArgumentException (); + } + + public static int GetSize (this 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, Table.GenericParamConstraint, Table.MethodSpec, + }; + 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; + case CodedIndex.HasCustomDebugInformation: + 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, Table.GenericParamConstraint, Table.MethodSpec, + Table.Document, Table.LocalScope, Table.LocalVariable, Table.LocalConstant, Table.ImportScope, + }; + 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/cecil-master/Mono.Cecil.PE/BinaryStreamReader.cs b/cecil-master/Mono.Cecil.PE/BinaryStreamReader.cs new file mode 100644 index 000000000..812adbc58 --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/BinaryStreamReader.cs @@ -0,0 +1,54 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.IO; + +namespace Mono.Cecil.PE { + + class BinaryStreamReader : BinaryReader { + + public int Position { + get { return (int) BaseStream.Position; } + set { BaseStream.Position = value; } + } + + public int Length { + get { return (int) BaseStream.Length; } + } + + public BinaryStreamReader (Stream stream) + : base (stream) + { + } + + public void Advance (int bytes) + { + BaseStream.Seek (bytes, SeekOrigin.Current); + } + + public void MoveTo (uint position) + { + BaseStream.Seek (position, SeekOrigin.Begin); + } + + public void Align (int align) + { + align--; + var position = Position; + Advance (((position + align) & ~align) - position); + } + + public DataDirectory ReadDataDirectory () + { + return new DataDirectory (ReadUInt32 (), ReadUInt32 ()); + } + } +} diff --git a/cecil-master/Mono.Cecil.PE/BinaryStreamWriter.cs b/cecil-master/Mono.Cecil.PE/BinaryStreamWriter.cs new file mode 100644 index 000000000..9c85a425b --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/BinaryStreamWriter.cs @@ -0,0 +1,89 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.IO; + +namespace Mono.Cecil.PE { + + class BinaryStreamWriter : BinaryWriter { + + public int Position { + get { return (int) BaseStream.Position; } + set { BaseStream.Position = value; } + } + + public BinaryStreamWriter (Stream stream) + : base (stream) + { + } + + public void WriteByte (byte value) + { + Write (value); + } + + public void WriteUInt16 (ushort value) + { + Write (value); + } + + public void WriteInt16 (short value) + { + Write (value); + } + + public void WriteUInt32 (uint value) + { + Write (value); + } + + public void WriteInt32 (int value) + { + Write (value); + } + + public void WriteUInt64 (ulong value) + { + Write (value); + } + + public void WriteBytes (byte [] bytes) + { + Write (bytes); + } + + public void WriteDataDirectory (DataDirectory directory) + { + Write (directory.VirtualAddress); + Write (directory.Size); + } + + public void WriteBuffer (ByteBuffer buffer) + { + Write (buffer.buffer, 0, buffer.length); + } + + protected void Advance (int bytes) + { + BaseStream.Seek (bytes, SeekOrigin.Current); + } + + public void Align (int align) + { + align--; + var position = Position; + var bytes = ((position + align) & ~align) - position; + + for (int i = 0; i < bytes; i++) + WriteByte (0); + } + } +} diff --git a/cecil-master/Mono.Cecil.PE/ByteBuffer.cs b/cecil-master/Mono.Cecil.PE/ByteBuffer.cs new file mode 100644 index 000000000..9a6567ce1 --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/ByteBuffer.cs @@ -0,0 +1,336 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 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 b = buffer [position]; + var u = (int) ReadCompressedUInt32 (); + var v = u >> 1; + if ((u & 1) == 0) + return v; + + switch (b & 0xc0) + { + case 0: + case 0x40: + return v - 0x40; + case 0x80: + return v - 0x2000; + default: + return v - 0x10000000; + } + } + + 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; + } + + public void WriteByte (byte value) + { + if (position == buffer.Length) + Grow (1); + + buffer [position++] = value; + + if (position > length) + length = position; + } + + public void WriteSByte (sbyte value) + { + WriteByte ((byte) value); + } + + public void WriteUInt16 (ushort value) + { + if (position + 2 > buffer.Length) + Grow (2); + + buffer [position++] = (byte) value; + buffer [position++] = (byte) (value >> 8); + + if (position > length) + length = position; + } + + public void WriteInt16 (short value) + { + WriteUInt16 ((ushort) value); + } + + public void WriteUInt32 (uint value) + { + if (position + 4 > buffer.Length) + Grow (4); + + buffer [position++] = (byte) value; + buffer [position++] = (byte) (value >> 8); + buffer [position++] = (byte) (value >> 16); + buffer [position++] = (byte) (value >> 24); + + if (position > length) + length = position; + } + + public void WriteInt32 (int value) + { + WriteUInt32 ((uint) value); + } + + public void WriteUInt64 (ulong value) + { + if (position + 8 > buffer.Length) + Grow (8); + + buffer [position++] = (byte) value; + buffer [position++] = (byte) (value >> 8); + buffer [position++] = (byte) (value >> 16); + buffer [position++] = (byte) (value >> 24); + buffer [position++] = (byte) (value >> 32); + buffer [position++] = (byte) (value >> 40); + buffer [position++] = (byte) (value >> 48); + buffer [position++] = (byte) (value >> 56); + + if (position > length) + length = position; + } + + public void WriteInt64 (long value) + { + WriteUInt64 ((ulong) value); + } + + public void WriteCompressedUInt32 (uint value) + { + if (value < 0x80) + WriteByte ((byte) value); + else if (value < 0x4000) { + WriteByte ((byte) (0x80 | (value >> 8))); + WriteByte ((byte) (value & 0xff)); + } else { + WriteByte ((byte) ((value >> 24) | 0xc0)); + WriteByte ((byte) ((value >> 16) & 0xff)); + WriteByte ((byte) ((value >> 8) & 0xff)); + WriteByte ((byte) (value & 0xff)); + } + } + + public void WriteCompressedInt32 (int value) + { + if (value >= 0) { + WriteCompressedUInt32 ((uint) (value << 1)); + return; + } + + if (value > -0x40) + value = 0x40 + value; + else if (value >= -0x2000) + value = 0x2000 + value; + else if (value >= -0x20000000) + value = 0x20000000 + value; + + WriteCompressedUInt32 ((uint) ((value << 1) | 1)); + } + + public void WriteBytes (byte [] bytes) + { + var length = bytes.Length; + if (position + length > buffer.Length) + Grow (length); + + Buffer.BlockCopy (bytes, 0, buffer, position, length); + position += length; + + if (position > this.length) + this.length = position; + } + + public void WriteBytes (int length) + { + if (position + length > buffer.Length) + Grow (length); + + position += length; + + if (position > this.length) + this.length = position; + } + + public void WriteBytes (ByteBuffer buffer) + { + if (position + buffer.length > this.buffer.Length) + Grow (buffer.length); + + Buffer.BlockCopy (buffer.buffer, 0, this.buffer, position, buffer.length); + position += buffer.length; + + if (position > this.length) + this.length = position; + } + + public void WriteSingle (float value) + { + var bytes = BitConverter.GetBytes (value); + + if (!BitConverter.IsLittleEndian) + Array.Reverse (bytes); + + WriteBytes (bytes); + } + + public void WriteDouble (double value) + { + var bytes = BitConverter.GetBytes (value); + + if (!BitConverter.IsLittleEndian) + Array.Reverse (bytes); + + WriteBytes (bytes); + } + + void Grow (int desired) + { + var current = this.buffer; + var current_length = current.Length; + + var buffer = new byte [System.Math.Max (current_length + desired, current_length * 2)]; + Buffer.BlockCopy (current, 0, buffer, 0, current_length); + this.buffer = buffer; + } + } +} diff --git a/cecil-master/Mono.Cecil.PE/ByteBufferEqualityComparer.cs b/cecil-master/Mono.Cecil.PE/ByteBufferEqualityComparer.cs new file mode 100644 index 000000000..8b7cb238e --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/ByteBufferEqualityComparer.cs @@ -0,0 +1,48 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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) + { + // See http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function + const int fnv_offset_bias = unchecked((int)2166136261); + const int fnv_prime = 16777619; + + var hash_code = fnv_offset_bias; + var bytes = buffer.buffer; + + for (int i = 0; i < buffer.length; i++) + hash_code = unchecked ((hash_code ^ bytes [i]) * fnv_prime); + + return hash_code; + } + } +} diff --git a/cecil-master/Mono.Cecil.PE/DataDirectory.cs b/cecil-master/Mono.Cecil.PE/DataDirectory.cs new file mode 100644 index 000000000..4922dd2f4 --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/DataDirectory.cs @@ -0,0 +1,32 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil.PE/Image.cs b/cecil-master/Mono.Cecil.PE/Image.cs new file mode 100644 index 000000000..97e69c010 --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/Image.cs @@ -0,0 +1,171 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.IO; + +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + sealed class Image : IDisposable { + + public Disposable Stream; + public string FileName; + + public ModuleKind Kind; + public uint Characteristics; + public string RuntimeVersion; + public TargetArchitecture Architecture; + public ModuleCharacteristics DllCharacteristics; + public ushort LinkerVersion; + public ushort SubSystemMajor; + public ushort SubSystemMinor; + + public ImageDebugHeader DebugHeader; + + public Section [] Sections; + + public Section MetadataSection; + + public uint EntryPointToken; + public uint Timestamp; + public ModuleAttributes Attributes; + + public DataDirectory Win32Resources; + public DataDirectory Debug; + public DataDirectory Resources; + public DataDirectory StrongName; + + public StringHeap StringHeap; + public BlobHeap BlobHeap; + public UserStringHeap UserStringHeap; + public GuidHeap GuidHeap; + public TableHeap TableHeap; + public PdbHeap PdbHeap; + + readonly int [] coded_index_sizes = new int [14]; + + 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] = coded_index.GetSize (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; + } + + BinaryStreamReader GetReaderAt (RVA rva) + { + var section = GetSectionAtVirtualAddress (rva); + if (section == null) + return null; + + var reader = new BinaryStreamReader (Stream.value); + reader.MoveTo (ResolveVirtualAddressInSection (rva, section)); + return reader; + } + + public TRet GetReaderAt (RVA rva, TItem item, Func read) where TRet : class + { + var position = Stream.value.Position; + try { + var reader = GetReaderAt (rva); + if (reader == null) + return null; + + return read (item, reader); + } finally { + Stream.value.Position = position; + } + } + + public bool HasDebugTables () + { + return HasTable (Table.Document) + || HasTable (Table.MethodDebugInformation) + || HasTable (Table.LocalScope) + || HasTable (Table.LocalVariable) + || HasTable (Table.LocalConstant) + || HasTable (Table.StateMachineMethod) + || HasTable (Table.CustomDebugInformation); + } + + public void Dispose () + { + Stream.Dispose (); + } + } +} diff --git a/cecil-master/Mono.Cecil.PE/ImageReader.cs b/cecil-master/Mono.Cecil.PE/ImageReader.cs new file mode 100644 index 000000000..a34e64d36 --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/ImageReader.cs @@ -0,0 +1,797 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.IO; + +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + sealed class ImageReader : BinaryStreamReader { + + readonly Image image; + + DataDirectory cli; + DataDirectory metadata; + + uint table_heap_offset; + uint pdb_heap_offset; + + public ImageReader (Disposable stream, string file_name) + : base (stream.value) + { + image = new Image (); + image.Stream = stream; + image.FileName = file_name; + } + + void MoveTo (DataDirectory directory) + { + BaseStream.Position = image.ResolveVirtualAddress (directory.VirtualAddress); + } + + 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 + image.Timestamp = ReadUInt32 (); + // PointerToSymbolTable 4 + // NumberOfSymbols 4 + // OptionalHeaderSize 2 + Advance (10); + + // Characteristics 2 + ushort characteristics = ReadUInt16 (); + + ushort subsystem, dll_characteristics; + ReadOptionalHeaders (out subsystem, out dll_characteristics); + ReadSections (sections); + ReadCLIHeader (); + ReadMetadata (); + ReadDebugHeader (); + + image.Characteristics = characteristics; + image.Kind = GetModuleKind (characteristics, subsystem); + image.DllCharacteristics = (ModuleCharacteristics) dll_characteristics; + } + + TargetArchitecture ReadArchitecture () + { + return (TargetArchitecture) ReadUInt16 (); + } + + 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 + + image.LinkerVersion = ReadUInt16 (); + // 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 + Advance(44); + + image.SubSystemMajor = ReadUInt16 (); + image.SubSystemMinor = ReadUInt16 (); + + // Reserved 4 + // ImageSize 4 + // HeaderSize 4 + // FileChecksum 4 + Advance (16); + + // 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 + + Advance (pe64 ? 56 : 40); + + // ResourceTable 8 + + image.Win32Resources = ReadDataDirectory (); + + // ExceptionTable 8 + // CertificateTable 8 + // BaseRelocationTable 8 + + Advance (24); + + // 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; + } + + image.Sections = sections; + } + + 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); + + image.RuntimeVersion = ReadZeroTerminatedString (ReadInt32 ()); + + // 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.PdbHeap != null) + ReadPdbHeap (); + + if (image.TableHeap != null) + ReadTableHeap (); + } + + void ReadDebugHeader () + { + if (image.Debug.IsZero) { + image.DebugHeader = new ImageDebugHeader (Empty.Array); + return; + } + + MoveTo (image.Debug); + + var entries = new ImageDebugHeaderEntry [(int) image.Debug.Size / ImageDebugDirectory.Size]; + + for (int i = 0; i < entries.Length; i++) { + var directory = new ImageDebugDirectory { + Characteristics = ReadInt32 (), + TimeDateStamp = ReadInt32 (), + MajorVersion = ReadInt16 (), + MinorVersion = ReadInt16 (), + Type = (ImageDebugType) ReadInt32 (), + SizeOfData = ReadInt32 (), + AddressOfRawData = ReadInt32 (), + PointerToRawData = ReadInt32 (), + }; + + if (directory.PointerToRawData == 0 || directory.SizeOfData < 0) { + entries [i] = new ImageDebugHeaderEntry (directory, Empty.Array); + continue; + } + + var position = Position; + try { + MoveTo ((uint) directory.PointerToRawData); + var data = ReadBytes (directory.SizeOfData); + entries [i] = new ImageDebugHeaderEntry (directory, data); + } finally { + Position = position; + } + } + + image.DebugHeader = new ImageDebugHeader (entries); + } + + void ReadMetadataStream (Section section) + { + // Offset 4 + uint offset = metadata.VirtualAddress - section.VirtualAddress + ReadUInt32 (); // relative to the section start + + // Size 4 + uint size = ReadUInt32 (); + + var data = ReadHeapData (offset, size); + + var name = ReadAlignedString (16); + switch (name) { + case "#~": + case "#-": + image.TableHeap = new TableHeap (data); + table_heap_offset = offset; + break; + case "#Strings": + image.StringHeap = new StringHeap (data); + break; + case "#Blob": + image.BlobHeap = new BlobHeap (data); + break; + case "#GUID": + image.GuidHeap = new GuidHeap (data); + break; + case "#US": + image.UserStringHeap = new UserStringHeap (data); + break; + case "#Pdb": + image.PdbHeap = new PdbHeap (data); + pdb_heap_offset = offset; + break; + } + } + + byte [] ReadHeapData (uint offset, uint size) + { + var position = BaseStream.Position; + MoveTo (offset + image.MetadataSection.PointerToRawData); + var data = ReadBytes ((int) size); + BaseStream.Position = position; + + return data; + } + + void ReadTableHeap () + { + var heap = image.TableHeap; + + MoveTo (table_heap_offset + image.MetadataSection.PointerToRawData); + + // 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 (); + + if (image.PdbHeap != null) { + for (int i = 0; i < Mixin.TableCount; i++) { + if (!image.PdbHeap.HasTable ((Table) i)) + continue; + + heap.Tables [i].Length = image.PdbHeap.TypeSystemTableRows [i]; + } + } + + for (int i = 0; i < Mixin.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 - table_heap_offset - image.MetadataSection.PointerToRawData; // header + + int stridx_size = image.StringHeap != null ? image.StringHeap.IndexSize : 2; + int guididx_size = image.GuidHeap != null ? image.GuidHeap.IndexSize : 2; + int blobidx_size = image.BlobHeap != null ? image.BlobHeap.IndexSize : 2; + + var heap = image.TableHeap; + var tables = heap.Tables; + + for (int i = 0; i < Mixin.TableCount; i++) { + var table = (Table) i; + if (!heap.HasTable (table)) + continue; + + int size; + switch (table) { + case Table.Module: + size = 2 // Generation + + stridx_size // Name + + (guididx_size * 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: + size = 8; + break; + 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; + case Table.Document: + size = blobidx_size // Name + + guididx_size // HashAlgorithm + + blobidx_size // Hash + + guididx_size; // Language + break; + case Table.MethodDebugInformation: + size = GetTableIndexSize (Table.Document) // Document + + blobidx_size; // SequencePoints + break; + case Table.LocalScope: + size = GetTableIndexSize (Table.Method) // Method + + GetTableIndexSize (Table.ImportScope) // ImportScope + + GetTableIndexSize (Table.LocalVariable) // VariableList + + GetTableIndexSize (Table.LocalConstant) // ConstantList + + 4 * 2; // StartOffset, Length + break; + case Table.LocalVariable: + size = 2 // Attributes + + 2 // Index + + stridx_size; // Name + break; + case Table.LocalConstant: + size = stridx_size // Name + + blobidx_size; // Signature + break; + case Table.ImportScope: + size = GetTableIndexSize (Table.ImportScope) // Parent + + blobidx_size; + break; + case Table.StateMachineMethod: + size = GetTableIndexSize (Table.Method) // MoveNextMethod + + GetTableIndexSize (Table.Method); // KickOffMethod + break; + case Table.CustomDebugInformation: + size = GetCodedIndexSize (CodedIndex.HasCustomDebugInformation) // Parent + + guididx_size // Kind + + blobidx_size; // Value + break; + default: + throw new NotSupportedException (); + } + + tables [i].RowSize = (uint) size; + tables [i].Offset = offset; + + offset += (uint) size * tables [i].Length; + } + } + + void ReadPdbHeap () + { + var heap = image.PdbHeap; + + var buffer = new ByteBuffer (heap.data); + + heap.Id = buffer.ReadBytes (20); + heap.EntryPoint = buffer.ReadUInt32 (); + heap.TypeSystemTables = buffer.ReadInt64 (); + heap.TypeSystemTableRows = new uint [Mixin.TableCount]; + + for (int i = 0; i < Mixin.TableCount; i++) { + var table = (Table) i; + if (!heap.HasTable (table)) + continue; + + heap.TypeSystemTableRows [i] = buffer.ReadUInt32 (); + } + } + + public static Image ReadImage (Disposable stream, string file_name) + { + try { + var reader = new ImageReader (stream, file_name); + reader.ReadImage (); + return reader.image; + } catch (EndOfStreamException e) { + throw new BadImageFormatException (stream.value.GetFileName (), e); + } + } + + public static Image ReadPortablePdb (Disposable stream, string file_name, out uint pdb_heap_offset) + { + try { + var reader = new ImageReader (stream, file_name); + var length = (uint) stream.value.Length; + + reader.image.Sections = new[] { + new Section { + PointerToRawData = 0, + SizeOfRawData = length, + VirtualAddress = 0, + VirtualSize = length, + } + }; + + reader.metadata = new DataDirectory (0, length); + reader.ReadMetadata (); + pdb_heap_offset = reader.pdb_heap_offset; + return reader.image; + } catch (EndOfStreamException e) { + throw new BadImageFormatException (stream.value.GetFileName (), e); + } + } + } +} diff --git a/cecil-master/Mono.Cecil.PE/ImageWriter.cs b/cecil-master/Mono.Cecil.PE/ImageWriter.cs new file mode 100644 index 000000000..3d8d8898a --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/ImageWriter.cs @@ -0,0 +1,866 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.IO; + +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + sealed class ImageWriter : BinaryStreamWriter { + + readonly ModuleDefinition module; + readonly MetadataBuilder metadata; + readonly TextMap text_map; + readonly internal Disposable stream; + + readonly string runtime_version; + + ImageDebugHeader debug_header; + + ByteBuffer win32_resources; + + const uint pe_header_size = 0x98u; + const uint section_header_size = 0x28u; + const uint file_alignment = 0x200; + const uint section_alignment = 0x2000; + const ulong image_base = 0x00400000; + + internal const RVA text_rva = 0x2000; + + readonly bool pe64; + readonly bool has_reloc; + + internal Section text; + internal Section rsrc; + internal Section reloc; + + ushort sections; + + internal long debug_header_entries_position; + + ImageWriter (ModuleDefinition module, string runtime_version, MetadataBuilder metadata, Disposable stream, bool metadataOnly = false) + : base (stream.value) + { + this.module = module; + this.runtime_version = runtime_version; + this.text_map = metadata.text_map; + this.stream = stream; + this.metadata = metadata; + if (metadataOnly) + return; + + this.pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64 || module.Architecture == TargetArchitecture.ARM64; + this.has_reloc = module.Architecture == TargetArchitecture.I386; + this.GetDebugHeader (); + this.GetWin32Resources (); + this.BuildTextMap (); + this.sections = (ushort)(has_reloc ? 2 : 1); // text + reloc? + } + + void GetDebugHeader () + { + var symbol_writer = metadata.symbol_writer; + if (symbol_writer != null) + debug_header = symbol_writer.GetDebugHeader (); + + if (module.HasDebugHeader) { + var header = module.GetDebugHeader (); + var deterministic = header.GetDeterministicEntry (); + if (deterministic == null) + return; + + debug_header = debug_header.AddDeterministicEntry (); + } + } + + void GetWin32Resources () + { + if (!module.HasImage) + return; + + DataDirectory win32_resources_directory = module.Image.Win32Resources; + var size = win32_resources_directory.Size; + + if (size > 0) { + win32_resources = module.Image.GetReaderAt (win32_resources_directory.VirtualAddress, size, (s, reader) => new ByteBuffer (reader.ReadBytes ((int) s))); + } + } + + public static ImageWriter CreateWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable stream) + { + var writer = new ImageWriter (module, module.runtime_version, metadata, stream, metadataOnly: false); + writer.BuildSections (); + return writer; + } + + public static ImageWriter CreateDebugWriter (ModuleDefinition module, MetadataBuilder metadata, Disposable stream) + { + var writer = new ImageWriter (module, "PDB v1.0", metadata, stream, metadataOnly: true); + var length = metadata.text_map.GetLength (); + writer.text = new Section { SizeOfRawData = length, VirtualSize = length }; + return writer; + } + + void BuildSections () + { + var has_win32_resources = win32_resources != null; + if (has_win32_resources) + sections++; + + text = CreateSection (".text", text_map.GetLength (), null); + var previous = text; + + if (has_win32_resources) { + rsrc = CreateSection (".rsrc", (uint) win32_resources.length, previous); + + PatchWin32Resources (win32_resources); + previous = rsrc; + } + + if (has_reloc) + reloc = CreateSection (".reloc", 12u, previous); + } + + Section CreateSection (string name, uint size, Section previous) + { + return new Section { + Name = name, + VirtualAddress = previous != null + ? previous.VirtualAddress + Align (previous.VirtualSize, section_alignment) + : text_rva, + VirtualSize = size, + PointerToRawData = previous != null + ? previous.PointerToRawData + previous.SizeOfRawData + : Align (GetHeaderSize (), file_alignment), + SizeOfRawData = Align (size, file_alignment) + }; + } + + static uint Align (uint value, uint align) + { + align--; + return (value + align) & ~align; + } + + void WriteDOSHeader () + { + Write (new byte [] { + // dos header start + 0x4d, 0x5a, 0x90, 0x00, 0x03, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x00, 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + // lfanew + 0x80, 0x00, 0x00, 0x00, + // dos header end + 0x0e, 0x1f, 0xba, 0x0e, 0x00, 0xb4, 0x09, + 0xcd, 0x21, 0xb8, 0x01, 0x4c, 0xcd, 0x21, + 0x54, 0x68, 0x69, 0x73, 0x20, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x63, + 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, + 0x65, 0x20, 0x72, 0x75, 0x6e, 0x20, 0x69, + 0x6e, 0x20, 0x44, 0x4f, 0x53, 0x20, 0x6d, + 0x6f, 0x64, 0x65, 0x2e, 0x0d, 0x0d, 0x0a, + 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00 + }); + } + + ushort SizeOfOptionalHeader () + { + return (ushort) (!pe64 ? 0xe0 : 0xf0); + } + + void WritePEFileHeader () + { + WriteUInt32 (0x00004550); // Magic + WriteUInt16 ((ushort) module.Architecture); // Machine + WriteUInt16 (sections); // NumberOfSections + WriteUInt32 (metadata.timestamp); + WriteUInt32 (0); // PointerToSymbolTable + WriteUInt32 (0); // NumberOfSymbols + WriteUInt16 (SizeOfOptionalHeader ()); // SizeOfOptionalHeader + + const ushort LargeAddressAware = 0x0020; + + // ExecutableImage | (!pe64 ? 32BitsMachine : LargeAddressAware) + var characteristics = (ushort) (0x0002 | (!pe64 ? 0x0100 : LargeAddressAware)); + if (module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule) + characteristics |= 0x2000; + + if (module.Image != null && (module.Image.Characteristics & LargeAddressAware) != 0) + characteristics |= LargeAddressAware; + + WriteUInt16 (characteristics); // Characteristics + } + + Section LastSection () + { + if (reloc != null) + return reloc; + + if (rsrc != null) + return rsrc; + + return text; + } + + void WriteOptionalHeaders () + { + WriteUInt16 ((ushort) (!pe64 ? 0x10b : 0x20b)); // Magic + WriteUInt16 (module.linker_version); + WriteUInt32 (text.SizeOfRawData); // CodeSize + WriteUInt32 ((reloc != null ? reloc.SizeOfRawData : 0) + + (rsrc != null ? rsrc.SizeOfRawData : 0)); // InitializedDataSize + WriteUInt32 (0); // UninitializedDataSize + + var startub_stub = text_map.GetRange (TextSegment.StartupStub); + WriteUInt32 (startub_stub.Length > 0 ? startub_stub.Start : 0); // EntryPointRVA + WriteUInt32 (text_rva); // BaseOfCode + + if (!pe64) { + WriteUInt32 (0); // BaseOfData + WriteUInt32 ((uint) image_base); // ImageBase + } else { + WriteUInt64 (image_base); // ImageBase + } + + WriteUInt32 (section_alignment); // SectionAlignment + WriteUInt32 (file_alignment); // FileAlignment + + WriteUInt16 (4); // OSMajor + WriteUInt16 (0); // OSMinor + WriteUInt16 (0); // UserMajor + WriteUInt16 (0); // UserMinor + WriteUInt16 (module.subsystem_major); // SubSysMajor + WriteUInt16 (module.subsystem_minor); // SubSysMinor + WriteUInt32 (0); // Reserved + + var last_section = LastSection(); + WriteUInt32 (last_section.VirtualAddress + Align (last_section.VirtualSize, section_alignment)); // ImageSize + WriteUInt32 (text.PointerToRawData); // HeaderSize + + WriteUInt32 (0); // Checksum + WriteUInt16 (GetSubSystem ()); // SubSystem + WriteUInt16 ((ushort) module.Characteristics); // DLLFlags + + if (!pe64) { + const uint stack_reserve = 0x100000; + const uint stack_commit = 0x1000; + const uint heap_reserve = 0x100000; + const uint heap_commit = 0x1000; + + WriteUInt32 (stack_reserve); + WriteUInt32 (stack_commit); + WriteUInt32 (heap_reserve); + WriteUInt32 (heap_commit); + } else { + const ulong stack_reserve = 0x400000; + const ulong stack_commit = 0x4000; + const ulong heap_reserve = 0x100000; + const ulong heap_commit = 0x2000; + + WriteUInt64 (stack_reserve); + WriteUInt64 (stack_commit); + WriteUInt64 (heap_reserve); + WriteUInt64 (heap_commit); + } + + WriteUInt32 (0); // LoaderFlags + WriteUInt32 (16); // NumberOfDataDir + + WriteZeroDataDirectory (); // ExportTable + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.ImportDirectory)); // ImportTable + if (rsrc != null) { // ResourceTable + WriteUInt32 (rsrc.VirtualAddress); + WriteUInt32 (rsrc.VirtualSize); + } else + WriteZeroDataDirectory (); + + WriteZeroDataDirectory (); // ExceptionTable + WriteZeroDataDirectory (); // CertificateTable + WriteUInt32 (reloc != null ? reloc.VirtualAddress : 0); // BaseRelocationTable + WriteUInt32 (reloc != null ? reloc.VirtualSize : 0); + + if (text_map.GetLength (TextSegment.DebugDirectory) > 0) { + WriteUInt32 (text_map.GetRVA (TextSegment.DebugDirectory)); + WriteUInt32 ((uint) (debug_header.Entries.Length * ImageDebugDirectory.Size)); + } else + WriteZeroDataDirectory (); + + WriteZeroDataDirectory (); // Copyright + WriteZeroDataDirectory (); // GlobalPtr + WriteZeroDataDirectory (); // TLSTable + WriteZeroDataDirectory (); // LoadConfigTable + WriteZeroDataDirectory (); // BoundImport + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.ImportAddressTable)); // IAT + WriteZeroDataDirectory (); // DelayImportDesc + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.CLIHeader)); // CLIHeader + WriteZeroDataDirectory (); // Reserved + } + + void WriteZeroDataDirectory () + { + WriteUInt32 (0); + WriteUInt32 (0); + } + + ushort GetSubSystem () + { + switch (module.Kind) { + case ModuleKind.Console: + case ModuleKind.Dll: + case ModuleKind.NetModule: + return 0x3; + case ModuleKind.Windows: + return 0x2; + default: + throw new ArgumentOutOfRangeException (); + } + } + + void WriteSectionHeaders () + { + WriteSection (text, 0x60000020); + + if (rsrc != null) + WriteSection (rsrc, 0x40000040); + + if (reloc != null) + WriteSection (reloc, 0x42000040); + } + + void WriteSection (Section section, uint characteristics) + { + var name = new byte [8]; + var sect_name = section.Name; + for (int i = 0; i < sect_name.Length; i++) + name [i] = (byte) sect_name [i]; + + WriteBytes (name); + WriteUInt32 (section.VirtualSize); + WriteUInt32 (section.VirtualAddress); + WriteUInt32 (section.SizeOfRawData); + WriteUInt32 (section.PointerToRawData); + WriteUInt32 (0); // PointerToRelocations + WriteUInt32 (0); // PointerToLineNumbers + WriteUInt16 (0); // NumberOfRelocations + WriteUInt16 (0); // NumberOfLineNumbers + WriteUInt32 (characteristics); + } + + uint GetRVAFileOffset (Section section, RVA rva) + { + return section.PointerToRawData + rva - section.VirtualAddress; + } + + void MoveTo (uint pointer) + { + BaseStream.Seek (pointer, SeekOrigin.Begin); + } + + void MoveToRVA (Section section, RVA rva) + { + BaseStream.Seek (GetRVAFileOffset (section, rva), SeekOrigin.Begin); + } + + internal void MoveToRVA (TextSegment segment) + { + MoveToRVA (text, text_map.GetRVA (segment)); + } + + void WriteRVA (RVA rva) + { + if (!pe64) + WriteUInt32 (rva); + else + WriteUInt64 (rva); + } + + void PrepareSection (Section section) + { + MoveTo (section.PointerToRawData); + + const int buffer_size = 4096; + + if (section.SizeOfRawData <= buffer_size) { + Write (new byte [section.SizeOfRawData]); + MoveTo (section.PointerToRawData); + return; + } + + var written = 0; + var buffer = new byte [buffer_size]; + while (written != section.SizeOfRawData) { + var write_size = System.Math.Min((int) section.SizeOfRawData - written, buffer_size); + Write (buffer, 0, write_size); + written += write_size; + } + + MoveTo (section.PointerToRawData); + } + + void WriteText () + { + PrepareSection (text); + + // ImportAddressTable + + if (has_reloc) { + WriteRVA (text_map.GetRVA (TextSegment.ImportHintNameTable)); + WriteRVA (0); + } + + // CLIHeader + + WriteUInt32 (0x48); + WriteUInt16 (2); + WriteUInt16 ((ushort) ((module.Runtime <= TargetRuntime.Net_1_1) ? 0 : 5)); + + WriteUInt32 (text_map.GetRVA (TextSegment.MetadataHeader)); + WriteUInt32 (GetMetadataLength ()); + WriteUInt32 ((uint) module.Attributes); + WriteUInt32 (metadata.entry_point.ToUInt32 ()); + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.Resources)); + WriteDataDirectory (text_map.GetDataDirectory (TextSegment.StrongNameSignature)); + WriteZeroDataDirectory (); // CodeManagerTable + WriteZeroDataDirectory (); // VTableFixups + WriteZeroDataDirectory (); // ExportAddressTableJumps + WriteZeroDataDirectory (); // ManagedNativeHeader + + // Code + + MoveToRVA (TextSegment.Code); + WriteBuffer (metadata.code); + + // Resources + + MoveToRVA (TextSegment.Resources); + WriteBuffer (metadata.resources); + + // Data + + if (metadata.data.length > 0) { + MoveToRVA (TextSegment.Data); + WriteBuffer (metadata.data); + } + + // StrongNameSignature + // stays blank + + // MetadataHeader + + MoveToRVA (TextSegment.MetadataHeader); + WriteMetadataHeader (); + + WriteMetadata (); + + // DebugDirectory + if (text_map.GetLength (TextSegment.DebugDirectory) > 0) { + MoveToRVA (TextSegment.DebugDirectory); + WriteDebugDirectory (); + } + + if (!has_reloc) + return; + + // ImportDirectory + MoveToRVA (TextSegment.ImportDirectory); + WriteImportDirectory (); + + // StartupStub + MoveToRVA (TextSegment.StartupStub); + WriteStartupStub (); + } + + uint GetMetadataLength () + { + return text_map.GetRVA (TextSegment.DebugDirectory) - text_map.GetRVA (TextSegment.MetadataHeader); + } + + public void WriteMetadataHeader () + { + WriteUInt32 (0x424a5342); // Signature + WriteUInt16 (1); // MajorVersion + WriteUInt16 (1); // MinorVersion + WriteUInt32 (0); // Reserved + + var version = GetZeroTerminatedString (runtime_version); + WriteUInt32 ((uint) version.Length); + WriteBytes (version); + WriteUInt16 (0); // Flags + WriteUInt16 (GetStreamCount ()); + + uint offset = text_map.GetRVA (TextSegment.TableHeap) - text_map.GetRVA (TextSegment.MetadataHeader); + + WriteStreamHeader (ref offset, TextSegment.TableHeap, "#~"); + WriteStreamHeader (ref offset, TextSegment.StringHeap, "#Strings"); + WriteStreamHeader (ref offset, TextSegment.UserStringHeap, "#US"); + WriteStreamHeader (ref offset, TextSegment.GuidHeap, "#GUID"); + WriteStreamHeader (ref offset, TextSegment.BlobHeap, "#Blob"); + WriteStreamHeader (ref offset, TextSegment.PdbHeap, "#Pdb"); + } + + ushort GetStreamCount () + { + return (ushort) ( + 1 // #~ + + 1 // #Strings + + (metadata.user_string_heap.IsEmpty ? 0 : 1) // #US + + (metadata.guid_heap.IsEmpty ? 0 : 1) // GUID + + (metadata.blob_heap.IsEmpty ? 0 : 1) + + (metadata.pdb_heap == null ? 0 : 1)); // #Blob + } + + void WriteStreamHeader (ref uint offset, TextSegment heap, string name) + { + var length = (uint) text_map.GetLength (heap); + if (length == 0) + return; + + WriteUInt32 (offset); + WriteUInt32 (length); + WriteBytes (GetZeroTerminatedString (name)); + offset += length; + } + + static int GetZeroTerminatedStringLength (string @string) + { + return (@string.Length + 1 + 3) & ~3; + } + + static byte [] GetZeroTerminatedString (string @string) + { + return GetString (@string, GetZeroTerminatedStringLength (@string)); + } + + static byte [] GetSimpleString (string @string) + { + return GetString (@string, @string.Length); + } + + static byte [] GetString (string @string, int length) + { + var bytes = new byte [length]; + for (int i = 0; i < @string.Length; i++) + bytes [i] = (byte) @string [i]; + + return bytes; + } + + public void WriteMetadata () + { + WriteHeap (TextSegment.TableHeap, metadata.table_heap); + WriteHeap (TextSegment.StringHeap, metadata.string_heap); + WriteHeap (TextSegment.UserStringHeap, metadata.user_string_heap); + WriteHeap (TextSegment.GuidHeap, metadata.guid_heap); + WriteHeap (TextSegment.BlobHeap, metadata.blob_heap); + WriteHeap (TextSegment.PdbHeap, metadata.pdb_heap); + } + + void WriteHeap (TextSegment heap, HeapBuffer buffer) + { + if (buffer == null || buffer.IsEmpty) + return; + + MoveToRVA (heap); + WriteBuffer (buffer); + } + + void WriteDebugDirectory () + { + var data_start = (int) BaseStream.Position + (debug_header.Entries.Length * ImageDebugDirectory.Size); + + for (var i = 0; i < debug_header.Entries.Length; i++) { + var entry = debug_header.Entries [i]; + var directory = entry.Directory; + WriteInt32 (directory.Characteristics); + WriteInt32 (directory.TimeDateStamp); + WriteInt16 (directory.MajorVersion); + WriteInt16 (directory.MinorVersion); + WriteInt32 ((int) directory.Type); + WriteInt32 (directory.SizeOfData); + WriteInt32 (directory.AddressOfRawData); + WriteInt32 (data_start); + + data_start += entry.Data.Length; + } + + debug_header_entries_position = BaseStream.Position; + + for (var i = 0; i < debug_header.Entries.Length; i++) { + var entry = debug_header.Entries [i]; + WriteBytes (entry.Data); + } + } + + void WriteImportDirectory () + { + WriteUInt32 (text_map.GetRVA (TextSegment.ImportDirectory) + 40); // ImportLookupTable + WriteUInt32 (0); // DateTimeStamp + WriteUInt32 (0); // ForwarderChain + WriteUInt32 (text_map.GetRVA (TextSegment.ImportHintNameTable) + 14); + WriteUInt32 (text_map.GetRVA (TextSegment.ImportAddressTable)); + Advance (20); + + // ImportLookupTable + WriteUInt32 (text_map.GetRVA (TextSegment.ImportHintNameTable)); + + // ImportHintNameTable + MoveToRVA (TextSegment.ImportHintNameTable); + + WriteUInt16 (0); // Hint + WriteBytes (GetRuntimeMain ()); + WriteByte (0); + WriteBytes (GetSimpleString ("mscoree.dll")); + WriteUInt16 (0); + } + + byte [] GetRuntimeMain () + { + return module.Kind == ModuleKind.Dll || module.Kind == ModuleKind.NetModule + ? GetSimpleString ("_CorDllMain") + : GetSimpleString ("_CorExeMain"); + } + + void WriteStartupStub () + { + switch (module.Architecture) { + case TargetArchitecture.I386: + WriteUInt16 (0x25ff); + WriteUInt32 ((uint) image_base + text_map.GetRVA (TextSegment.ImportAddressTable)); + return; + default: + throw new NotSupportedException (); + } + } + + void WriteRsrc () + { + PrepareSection (rsrc); + WriteBuffer (win32_resources); + } + + void WriteReloc () + { + PrepareSection (reloc); + + var reloc_rva = text_map.GetRVA (TextSegment.StartupStub); + reloc_rva += module.Architecture == TargetArchitecture.IA64 ? 0x20u : 2; + var page_rva = reloc_rva & ~0xfffu; + + WriteUInt32 (page_rva); // PageRVA + WriteUInt32 (0x000c); // Block Size + + switch (module.Architecture) { + case TargetArchitecture.I386: + WriteUInt32 (0x3000 + reloc_rva - page_rva); + break; + default: + throw new NotSupportedException(); + } + } + + public void WriteImage () + { + WriteDOSHeader (); + WritePEFileHeader (); + WriteOptionalHeaders (); + WriteSectionHeaders (); + WriteText (); + if (rsrc != null) + WriteRsrc (); + if (reloc != null) + WriteReloc (); + Flush (); + } + + void BuildTextMap () + { + var map = text_map; + + map.AddMap (TextSegment.Code, metadata.code.length, !pe64 ? 4 : 16); + map.AddMap (TextSegment.Resources, metadata.resources.length, 8); + map.AddMap (TextSegment.Data, metadata.data.length, metadata.data.BufferAlign); + if (metadata.data.length > 0) + metadata.table_heap.FixupData (map.GetRVA (TextSegment.Data)); + map.AddMap (TextSegment.StrongNameSignature, GetStrongNameLength (), 4); + + BuildMetadataTextMap (); + + int debug_dir_len = 0; + if (debug_header != null && debug_header.HasEntries) { + var directories_len = debug_header.Entries.Length * ImageDebugDirectory.Size; + var data_address = (int) map.GetNextRVA (TextSegment.BlobHeap) + directories_len; + var data_len = 0; + + for (var i = 0; i < debug_header.Entries.Length; i++) { + var entry = debug_header.Entries [i]; + var directory = entry.Directory; + + directory.AddressOfRawData = entry.Data.Length == 0 ? 0 : data_address; + entry.Directory = directory; + + data_len += entry.Data.Length; + data_address += entry.Data.Length; + } + + debug_dir_len = directories_len + data_len; + } + + map.AddMap (TextSegment.DebugDirectory, debug_dir_len, 4); + + if (!has_reloc) { + var start = map.GetNextRVA (TextSegment.DebugDirectory); + map.AddMap (TextSegment.ImportDirectory, new Range (start, 0)); + map.AddMap (TextSegment.ImportHintNameTable, new Range (start, 0)); + map.AddMap (TextSegment.StartupStub, new Range (start, 0)); + return; + } + + RVA import_dir_rva = map.GetNextRVA (TextSegment.DebugDirectory); + RVA import_hnt_rva = import_dir_rva + 48u; + import_hnt_rva = (import_hnt_rva + 15u) & ~15u; + uint import_dir_len = (import_hnt_rva - import_dir_rva) + 27u; + + RVA startup_stub_rva = import_dir_rva + import_dir_len; + startup_stub_rva = module.Architecture == TargetArchitecture.IA64 + ? (startup_stub_rva + 15u) & ~15u + : 2 + ((startup_stub_rva + 3u) & ~3u); + + map.AddMap (TextSegment.ImportDirectory, new Range (import_dir_rva, import_dir_len)); + map.AddMap (TextSegment.ImportHintNameTable, new Range (import_hnt_rva, 0)); + map.AddMap (TextSegment.StartupStub, new Range (startup_stub_rva, GetStartupStubLength ())); + } + + public void BuildMetadataTextMap () + { + var map = text_map; + + map.AddMap (TextSegment.MetadataHeader, GetMetadataHeaderLength (module.RuntimeVersion)); + map.AddMap (TextSegment.TableHeap, metadata.table_heap.length, 4); + map.AddMap (TextSegment.StringHeap, metadata.string_heap.length, 4); + map.AddMap (TextSegment.UserStringHeap, metadata.user_string_heap.IsEmpty ? 0 : metadata.user_string_heap.length, 4); + map.AddMap (TextSegment.GuidHeap, metadata.guid_heap.length, 4); + map.AddMap (TextSegment.BlobHeap, metadata.blob_heap.IsEmpty ? 0 : metadata.blob_heap.length, 4); + map.AddMap (TextSegment.PdbHeap, metadata.pdb_heap == null ? 0 : metadata.pdb_heap.length, 4); + } + + uint GetStartupStubLength () + { + switch (module.Architecture) { + case TargetArchitecture.I386: + return 6; + default: + throw new NotSupportedException (); + } + } + + int GetMetadataHeaderLength (string runtimeVersion) + { + return + // MetadataHeader + 20 + GetZeroTerminatedStringLength (runtimeVersion) + // #~ header + + 12 + // #Strings header + + 20 + // #US header + + (metadata.user_string_heap.IsEmpty ? 0 : 12) + // #GUID header + + 16 + // #Blob header + + (metadata.blob_heap.IsEmpty ? 0 : 16) + // + + (metadata.pdb_heap == null ? 0 : 16); + } + + int GetStrongNameLength () + { + if (module.kind == ModuleKind.NetModule || module.Assembly == null) + return 0; + + var public_key = module.Assembly.Name.PublicKey; + if (public_key.IsNullOrEmpty ()) + return 0; + + // in fx 2.0 the key may be from 384 to 16384 bits + // so we must calculate the signature size based on + // the size of the public key (minus the 32 byte header) + int size = public_key.Length; + if (size > 32) + return size - 32; + + // note: size == 16 for the ECMA "key" which is replaced + // by the runtime with a 1024 bits key (128 bytes) + + return 128; // default strongname signature size + } + + public DataDirectory GetStrongNameSignatureDirectory () + { + return text_map.GetDataDirectory (TextSegment.StrongNameSignature); + } + + public uint GetHeaderSize () + { + return pe_header_size + SizeOfOptionalHeader () + (sections * section_header_size); + } + + void PatchWin32Resources (ByteBuffer resources) + { + PatchResourceDirectoryTable (resources); + } + + void PatchResourceDirectoryTable (ByteBuffer resources) + { + resources.Advance (12); + + var entries = resources.ReadUInt16 () + resources.ReadUInt16 (); + + for (int i = 0; i < entries; i++) + PatchResourceDirectoryEntry (resources); + } + + void PatchResourceDirectoryEntry (ByteBuffer resources) + { + resources.Advance (4); + var child = resources.ReadUInt32 (); + + var position = resources.position; + resources.position = (int) child & 0x7fffffff; + + if ((child & 0x80000000) != 0) + PatchResourceDirectoryTable (resources); + else + PatchResourceDataEntry (resources); + + resources.position = position; + } + + void PatchResourceDataEntry (ByteBuffer resources) + { + var rva = resources.ReadUInt32 (); + resources.position -= 4; + + resources.WriteUInt32 (rva - module.Image.Win32Resources.VirtualAddress + rsrc.VirtualAddress); + } + } +} diff --git a/cecil-master/Mono.Cecil.PE/Section.cs b/cecil-master/Mono.Cecil.PE/Section.cs new file mode 100644 index 000000000..49d8e9001 --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/Section.cs @@ -0,0 +1,24 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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; + } +} diff --git a/cecil-master/Mono.Cecil.PE/TextMap.cs b/cecil-master/Mono.Cecil.PE/TextMap.cs new file mode 100644 index 000000000..548e471a7 --- /dev/null +++ b/cecil-master/Mono.Cecil.PE/TextMap.cs @@ -0,0 +1,129 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Diagnostics; + +using RVA = System.UInt32; + +namespace Mono.Cecil.PE { + + enum TextSegment { + ImportAddressTable, + CLIHeader, + Code, + Resources, + Data, + StrongNameSignature, + + // Metadata + MetadataHeader, + TableHeap, + StringHeap, + UserStringHeap, + GuidHeap, + BlobHeap, + PdbHeap, + // End Metadata + + DebugDirectory, + ImportDirectory, + ImportHintNameTable, + StartupStub, + } + + sealed class TextMap { + + readonly Range [] map = new Range [17 /*Enum.GetValues (typeof (TextSegment)).Length*/]; + + public void AddMap (TextSegment segment, int length) + { + map [(int) segment] = new Range (GetStart (segment), (uint) length); + } + + uint AlignUp (uint value, uint align) + { + align--; + return (value + align) & ~align; + } + + public void AddMap (TextSegment segment, int length, int align) + { + var index = (int) segment; + uint start; + if (index != 0) { + // Align up the previous segment's length so that the new + // segment's start will be aligned. + index--; + Range previous = map [index]; + start = AlignUp (previous.Start + previous.Length, (uint) align); + map [index].Length = start - previous.Start; + } else { + start = ImageWriter.text_rva; + // Should already be aligned. + Debug.Assert (start == AlignUp (start, (uint) align)); + } + Debug.Assert (start == GetStart (segment)); + + map [(int) segment] = new Range (start, (uint) length); + } + + public void AddMap (TextSegment segment, Range range) + { + map [(int) segment] = range; + } + + public Range GetRange (TextSegment segment) + { + return map [(int) segment]; + } + + public DataDirectory GetDataDirectory (TextSegment segment) + { + var range = map [(int) segment]; + + return new DataDirectory (range.Length == 0 ? 0 : range.Start, range.Length); + } + + public RVA GetRVA (TextSegment segment) + { + return map [(int) segment].Start; + } + + public RVA GetNextRVA (TextSegment segment) + { + var i = (int) segment; + return map [i].Start + map [i].Length; + } + + public int GetLength (TextSegment segment) + { + return (int) map [(int) segment].Length; + } + + RVA GetStart (TextSegment segment) + { + var index = (int) segment; + return index == 0 ? ImageWriter.text_rva : ComputeStart (index); + } + + RVA ComputeStart (int index) + { + index--; + return map [index].Start + map [index].Length; + } + + public uint GetLength () + { + var range = map [(int) TextSegment.StartupStub]; + return range.Start - ImageWriter.text_rva + range.Length; + } + } +} diff --git a/cecil-master/Mono.Cecil.Tests.props b/cecil-master/Mono.Cecil.Tests.props new file mode 100644 index 000000000..bd6df1f5e --- /dev/null +++ b/cecil-master/Mono.Cecil.Tests.props @@ -0,0 +1,16 @@ + + + true + + + + 3.11.0 + + + 15.9.0 + + + 3.12.0 + + + diff --git a/cecil-master/Mono.Cecil.csproj b/cecil-master/Mono.Cecil.csproj new file mode 100644 index 000000000..44a43f8c0 --- /dev/null +++ b/cecil-master/Mono.Cecil.csproj @@ -0,0 +1,18 @@ + + + netstandard2.0 + + + False + + + + + + + + + + + + diff --git a/cecil-master/Mono.Cecil.nunit b/cecil-master/Mono.Cecil.nunit new file mode 100644 index 000000000..2acfc126c --- /dev/null +++ b/cecil-master/Mono.Cecil.nunit @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/cecil-master/Mono.Cecil.nuspec b/cecil-master/Mono.Cecil.nuspec new file mode 100644 index 000000000..82cb30033 --- /dev/null +++ b/cecil-master/Mono.Cecil.nuspec @@ -0,0 +1,42 @@ + + + + Mono.Cecil + 0.11.5.0 + Mono.Cecil + Jb Evain + Jb Evain + MIT + false + http://github.com/jbevain/cecil/ + Cecil is a library written by Jb Evain to generate and inspect programs and libraries in the ECMA CIL format. + Cecil is a library written by Jb Evain to generate and inspect programs and libraries in the ECMA CIL format. It has full support for generics, and support some debugging symbol format. In simple English, with Cecil, you can load existing managed assemblies, browse all the contained types, modify them on the fly and save back to the disk the modified assembly. + en-US + assembly assemblies module modules il cil msil bytecode reflection injection cecil mono aop + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cecil-master/Mono.Cecil.sln b/cecil-master/Mono.Cecil.sln new file mode 100644 index 000000000..7b3ff986c --- /dev/null +++ b/cecil-master/Mono.Cecil.sln @@ -0,0 +1,67 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28516.95 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil", "Mono.Cecil.csproj", "{16C3FA32-4775-497F-8794-DD5AF13CFE22}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil.Pdb", "symbols\pdb\Mono.Cecil.Pdb.csproj", "{4D22D51C-4230-46AF-8657-4FD757D9C8BC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil.Mdb", "symbols\mdb\Mono.Cecil.Mdb.csproj", "{5A5F84B1-DD1A-4134-932C-C3AF5BDAD391}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil.Tests", "Test\Mono.Cecil.Tests.csproj", "{EA7ADB7D-9FC1-4B4C-BBE9-359DD5B2E345}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil.Mdb.Tests", "symbols\mdb\Test\Mono.Cecil.Mdb.Tests.csproj", "{901E005D-CD64-4DC5-8CD0-4A49A7B0AF71}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil.Pdb.Tests", "symbols\pdb\Test\Mono.Cecil.Pdb.Tests.csproj", "{50FC1815-A653-48D0-95E2-DB48CB01F4E1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil.Rocks", "rocks\Mono.Cecil.Rocks.csproj", "{70E05599-64EE-4C11-A2F8-EE4113309039}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Mono.Cecil.Rocks.Tests", "rocks\Test\Mono.Cecil.Rocks.Tests.csproj", "{EF768F7A-3C08-45EE-8A7E-BB5A81BADB7B}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {16C3FA32-4775-497F-8794-DD5AF13CFE22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {16C3FA32-4775-497F-8794-DD5AF13CFE22}.Debug|Any CPU.Build.0 = Debug|Any CPU + {16C3FA32-4775-497F-8794-DD5AF13CFE22}.Release|Any CPU.ActiveCfg = Release|Any CPU + {16C3FA32-4775-497F-8794-DD5AF13CFE22}.Release|Any CPU.Build.0 = Release|Any CPU + {4D22D51C-4230-46AF-8657-4FD757D9C8BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4D22D51C-4230-46AF-8657-4FD757D9C8BC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4D22D51C-4230-46AF-8657-4FD757D9C8BC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4D22D51C-4230-46AF-8657-4FD757D9C8BC}.Release|Any CPU.Build.0 = Release|Any CPU + {5A5F84B1-DD1A-4134-932C-C3AF5BDAD391}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5A5F84B1-DD1A-4134-932C-C3AF5BDAD391}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5A5F84B1-DD1A-4134-932C-C3AF5BDAD391}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5A5F84B1-DD1A-4134-932C-C3AF5BDAD391}.Release|Any CPU.Build.0 = Release|Any CPU + {EA7ADB7D-9FC1-4B4C-BBE9-359DD5B2E345}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EA7ADB7D-9FC1-4B4C-BBE9-359DD5B2E345}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EA7ADB7D-9FC1-4B4C-BBE9-359DD5B2E345}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EA7ADB7D-9FC1-4B4C-BBE9-359DD5B2E345}.Release|Any CPU.Build.0 = Release|Any CPU + {901E005D-CD64-4DC5-8CD0-4A49A7B0AF71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {901E005D-CD64-4DC5-8CD0-4A49A7B0AF71}.Debug|Any CPU.Build.0 = Debug|Any CPU + {901E005D-CD64-4DC5-8CD0-4A49A7B0AF71}.Release|Any CPU.ActiveCfg = Release|Any CPU + {901E005D-CD64-4DC5-8CD0-4A49A7B0AF71}.Release|Any CPU.Build.0 = Release|Any CPU + {50FC1815-A653-48D0-95E2-DB48CB01F4E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {50FC1815-A653-48D0-95E2-DB48CB01F4E1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {50FC1815-A653-48D0-95E2-DB48CB01F4E1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {50FC1815-A653-48D0-95E2-DB48CB01F4E1}.Release|Any CPU.Build.0 = Release|Any CPU + {70E05599-64EE-4C11-A2F8-EE4113309039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {70E05599-64EE-4C11-A2F8-EE4113309039}.Debug|Any CPU.Build.0 = Debug|Any CPU + {70E05599-64EE-4C11-A2F8-EE4113309039}.Release|Any CPU.ActiveCfg = Release|Any CPU + {70E05599-64EE-4C11-A2F8-EE4113309039}.Release|Any CPU.Build.0 = Release|Any CPU + {EF768F7A-3C08-45EE-8A7E-BB5A81BADB7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EF768F7A-3C08-45EE-8A7E-BB5A81BADB7B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EF768F7A-3C08-45EE-8A7E-BB5A81BADB7B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EF768F7A-3C08-45EE-8A7E-BB5A81BADB7B}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {97A7013A-E1DE-4D11-93C5-212D0A7E85C9} + EndGlobalSection +EndGlobal diff --git a/cecil-master/Mono.Cecil/ArrayType.cs b/cecil-master/Mono.Cecil/ArrayType.cs new file mode 100644 index 000000000..7413b1cba --- /dev/null +++ b/cecil-master/Mono.Cecil/ArrayType.cs @@ -0,0 +1,145 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Text; +using System.Threading; +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; + + var empty_dimensions = new Collection (); + empty_dimensions.Add (new ArrayDimension ()); + + Interlocked.CompareExchange (ref dimensions, empty_dimensions, null); + + 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/cecil-master/Mono.Cecil/AssemblyDefinition.cs b/cecil-master/Mono.Cecil/AssemblyDefinition.cs new file mode 100644 index 000000000..93c9c9bd5 --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyDefinition.cs @@ -0,0 +1,189 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.IO; +using System.Threading; +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class AssemblyDefinition : ICustomAttributeProvider, ISecurityDeclarationProvider, IDisposable { + + 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 ()); + + Interlocked.CompareExchange (ref modules, new Collection (1) { main_module }, null); + return modules; + } + } + + 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 this.GetHasCustomAttributes (main_module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, main_module)); } + } + + public bool HasSecurityDeclarations { + get { + if (security_declarations != null) + return security_declarations.Count > 0; + + return this.GetHasSecurityDeclarations (main_module); + } + } + + public Collection SecurityDeclarations { + get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, main_module)); } + } + + internal AssemblyDefinition () + { + } + + public void Dispose () + { + if (this.modules == null) { + main_module.Dispose (); + return; + } + + var modules = this.Modules; + for (int i = 0; i < modules.Count; i++) + modules [i].Dispose (); + } + public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleKind kind) + { + return CreateAssembly (assemblyName, moduleName, new ModuleParameters { Kind = kind }); + } + + public static AssemblyDefinition CreateAssembly (AssemblyNameDefinition assemblyName, string moduleName, ModuleParameters parameters) + { + if (assemblyName == null) + throw new ArgumentNullException ("assemblyName"); + if (moduleName == null) + throw new ArgumentNullException ("moduleName"); + Mixin.CheckParameters (parameters); + if (parameters.Kind == ModuleKind.NetModule) + throw new ArgumentException ("kind"); + + var assembly = ModuleDefinition.CreateModule (moduleName, parameters).Assembly; + assembly.Name = assemblyName; + + return assembly; + } + + 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 void Write (string fileName) + { + Write (fileName, new WriterParameters ()); + } + + public void Write (string fileName, WriterParameters parameters) + { + main_module.Write (fileName, parameters); + } + + public void Write () + { + main_module.Write (); + } + + public void Write (WriterParameters parameters) + { + main_module.Write (parameters); + } + + public void Write (Stream stream) + { + Write (stream, new WriterParameters ()); + } + + public void Write (Stream stream, WriterParameters parameters) + { + main_module.Write (stream, parameters); + } + + public override string ToString () + { + return this.FullName; + } + } +} diff --git a/cecil-master/Mono.Cecil/AssemblyFlags.cs b/cecil-master/Mono.Cecil/AssemblyFlags.cs new file mode 100644 index 000000000..6ca5bc274 --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyFlags.cs @@ -0,0 +1,24 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/AssemblyHashAlgorithm.cs b/cecil-master/Mono.Cecil/AssemblyHashAlgorithm.cs new file mode 100644 index 000000000..6684c2ceb --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyHashAlgorithm.cs @@ -0,0 +1,22 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum AssemblyHashAlgorithm : uint { + None = 0x0000, + MD5 = 0x8003, + SHA1 = 0x8004, + SHA256 = 0x800C, + SHA384 = 0x800D, + SHA512 = 0x800E, + Reserved = 0x8003, // MD5 + } +} diff --git a/cecil-master/Mono.Cecil/AssemblyInfo.cs b/cecil-master/Mono.Cecil/AssemblyInfo.cs new file mode 100644 index 000000000..b5455d1b8 --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyInfo.cs @@ -0,0 +1,22 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle (Consts.AssemblyName)] + +[assembly: Guid ("fd225bb4-fa53-44b2-a6db-85f5e48dcb54")] + +[assembly: InternalsVisibleTo ("Mono.Cecil.Tests, PublicKey=" + Consts.PublicKey)] +[assembly: InternalsVisibleTo ("Mono.Cecil.Pdb, PublicKey=" + Consts.PublicKey)] +[assembly: InternalsVisibleTo ("Mono.Cecil.Mdb, PublicKey=" + Consts.PublicKey)] +[assembly: InternalsVisibleTo ("Mono.Cecil.Rocks, PublicKey=" + Consts.PublicKey)] diff --git a/cecil-master/Mono.Cecil/AssemblyLinkedResource.cs b/cecil-master/Mono.Cecil/AssemblyLinkedResource.cs new file mode 100644 index 000000000..f4896bd24 --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyLinkedResource.cs @@ -0,0 +1,39 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/AssemblyNameDefinition.cs b/cecil-master/Mono.Cecil/AssemblyNameDefinition.cs new file mode 100644 index 000000000..2511d7934 --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyNameDefinition.cs @@ -0,0 +1,32 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/AssemblyNameReference.cs b/cecil-master/Mono.Cecil/AssemblyNameReference.cs new file mode 100644 index 000000000..168ad14da --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyNameReference.cs @@ -0,0 +1,269 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Globalization; +using System.Security.Cryptography; +using System.Text; +using System.Threading; + +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 = Mixin.CheckVersion (value); + full_name = null; + } + } + + public AssemblyAttributes Attributes { + get { return (AssemblyAttributes) attributes; } + set { attributes = (uint) value; } + } + + public bool HasPublicKey { + get { return attributes.GetAttributes ((uint) AssemblyAttributes.PublicKey); } + set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.PublicKey, value); } + } + + public bool IsSideBySideCompatible { + get { return attributes.GetAttributes ((uint) AssemblyAttributes.SideBySideCompatible); } + set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.SideBySideCompatible, value); } + } + + public bool IsRetargetable { + get { return attributes.GetAttributes ((uint) AssemblyAttributes.Retargetable); } + set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.Retargetable, value); } + } + + public bool IsWindowsRuntime { + get { return attributes.GetAttributes ((uint) AssemblyAttributes.WindowsRuntime); } + set { attributes = attributes.SetAttributes ((uint) AssemblyAttributes.WindowsRuntime, value); } + } + + public byte [] PublicKey { + get { return public_key ?? Empty.Array; } + set { + public_key = value; + HasPublicKey = !public_key.IsNullOrEmpty (); + public_key_token = null; + full_name = null; + } + } + + public byte [] PublicKeyToken { + get { + if (public_key_token == null && !public_key.IsNullOrEmpty ()) { + var hash = HashPublicKey (); + // we need the last 8 bytes in reverse order + var 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); + Interlocked.CompareExchange (ref public_key_token, local_public_key_token, null); // 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: + algorithm = MD5.Create (); + break; + default: + // None default to SHA1 + algorithm = SHA1.Create (); + 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); + builder.Append (sep); + builder.Append ("Version="); + builder.Append (version.ToString (fieldCount: 4)); + builder.Append (sep); + builder.Append ("Culture="); + builder.Append (string.IsNullOrEmpty (culture) ? "neutral" : culture); + builder.Append (sep); + builder.Append ("PublicKeyToken="); + + var pk_token = PublicKeyToken; + if (!pk_token.IsNullOrEmpty () && pk_token.Length > 0) { + for (int i = 0 ; i < pk_token.Length ; i++) { + builder.Append (pk_token [i].ToString ("x2")); + } + } else + builder.Append ("null"); + + if (IsRetargetable) { + builder.Append (sep); + builder.Append ("Retargetable=Yes"); + } + + Interlocked.CompareExchange (ref full_name, builder.ToString (), null); + + return full_name; + } + } + + 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] == "neutral" ? "" : 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 () + { + this.version = Mixin.ZeroVersion; + this.token = new MetadataToken (TokenType.AssemblyRef); + } + + public AssemblyNameReference (string name, Version version) + { + Mixin.CheckName (name); + + this.name = name; + this.version = Mixin.CheckVersion (version); + this.hash_algorithm = AssemblyHashAlgorithm.None; + this.token = new MetadataToken (TokenType.AssemblyRef); + } + + public override string ToString () + { + return this.FullName; + } + } + + partial class Mixin { + + public static Version ZeroVersion = new Version (0, 0, 0 ,0); + + public static Version CheckVersion (Version version) + { + if (version == null) + return ZeroVersion; + + if (version.Build == -1) + return new Version (version.Major, version.Minor, 0, 0); + + if (version.Revision == -1) + return new Version (version.Major, version.Minor, version.Build, 0); + + return version; + } + } +} diff --git a/cecil-master/Mono.Cecil/AssemblyReader.cs b/cecil-master/Mono.Cecil/AssemblyReader.cs new file mode 100644 index 000000000..4564071e8 --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyReader.cs @@ -0,0 +1,3883 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +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 ModuleDefinition module; + + protected ModuleReader (Image image, ReadingMode mode) + { + this.module = new ModuleDefinition (image); + this.module.ReadingMode = mode; + } + + protected abstract void ReadModule (); + public abstract void ReadSymbols (ModuleDefinition module); + + 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 CreateModule (Image image, ReaderParameters parameters) + { + var reader = CreateModuleReader (image, parameters.ReadingMode); + var module = reader.module; + + if (parameters.assembly_resolver != null) + module.assembly_resolver = Disposable.NotOwned (parameters.assembly_resolver); + + if (parameters.metadata_resolver != null) + module.metadata_resolver = parameters.metadata_resolver; + + if (parameters.metadata_importer_provider != null) + module.metadata_importer = parameters.metadata_importer_provider.GetMetadataImporter (module); + + if (parameters.reflection_importer_provider != null) + module.reflection_importer = parameters.reflection_importer_provider.GetReflectionImporter (module); + + GetMetadataKind (module, parameters); + + reader.ReadModule (); + + ReadSymbols (module, parameters); + + reader.ReadSymbols (module); + + if (parameters.ReadingMode == ReadingMode.Immediate) + module.MetadataSystem.Clear (); + + 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 = new DefaultSymbolReaderProvider (); + + 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.FileName); + + if (reader != null) { + try { + module.ReadSymbols (reader, parameters.ThrowIfSymbolsAreNotMatching); + } catch (Exception) { + reader.Dispose (); + throw; + } + } + } + + if (module.Image.HasDebugTables ()) + module.ReadSymbols (new PortablePdbReader (module.Image, module)); + } + + static void GetMetadataKind (ModuleDefinition module, ReaderParameters parameters) + { + if (!parameters.ApplyWindowsRuntimeProjections) { + module.MetadataKind = MetadataKind.Ecma335; + return; + } + + var runtime_version = module.RuntimeVersion; + + if (!runtime_version.Contains ("WindowsRuntime")) + module.MetadataKind = MetadataKind.Ecma335; + else if (runtime_version.Contains ("CLR")) + module.MetadataKind = MetadataKind.ManagedWindowsMetadata; + else + module.MetadataKind = MetadataKind.WindowsMetadata; + } + + 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 { + + bool resolve_attributes; + + public ImmediateModuleReader (Image image) + : base (image, ReadingMode.Immediate) + { + } + + protected override void ReadModule () + { + this.module.Read (this.module, (module, reader) => { + ReadModuleManifest (reader); + ReadModule (module, resolve_attributes: true); + }); + } + + public void ReadModule (ModuleDefinition module, bool resolve_attributes) + { + this.resolve_attributes = resolve_attributes; + + if (module.HasAssemblyReferences) + Mixin.Read (module.AssemblyReferences); + if (module.HasResources) + Mixin.Read (module.Resources); + if (module.HasModuleReferences) + Mixin.Read (module.ModuleReferences); + if (module.HasTypes) + ReadTypes (module.Types); + if (module.HasExportedTypes) + Mixin.Read (module.ExportedTypes); + + ReadCustomAttributes (module); + + var assembly = module.Assembly; + if (module.kind == ModuleKind.NetModule || assembly == null) + return; + + ReadCustomAttributes (assembly); + ReadSecurityDeclarations (assembly); + } + + void ReadTypes (Collection types) + { + for (int i = 0; i < types.Count; i++) + ReadType (types [i]); + } + + void ReadType (TypeDefinition type) + { + ReadGenericParameters (type); + + if (type.HasInterfaces) + ReadInterfaces (type); + + if (type.HasNestedTypes) + ReadTypes (type.NestedTypes); + + if (type.HasLayoutInfo) + Mixin.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); + } + + void ReadInterfaces (TypeDefinition type) + { + var interfaces = type.Interfaces; + + for (int i = 0; i < interfaces.Count; i++) + ReadCustomAttributes (interfaces [i]); + } + + 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) + ReadGenericParameterConstraints (parameter); + + ReadCustomAttributes (parameter); + } + } + + void ReadGenericParameterConstraints (GenericParameter parameter) + { + var constraints = parameter.Constraints; + + for (int i = 0; i < constraints.Count; i++) + ReadCustomAttributes (constraints [i]); + } + + void ReadSecurityDeclarations (ISecurityDeclarationProvider provider) + { + if (!provider.HasSecurityDeclarations) + return; + + var security_declarations = provider.SecurityDeclarations; + + if (!resolve_attributes) + return; + + for (int i = 0; i < security_declarations.Count; i++) { + var security_declaration = security_declarations [i]; + + Mixin.Read (security_declaration.SecurityAttributes); + } + } + + void ReadCustomAttributes (ICustomAttributeProvider provider) + { + if (!provider.HasCustomAttributes) + return; + + var custom_attributes = provider.CustomAttributes; + + if (!resolve_attributes) + return; + + for (int i = 0; i < custom_attributes.Count; i++) { + var custom_attribute = custom_attributes [i]; + + Mixin.Read (custom_attribute.ConstructorArguments); + } + } + + void ReadFields (TypeDefinition type) + { + var fields = type.Fields; + + for (int i = 0; i < fields.Count; i++) { + var field = fields [i]; + + if (field.HasConstant) + Mixin.Read (field.Constant); + + if (field.HasLayoutInfo) + Mixin.Read (field.Offset); + + if (field.RVA > 0) + Mixin.Read (field.InitialValue); + + if (field.HasMarshalInfo) + Mixin.Read (field.MarshalInfo); + + ReadCustomAttributes (field); + } + } + + 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) + Mixin.Read (method.Overrides); + + if (method.IsPInvokeImpl) + Mixin.Read (method.PInvokeInfo); + + ReadSecurityDeclarations (method); + ReadCustomAttributes (method); + + var return_type = method.MethodReturnType; + if (return_type.HasConstant) + Mixin.Read (return_type.Constant); + + if (return_type.HasMarshalInfo) + Mixin.Read (return_type.MarshalInfo); + + ReadCustomAttributes (return_type); + } + } + + void ReadParameters (MethodDefinition method) + { + var parameters = method.Parameters; + + for (int i = 0; i < parameters.Count; i++) { + var parameter = parameters [i]; + + if (parameter.HasConstant) + Mixin.Read (parameter.Constant); + + if (parameter.HasMarshalInfo) + Mixin.Read (parameter.MarshalInfo); + + ReadCustomAttributes (parameter); + } + } + + void ReadProperties (TypeDefinition type) + { + var properties = type.Properties; + + for (int i = 0; i < properties.Count; i++) { + var property = properties [i]; + + Mixin.Read (property.GetMethod); + + if (property.HasConstant) + Mixin.Read (property.Constant); + + ReadCustomAttributes (property); + } + } + + void ReadEvents (TypeDefinition type) + { + var events = type.Events; + + for (int i = 0; i < events.Count; i++) { + var @event = events [i]; + + Mixin.Read (@event.AddMethod); + + ReadCustomAttributes (@event); + } + } + + public override void ReadSymbols (ModuleDefinition module) + { + if (module.symbol_reader == null) + return; + + ReadTypesSymbols (module.Types, module.symbol_reader); + } + + void ReadTypesSymbols (Collection types, ISymbolReader symbol_reader) + { + for (int i = 0; i < types.Count; i++) { + var type = types [i]; + + if (type.HasNestedTypes) + ReadTypesSymbols (type.NestedTypes, symbol_reader); + + if (type.HasMethods) + ReadMethodsSymbols (type, symbol_reader); + } + } + + void ReadMethodsSymbols (TypeDefinition type, ISymbolReader symbol_reader) + { + var methods = type.Methods; + for (int i = 0; i < methods.Count; i++) { + var method = methods [i]; + + if (method.HasBody && method.token.RID != 0 && method.debug_info == null) + method.debug_info = symbol_reader.Read (method); + } + } + } + + sealed class DeferredModuleReader : ModuleReader { + + public DeferredModuleReader (Image image) + : base (image, ReadingMode.Deferred) + { + } + + protected override void ReadModule () + { + this.module.Read (this.module, (_, reader) => ReadModuleManifest (reader)); + } + + public override void ReadSymbols (ModuleDefinition module) + { + } + } + + sealed class MetadataReader : ByteBuffer { + + readonly internal Image image; + readonly internal ModuleDefinition module; + readonly internal MetadataSystem metadata; + + internal CodeReader code; + internal IGenericContext context; + + readonly MetadataReader metadata_reader; + + public MetadataReader (ModuleDefinition module) + : base (module.Image.TableHeap.data) + { + this.image = module.Image; + this.module = module; + this.metadata = module.MetadataSystem; + this.code = new CodeReader (this); + } + + public MetadataReader (Image image, ModuleDefinition module, MetadataReader metadata_reader) + : base (image.TableHeap.data) + { + this.image = image; + this.module = module; + this.metadata = module.MetadataSystem; + this.metadata_reader = metadata_reader; + } + + 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); + } + + void GetBlobView (uint signature, out byte [] blob, out int index, out int count) + { + var blob_heap = image.BlobHeap; + if (blob_heap == null) { + blob = null; + index = count = 0; + return; + } + + blob_heap.GetView (signature, out blob, out index, out count); + } + + string ReadString () + { + return image.StringHeap.Read (ReadByIndexSize (image.StringHeap.IndexSize)); + } + + uint ReadStringIndex () + { + return ReadByIndexSize (image.StringHeap.IndexSize); + } + + Guid ReadGuid () + { + return image.GuidHeap.Read (ReadByIndexSize (image.GuidHeap.IndexSize)); + } + + uint ReadTableIndex (Table table) + { + return ReadByIndexSize (image.GetTableIndexSize (table)); + } + + MetadataToken ReadMetadataToken (CodedIndex index) + { + return index.GetMetadataToken (ReadByIndexSize (GetCodedIndexSize (index))); + } + + int MoveTo (Table table) + { + var info = image.TableHeap [table]; + if (info.Length != 0) + this.position = (int) 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; + + this.position = (int) (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 = ReadGuid (); + + 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 (); + + var references = new Collection (metadata.AssemblyReferences); + if (module.IsWindowsMetadata ()) + module.Projections.AddVirtualReferences (references); + + return references; + } + + 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, + AssemblyResolver = module.AssemblyResolver + }; + + var netmodule = ModuleDefinition.ReadModule (GetModuleFileName (name), parameters); + netmodule.assembly = this.module.assembly; + + modules.Add (netmodule); + } + + return modules; + } + + string GetModuleFileName (string name) + { + if (module.FileName == null) + throw new NotSupportedException (); + + var path = Path.GetDirectoryName (module.FileName); + 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 + continue; + + 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 byte [] GetManagedResource (uint offset) + { + return image.GetReaderAt (image.Resources.VirtualAddress, offset, (o, reader) => { + reader.Advance ((int) o); + return reader.ReadBytes (reader.ReadInt32 ()); + }) ?? Empty.Array; + } + + 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]; + + Mixin.Read (type.Fields); + Mixin.Read (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); + } + + if (module.IsWindowsMetadata ()) { + for (uint i = 0; i < length; i++) { + WindowsRuntimeProjections.Project (types [i]); + } + } + } + + 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) + { + Collection mapping; + InitializeNestedTypes (); + + if (!metadata.TryGetNestedTypeMapping (type, out mapping)) + return false; + + return mapping.Count > 0; + } + + public Collection ReadNestedTypes (TypeDefinition type) + { + InitializeNestedTypes (); + Collection mapping; + if (!metadata.TryGetNestedTypeMapping (type, out mapping)) + return new MemberDefinitionCollection (type); + + var nested_types = new MemberDefinitionCollection (type, mapping.Count); + + for (int i = 0; i < mapping.Count; i++) { + var nested_type = GetTypeDefinition (mapping [i]); + + if (nested_type != null) + nested_types.Add (nested_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 Collection AddMapping (Dictionary> cache, TKey key, TValue value) + { + Collection mapped; + if (!cache.TryGetValue (key, out mapped)) { + mapped = new Collection (); + } + mapped.Add (value); + return 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 = ReadListRange (rid, Table.TypeDef, Table.Field); + type.methods_range = ReadListRange (rid, Table.TypeDef, Table.Method); + + 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; + + return GetTypeDefinition (declaring_rid); + } + + Range ReadListRange (uint current_index, Table current, Table target) + { + var list = new Range (); + + var start = ReadTableIndex (target); + if (start == 0) + return list; + + 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 = this.position; + this.position += (int) (current_table.RowSize - image.GetTableIndexSize (target)); + next_index = ReadTableIndex (target); + this.position = position; + } + + list.Start = start; + list.Length = next_index - 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; + + type = ReadTypeDefinition (rid); + + if (module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (type); + + return type; + } + + 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) { + if (scope_token.RID != rid) { + declaring_type = GetTypeDefOrRef (scope_token); + + scope = declaring_type != null + ? declaring_type.Scope + : module; + } else // obfuscated typeref row pointing to self + scope = module; + } else + scope = GetTypeReferenceScope (scope_token); + + type.scope = scope; + type.DeclaringType = declaring_type; + + MetadataSystem.TryProcessPrimitiveTypeReference (type); + + if (type.Module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (type); + + return type; + } + + IMetadataScope GetTypeReferenceScope (MetadataToken scope) + { + if (scope.TokenType == TokenType.Module) + return module; + + IMetadataScope[] scopes; + + switch (scope.TokenType) { + case TokenType.AssemblyRef: + InitializeAssemblyReferences (); + scopes = metadata.AssemblyReferences; + break; + case TokenType.ModuleRef: + InitializeModuleReferences (); + scopes = metadata.ModuleReferences; + break; + default: + throw new NotSupportedException (); + } + + var index = scope.RID - 1; + if (index < 0 || index >= scopes.Length) + return null; + + return scopes [index]; + } + + 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 (); + Collection> mapping; + + return metadata.TryGetInterfaceMapping (type, out mapping); + } + + public InterfaceImplementationCollection ReadInterfaces (TypeDefinition type) + { + InitializeInterfaces (); + Collection> mapping; + + if (!metadata.TryGetInterfaceMapping (type, out mapping)) + return new InterfaceImplementationCollection (type); + + var interfaces = new InterfaceImplementationCollection (type, mapping.Count); + + this.context = type; + + for (int i = 0; i < mapping.Count; i++) { + interfaces.Add ( + new InterfaceImplementation ( + GetTypeDefOrRef (mapping [i].Col2), + new MetadataToken(TokenType.InterfaceImpl, mapping [i].Col1))); + } + + return interfaces; + } + + void InitializeInterfaces () + { + if (metadata.Interfaces != null) + return; + + int length = MoveTo (Table.InterfaceImpl); + + metadata.Interfaces = new Dictionary>> (length); + + for (uint i = 1; i <= length; i++) { + var type = ReadTableIndex (Table.TypeDef); + var @interface = ReadMetadataToken (CodedIndex.TypeDefOrRef); + + AddInterfaceMapping (type, new Row (i, @interface)); + } + } + + void AddInterfaceMapping (uint type, Row @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); + + if (module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (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) + { + return image.GetReaderAt (rva, size, (s, reader) => reader.ReadBytes (s)) ?? Empty.Array; + } + + 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 = type.Resolve (); + if (field_type != null && 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); + + 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 = ReadListRange (i, Table.EventMap, Table.Event); + metadata.AddEventsRange (type_rid, events_range); + } + } + + 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); + + 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 = ReadListRange (i, Table.PropertyMap, Table.Property); + metadata.AddPropertiesRange (type_rid, properties_range); + } + } + + 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 void ReadMethods (PropertyDefinition property) + { + ReadAllSemantics (property.DeclaringType); + } + + public void ReadMethods (EventDefinition @event) + { + ReadAllSemantics (@event.DeclaringType); + } + + public void ReadAllSemantics (MethodDefinition method) + { + ReadAllSemantics (method.DeclaringType); + } + + 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; + } + } + + 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 = ReadListRange (method_rid, Table.Method, Table.Param); + + this.context = method; + + ReadMethodSignature (signature, method); + metadata.AddMethodDefinition (method); + + if (param_range.Length != 0) { + var position = base.position; + ReadParameters (method, param_range); + base.position = position; + } + + if (module.IsWindowsMetadata ()) + WindowsRuntimeProjections.Project (method); + } + + 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 [] ranges; + if (!metadata.TryGetGenericParameterRanges (provider, out ranges)) + return false; + + return RangesSize (ranges) > 0; + } + + public Collection ReadGenericParameters (IGenericParameterProvider provider) + { + InitializeGenericParameters (); + + Range [] ranges; + if (!metadata.TryGetGenericParameterRanges (provider, out ranges)) + return new GenericParameterCollection (provider); + + var generic_parameters = new GenericParameterCollection (provider, RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadGenericParametersRange (ranges [i], provider, generic_parameters); + + return generic_parameters; + } + + void ReadGenericParametersRange (Range range, IGenericParameterProvider provider, GenericParameterCollection generic_parameters) + { + if (!MoveTo (Table.GenericParam, range.Start)) + return; + + 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); + } + } + + 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) { + AddRange (ranges, owner, range); + range = new Range (i, 1); + owner = next; + } else + range.Length++; + } + + AddRange (ranges, owner, range); + + return ranges; + } + + static void AddRange (Dictionary ranges, MetadataToken owner, Range range) + { + if (owner.RID == 0) + return; + + Range [] slots; + if (!ranges.TryGetValue (owner, out slots)) { + ranges.Add (owner, new [] { range }); + return; + } + + ranges [owner] = slots.Add(range); + } + + public bool HasGenericConstraints (GenericParameter generic_parameter) + { + InitializeGenericConstraints (); + + Collection> mapping; + if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping)) + return false; + + return mapping.Count > 0; + } + + public GenericParameterConstraintCollection ReadGenericConstraints (GenericParameter generic_parameter) + { + InitializeGenericConstraints (); + + Collection> mapping; + if (!metadata.TryGetGenericConstraintMapping (generic_parameter, out mapping)) + return new GenericParameterConstraintCollection (generic_parameter); + + var constraints = new GenericParameterConstraintCollection (generic_parameter, mapping.Count); + + this.context = (IGenericContext) generic_parameter.Owner; + + for (int i = 0; i < mapping.Count; i++) { + constraints.Add ( + new GenericParameterConstraint ( + GetTypeDefOrRef (mapping [i].Col2), + new MetadataToken (TokenType.GenericParamConstraint, mapping [i].Col1))); + } + + return constraints; + } + + void InitializeGenericConstraints () + { + if (metadata.GenericConstraints != null) + return; + + var length = MoveTo (Table.GenericParamConstraint); + + metadata.GenericConstraints = new Dictionary>> (length); + + for (uint i = 1; i <= length; i++) { + AddGenericConstraintMapping ( + ReadTableIndex (Table.GenericParam), + new Row (i, ReadMetadataToken (CodedIndex.TypeDefOrRef))); + } + } + + void AddGenericConstraintMapping (uint generic_parameter, Row constraint) + { + metadata.SetGenericConstraintMapping ( + generic_parameter, + AddMapping (metadata.GenericConstraints, generic_parameter, constraint)); + } + + public bool HasOverrides (MethodDefinition method) + { + InitializeOverrides (); + Collection mapping; + + if (!metadata.TryGetOverrideMapping (method, out mapping)) + return false; + + return mapping.Count > 0; + } + + public Collection ReadOverrides (MethodDefinition method) + { + InitializeOverrides (); + + Collection mapping; + if (!metadata.TryGetOverrideMapping (method, out mapping)) + return new Collection (); + + var overrides = new Collection (mapping.Count); + + this.context = method; + + for (int i = 0; i < mapping.Count; i++) + overrides.Add ((MethodReference) LookupToken (mapping [i])); + + 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 int ReadCodeSize (MethodDefinition method) + { + return code.ReadCodeSize (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, MethodDefinition method = null) + { + 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 (method, (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; + + if (metadata_reader != null) + return metadata_reader.LookupToken (token); + + 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; + + Mixin.Read (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; + + Mixin.Read (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 arity = reader.ReadCompressedUInt32 (); + + var instance = new GenericInstanceMethod (method, (int) arity); + + reader.ReadGenericInstanceSignature (method, instance, arity); + + 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 MethodDefinition (string.Empty, MethodAttributes.Static, type_system.Void); + context.DeclaringType = new TypeDefinition (string.Empty, string.Empty, TypeAttributes.Public); + + 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 TypeReference ReadConstantSignature (MetadataToken token) + { + if (token.TokenType != TokenType.Signature) + throw new NotSupportedException (); + + if (token.RID == 0) + return null; + + if (!MoveTo (Table.StandAloneSig, token.RID)) + return null; + + return ReadFieldType (ReadBlobIndex ()); + } + + public object ReadConstant (IConstantProvider owner) + { + InitializeConstants (); + + Row row; + if (!metadata.Constants.TryGetValue (owner.MetadataToken, out row)) + return Mixin.NoValue; + + metadata.Constants.Remove (owner.MetadataToken); + + return ReadConstantValue (row.Col1, row.Col2); + } + + object ReadConstantValue (ElementType etype, uint signature) + { + switch (etype) { + case ElementType.Class: + case ElementType.Object: + return null; + case ElementType.String: + return ReadConstantString (signature); + default: + return ReadConstantPrimitive (etype, signature); + } + } + + string ReadConstantString (uint signature) + { + byte [] blob; + int index, count; + + GetBlobView (signature, out blob, out index, out count); + if (count == 0) + return string.Empty; + + if ((count & 1) == 1) + count--; + + return Encoding.Unicode.GetString (blob, index, count); + } + + object ReadConstantPrimitive (ElementType type, uint signature) + { + var reader = ReadSignature (signature); + return reader.ReadConstantSignature (type); + } + + internal 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 [] ranges; + if (!metadata.TryGetCustomAttributeRanges (owner, out ranges)) + return false; + + return RangesSize (ranges) > 0; + } + + public Collection ReadCustomAttributes (ICustomAttributeProvider owner) + { + InitializeCustomAttributes (); + + Range [] ranges; + if (!metadata.TryGetCustomAttributeRanges (owner, out ranges)) + return new Collection (); + + var custom_attributes = new Collection (RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadCustomAttributeRange (ranges [i], custom_attributes); + + if (module.IsWindowsMetadata ()) + foreach (var custom_attribute in custom_attributes) + WindowsRuntimeProjections.Project (owner, custom_attributes, custom_attribute); + + return custom_attributes; + } + + void ReadCustomAttributeRange (Range range, Collection custom_attributes) + { + if (!MoveTo (Table.CustomAttribute, range.Start)) + return; + + for (var 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)); + } + } + + static int RangesSize (Range [] ranges) + { + uint size = 0; + for (int i = 0; i < ranges.Length; i++) + size += ranges [i].Length; + + return (int) size; + } + + public IEnumerable GetCustomAttributes () + { + InitializeTypeDefinitions (); + + var length = image.TableHeap [Table.CustomAttribute].Length; + var custom_attributes = new Collection ((int) length); + ReadCustomAttributeRange (new Range (1, length), custom_attributes); + + 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 [] ranges; + if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges)) + return false; + + return RangesSize (ranges) > 0; + } + + public Collection ReadSecurityDeclarations (ISecurityDeclarationProvider owner) + { + InitializeSecurityDeclarations (); + + Range [] ranges; + if (!metadata.TryGetSecurityDeclarationRanges (owner, out ranges)) + return new Collection (); + + var security_declarations = new Collection (RangesSize (ranges)); + + for (int i = 0; i < ranges.Length; i++) + ReadSecurityDeclarationRange (ranges [i], security_declarations); + + return security_declarations; + } + + void ReadSecurityDeclarationRange (Range range, Collection security_declarations) + { + if (!MoveTo (Table.DeclSecurity, range.Start)) + return; + + 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)); + } + } + + 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 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, + ReadUnicodeStringBlob (signature)))); + + 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.GetAssemblyNameReference (token.RID); + 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; + } + + void InitializeDocuments () + { + if (metadata.Documents != null) + return; + + int length = MoveTo (Table.Document); + + var documents = metadata.Documents = new Document [length]; + + for (uint i = 1; i <= length; i++) { + var name_index = ReadBlobIndex (); + var hash_algorithm = ReadGuid (); + var hash = ReadBlob (); + var language = ReadGuid (); + + var signature = ReadSignature (name_index); + var name = signature.ReadDocumentName (); + + documents [i - 1] = new Document (name) { + HashAlgorithmGuid = hash_algorithm, + Hash = hash, + LanguageGuid = language, + token = new MetadataToken (TokenType.Document, i), + }; + } + } + + public Collection ReadSequencePoints (MethodDefinition method) + { + InitializeDocuments (); + + if (!MoveTo (Table.MethodDebugInformation, method.MetadataToken.RID)) + return new Collection (0); + + var document_index = ReadTableIndex (Table.Document); + var signature = ReadBlobIndex (); + if (signature == 0) + return new Collection (0); + + var document = GetDocument (document_index); + var reader = ReadSignature (signature); + + return reader.ReadSequencePoints (document); + } + + public Document GetDocument (uint rid) + { + var document = metadata.GetDocument (rid); + if (document == null) + return null; + + document.custom_infos = GetCustomDebugInformation (document); + return document; + } + + void InitializeLocalScopes () + { + if (metadata.LocalScopes != null) + return; + + InitializeMethods (); + + int length = MoveTo (Table.LocalScope); + + metadata.LocalScopes = new Dictionary>> (); + + for (uint i = 1; i <= length; i++) { + var method = ReadTableIndex (Table.Method); + var import = ReadTableIndex (Table.ImportScope); + var variables = ReadListRange (i, Table.LocalScope, Table.LocalVariable); + var constants = ReadListRange (i, Table.LocalScope, Table.LocalConstant); + var scope_start = ReadUInt32 (); + var scope_length = ReadUInt32 (); + + metadata.SetLocalScopes (method, AddMapping (metadata.LocalScopes, method, new Row (import, variables, constants, scope_start, scope_length, i))); + } + } + + public ScopeDebugInformation ReadScope (MethodDefinition method) + { + InitializeLocalScopes (); + InitializeImportScopes (); + + Collection> records; + if (!metadata.TryGetLocalScopes (method, out records)) + return null; + + var method_scope = null as ScopeDebugInformation; + + for (int i = 0; i < records.Count; i++) { + var scope = ReadLocalScope (records [i]); + + if (i == 0) { + method_scope = scope; + continue; + } + + if (!AddScope (method_scope.scopes, scope)) + method_scope.Scopes.Add (scope); + } + + return method_scope; + } + + static bool AddScope (Collection scopes, ScopeDebugInformation scope) + { + if (scopes.IsNullOrEmpty ()) + return false; + + foreach (var sub_scope in scopes) { + if (sub_scope.HasScopes && AddScope (sub_scope.Scopes, scope)) + return true; + + if (scope.Start.Offset >= sub_scope.Start.Offset && scope.End.Offset <= sub_scope.End.Offset) { + sub_scope.Scopes.Add (scope); + return true; + } + } + + return false; + } + + ScopeDebugInformation ReadLocalScope (Row record) + { + var scope = new ScopeDebugInformation + { + start = new InstructionOffset ((int) record.Col4), + end = new InstructionOffset ((int) (record.Col4 + record.Col5)), + token = new MetadataToken (TokenType.LocalScope, record.Col6), + }; + + if (record.Col1 > 0) + scope.import = metadata.GetImportScope (record.Col1); + + if (record.Col2.Length > 0) { + scope.variables = new Collection ((int) record.Col2.Length); + for (uint i = 0; i < record.Col2.Length; i++) { + var variable = ReadLocalVariable (record.Col2.Start + i); + if (variable != null) + scope.variables.Add (variable); + } + } + + if (record.Col3.Length > 0) { + scope.constants = new Collection ((int) record.Col3.Length); + for (uint i = 0; i < record.Col3.Length; i++) { + var constant = ReadLocalConstant (record.Col3.Start + i); + if (constant != null) + scope.constants.Add (constant); + } + } + + return scope; + } + + VariableDebugInformation ReadLocalVariable (uint rid) + { + if (!MoveTo (Table.LocalVariable, rid)) + return null; + + var attributes = (VariableAttributes) ReadUInt16 (); + var index = ReadUInt16 (); + var name = ReadString (); + + var variable = new VariableDebugInformation (index, name) { Attributes = attributes, token = new MetadataToken (TokenType.LocalVariable, rid) }; + variable.custom_infos = GetCustomDebugInformation (variable); + return variable; + } + + ConstantDebugInformation ReadLocalConstant (uint rid) + { + if (!MoveTo (Table.LocalConstant, rid)) + return null; + + var name = ReadString (); + var signature = ReadSignature (ReadBlobIndex ()); + var type = signature.ReadTypeSignature (); + + object value; + if (type.etype == ElementType.String) { + if (!signature.CanReadMore ()) + value = ""; + else if (signature.buffer [signature.position] != 0xff) { + var bytes = signature.ReadBytes ((int) (signature.sig_length - (signature.position - signature.start))); + value = Encoding.Unicode.GetString (bytes, 0, bytes.Length); + } else + value = null; + } else if (type.IsTypeOf ("System", "Decimal")) { + var b = signature.ReadByte (); + value = new decimal (signature.ReadInt32 (), signature.ReadInt32 (), signature.ReadInt32 (), (b & 0x80) != 0, (byte) (b & 0x7f)); + } else if (type.IsTypeOf ("System", "DateTime")) { + value = new DateTime (signature.ReadInt64()); + } else if (type.etype == ElementType.Object || type.etype == ElementType.None || type.etype == ElementType.Class || type.etype == ElementType.Array || type.etype == ElementType.GenericInst) { + value = null; + } else + value = signature.ReadConstantSignature (type.etype); + + var constant = new ConstantDebugInformation (name, type, value) { token = new MetadataToken (TokenType.LocalConstant, rid) }; + constant.custom_infos = GetCustomDebugInformation (constant); + return constant; + } + + void InitializeImportScopes () + { + if (metadata.ImportScopes != null) + return; + + var length = MoveTo (Table.ImportScope); + + metadata.ImportScopes = new ImportDebugInformation [length]; + + for (int i = 1; i <= length; i++) { + ReadTableIndex (Table.ImportScope); + + var import = new ImportDebugInformation (); + import.token = new MetadataToken (TokenType.ImportScope, i); + + var signature = ReadSignature (ReadBlobIndex ()); + while (signature.CanReadMore ()) + import.Targets.Add (ReadImportTarget (signature)); + + metadata.ImportScopes [i - 1] = import; + } + + MoveTo (Table.ImportScope); + + for (int i = 0; i < length; i++) { + var parent = ReadTableIndex (Table.ImportScope); + + ReadBlobIndex (); + + if (parent != 0) + metadata.ImportScopes [i].Parent = metadata.GetImportScope (parent); + } + } + + public string ReadUTF8StringBlob (uint signature) + { + return ReadStringBlob (signature, Encoding.UTF8); + } + + string ReadUnicodeStringBlob (uint signature) + { + return ReadStringBlob (signature, Encoding.Unicode); + } + + string ReadStringBlob (uint signature, Encoding encoding) + { + byte [] blob; + int index, count; + + GetBlobView (signature, out blob, out index, out count); + if (count == 0) + return string.Empty; + + return encoding.GetString (blob, index, count); + } + + ImportTarget ReadImportTarget (SignatureReader signature) + { + AssemblyNameReference reference = null; + string @namespace = null; + string alias = null; + TypeReference type = null; + + var kind = (ImportTargetKind) signature.ReadCompressedUInt32 (); + switch (kind) { + case ImportTargetKind.ImportNamespace: + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.ImportNamespaceInAssembly: + reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.ImportType: + type = signature.ReadTypeToken (); + break; + case ImportTargetKind.ImportXmlNamespaceWithAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.ImportAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.DefineAssemblyAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.DefineNamespaceAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.DefineNamespaceInAssemblyAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + reference = metadata.GetAssemblyNameReference (signature.ReadCompressedUInt32 ()); + @namespace = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + break; + case ImportTargetKind.DefineTypeAlias: + alias = ReadUTF8StringBlob (signature.ReadCompressedUInt32 ()); + type = signature.ReadTypeToken (); + break; + } + + return new ImportTarget (kind) { + alias = alias, + type = type, + @namespace = @namespace, + reference = reference, + }; + } + + void InitializeStateMachineMethods () + { + if (metadata.StateMachineMethods != null) + return; + + var length = MoveTo (Table.StateMachineMethod); + + metadata.StateMachineMethods = new Dictionary (length); + + for (int i = 0; i < length; i++) + metadata.StateMachineMethods.Add (ReadTableIndex (Table.Method), ReadTableIndex (Table.Method)); + } + + public MethodDefinition ReadStateMachineKickoffMethod (MethodDefinition method) + { + InitializeStateMachineMethods (); + + uint rid; + if (!metadata.TryGetStateMachineKickOffMethod (method, out rid)) + return null; + + return GetMethodDefinition (rid); + } + + void InitializeCustomDebugInformations () + { + if (metadata.CustomDebugInformations != null) + return; + + var length = MoveTo (Table.CustomDebugInformation); + + metadata.CustomDebugInformations = new Dictionary []> (); + + for (uint i = 1; i <= length; i++) { + var token = ReadMetadataToken (CodedIndex.HasCustomDebugInformation); + var info = new Row (ReadGuid (), ReadBlobIndex (), i); + + Row [] infos; + metadata.CustomDebugInformations.TryGetValue (token, out infos); + metadata.CustomDebugInformations [token] = infos.Add (info); + } + } + + public Collection GetCustomDebugInformation (ICustomDebugInformationProvider provider) + { + InitializeCustomDebugInformations (); + + Row [] rows; + if (!metadata.CustomDebugInformations.TryGetValue (provider.MetadataToken, out rows)) + return null; + + var infos = new Collection (rows.Length); + + for (int i = 0; i < rows.Length; i++) { + if (rows [i].Col1 == StateMachineScopeDebugInformation.KindIdentifier) { + var signature = ReadSignature (rows [i].Col2); + var scopes = new Collection (); + + while (signature.CanReadMore ()) { + var start = signature.ReadInt32 (); + var end = start + signature.ReadInt32 (); + scopes.Add (new StateMachineScope (start, end)); + } + + var state_machine = new StateMachineScopeDebugInformation (); + state_machine.scopes = scopes; + + infos.Add (state_machine); + } else if (rows [i].Col1 == AsyncMethodBodyDebugInformation.KindIdentifier) { + var signature = ReadSignature (rows [i].Col2); + + var catch_offset = signature.ReadInt32 () - 1; + var yields = new Collection (); + var resumes = new Collection (); + var resume_methods = new Collection (); + + while (signature.CanReadMore ()) { + yields.Add (new InstructionOffset (signature.ReadInt32 ())); + resumes.Add (new InstructionOffset (signature.ReadInt32 ())); + resume_methods.Add (GetMethodDefinition (signature.ReadCompressedUInt32 ())); + } + + var async_body = new AsyncMethodBodyDebugInformation (catch_offset); + async_body.yields = yields; + async_body.resumes = resumes; + async_body.resume_methods = resume_methods; + + infos.Add (async_body); + } else if (rows [i].Col1 == EmbeddedSourceDebugInformation.KindIdentifier) { + infos.Add (new EmbeddedSourceDebugInformation (rows [i].Col2, this)); + } else if (rows [i].Col1 == SourceLinkDebugInformation.KindIdentifier) { + infos.Add (new SourceLinkDebugInformation (Encoding.UTF8.GetString (ReadBlob (rows [i].Col2)))); + } else { + infos.Add (new BinaryCustomDebugInformation (rows [i].Col1, ReadBlob (rows [i].Col2))); + } + + infos [i].token = new MetadataToken (TokenType.CustomDebugInformation, rows [i].Col3); + } + + return infos; + } + + public byte [] ReadRawEmbeddedSourceDebugInformation (uint index) + { + var signature = ReadSignature (index); + return signature.ReadBytes ((int) signature.sig_length); + } + + public Row ReadEmbeddedSourceDebugInformation (uint index) + { + var signature = ReadSignature (index); + var format = signature.ReadInt32 (); + var length = signature.sig_length - 4; + + if (format == 0) { + return new Row (signature.ReadBytes ((int) length), false); + } else if (format > 0) { + var compressed_stream = new MemoryStream (signature.ReadBytes ((int) length)); + var decompressed_document = new byte [format]; // if positive, format is the decompressed length of the document + var decompressed_stream = new MemoryStream (decompressed_document); + + using (var deflate_stream = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true)) + deflate_stream.CopyTo (decompressed_stream); + + return new Row (decompressed_document, true); + } else + throw new NotSupportedException (); + } + } + + sealed class SignatureReader : ByteBuffer { + + readonly MetadataReader reader; + readonly internal uint start, sig_length; + + TypeSystem TypeSystem { + get { return reader.module.TypeSystem; } + } + + public SignatureReader (uint blob, MetadataReader reader) + : base (reader.image.BlobHeap.data) + { + this.reader = reader; + this.position = (int) blob; + this.sig_length = ReadCompressedUInt32(); + this.start = (uint) this.position; + } + + MetadataToken ReadTypeTokenSignature () + { + return CodedIndex.TypeDefOrRef.GetMetadataToken (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, uint arity) + { + 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 ()); + } + + public TypeReference ReadTypeToken () + { + return GetTypeDefOrRef (ReadTypeTokenSignature ()); + } + + TypeReference ReadTypeSignature (ElementType etype) + { + switch (etype) { + case ElementType.ValueType: { + var value_type = GetTypeDefOrRef (ReadTypeTokenSignature ()); + value_type.KnownValueType (); + 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 arity = ReadCompressedUInt32 (); + var generic_instance = new GenericInstanceType (element_type, (int) arity); + + ReadGenericInstanceSignature (element_type, generic_instance, arity); + + if (is_value_type) { + generic_instance.KnownValueType (); + element_type.GetElementType ().KnownValueType (); + } + + 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++) { + var parameterType = GenericParameterResolver.ResolveParameterTypeIfNeeded ( + attribute.Constructor, parameters [i]); + attribute.arguments.Add ( + ReadCustomAttributeFixedArgument (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++) { + if (!CanReadMore ()) + return; + 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; + if (etype == ElementType.GenericInst) { + // The only way to get a generic here is that it's an enum on a generic type + // so for enum we don't need to know the generic arguments (they have no effect) + type = type.GetElementType (); + etype = type.etype; + } + + switch (etype) { + case ElementType.String: + return ReadUTF8String (); + case ElementType.None: + if (type.IsTypeOf ("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 = enum_type.CheckedResolve (); + if (!type.IsEnum) + throw new ArgumentException (); + + return ReadCustomAttributeElementValue (type.GetEnumUnderlyingType ()); + } + + 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; + + if (position + length > buffer.Length) + return string.Empty; + + var @string = Encoding.UTF8.GetString (buffer, position, length); + + position += length; + return @string; + } + + public string ReadDocumentName () + { + var separator = (char) buffer [position]; + position++; + + var builder = new StringBuilder (); + for (int i = 0; CanReadMore (); i++) { + if (i > 0 && separator != 0) + builder.Append (separator); + + uint part = ReadCompressedUInt32 (); + if (part != 0) + builder.Append (reader.ReadUTF8StringBlob (part)); + } + + return builder.ToString (); + } + + public Collection ReadSequencePoints (Document document) + { + ReadCompressedUInt32 (); // local_sig_token + + if (document == null) + document = reader.GetDocument (ReadCompressedUInt32 ()); + + var offset = 0; + var start_line = 0; + var start_column = 0; + var first_non_hidden = true; + + //there's about 5 compressed int32's per sequenec points. we don't know exactly how many + //but let's take a conservative guess so we dont end up reallocating the sequence_points collection + //as it grows. + var bytes_remaining_for_sequencepoints = sig_length - (position - start); + var estimated_sequencepoint_amount = (int)bytes_remaining_for_sequencepoints / 5; + var sequence_points = new Collection (estimated_sequencepoint_amount); + + for (var i = 0; CanReadMore (); i++) { + var delta_il = (int) ReadCompressedUInt32 (); + if (i > 0 && delta_il == 0) { + document = reader.GetDocument (ReadCompressedUInt32 ()); + continue; + } + + offset += delta_il; + + var delta_lines = (int) ReadCompressedUInt32 (); + var delta_columns = delta_lines == 0 + ? (int) ReadCompressedUInt32 () + : ReadCompressedInt32 (); + + if (delta_lines == 0 && delta_columns == 0) { + sequence_points.Add (new SequencePoint (offset, document) { + StartLine = 0xfeefee, + EndLine = 0xfeefee, + StartColumn = 0, + EndColumn = 0, + }); + continue; + } + + if (first_non_hidden) { + start_line = (int) ReadCompressedUInt32 (); + start_column = (int) ReadCompressedUInt32 (); + } else { + start_line += ReadCompressedInt32 (); + start_column += ReadCompressedInt32 (); + } + + sequence_points.Add (new SequencePoint (offset, document) { + StartLine = start_line, + StartColumn = start_column, + EndLine = start_line + delta_lines, + EndColumn = start_column + delta_columns, + }); + first_non_hidden = false; + } + + return sequence_points; + } + + public bool CanReadMore () + { + return (position - start) < sig_length; + } + } +} diff --git a/cecil-master/Mono.Cecil/AssemblyWriter.cs b/cecil-master/Mono.Cecil/AssemblyWriter.cs new file mode 100644 index 000000000..836aa2172 --- /dev/null +++ b/cecil-master/Mono.Cecil/AssemblyWriter.cs @@ -0,0 +1,3377 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.IO.Compression; +using System.Text; +using System.Security.Cryptography; + +using Mono; +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; +using GuidIndex = System.UInt32; + +namespace Mono.Cecil { + + using ModuleRow = Row; + using TypeRefRow = Row; + using TypeDefRow = Row; + using FieldRow = Row; + using MethodRow = Row; + using ParamRow = Row; + using InterfaceImplRow = Row; + using MemberRefRow = Row; + using ConstantRow = Row; + using CustomAttributeRow = Row; + using FieldMarshalRow = Row; + using DeclSecurityRow = Row; + using ClassLayoutRow = Row; + using FieldLayoutRow = Row; + using EventMapRow = Row; + using EventRow = Row; + using PropertyMapRow = Row; + using PropertyRow = Row; + using MethodSemanticsRow = Row; + using MethodImplRow = Row; + using ImplMapRow = Row; + using FieldRVARow = Row; + using AssemblyRow = Row; + using AssemblyRefRow = Row; + using FileRow = Row; + using ExportedTypeRow = Row; + using ManifestResourceRow = Row; + using NestedClassRow = Row; + using GenericParamRow = Row; + using MethodSpecRow = Row; + using GenericParamConstraintRow = Row; + using DocumentRow = Row; + using MethodDebugInformationRow = Row; + using LocalScopeRow = Row; + using LocalVariableRow = Row; + using LocalConstantRow = Row; + using ImportScopeRow = Row; + using StateMachineMethodRow = Row; + using CustomDebugInformationRow = Row; + + static class ModuleWriter { + + public static void WriteModule (ModuleDefinition module, Disposable stream, WriterParameters parameters) + { + using (stream) + Write (module, stream, parameters); + } + + static void Write (ModuleDefinition module, Disposable stream, WriterParameters parameters) + { + if ((module.Attributes & ModuleAttributes.ILOnly) == 0) + throw new NotSupportedException ("Writing mixed-mode assemblies is not supported"); + + if (module.HasImage && module.ReadingMode == ReadingMode.Deferred) { + var immediate_reader = new ImmediateModuleReader (module.Image); + immediate_reader.ReadModule (module, resolve_attributes: false); + immediate_reader.ReadSymbols (module); + } + + module.MetadataSystem.Clear (); + + if (module.symbol_reader != null) + module.symbol_reader.Dispose (); + + var name = module.assembly != null && module.kind != ModuleKind.NetModule ? module.assembly.Name : null; + var fq_name = stream.value.GetFileName (); + var timestamp = parameters.Timestamp ?? module.timestamp; + var symbol_writer_provider = parameters.SymbolWriterProvider; + + if (symbol_writer_provider == null && parameters.WriteSymbols) + symbol_writer_provider = new DefaultSymbolWriterProvider (); + + if (parameters.HasStrongNameKey && name != null) { + name.PublicKey = CryptoService.GetPublicKey (parameters); + module.Attributes |= ModuleAttributes.StrongNameSigned; + } + + if (parameters.DeterministicMvid) + module.Mvid = Guid.Empty; + + var metadata = new MetadataBuilder (module, fq_name, timestamp, symbol_writer_provider); + try { + module.metadata_builder = metadata; + + using (var symbol_writer = GetSymbolWriter (module, fq_name, symbol_writer_provider, parameters)) { + metadata.SetSymbolWriter (symbol_writer); + BuildMetadata (module, metadata); + + if (symbol_writer != null) + symbol_writer.Write (); + + var writer = ImageWriter.CreateWriter (module, metadata, stream); + stream.value.SetLength (0); + writer.WriteImage (); + + if (parameters.DeterministicMvid) + ComputeDeterministicMvid (writer, module); + + if (parameters.HasStrongNameKey) + CryptoService.StrongName (stream.value, writer, parameters); + } + } finally { + module.metadata_builder = null; + } + } + + static void BuildMetadata (ModuleDefinition module, MetadataBuilder metadata) + { + if (!module.HasImage) { + metadata.BuildMetadata (); + return; + } + + module.Read (metadata, (builder, _) => { + builder.BuildMetadata (); + return builder; + }); + } + + static ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fq_name, ISymbolWriterProvider symbol_writer_provider, WriterParameters parameters) + { + if (symbol_writer_provider == null) + return null; + + if (parameters.SymbolStream != null) + return symbol_writer_provider.GetSymbolWriter (module, parameters.SymbolStream); + + return symbol_writer_provider.GetSymbolWriter (module, fq_name); + } + + static void ComputeDeterministicMvid (ImageWriter writer, ModuleDefinition module) + { + long previousPosition = writer.BaseStream.Position; + writer.BaseStream.Seek(0, SeekOrigin.Begin); + + // The hash should be computed with the MVID set to all zeroes + // which it is - we explicitly write all zeroes GUID into the heap + // as the MVID. + // Same goes for strong name signature, which also already in the image but all zeroes right now. + Guid guid = CryptoService.ComputeGuid (CryptoService.ComputeHash (writer.BaseStream)); + + // The MVID GUID is always the first GUID in the GUID heap + writer.MoveToRVA (TextSegment.GuidHeap); + writer.WriteBytes (guid.ToByteArray ()); + writer.Flush (); + module.Mvid = guid; + + writer.BaseStream.Seek(previousPosition, SeekOrigin.Begin); + } + } + + abstract class MetadataTable { + + public abstract int Length { get; } + + public bool IsLarge { + get { return Length > ushort.MaxValue; } + } + + public abstract void Write (TableHeapBuffer buffer); + public abstract void Sort (); + } + + abstract class OneRowTable : MetadataTable where TRow : struct { + + internal TRow row; + + public sealed override int Length { + get { return 1; } + } + + public sealed override void Sort () + { + } + } + + abstract class MetadataTable : MetadataTable where TRow : struct { + + internal TRow [] rows = new TRow [2]; + internal int length; + + public sealed override int Length { + get { return length; } + } + + public int AddRow (TRow row) + { + if (rows.Length == length) + Grow (); + + rows [length++] = row; + return length; + } + + void Grow () + { + var rows = new TRow [this.rows.Length * 2]; + Array.Copy (this.rows, rows, this.rows.Length); + this.rows = rows; + } + + public override void Sort () + { + } + } + + abstract class SortedTable : MetadataTable, IComparer where TRow : struct { + + public sealed override void Sort () + { + MergeSort.Sort (rows, 0, this.length, this); + } + + protected static int Compare (uint x, uint y) + { + return x == y ? 0 : x > y ? 1 : -1; + } + + public abstract int Compare (TRow x, TRow y); + } + + sealed class ModuleTable : OneRowTable { + + public override void Write (TableHeapBuffer buffer) + { + buffer.WriteUInt16 (0); // Generation + buffer.WriteString (row.Col1); // Name + buffer.WriteGuid (row.Col2); // Mvid + buffer.WriteUInt16 (0); // EncId + buffer.WriteUInt16 (0); // EncBaseId + } + } + + sealed class TypeRefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID ( + rows [i].Col1, CodedIndex.ResolutionScope); // Scope + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteString (rows [i].Col3); // Namespace + } + } + } + + sealed class TypeDefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 ((uint) rows [i].Col1); // Attributes + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteString (rows [i].Col3); // Namespace + buffer.WriteCodedRID ( + rows [i].Col4, CodedIndex.TypeDefOrRef); // Extends + buffer.WriteRID (rows [i].Col5, Table.Field); // FieldList + buffer.WriteRID (rows [i].Col6, Table.Method); // MethodList + } + } + } + + sealed class FieldTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteBlob (rows [i].Col3); // Signature + } + } + } + + sealed class MethodTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 (rows [i].Col1); // RVA + buffer.WriteUInt16 ((ushort) rows [i].Col2); // ImplFlags + buffer.WriteUInt16 ((ushort) rows [i].Col3); // Flags + buffer.WriteString (rows [i].Col4); // Name + buffer.WriteBlob (rows [i].Col5); // Signature + buffer.WriteRID (rows [i].Col6, Table.Param); // ParamList + } + } + } + + sealed class ParamTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes + buffer.WriteUInt16 (rows [i].Col2); // Sequence + buffer.WriteString (rows [i].Col3); // Name + } + } + } + + sealed class InterfaceImplTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Interface + } + } + + /*public override int Compare (InterfaceImplRow x, InterfaceImplRow y) + { + return (int) (x.Col1 == y.Col1 ? y.Col2 - x.Col2 : x.Col1 - y.Col1); + }*/ + } + + sealed class MemberRefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MemberRefParent); + buffer.WriteString (rows [i].Col2); + buffer.WriteBlob (rows [i].Col3); + } + } + } + + sealed class ConstantTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasConstant); + buffer.WriteBlob (rows [i].Col3); + } + } + + public override int Compare (ConstantRow x, ConstantRow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class CustomAttributeTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomAttribute); // Parent + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.CustomAttributeType); // Type + buffer.WriteBlob (rows [i].Col3); + } + } + + public override int Compare (CustomAttributeRow x, CustomAttributeRow y) + { + return Compare (x.Col1, y.Col1); + } + } + + sealed class FieldMarshalTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasFieldMarshal); + buffer.WriteBlob (rows [i].Col2); + } + } + + public override int Compare (FieldMarshalRow x, FieldMarshalRow y) + { + return Compare (x.Col1, y.Col1); + } + } + + sealed class DeclSecurityTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.HasDeclSecurity); + buffer.WriteBlob (rows [i].Col3); + } + } + + public override int Compare (DeclSecurityRow x, DeclSecurityRow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class ClassLayoutTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 (rows [i].Col1); // PackingSize + buffer.WriteUInt32 (rows [i].Col2); // ClassSize + buffer.WriteRID (rows [i].Col3, Table.TypeDef); // Parent + } + } + + public override int Compare (ClassLayoutRow x, ClassLayoutRow y) + { + return Compare (x.Col3, y.Col3); + } + } + + sealed class FieldLayoutTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 (rows [i].Col1); // Offset + buffer.WriteRID (rows [i].Col2, Table.Field); // Parent + } + } + + public override int Compare (FieldLayoutRow x, FieldLayoutRow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class StandAloneSigTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) + buffer.WriteBlob (rows [i]); + } + } + + sealed class EventMapTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent + buffer.WriteRID (rows [i].Col2, Table.Event); // EventList + } + } + } + + sealed class EventTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeDefOrRef); // EventType + } + } + } + + sealed class PropertyMapTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Parent + buffer.WriteRID (rows [i].Col2, Table.Property); // PropertyList + } + } + } + + sealed class PropertyTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags + buffer.WriteString (rows [i].Col2); // Name + buffer.WriteBlob (rows [i].Col3); // Type + } + } + } + + sealed class MethodSemanticsTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags + buffer.WriteRID (rows [i].Col2, Table.Method); // Method + buffer.WriteCodedRID (rows [i].Col3, CodedIndex.HasSemantics); // Association + } + } + + public override int Compare (MethodSemanticsRow x, MethodSemanticsRow y) + { + return Compare (x.Col3, y.Col3); + } + } + + sealed class MethodImplTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // Class + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MethodDefOrRef); // MethodBody + buffer.WriteCodedRID (rows [i].Col3, CodedIndex.MethodDefOrRef); // MethodDeclaration + } + } + } + + sealed class ModuleRefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) + buffer.WriteString (rows [i]); // Name + } + } + + sealed class TypeSpecTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) + buffer.WriteBlob (rows [i]); // Signature + } + } + + sealed class ImplMapTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Flags + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.MemberForwarded); // MemberForwarded + buffer.WriteString (rows [i].Col3); // ImportName + buffer.WriteRID (rows [i].Col4, Table.ModuleRef); // ImportScope + } + } + + public override int Compare (ImplMapRow x, ImplMapRow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class FieldRVATable : SortedTable { + + internal int position; + + public override void Write (TableHeapBuffer buffer) + { + position = buffer.position; + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 (rows [i].Col1); // RVA + buffer.WriteRID (rows [i].Col2, Table.Field); // Field + } + } + + public override int Compare (FieldRVARow x, FieldRVARow y) + { + return Compare (x.Col2, y.Col2); + } + } + + sealed class AssemblyTable : OneRowTable { + + public override void Write (TableHeapBuffer buffer) + { + buffer.WriteUInt32 ((uint) row.Col1); // AssemblyHashAlgorithm + buffer.WriteUInt16 (row.Col2); // MajorVersion + buffer.WriteUInt16 (row.Col3); // MinorVersion + buffer.WriteUInt16 (row.Col4); // Build + buffer.WriteUInt16 (row.Col5); // Revision + buffer.WriteUInt32 ((uint) row.Col6); // Flags + buffer.WriteBlob (row.Col7); // PublicKey + buffer.WriteString (row.Col8); // Name + buffer.WriteString (row.Col9); // Culture + } + } + + sealed class AssemblyRefTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 (rows [i].Col1); // MajorVersion + buffer.WriteUInt16 (rows [i].Col2); // MinorVersion + buffer.WriteUInt16 (rows [i].Col3); // Build + buffer.WriteUInt16 (rows [i].Col4); // Revision + buffer.WriteUInt32 ((uint) rows [i].Col5); // Flags + buffer.WriteBlob (rows [i].Col6); // PublicKeyOrToken + buffer.WriteString (rows [i].Col7); // Name + buffer.WriteString (rows [i].Col8); // Culture + buffer.WriteBlob (rows [i].Col9); // Hash + } + } + } + + sealed class FileTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 ((uint) rows [i].Col1); + buffer.WriteString (rows [i].Col2); + buffer.WriteBlob (rows [i].Col3); + } + } + } + + sealed class ExportedTypeTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 ((uint) rows [i].Col1); + buffer.WriteUInt32 (rows [i].Col2); + buffer.WriteString (rows [i].Col3); + buffer.WriteString (rows [i].Col4); + buffer.WriteCodedRID (rows [i].Col5, CodedIndex.Implementation); + } + } + } + + sealed class ManifestResourceTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt32 (rows [i].Col1); + buffer.WriteUInt32 ((uint) rows [i].Col2); + buffer.WriteString (rows [i].Col3); + buffer.WriteCodedRID (rows [i].Col4, CodedIndex.Implementation); + } + } + } + + sealed class NestedClassTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.TypeDef); // NestedClass + buffer.WriteRID (rows [i].Col2, Table.TypeDef); // EnclosingClass + } + } + + public override int Compare (NestedClassRow x, NestedClassRow y) + { + return Compare (x.Col1, y.Col1); + } + } + + sealed class GenericParamTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 (rows [i].Col1); // Number + buffer.WriteUInt16 ((ushort) rows [i].Col2); // Flags + buffer.WriteCodedRID (rows [i].Col3, CodedIndex.TypeOrMethodDef); // Owner + buffer.WriteString (rows [i].Col4); // Name + } + } + } + + sealed class MethodSpecTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.MethodDefOrRef); // Method + buffer.WriteBlob (rows [i].Col2); // Instantiation + } + } + } + + sealed class GenericParamConstraintTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.GenericParam); // Owner + buffer.WriteCodedRID (rows [i].Col2, CodedIndex.TypeDefOrRef); // Constraint + } + } + } + + sealed class DocumentTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteBlob (rows [i].Col1); // Name + buffer.WriteGuid (rows [i].Col2); // HashAlgorithm + buffer.WriteBlob (rows [i].Col3); // Hash + buffer.WriteGuid (rows [i].Col4); // Language + } + } + } + + sealed class MethodDebugInformationTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.Document); // Document + buffer.WriteBlob (rows [i].Col2); // SequencePoints + } + } + } + + sealed class LocalScopeTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.Method); // Method + buffer.WriteRID (rows [i].Col2, Table.ImportScope); // ImportScope + buffer.WriteRID (rows [i].Col3, Table.LocalVariable); // VariableList + buffer.WriteRID (rows [i].Col4, Table.LocalConstant); // ConstantList + buffer.WriteUInt32 (rows [i].Col5); // StartOffset + buffer.WriteUInt32 (rows [i].Col6); // Length + } + } + } + + sealed class LocalVariableTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteUInt16 ((ushort) rows [i].Col1); // Attributes + buffer.WriteUInt16 (rows [i].Col2); // Index + buffer.WriteString (rows [i].Col3); // Name + } + } + } + + sealed class LocalConstantTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteString (rows [i].Col1); // Name + buffer.WriteBlob (rows [i].Col2); // Signature + } + } + } + + sealed class ImportScopeTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.ImportScope); // Parent + buffer.WriteBlob (rows [i].Col2); // Imports + } + } + } + + sealed class StateMachineMethodTable : MetadataTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteRID (rows [i].Col1, Table.Method); // MoveNextMethod + buffer.WriteRID (rows [i].Col2, Table.Method); // KickoffMethod + } + } + } + + sealed class CustomDebugInformationTable : SortedTable { + + public override void Write (TableHeapBuffer buffer) + { + for (int i = 0; i < length; i++) { + buffer.WriteCodedRID (rows [i].Col1, CodedIndex.HasCustomDebugInformation); // Parent + buffer.WriteGuid (rows [i].Col2); // Kind + buffer.WriteBlob (rows [i].Col3); // Value + } + } + + public override int Compare (CustomDebugInformationRow x, CustomDebugInformationRow y) + { + return Compare(x.Col1, y.Col1); + } + } + + sealed class MetadataBuilder { + + readonly internal ModuleDefinition module; + readonly internal ISymbolWriterProvider symbol_writer_provider; + internal ISymbolWriter symbol_writer; + readonly internal TextMap text_map; + readonly internal string fq_name; + readonly internal uint timestamp; + + readonly Dictionary type_ref_map; + readonly Dictionary type_spec_map; + readonly Dictionary member_ref_map; + readonly Dictionary method_spec_map; + readonly Collection generic_parameters; + + readonly internal CodeWriter code; + readonly internal DataBuffer data; + readonly internal ResourceBuffer resources; + readonly internal StringHeapBuffer string_heap; + readonly internal GuidHeapBuffer guid_heap; + readonly internal UserStringHeapBuffer user_string_heap; + readonly internal BlobHeapBuffer blob_heap; + readonly internal TableHeapBuffer table_heap; + readonly internal PdbHeapBuffer pdb_heap; + + internal MetadataToken entry_point; + + internal RID type_rid = 1; + internal RID field_rid = 1; + internal RID method_rid = 1; + internal RID param_rid = 1; + internal RID property_rid = 1; + internal RID event_rid = 1; + internal RID local_variable_rid = 1; + internal RID local_constant_rid = 1; + + readonly TypeRefTable type_ref_table; + readonly TypeDefTable type_def_table; + readonly FieldTable field_table; + readonly MethodTable method_table; + readonly ParamTable param_table; + readonly InterfaceImplTable iface_impl_table; + readonly MemberRefTable member_ref_table; + readonly ConstantTable constant_table; + readonly CustomAttributeTable custom_attribute_table; + readonly DeclSecurityTable declsec_table; + readonly StandAloneSigTable standalone_sig_table; + readonly EventMapTable event_map_table; + readonly EventTable event_table; + readonly PropertyMapTable property_map_table; + readonly PropertyTable property_table; + readonly TypeSpecTable typespec_table; + readonly MethodSpecTable method_spec_table; + + internal MetadataBuilder metadata_builder; + + readonly DocumentTable document_table; + readonly MethodDebugInformationTable method_debug_information_table; + readonly LocalScopeTable local_scope_table; + readonly LocalVariableTable local_variable_table; + readonly LocalConstantTable local_constant_table; + readonly ImportScopeTable import_scope_table; + readonly StateMachineMethodTable state_machine_method_table; + readonly CustomDebugInformationTable custom_debug_information_table; + + readonly Dictionary import_scope_map; + readonly Dictionary document_map; + + public MetadataBuilder (ModuleDefinition module, string fq_name, uint timestamp, ISymbolWriterProvider symbol_writer_provider) + { + this.module = module; + this.text_map = CreateTextMap (); + this.fq_name = fq_name; + this.timestamp = timestamp; + this.symbol_writer_provider = symbol_writer_provider; + + this.code = new CodeWriter (this); + this.data = new DataBuffer (); + this.resources = new ResourceBuffer (); + this.string_heap = new StringHeapBuffer (); + this.guid_heap = new GuidHeapBuffer (); + this.user_string_heap = new UserStringHeapBuffer (); + this.blob_heap = new BlobHeapBuffer (); + this.table_heap = new TableHeapBuffer (module, this); + + this.type_ref_table = GetTable (Table.TypeRef); + this.type_def_table = GetTable (Table.TypeDef); + this.field_table = GetTable (Table.Field); + this.method_table = GetTable (Table.Method); + this.param_table = GetTable (Table.Param); + this.iface_impl_table = GetTable (Table.InterfaceImpl); + this.member_ref_table = GetTable (Table.MemberRef); + this.constant_table = GetTable (Table.Constant); + this.custom_attribute_table = GetTable (Table.CustomAttribute); + this.declsec_table = GetTable (Table.DeclSecurity); + this.standalone_sig_table = GetTable (Table.StandAloneSig); + this.event_map_table = GetTable (Table.EventMap); + this.event_table = GetTable (Table.Event); + this.property_map_table = GetTable (Table.PropertyMap); + this.property_table = GetTable (Table.Property); + this.typespec_table = GetTable (Table.TypeSpec); + this.method_spec_table = GetTable (Table.MethodSpec); + + var row_equality_comparer = new RowEqualityComparer (); + type_ref_map = new Dictionary (row_equality_comparer); + type_spec_map = new Dictionary (); + member_ref_map = new Dictionary (row_equality_comparer); + method_spec_map = new Dictionary (row_equality_comparer); + generic_parameters = new Collection (); + + this.document_table = GetTable (Table.Document); + this.method_debug_information_table = GetTable (Table.MethodDebugInformation); + this.local_scope_table = GetTable (Table.LocalScope); + this.local_variable_table = GetTable (Table.LocalVariable); + this.local_constant_table = GetTable (Table.LocalConstant); + this.import_scope_table = GetTable (Table.ImportScope); + this.state_machine_method_table = GetTable (Table.StateMachineMethod); + this.custom_debug_information_table = GetTable (Table.CustomDebugInformation); + + this.document_map = new Dictionary (StringComparer.Ordinal); + this.import_scope_map = new Dictionary (row_equality_comparer); + } + + public MetadataBuilder (ModuleDefinition module, PortablePdbWriterProvider writer_provider) + { + this.module = module; + this.text_map = new TextMap (); + this.symbol_writer_provider = writer_provider; + + this.string_heap = new StringHeapBuffer (); + this.guid_heap = new GuidHeapBuffer (); + this.user_string_heap = new UserStringHeapBuffer (); + this.blob_heap = new BlobHeapBuffer (); + this.table_heap = new TableHeapBuffer (module, this); + this.pdb_heap = new PdbHeapBuffer(); + + this.document_table = GetTable (Table.Document); + this.method_debug_information_table = GetTable (Table.MethodDebugInformation); + this.local_scope_table = GetTable (Table.LocalScope); + this.local_variable_table = GetTable (Table.LocalVariable); + this.local_constant_table = GetTable (Table.LocalConstant); + this.import_scope_table = GetTable (Table.ImportScope); + this.state_machine_method_table = GetTable (Table.StateMachineMethod); + this.custom_debug_information_table = GetTable (Table.CustomDebugInformation); + + var row_equality_comparer = new RowEqualityComparer (); + + this.document_map = new Dictionary (); + this.import_scope_map = new Dictionary (row_equality_comparer); + } + + public void SetSymbolWriter (ISymbolWriter writer) + { + symbol_writer = writer; + + if (symbol_writer == null && module.HasImage && module.Image.HasDebugTables ()) + symbol_writer = new PortablePdbWriter (this, module); + } + + TextMap CreateTextMap () + { + var map = new TextMap (); + map.AddMap (TextSegment.ImportAddressTable, module.Architecture == TargetArchitecture.I386 ? 8 : 0); + map.AddMap (TextSegment.CLIHeader, 0x48, 8); + var pe64 = module.Architecture == TargetArchitecture.AMD64 || module.Architecture == TargetArchitecture.IA64 || module.Architecture == TargetArchitecture.ARM64; + // Alignment of the code segment must be set before the code is written + // These alignment values are probably not necessary, but are being left in + // for now in case something requires them. + map.AddMap (TextSegment.Code, 0, !pe64 ? 4 : 16); + return map; + } + + TTable GetTable (Table table) where TTable : MetadataTable, new () + { + return table_heap.GetTable (table); + } + + uint GetStringIndex (string @string) + { + if (string.IsNullOrEmpty (@string)) + return 0; + + return string_heap.GetStringIndex (@string); + } + + uint GetGuidIndex (Guid guid) + { + return guid_heap.GetGuidIndex (guid); + } + + uint GetBlobIndex (ByteBuffer blob) + { + if (blob.length == 0) + return 0; + + return blob_heap.GetBlobIndex (blob); + } + + uint GetBlobIndex (byte [] blob) + { + if (blob.IsNullOrEmpty ()) + return 0; + + return GetBlobIndex (new ByteBuffer (blob)); + } + + public void BuildMetadata () + { + BuildModule (); + + table_heap.string_offsets = string_heap.WriteStrings (); + table_heap.ComputeTableInformations (); + table_heap.WriteTableHeap (); + } + + void BuildModule () + { + var table = GetTable (Table.Module); + table.row.Col1 = GetStringIndex (module.Name); + table.row.Col2 = GetGuidIndex (module.Mvid); + + var assembly = module.Assembly; + + if (module.kind != ModuleKind.NetModule && assembly != null) + BuildAssembly (); + + if (module.HasAssemblyReferences) + AddAssemblyReferences (); + + if (module.HasModuleReferences) + AddModuleReferences (); + + if (module.HasResources) + AddResources (); + + if (module.HasExportedTypes) + AddExportedTypes (); + + BuildTypes (); + + if (module.kind != ModuleKind.NetModule && assembly != null) { + if (assembly.HasCustomAttributes) + AddCustomAttributes (assembly); + + if (assembly.HasSecurityDeclarations) + AddSecurityDeclarations (assembly); + } + + if (module.HasCustomAttributes) + AddCustomAttributes (module); + + if (module.EntryPoint != null) + entry_point = LookupToken (module.EntryPoint); + } + + void BuildAssembly () + { + var assembly = module.Assembly; + var name = assembly.Name; + + var table = GetTable (Table.Assembly); + + table.row = new AssemblyRow ( + name.HashAlgorithm, + (ushort) name.Version.Major, + (ushort) name.Version.Minor, + (ushort) name.Version.Build, + (ushort) name.Version.Revision, + name.Attributes, + GetBlobIndex (name.PublicKey), + GetStringIndex (name.Name), + GetStringIndex (name.Culture)); + + if (assembly.Modules.Count > 1) + BuildModules (); + } + + void BuildModules () + { + var modules = this.module.Assembly.Modules; + var table = GetTable (Table.File); + + for (int i = 0; i < modules.Count; i++) { + var module = modules [i]; + if (module.IsMain) + continue; + +#if NET_CORE + throw new NotSupportedException (); +#else + var parameters = new WriterParameters { + SymbolWriterProvider = symbol_writer_provider, + }; + + var file_name = GetModuleFileName (module.Name); + module.Write (file_name, parameters); + + var hash = CryptoService.ComputeHash (file_name); + + table.AddRow (new FileRow ( + FileAttributes.ContainsMetaData, + GetStringIndex (module.Name), + GetBlobIndex (hash))); +#endif + } + } + +#if !NET_CORE + string GetModuleFileName (string name) + { + if (string.IsNullOrEmpty (name)) + throw new NotSupportedException (); + + var path = Path.GetDirectoryName (fq_name); + return Path.Combine (path, name); + } +#endif + + void AddAssemblyReferences () + { + var references = module.AssemblyReferences; + var table = GetTable (Table.AssemblyRef); + + if (module.IsWindowsMetadata ()) + module.Projections.RemoveVirtualReferences (references); + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; + + var key_or_token = reference.PublicKey.IsNullOrEmpty () + ? reference.PublicKeyToken + : reference.PublicKey; + + var version = reference.Version; + + var rid = table.AddRow (new AssemblyRefRow ( + (ushort) version.Major, + (ushort) version.Minor, + (ushort) version.Build, + (ushort) version.Revision, + reference.Attributes, + GetBlobIndex (key_or_token), + GetStringIndex (reference.Name), + GetStringIndex (reference.Culture), + GetBlobIndex (reference.Hash))); + + reference.token = new MetadataToken (TokenType.AssemblyRef, rid); + } + + if (module.IsWindowsMetadata ()) + module.Projections.AddVirtualReferences (references); + } + + void AddModuleReferences () + { + var references = module.ModuleReferences; + var table = GetTable (Table.ModuleRef); + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; + + reference.token = new MetadataToken ( + TokenType.ModuleRef, + table.AddRow (GetStringIndex (reference.Name))); + } + } + + void AddResources () + { + var resources = module.Resources; + var table = GetTable (Table.ManifestResource); + + for (int i = 0; i < resources.Count; i++) { + var resource = resources [i]; + + var row = new ManifestResourceRow ( + 0, + resource.Attributes, + GetStringIndex (resource.Name), + 0); + + switch (resource.ResourceType) { + case ResourceType.Embedded: + row.Col1 = AddEmbeddedResource ((EmbeddedResource) resource); + break; + case ResourceType.Linked: + row.Col4 = CodedIndex.Implementation.CompressMetadataToken ( + new MetadataToken ( + TokenType.File, + AddLinkedResource ((LinkedResource) resource))); + break; + case ResourceType.AssemblyLinked: + row.Col4 = CodedIndex.Implementation.CompressMetadataToken ( + ((AssemblyLinkedResource) resource).Assembly.MetadataToken); + break; + default: + throw new NotSupportedException (); + } + + table.AddRow (row); + } + } + + uint AddLinkedResource (LinkedResource resource) + { + var table = GetTable (Table.File); + var hash = resource.Hash; + + if (hash.IsNullOrEmpty ()) + hash = CryptoService.ComputeHash (resource.File); + + return (uint) table.AddRow (new FileRow ( + FileAttributes.ContainsNoMetaData, + GetStringIndex (resource.File), + GetBlobIndex (hash))); + } + + uint AddEmbeddedResource (EmbeddedResource resource) + { + return resources.AddResource (resource.GetResourceData ()); + } + + void AddExportedTypes () + { + var exported_types = module.ExportedTypes; + var table = GetTable (Table.ExportedType); + + for (int i = 0; i < exported_types.Count; i++) { + var exported_type = exported_types [i]; + + var rid = table.AddRow (new ExportedTypeRow ( + exported_type.Attributes, + (uint) exported_type.Identifier, + GetStringIndex (exported_type.Name), + GetStringIndex (exported_type.Namespace), + MakeCodedRID (GetExportedTypeScope (exported_type), CodedIndex.Implementation))); + + exported_type.token = new MetadataToken (TokenType.ExportedType, rid); + } + } + + MetadataToken GetExportedTypeScope (ExportedType exported_type) + { + if (exported_type.DeclaringType != null) + return exported_type.DeclaringType.MetadataToken; + + var scope = exported_type.Scope; + switch (scope.MetadataToken.TokenType) { + case TokenType.AssemblyRef: + return scope.MetadataToken; + case TokenType.ModuleRef: + var file_table = GetTable (Table.File); + for (int i = 0; i < file_table.length; i++) + if (file_table.rows [i].Col2 == GetStringIndex (scope.Name)) + return new MetadataToken (TokenType.File, i + 1); + + break; + } + + throw new NotSupportedException (); + } + + void BuildTypes () + { + if (!module.HasTypes) + return; + + AttachTokens (); + AddTypes (); + AddGenericParameters (); + } + + void AttachTokens () + { + var types = module.Types; + + for (int i = 0; i < types.Count; i++) + AttachTypeToken (types [i]); + } + + void AttachTypeToken (TypeDefinition type) + { + var treatment = WindowsRuntimeProjections.RemoveProjection (type); + + type.token = new MetadataToken (TokenType.TypeDef, type_rid++); + type.fields_range.Start = field_rid; + type.methods_range.Start = method_rid; + + if (type.HasFields) + AttachFieldsToken (type); + + if (type.HasMethods) + AttachMethodsToken (type); + + if (type.HasNestedTypes) + AttachNestedTypesToken (type); + + WindowsRuntimeProjections.ApplyProjection (type, treatment); + } + + void AttachNestedTypesToken (TypeDefinition type) + { + var nested_types = type.NestedTypes; + for (int i = 0; i < nested_types.Count; i++) + AttachTypeToken (nested_types [i]); + } + + void AttachFieldsToken (TypeDefinition type) + { + var fields = type.Fields; + type.fields_range.Length = (uint) fields.Count; + for (int i = 0; i < fields.Count; i++) + fields [i].token = new MetadataToken (TokenType.Field, field_rid++); + } + + void AttachMethodsToken (TypeDefinition type) + { + var methods = type.Methods; + type.methods_range.Length = (uint) methods.Count; + for (int i = 0; i < methods.Count; i++) + methods [i].token = new MetadataToken (TokenType.Method, method_rid++); + } + + MetadataToken GetTypeToken (TypeReference type) + { + if (type == null) + return MetadataToken.Zero; + + if (type.IsDefinition) + return type.token; + + if (type.IsTypeSpecification ()) + return GetTypeSpecToken (type); + + return GetTypeRefToken (type); + } + + MetadataToken GetTypeSpecToken (TypeReference type) + { + var row = GetBlobIndex (GetTypeSpecSignature (type)); + + MetadataToken token; + if (type_spec_map.TryGetValue (row, out token)) + return token; + + return AddTypeSpecification (type, row); + } + + MetadataToken AddTypeSpecification (TypeReference type, uint row) + { + type.token = new MetadataToken (TokenType.TypeSpec, typespec_table.AddRow (row)); + + var token = type.token; + type_spec_map.Add (row, token); + return token; + } + + MetadataToken GetTypeRefToken (TypeReference type) + { + var projection = WindowsRuntimeProjections.RemoveProjection (type); + + var row = CreateTypeRefRow (type); + + MetadataToken token; + if (!type_ref_map.TryGetValue (row, out token)) + token = AddTypeReference (type, row); + + WindowsRuntimeProjections.ApplyProjection (type, projection); + + return token; + } + + TypeRefRow CreateTypeRefRow (TypeReference type) + { + var scope_token = GetScopeToken (type); + + return new TypeRefRow ( + MakeCodedRID (scope_token, CodedIndex.ResolutionScope), + GetStringIndex (type.Name), + GetStringIndex (type.Namespace)); + } + + MetadataToken GetScopeToken (TypeReference type) + { + if (type.IsNested) + return GetTypeRefToken (type.DeclaringType); + + var scope = type.Scope; + + if (scope == null) + return MetadataToken.Zero; + + return scope.MetadataToken; + } + + static CodedRID MakeCodedRID (IMetadataTokenProvider provider, CodedIndex index) + { + return MakeCodedRID (provider.MetadataToken, index); + } + + static CodedRID MakeCodedRID (MetadataToken token, CodedIndex index) + { + return index.CompressMetadataToken (token); + } + + MetadataToken AddTypeReference (TypeReference type, TypeRefRow row) + { + type.token = new MetadataToken (TokenType.TypeRef, type_ref_table.AddRow (row)); + + var token = type.token; + type_ref_map.Add (row, token); + return token; + } + + void AddTypes () + { + var types = module.Types; + + for (int i = 0; i < types.Count; i++) + AddType (types [i]); + } + + void AddType (TypeDefinition type) + { + var treatment = WindowsRuntimeProjections.RemoveProjection (type); + + type_def_table.AddRow (new TypeDefRow ( + type.Attributes, + GetStringIndex (type.Name), + GetStringIndex (type.Namespace), + MakeCodedRID (GetTypeToken (type.BaseType), CodedIndex.TypeDefOrRef), + type.fields_range.Start, + type.methods_range.Start)); + + if (type.HasGenericParameters) + AddGenericParameters (type); + + if (type.HasInterfaces) + AddInterfaces (type); + + if (type.HasLayoutInfo) + AddLayoutInfo (type); + + if (type.HasFields) + AddFields (type); + + if (type.HasMethods) + AddMethods (type); + + if (type.HasProperties) + AddProperties (type); + + if (type.HasEvents) + AddEvents (type); + + if (type.HasCustomAttributes) + AddCustomAttributes (type); + + if (type.HasSecurityDeclarations) + AddSecurityDeclarations (type); + + if (type.HasNestedTypes) + AddNestedTypes (type); + + WindowsRuntimeProjections.ApplyProjection (type, treatment); + } + + void AddGenericParameters (IGenericParameterProvider owner) + { + var parameters = owner.GenericParameters; + + for (int i = 0; i < parameters.Count; i++) + generic_parameters.Add (parameters [i]); + } + + sealed class GenericParameterComparer : IComparer { + + public int Compare (GenericParameter a, GenericParameter b) + { + var a_owner = MakeCodedRID (a.Owner, CodedIndex.TypeOrMethodDef); + var b_owner = MakeCodedRID (b.Owner, CodedIndex.TypeOrMethodDef); + if (a_owner == b_owner) { + var a_pos = a.Position; + var b_pos = b.Position; + return a_pos == b_pos ? 0 : a_pos > b_pos ? 1 : -1; + } + + return a_owner > b_owner ? 1 : -1; + } + } + + void AddGenericParameters () + { + var items = this.generic_parameters.items; + var size = this.generic_parameters.size; + Array.Sort (items, 0, size, new GenericParameterComparer ()); + + var generic_param_table = GetTable (Table.GenericParam); + var generic_param_constraint_table = GetTable (Table.GenericParamConstraint); + + for (int i = 0; i < size; i++) { + var generic_parameter = items [i]; + + var rid = generic_param_table.AddRow (new GenericParamRow ( + (ushort) generic_parameter.Position, + generic_parameter.Attributes, + MakeCodedRID (generic_parameter.Owner, CodedIndex.TypeOrMethodDef), + GetStringIndex (generic_parameter.Name))); + + generic_parameter.token = new MetadataToken (TokenType.GenericParam, rid); + + if (generic_parameter.HasConstraints) + AddConstraints (generic_parameter, generic_param_constraint_table); + + if (generic_parameter.HasCustomAttributes) + AddCustomAttributes (generic_parameter); + } + } + + void AddConstraints (GenericParameter generic_parameter, GenericParamConstraintTable table) + { + var constraints = generic_parameter.Constraints; + + var gp_rid = generic_parameter.token.RID; + + for (int i = 0; i < constraints.Count; i++) { + var constraint = constraints [i]; + + var rid = table.AddRow (new GenericParamConstraintRow ( + gp_rid, + MakeCodedRID (GetTypeToken (constraint.ConstraintType), CodedIndex.TypeDefOrRef))); + + constraint.token = new MetadataToken (TokenType.GenericParamConstraint, rid); + + if (constraint.HasCustomAttributes) + AddCustomAttributes (constraint); + } + } + + void AddInterfaces (TypeDefinition type) + { + var interfaces = type.Interfaces; + var type_rid = type.token.RID; + + for (int i = 0; i < interfaces.Count; i++) { + var iface_impl = interfaces [i]; + + var rid = iface_impl_table.AddRow (new InterfaceImplRow ( + type_rid, + MakeCodedRID (GetTypeToken (iface_impl.InterfaceType), CodedIndex.TypeDefOrRef))); + + iface_impl.token = new MetadataToken (TokenType.InterfaceImpl, rid); + + if (iface_impl.HasCustomAttributes) + AddCustomAttributes (iface_impl); + } + } + + void AddLayoutInfo (TypeDefinition type) + { + var table = GetTable (Table.ClassLayout); + + table.AddRow (new ClassLayoutRow ( + (ushort) type.PackingSize, + (uint) type.ClassSize, + type.token.RID)); + } + + void AddNestedTypes (TypeDefinition type) + { + var nested_types = type.NestedTypes; + var nested_table = GetTable (Table.NestedClass); + + for (int i = 0; i < nested_types.Count; i++) { + var nested = nested_types [i]; + AddType (nested); + nested_table.AddRow (new NestedClassRow (nested.token.RID, type.token.RID)); + } + } + + void AddFields (TypeDefinition type) + { + var fields = type.Fields; + + for (int i = 0; i < fields.Count; i++) + AddField (fields [i]); + } + + void AddField (FieldDefinition field) + { + var projection = WindowsRuntimeProjections.RemoveProjection (field); + + field_table.AddRow (new FieldRow ( + field.Attributes, + GetStringIndex (field.Name), + GetBlobIndex (GetFieldSignature (field)))); + + if (!field.InitialValue.IsNullOrEmpty ()) + AddFieldRVA (field); + + if (field.HasLayoutInfo) + AddFieldLayout (field); + + if (field.HasCustomAttributes) + AddCustomAttributes (field); + + if (field.HasConstant) + AddConstant (field, field.FieldType); + + if (field.HasMarshalInfo) + AddMarshalInfo (field); + + WindowsRuntimeProjections.ApplyProjection (field, projection); + } + + void AddFieldRVA (FieldDefinition field) + { + var table = GetTable (Table.FieldRVA); + + // To allow for safe implementation of metadata rewriters for code which uses CreateSpan + // if the Field RVA refers to a locally defined type with a pack > 1, align the InitialValue + // to pack boundary. This logic is restricted to only being affected by metadata local to the module + // as PackingSize is only used when examining a type local to the module being written. + + int align = 1; + if (field.FieldType.IsDefinition && !field.FieldType.IsGenericInstance) { + var type = field.FieldType.Resolve (); + + if ((type.Module == module) && (type.PackingSize > 1)) + align = type.PackingSize; + } + table.AddRow (new FieldRVARow ( + data.AddData (field.InitialValue, align), + field.token.RID)); + } + + void AddFieldLayout (FieldDefinition field) + { + var table = GetTable (Table.FieldLayout); + table.AddRow (new FieldLayoutRow ((uint) field.Offset, field.token.RID)); + } + + void AddMethods (TypeDefinition type) + { + var methods = type.Methods; + + for (int i = 0; i < methods.Count; i++) + AddMethod (methods [i]); + } + + void AddMethod (MethodDefinition method) + { + var projection = WindowsRuntimeProjections.RemoveProjection (method); + + method_table.AddRow (new MethodRow ( + method.HasBody ? code.WriteMethodBody (method) : 0, + method.ImplAttributes, + method.Attributes, + GetStringIndex (method.Name), + GetBlobIndex (GetMethodSignature (method)), + param_rid)); + + AddParameters (method); + + if (method.HasGenericParameters) + AddGenericParameters (method); + + if (method.IsPInvokeImpl) + AddPInvokeInfo (method); + + if (method.HasCustomAttributes) + AddCustomAttributes (method); + + if (method.HasSecurityDeclarations) + AddSecurityDeclarations (method); + + if (method.HasOverrides) + AddOverrides (method); + + WindowsRuntimeProjections.ApplyProjection (method, projection); + } + + void AddParameters (MethodDefinition method) + { + var return_parameter = method.MethodReturnType.parameter; + + if (return_parameter != null && RequiresParameterRow (return_parameter)) + AddParameter (0, return_parameter, param_table); + + if (!method.HasParameters) + return; + + var parameters = method.Parameters; + + for (int i = 0; i < parameters.Count; i++) { + var parameter = parameters [i]; + if (!RequiresParameterRow (parameter)) + continue; + + AddParameter ((ushort) (i + 1), parameter, param_table); + } + } + + void AddPInvokeInfo (MethodDefinition method) + { + var pinvoke = method.PInvokeInfo; + if (pinvoke == null) + return; + + var table = GetTable (Table.ImplMap); + table.AddRow (new ImplMapRow ( + pinvoke.Attributes, + MakeCodedRID (method, CodedIndex.MemberForwarded), + GetStringIndex (pinvoke.EntryPoint), + pinvoke.Module.MetadataToken.RID)); + } + + void AddOverrides (MethodDefinition method) + { + var overrides = method.Overrides; + var table = GetTable (Table.MethodImpl); + + for (int i = 0; i < overrides.Count; i++) { + table.AddRow (new MethodImplRow ( + method.DeclaringType.token.RID, + MakeCodedRID (method, CodedIndex.MethodDefOrRef), + MakeCodedRID (LookupToken (overrides [i]), CodedIndex.MethodDefOrRef))); + } + } + + static bool RequiresParameterRow (ParameterDefinition parameter) + { + return !string.IsNullOrEmpty (parameter.Name) + || parameter.Attributes != ParameterAttributes.None + || parameter.HasMarshalInfo + || parameter.HasConstant + || parameter.HasCustomAttributes; + } + + void AddParameter (ushort sequence, ParameterDefinition parameter, ParamTable table) + { + table.AddRow (new ParamRow ( + parameter.Attributes, + sequence, + GetStringIndex (parameter.Name))); + + parameter.token = new MetadataToken (TokenType.Param, param_rid++); + + if (parameter.HasCustomAttributes) + AddCustomAttributes (parameter); + + if (parameter.HasConstant) + AddConstant (parameter, parameter.ParameterType); + + if (parameter.HasMarshalInfo) + AddMarshalInfo (parameter); + } + + void AddMarshalInfo (IMarshalInfoProvider owner) + { + var table = GetTable (Table.FieldMarshal); + + table.AddRow (new FieldMarshalRow ( + MakeCodedRID (owner, CodedIndex.HasFieldMarshal), + GetBlobIndex (GetMarshalInfoSignature (owner)))); + } + + void AddProperties (TypeDefinition type) + { + var properties = type.Properties; + + property_map_table.AddRow (new PropertyMapRow (type.token.RID, property_rid)); + + for (int i = 0; i < properties.Count; i++) + AddProperty (properties [i]); + } + + void AddProperty (PropertyDefinition property) + { + property_table.AddRow (new PropertyRow ( + property.Attributes, + GetStringIndex (property.Name), + GetBlobIndex (GetPropertySignature (property)))); + property.token = new MetadataToken (TokenType.Property, property_rid++); + + var method = property.GetMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.Getter, property, method); + + method = property.SetMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.Setter, property, method); + + if (property.HasOtherMethods) + AddOtherSemantic (property, property.OtherMethods); + + if (property.HasCustomAttributes) + AddCustomAttributes (property); + + if (property.HasConstant) + AddConstant (property, property.PropertyType); + } + + void AddOtherSemantic (IMetadataTokenProvider owner, Collection others) + { + for (int i = 0; i < others.Count; i++) + AddSemantic (MethodSemanticsAttributes.Other, owner, others [i]); + } + + void AddEvents (TypeDefinition type) + { + var events = type.Events; + + event_map_table.AddRow (new EventMapRow (type.token.RID, event_rid)); + + for (int i = 0; i < events.Count; i++) + AddEvent (events [i]); + } + + void AddEvent (EventDefinition @event) + { + event_table.AddRow (new EventRow ( + @event.Attributes, + GetStringIndex (@event.Name), + MakeCodedRID (GetTypeToken (@event.EventType), CodedIndex.TypeDefOrRef))); + @event.token = new MetadataToken (TokenType.Event, event_rid++); + + var method = @event.AddMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.AddOn, @event, method); + + method = @event.InvokeMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.Fire, @event, method); + + method = @event.RemoveMethod; + if (method != null) + AddSemantic (MethodSemanticsAttributes.RemoveOn, @event, method); + + if (@event.HasOtherMethods) + AddOtherSemantic (@event, @event.OtherMethods); + + if (@event.HasCustomAttributes) + AddCustomAttributes (@event); + } + + void AddSemantic (MethodSemanticsAttributes semantics, IMetadataTokenProvider provider, MethodDefinition method) + { + method.SemanticsAttributes = semantics; + var table = GetTable (Table.MethodSemantics); + + table.AddRow (new MethodSemanticsRow ( + semantics, + method.token.RID, + MakeCodedRID (provider, CodedIndex.HasSemantics))); + } + + void AddConstant (IConstantProvider owner, TypeReference type) + { + var constant = owner.Constant; + var etype = GetConstantType (type, constant); + + constant_table.AddRow (new ConstantRow ( + etype, + MakeCodedRID (owner.MetadataToken, CodedIndex.HasConstant), + GetBlobIndex (GetConstantSignature (etype, constant)))); + } + + static ElementType GetConstantType (TypeReference constant_type, object constant) + { + if (constant == null) + return ElementType.Class; + + var etype = constant_type.etype; + switch (etype) { + case ElementType.None: + var type = constant_type.CheckedResolve (); + if (type.IsEnum) + return GetConstantType (type.GetEnumUnderlyingType (), constant); + + return ElementType.Class; + case ElementType.String: + return ElementType.String; + case ElementType.Object: + return GetConstantType (constant.GetType ()); + case ElementType.Array: + case ElementType.SzArray: + case ElementType.MVar: + case ElementType.Var: + return ElementType.Class; + case ElementType.GenericInst: + var generic_instance = (GenericInstanceType) constant_type; + if (generic_instance.ElementType.IsTypeOf ("System", "Nullable`1")) + return GetConstantType (generic_instance.GenericArguments [0], constant); + + return GetConstantType (((TypeSpecification) constant_type).ElementType, constant); + case ElementType.CModOpt: + case ElementType.CModReqD: + case ElementType.ByRef: + case ElementType.Sentinel: + return GetConstantType (((TypeSpecification) constant_type).ElementType, constant); + case ElementType.Boolean: + case ElementType.Char: + case ElementType.I: + case ElementType.I1: + case ElementType.I2: + case ElementType.I4: + case ElementType.I8: + case ElementType.U: + case ElementType.U1: + case ElementType.U2: + case ElementType.U4: + case ElementType.U8: + case ElementType.R4: + case ElementType.R8: + return GetConstantType (constant.GetType ()); + default: + return etype; + } + } + + static ElementType GetConstantType (Type type) + { + switch (Type.GetTypeCode (type)) { + case TypeCode.Boolean: + return ElementType.Boolean; + case TypeCode.Byte: + return ElementType.U1; + case TypeCode.SByte: + return ElementType.I1; + case TypeCode.Char: + return ElementType.Char; + case TypeCode.Int16: + return ElementType.I2; + case TypeCode.UInt16: + return ElementType.U2; + case TypeCode.Int32: + return ElementType.I4; + case TypeCode.UInt32: + return ElementType.U4; + case TypeCode.Int64: + return ElementType.I8; + case TypeCode.UInt64: + return ElementType.U8; + case TypeCode.Single: + return ElementType.R4; + case TypeCode.Double: + return ElementType.R8; + case TypeCode.String: + return ElementType.String; + default: + throw new NotSupportedException (type.FullName); + } + } + + void AddCustomAttributes (ICustomAttributeProvider owner) + { + var custom_attributes = owner.CustomAttributes; + + for (int i = 0; i < custom_attributes.Count; i++) { + var attribute = custom_attributes [i]; + + var projection = WindowsRuntimeProjections.RemoveProjection (attribute); + + custom_attribute_table.AddRow (new CustomAttributeRow ( + MakeCodedRID (owner, CodedIndex.HasCustomAttribute), + MakeCodedRID (LookupToken (attribute.Constructor), CodedIndex.CustomAttributeType), + GetBlobIndex (GetCustomAttributeSignature (attribute)))); + + WindowsRuntimeProjections.ApplyProjection (attribute, projection); + } + } + + void AddSecurityDeclarations (ISecurityDeclarationProvider owner) + { + var declarations = owner.SecurityDeclarations; + + for (int i = 0; i < declarations.Count; i++) { + var declaration = declarations [i]; + + declsec_table.AddRow (new DeclSecurityRow ( + declaration.Action, + MakeCodedRID (owner, CodedIndex.HasDeclSecurity), + GetBlobIndex (GetSecurityDeclarationSignature (declaration)))); + } + } + + MetadataToken GetMemberRefToken (MemberReference member) + { + var row = CreateMemberRefRow (member); + + MetadataToken token; + if (!member_ref_map.TryGetValue (row, out token)) + token = AddMemberReference (member, row); + + return token; + } + + MemberRefRow CreateMemberRefRow (MemberReference member) + { + return new MemberRefRow ( + MakeCodedRID (GetTypeToken (member.DeclaringType), CodedIndex.MemberRefParent), + GetStringIndex (member.Name), + GetBlobIndex (GetMemberRefSignature (member))); + } + + MetadataToken AddMemberReference (MemberReference member, MemberRefRow row) + { + member.token = new MetadataToken (TokenType.MemberRef, member_ref_table.AddRow (row)); + + var token = member.token; + member_ref_map.Add (row, token); + return token; + } + + MetadataToken GetMethodSpecToken (MethodSpecification method_spec) + { + var row = CreateMethodSpecRow (method_spec); + + MetadataToken token; + if (method_spec_map.TryGetValue (row, out token)) + return token; + + AddMethodSpecification (method_spec, row); + + return method_spec.token; + } + + void AddMethodSpecification (MethodSpecification method_spec, MethodSpecRow row) + { + method_spec.token = new MetadataToken (TokenType.MethodSpec, method_spec_table.AddRow (row)); + method_spec_map.Add (row, method_spec.token); + } + + MethodSpecRow CreateMethodSpecRow (MethodSpecification method_spec) + { + return new MethodSpecRow ( + MakeCodedRID (LookupToken (method_spec.ElementMethod), CodedIndex.MethodDefOrRef), + GetBlobIndex (GetMethodSpecSignature (method_spec))); + } + + SignatureWriter CreateSignatureWriter () + { + return new SignatureWriter (this); + } + + SignatureWriter GetMethodSpecSignature (MethodSpecification method_spec) + { + if (!method_spec.IsGenericInstance) + throw new NotSupportedException (); + + var generic_instance = (GenericInstanceMethod) method_spec; + + var signature = CreateSignatureWriter (); + signature.WriteByte (0x0a); + + signature.WriteGenericInstanceSignature (generic_instance); + + return signature; + } + + public uint AddStandAloneSignature (uint signature) + { + return (uint) standalone_sig_table.AddRow (signature); + } + + public uint GetLocalVariableBlobIndex (Collection variables) + { + return GetBlobIndex (GetVariablesSignature (variables)); + } + + public uint GetCallSiteBlobIndex (CallSite call_site) + { + return GetBlobIndex (GetMethodSignature (call_site)); + } + + public uint GetConstantTypeBlobIndex (TypeReference constant_type) + { + return GetBlobIndex (GetConstantTypeSignature (constant_type)); + } + + SignatureWriter GetVariablesSignature (Collection variables) + { + var signature = CreateSignatureWriter (); + signature.WriteByte (0x7); + signature.WriteCompressedUInt32 ((uint) variables.Count); + for (int i = 0; i < variables.Count; i++) + signature.WriteTypeSignature (variables [i].VariableType); + return signature; + } + + SignatureWriter GetConstantTypeSignature (TypeReference constant_type) + { + var signature = CreateSignatureWriter (); + signature.WriteByte (0x6); + signature.WriteTypeSignature (constant_type); + return signature; + } + + SignatureWriter GetFieldSignature (FieldReference field) + { + var signature = CreateSignatureWriter (); + signature.WriteByte (0x6); + signature.WriteTypeSignature (field.FieldType); + return signature; + } + + SignatureWriter GetMethodSignature (IMethodSignature method) + { + var signature = CreateSignatureWriter (); + signature.WriteMethodSignature (method); + return signature; + } + + SignatureWriter GetMemberRefSignature (MemberReference member) + { + var field = member as FieldReference; + if (field != null) + return GetFieldSignature (field); + + var method = member as MethodReference; + if (method != null) + return GetMethodSignature (method); + + throw new NotSupportedException (); + } + + SignatureWriter GetPropertySignature (PropertyDefinition property) + { + var signature = CreateSignatureWriter (); + byte calling_convention = 0x8; + if (property.HasThis) + calling_convention |= 0x20; + + uint param_count = 0; + Collection parameters = null; + + if (property.HasParameters) { + parameters = property.Parameters; + param_count = (uint) parameters.Count; + } + + signature.WriteByte (calling_convention); + signature.WriteCompressedUInt32 (param_count); + signature.WriteTypeSignature (property.PropertyType); + + if (param_count == 0) + return signature; + + for (int i = 0; i < param_count; i++) + signature.WriteTypeSignature (parameters [i].ParameterType); + + return signature; + } + + SignatureWriter GetTypeSpecSignature (TypeReference type) + { + var signature = CreateSignatureWriter (); + signature.WriteTypeSignature (type); + return signature; + } + + SignatureWriter GetConstantSignature (ElementType type, object value) + { + var signature = CreateSignatureWriter (); + + switch (type) { + case ElementType.Array: + case ElementType.SzArray: + case ElementType.Class: + case ElementType.Object: + case ElementType.None: + case ElementType.Var: + case ElementType.MVar: + case ElementType.GenericInst: + signature.WriteInt32 (0); + break; + case ElementType.String: + signature.WriteConstantString ((string) value); + break; + default: + signature.WriteConstantPrimitive (value); + break; + } + + return signature; + } + + SignatureWriter GetCustomAttributeSignature (CustomAttribute attribute) + { + var signature = CreateSignatureWriter (); + if (!attribute.resolved) { + signature.WriteBytes (attribute.GetBlob ()); + return signature; + } + + signature.WriteUInt16 (0x0001); + + signature.WriteCustomAttributeConstructorArguments (attribute); + + signature.WriteCustomAttributeNamedArguments (attribute); + + return signature; + } + + SignatureWriter GetSecurityDeclarationSignature (SecurityDeclaration declaration) + { + var signature = CreateSignatureWriter (); + + if (!declaration.resolved) + signature.WriteBytes (declaration.GetBlob ()); + else if (module.Runtime < TargetRuntime.Net_2_0) + signature.WriteXmlSecurityDeclaration (declaration); + else + signature.WriteSecurityDeclaration (declaration); + + return signature; + } + + SignatureWriter GetMarshalInfoSignature (IMarshalInfoProvider owner) + { + var signature = CreateSignatureWriter (); + + signature.WriteMarshalInfo (owner.MarshalInfo); + + return signature; + } + + static Exception CreateForeignMemberException (MemberReference member) + { + return new ArgumentException (string.Format ("Member '{0}' is declared in another module and needs to be imported", member)); + } + + public MetadataToken LookupToken (IMetadataTokenProvider provider) + { + if (provider == null) + throw new ArgumentNullException (); + + if (metadata_builder != null) + return metadata_builder.LookupToken (provider); + + var member = provider as MemberReference; + if (member == null || member.Module != module) + throw CreateForeignMemberException (member); + + var token = provider.MetadataToken; + + switch (token.TokenType) { + case TokenType.TypeDef: + case TokenType.Method: + case TokenType.Field: + case TokenType.Event: + case TokenType.Property: + return token; + case TokenType.TypeRef: + case TokenType.TypeSpec: + case TokenType.GenericParam: + return GetTypeToken ((TypeReference) provider); + case TokenType.MethodSpec: + return GetMethodSpecToken ((MethodSpecification) provider); + case TokenType.MemberRef: + return GetMemberRefToken (member); + default: + throw new NotSupportedException (); + } + } + + public void AddMethodDebugInformation (MethodDebugInformation method_info) + { + if (method_info.HasSequencePoints) + AddSequencePoints (method_info); + + if (method_info.Scope != null) + AddLocalScope (method_info, method_info.Scope); + + if (method_info.StateMachineKickOffMethod != null) + AddStateMachineMethod (method_info); + + AddCustomDebugInformations (method_info.Method); + } + + void AddStateMachineMethod (MethodDebugInformation method_info) + { + state_machine_method_table.AddRow (new StateMachineMethodRow (method_info.Method.MetadataToken.RID, method_info.StateMachineKickOffMethod.MetadataToken.RID)); + } + + void AddLocalScope (MethodDebugInformation method_info, ScopeDebugInformation scope) + { + var rid = local_scope_table.AddRow (new LocalScopeRow ( + method_info.Method.MetadataToken.RID, + scope.import != null ? AddImportScope (scope.import) : 0, + local_variable_rid, + local_constant_rid, + (uint) scope.Start.Offset, + (uint) ((scope.End.IsEndOfMethod ? method_info.code_size : scope.End.Offset) - scope.Start.Offset))); + + scope.token = new MetadataToken (TokenType.LocalScope, rid); + + AddCustomDebugInformations (scope); + + if (scope.HasVariables) + AddLocalVariables (scope); + + if (scope.HasConstants) + AddLocalConstants (scope); + + for (int i = 0; i < scope.Scopes.Count; i++) + AddLocalScope (method_info, scope.Scopes [i]); + } + + void AddLocalVariables (ScopeDebugInformation scope) + { + for (int i = 0; i < scope.Variables.Count; i++) { + var variable = scope.Variables [i]; + local_variable_table.AddRow (new LocalVariableRow (variable.Attributes, (ushort) variable.Index, GetStringIndex (variable.Name))); + variable.token = new MetadataToken (TokenType.LocalVariable, local_variable_rid); + local_variable_rid++; + + AddCustomDebugInformations (variable); + } + } + + void AddLocalConstants (ScopeDebugInformation scope) + { + for (int i = 0; i < scope.Constants.Count; i++) { + var constant = scope.Constants [i]; + local_constant_table.AddRow (new LocalConstantRow (GetStringIndex (constant.Name), GetBlobIndex (GetConstantSignature(constant)))); + constant.token = new MetadataToken (TokenType.LocalConstant, local_constant_rid); + local_constant_rid++; + } + } + + SignatureWriter GetConstantSignature (ConstantDebugInformation constant) + { + var type = constant.ConstantType; + + var signature = CreateSignatureWriter (); + signature.WriteTypeSignature (type); + + if (type.IsTypeOf ("System", "Decimal")) { + var bits = decimal.GetBits ((decimal) constant.Value); + + var low = (uint) bits [0]; + var mid = (uint) bits [1]; + var high = (uint) bits [2]; + + var scale = (byte) (bits [3] >> 16); + var negative = (bits [3] & 0x80000000) != 0; + + signature.WriteByte ((byte) (scale | (negative ? 0x80 : 0x00))); + signature.WriteUInt32 (low); + signature.WriteUInt32 (mid); + signature.WriteUInt32 (high); + + return signature; + } + + if (type.IsTypeOf ("System", "DateTime")) { + var date = (DateTime) constant.Value; + signature.WriteInt64 (date.Ticks); + return signature; + } + + signature.WriteBytes (GetConstantSignature (type.etype, constant.Value)); + + return signature; + } + + public void AddCustomDebugInformations (ICustomDebugInformationProvider provider) + { + if (!provider.HasCustomDebugInformations) + return; + + var custom_infos = provider.CustomDebugInformations; + + for (int i = 0; i < custom_infos.Count; i++) { + var custom_info = custom_infos [i]; + switch (custom_info.Kind) { + case CustomDebugInformationKind.Binary: + var binary_info = (BinaryCustomDebugInformation) custom_info; + AddCustomDebugInformation (provider, binary_info, GetBlobIndex (binary_info.Data)); + break; + case CustomDebugInformationKind.AsyncMethodBody: + AddAsyncMethodBodyDebugInformation (provider, (AsyncMethodBodyDebugInformation) custom_info); + break; + case CustomDebugInformationKind.StateMachineScope: + AddStateMachineScopeDebugInformation (provider, (StateMachineScopeDebugInformation) custom_info); + break; + case CustomDebugInformationKind.EmbeddedSource: + AddEmbeddedSourceDebugInformation (provider, (EmbeddedSourceDebugInformation) custom_info); + break; + case CustomDebugInformationKind.SourceLink: + AddSourceLinkDebugInformation (provider, (SourceLinkDebugInformation) custom_info); + break; + default: + throw new NotImplementedException (); + } + } + } + + void AddStateMachineScopeDebugInformation (ICustomDebugInformationProvider provider, StateMachineScopeDebugInformation state_machine_scope) + { + var method_info = ((MethodDefinition) provider).DebugInformation; + + var signature = CreateSignatureWriter (); + + var scopes = state_machine_scope.Scopes; + + for (int i = 0; i < scopes.Count; i++) { + var scope = scopes [i]; + signature.WriteUInt32 ((uint) scope.Start.Offset); + + var end_offset = scope.End.IsEndOfMethod + ? method_info.code_size + : scope.End.Offset; + + signature.WriteUInt32 ((uint) (end_offset - scope.Start.Offset)); + } + + AddCustomDebugInformation (provider, state_machine_scope, signature); + } + + void AddAsyncMethodBodyDebugInformation (ICustomDebugInformationProvider provider, AsyncMethodBodyDebugInformation async_method) + { + var signature = CreateSignatureWriter (); + signature.WriteUInt32 ((uint) async_method.catch_handler.Offset + 1); + + if (!async_method.yields.IsNullOrEmpty ()) { + for (int i = 0; i < async_method.yields.Count; i++) { + signature.WriteUInt32 ((uint) async_method.yields [i].Offset); + signature.WriteUInt32 ((uint) async_method.resumes [i].Offset); + signature.WriteCompressedUInt32 (async_method.resume_methods [i].MetadataToken.RID); + } + } + + AddCustomDebugInformation (provider, async_method, signature); + } + + void AddEmbeddedSourceDebugInformation (ICustomDebugInformationProvider provider, EmbeddedSourceDebugInformation embedded_source) + { + var signature = CreateSignatureWriter (); + + if (!embedded_source.resolved) { + signature.WriteBytes (embedded_source.ReadRawEmbeddedSourceDebugInformation ()); + AddCustomDebugInformation (provider, embedded_source, signature); + return; + } + + var content = embedded_source.content ?? Empty.Array; + if (embedded_source.compress) { + signature.WriteInt32 (content.Length); + + var decompressed_stream = new MemoryStream (content); + var content_stream = new MemoryStream (); + + using (var compress_stream = new DeflateStream (content_stream, CompressionMode.Compress, leaveOpen: true)) + decompressed_stream.CopyTo (compress_stream); + + signature.WriteBytes (content_stream.ToArray ()); + } else { + signature.WriteInt32 (0); + signature.WriteBytes (content); + } + + AddCustomDebugInformation (provider, embedded_source, signature); + } + + void AddSourceLinkDebugInformation (ICustomDebugInformationProvider provider, SourceLinkDebugInformation source_link) + { + var signature = CreateSignatureWriter (); + signature.WriteBytes (Encoding.UTF8.GetBytes (source_link.content)); + + AddCustomDebugInformation (provider, source_link, signature); + } + + void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, SignatureWriter signature) + { + AddCustomDebugInformation (provider, custom_info, GetBlobIndex (signature)); + } + + void AddCustomDebugInformation (ICustomDebugInformationProvider provider, CustomDebugInformation custom_info, uint blob_index) + { + var rid = custom_debug_information_table.AddRow (new CustomDebugInformationRow ( + MakeCodedRID (provider.MetadataToken, CodedIndex.HasCustomDebugInformation), + GetGuidIndex (custom_info.Identifier), + blob_index)); + + custom_info.token = new MetadataToken (TokenType.CustomDebugInformation, rid); + } + + uint AddImportScope (ImportDebugInformation import) + { + uint parent = 0; + if (import.Parent != null) + parent = AddImportScope (import.Parent); + + uint targets_index = 0; + if (import.HasTargets) { + var signature = CreateSignatureWriter (); + + for (int i = 0; i < import.Targets.Count; i++) + AddImportTarget (import.Targets [i], signature); + + targets_index = GetBlobIndex (signature); + } + + var row = new ImportScopeRow (parent, targets_index); + + MetadataToken import_token; + if (import_scope_map.TryGetValue (row, out import_token)) + return import_token.RID; + + import_token = new MetadataToken (TokenType.ImportScope, import_scope_table.AddRow (row)); + import_scope_map.Add (row, import_token); + + return import_token.RID; + } + + void AddImportTarget (ImportTarget target, SignatureWriter signature) + { + signature.WriteCompressedUInt32 ((uint)target.kind); + + switch (target.kind) { + case ImportTargetKind.ImportNamespace: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.ImportNamespaceInAssembly: + signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.ImportType: + signature.WriteTypeToken (target.type); + break; + case ImportTargetKind.ImportXmlNamespaceWithAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.ImportAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + break; + case ImportTargetKind.DefineAssemblyAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); + break; + case ImportTargetKind.DefineNamespaceAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.DefineNamespaceInAssemblyAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteCompressedUInt32 (target.reference.MetadataToken.RID); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.@namespace)); + break; + case ImportTargetKind.DefineTypeAlias: + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (target.alias)); + signature.WriteTypeToken (target.type); + break; + } + } + + uint GetUTF8StringBlobIndex (string s) + { + return GetBlobIndex (Encoding.UTF8.GetBytes (s)); + } + + public MetadataToken GetDocumentToken (Document document) + { + MetadataToken token; + if (document_map.TryGetValue (document.Url, out token)) + return token; + + token = new MetadataToken (TokenType.Document, document_table.AddRow ( + new DocumentRow (GetBlobIndex (GetDocumentNameSignature (document)), + GetGuidIndex (document.HashAlgorithm.ToGuid ()), + GetBlobIndex (document.Hash), + GetGuidIndex (document.Language.ToGuid ())))); + + document.token = token; + + AddCustomDebugInformations (document); + + document_map.Add (document.Url, token); + + return token; + } + + SignatureWriter GetDocumentNameSignature (Document document) + { + var name = document.Url; + var signature = CreateSignatureWriter (); + + char separator; + if (!TryGetDocumentNameSeparator (name, out separator)) { + signature.WriteByte (0); + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (name)); + return signature; + } + + signature.WriteByte ((byte) separator); + var parts = name.Split (new [] { separator }); + for (int i = 0; i < parts.Length; i++) { + if (parts [i] == String.Empty) + signature.WriteCompressedUInt32 (0); + else + signature.WriteCompressedUInt32 (GetUTF8StringBlobIndex (parts [i])); + } + + return signature; + } + + static bool TryGetDocumentNameSeparator (string path, out char separator) + { + const char unix = '/'; + const char win = '\\'; + const char zero = (char) 0; + + separator = zero; + if (string.IsNullOrEmpty (path)) + return false; + + int unix_count = 0; + int win_count = 0; + + for (int i = 0; i < path.Length; i++) { + if (path [i] == unix) + unix_count++; + else if (path [i] == win) + win_count++; + } + + if (unix_count == 0 && win_count == 0) + return false; + + if (unix_count >= win_count) { + separator = unix; + return true; + } + + separator = win; + return true; + } + + void AddSequencePoints (MethodDebugInformation info) + { + var rid = info.Method.MetadataToken.RID; + + Document document; + if (info.TryGetUniqueDocument (out document)) + method_debug_information_table.rows [rid - 1].Col1 = GetDocumentToken (document).RID; + + var signature = CreateSignatureWriter (); + signature.WriteSequencePoints (info); + + method_debug_information_table.rows [rid - 1].Col2 = GetBlobIndex (signature); + } + } + + sealed class SignatureWriter : ByteBuffer { + + readonly MetadataBuilder metadata; + + public SignatureWriter (MetadataBuilder metadata) + : base (6) + { + this.metadata = metadata; + } + + public void WriteElementType (ElementType element_type) + { + WriteByte ((byte) element_type); + } + + public void WriteUTF8String (string @string) + { + if (@string == null) { + WriteByte (0xff); + return; + } + + var bytes = Encoding.UTF8.GetBytes (@string); + WriteCompressedUInt32 ((uint) bytes.Length); + WriteBytes (bytes); + } + + public void WriteMethodSignature (IMethodSignature method) + { + byte calling_convention = (byte) method.CallingConvention; + if (method.HasThis) + calling_convention |= 0x20; + if (method.ExplicitThis) + calling_convention |= 0x40; + + var generic_provider = method as IGenericParameterProvider; + var generic_arity = generic_provider != null && generic_provider.HasGenericParameters + ? generic_provider.GenericParameters.Count + : 0; + + if (generic_arity > 0) + calling_convention |= 0x10; + + var param_count = method.HasParameters ? method.Parameters.Count : 0; + + WriteByte (calling_convention); + + if (generic_arity > 0) + WriteCompressedUInt32 ((uint) generic_arity); + + WriteCompressedUInt32 ((uint) param_count); + WriteTypeSignature (method.ReturnType); + + if (param_count == 0) + return; + + var parameters = method.Parameters; + + for (int i = 0; i < param_count; i++) + WriteTypeSignature (parameters [i].ParameterType); + } + + uint MakeTypeDefOrRefCodedRID (TypeReference type) + { + return CodedIndex.TypeDefOrRef.CompressMetadataToken (metadata.LookupToken (type)); + } + + public void WriteTypeToken (TypeReference type) + { + WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type)); + } + + public void WriteTypeSignature (TypeReference type) + { + if (type == null) + throw new ArgumentNullException (); + + var etype = type.etype; + + switch (etype) { + case ElementType.MVar: + case ElementType.Var: { + var generic_parameter = (GenericParameter) type; + + WriteElementType (etype); + var position = generic_parameter.Position; + if (position == -1) + throw new NotSupportedException (); + + WriteCompressedUInt32 ((uint) position); + break; + } + + case ElementType.GenericInst: { + var generic_instance = (GenericInstanceType) type; + WriteElementType (ElementType.GenericInst); + WriteElementType (generic_instance.IsValueType ? ElementType.ValueType : ElementType.Class); + WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (generic_instance.ElementType)); + + WriteGenericInstanceSignature (generic_instance); + break; + } + + case ElementType.Ptr: + case ElementType.ByRef: + case ElementType.Pinned: + case ElementType.Sentinel: { + var type_spec = (TypeSpecification) type; + WriteElementType (etype); + WriteTypeSignature (type_spec.ElementType); + break; + } + + case ElementType.FnPtr: { + var fptr = (FunctionPointerType) type; + WriteElementType (ElementType.FnPtr); + WriteMethodSignature (fptr); + break; + } + + case ElementType.CModOpt: + case ElementType.CModReqD: { + var modifier = (IModifierType) type; + WriteModifierSignature (etype, modifier); + break; + } + + case ElementType.Array: { + var array = (ArrayType) type; + if (!array.IsVector) { + WriteArrayTypeSignature (array); + break; + } + + WriteElementType (ElementType.SzArray); + WriteTypeSignature (array.ElementType); + break; + } + + case ElementType.None: { + WriteElementType (type.IsValueType ? ElementType.ValueType : ElementType.Class); + WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type)); + break; + } + + default: + if (!TryWriteElementType (type)) + throw new NotSupportedException (); + + break; + + } + } + + void WriteArrayTypeSignature (ArrayType array) + { + WriteElementType (ElementType.Array); + WriteTypeSignature (array.ElementType); + + var dimensions = array.Dimensions; + var rank = dimensions.Count; + + WriteCompressedUInt32 ((uint) rank); + + var sized = 0; + var lbounds = 0; + + for (int i = 0; i < rank; i++) { + var dimension = dimensions [i]; + + if (dimension.UpperBound.HasValue) { + sized++; + lbounds++; + } else if (dimension.LowerBound.HasValue) + lbounds++; + } + + var sizes = new int [sized]; + var low_bounds = new int [lbounds]; + + for (int i = 0; i < lbounds; i++) { + var dimension = dimensions [i]; + low_bounds [i] = dimension.LowerBound.GetValueOrDefault (); + if (dimension.UpperBound.HasValue) + sizes [i] = dimension.UpperBound.Value - low_bounds [i] + 1; + } + + WriteCompressedUInt32 ((uint) sized); + for (int i = 0; i < sized; i++) + WriteCompressedUInt32 ((uint) sizes [i]); + + WriteCompressedUInt32 ((uint) lbounds); + for (int i = 0; i < lbounds; i++) + WriteCompressedInt32 (low_bounds [i]); + } + + public void WriteGenericInstanceSignature (IGenericInstance instance) + { + var generic_arguments = instance.GenericArguments; + var arity = generic_arguments.Count; + + WriteCompressedUInt32 ((uint) arity); + for (int i = 0; i < arity; i++) + WriteTypeSignature (generic_arguments [i]); + } + + void WriteModifierSignature (ElementType element_type, IModifierType type) + { + WriteElementType (element_type); + WriteCompressedUInt32 (MakeTypeDefOrRefCodedRID (type.ModifierType)); + WriteTypeSignature (type.ElementType); + } + + bool TryWriteElementType (TypeReference type) + { + var element = type.etype; + + if (element == ElementType.None) + return false; + + WriteElementType (element); + return true; + } + + public void WriteConstantString (string value) + { + if (value != null) + WriteBytes (Encoding.Unicode.GetBytes (value)); + else + WriteByte (0xff); + } + + public void WriteConstantPrimitive (object value) + { + WritePrimitiveValue (value); + } + + public void WriteCustomAttributeConstructorArguments (CustomAttribute attribute) + { + if (!attribute.HasConstructorArguments) + return; + + var arguments = attribute.ConstructorArguments; + var parameters = attribute.Constructor.Parameters; + + if (parameters.Count != arguments.Count) + throw new InvalidOperationException (); + + for (int i = 0; i < arguments.Count; i++) { + var parameterType = GenericParameterResolver.ResolveParameterTypeIfNeeded ( + attribute.Constructor, parameters [i]); + WriteCustomAttributeFixedArgument (parameterType, arguments [i]); + } + } + + void WriteCustomAttributeFixedArgument (TypeReference type, CustomAttributeArgument argument) + { + if (type.IsArray) { + WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument); + return; + } + + WriteCustomAttributeElement (type, argument); + } + + void WriteCustomAttributeFixedArrayArgument (ArrayType type, CustomAttributeArgument argument) + { + var values = argument.Value as CustomAttributeArgument []; + + if (values == null) { + WriteUInt32 (0xffffffff); + return; + } + + WriteInt32 (values.Length); + + if (values.Length == 0) + return; + + var element_type = type.ElementType; + + for (int i = 0; i < values.Length; i++) + WriteCustomAttributeElement (element_type, values [i]); + } + + void WriteCustomAttributeElement (TypeReference type, CustomAttributeArgument argument) + { + if (type.IsArray) { + WriteCustomAttributeFixedArrayArgument ((ArrayType) type, argument); + return; + } + + if (type.etype == ElementType.Object) { + argument = (CustomAttributeArgument) argument.Value; + type = argument.Type; + + WriteCustomAttributeFieldOrPropType (type); + WriteCustomAttributeElement (type, argument); + return; + } + + WriteCustomAttributeValue (type, argument.Value); + } + + void WriteCustomAttributeValue (TypeReference type, object value) + { + var etype = type.etype; + + switch (etype) { + case ElementType.String: + var @string = (string) value; + if (@string == null) + WriteByte (0xff); + else + WriteUTF8String (@string); + break; + case ElementType.None: + if (type.IsTypeOf ("System", "Type")) + WriteCustomAttributeTypeValue ((TypeReference) value); + else + WriteCustomAttributeEnumValue (type, value); + break; + case ElementType.GenericInst: + // Generic instantiation can only happen for an enum (no other generic like types can appear in attribute value) + WriteCustomAttributeEnumValue (type, value); + break; + default: + WritePrimitiveValue (value); + break; + } + } + + private void WriteCustomAttributeTypeValue (TypeReference value) + { + var typeDefinition = value as TypeDefinition; + + if (typeDefinition != null) { + TypeDefinition outermostDeclaringType = typeDefinition; + while (outermostDeclaringType.DeclaringType != null) + outermostDeclaringType = outermostDeclaringType.DeclaringType; + + // In CLR .winmd files, custom attribute arguments reference unmangled type names (rather than Name) + if (WindowsRuntimeProjections.IsClrImplementationType (outermostDeclaringType)) { + WindowsRuntimeProjections.Project (outermostDeclaringType); + WriteTypeReference (value); + WindowsRuntimeProjections.RemoveProjection (outermostDeclaringType); + return; + } + } + + WriteTypeReference (value); + } + + void WritePrimitiveValue (object value) + { + if (value == null) + throw new ArgumentNullException (); + + switch (Type.GetTypeCode (value.GetType ())) { + case TypeCode.Boolean: + WriteByte ((byte) (((bool) value) ? 1 : 0)); + break; + case TypeCode.Byte: + WriteByte ((byte) value); + break; + case TypeCode.SByte: + WriteSByte ((sbyte) value); + break; + case TypeCode.Int16: + WriteInt16 ((short) value); + break; + case TypeCode.UInt16: + WriteUInt16 ((ushort) value); + break; + case TypeCode.Char: + WriteInt16 ((short) (char) value); + break; + case TypeCode.Int32: + WriteInt32 ((int) value); + break; + case TypeCode.UInt32: + WriteUInt32 ((uint) value); + break; + case TypeCode.Single: + WriteSingle ((float) value); + break; + case TypeCode.Int64: + WriteInt64 ((long) value); + break; + case TypeCode.UInt64: + WriteUInt64 ((ulong) value); + break; + case TypeCode.Double: + WriteDouble ((double) value); + break; + default: + throw new NotSupportedException (value.GetType ().FullName); + } + } + + void WriteCustomAttributeEnumValue (TypeReference enum_type, object value) + { + var type = enum_type.CheckedResolve (); + if (!type.IsEnum) + throw new ArgumentException (); + + WriteCustomAttributeValue (type.GetEnumUnderlyingType (), value); + } + + void WriteCustomAttributeFieldOrPropType (TypeReference type) + { + if (type.IsArray) { + var array = (ArrayType) type; + WriteElementType (ElementType.SzArray); + WriteCustomAttributeFieldOrPropType (array.ElementType); + return; + } + + var etype = type.etype; + + switch (etype) { + case ElementType.Object: + WriteElementType (ElementType.Boxed); + return; + case ElementType.None: + if (type.IsTypeOf ("System", "Type")) + WriteElementType (ElementType.Type); + else { + WriteElementType (ElementType.Enum); + WriteTypeReference (type); + } + return; + case ElementType.GenericInst: + // Generic instantiation can really only happen if it's an enum type since no other + // types are allowed in the attribute value. + // Enums are special in attribute data, they're encoded as ElementType.Enum followed by a typeref + // followed by the value. + WriteElementType (ElementType.Enum); + WriteTypeReference (type); + return; + default: + WriteElementType (etype); + return; + } + } + + public void WriteCustomAttributeNamedArguments (CustomAttribute attribute) + { + var count = GetNamedArgumentCount (attribute); + + WriteUInt16 ((ushort) count); + + if (count == 0) + return; + + WriteICustomAttributeNamedArguments (attribute); + } + + static int GetNamedArgumentCount (ICustomAttribute attribute) + { + int count = 0; + + if (attribute.HasFields) + count += attribute.Fields.Count; + + if (attribute.HasProperties) + count += attribute.Properties.Count; + + return count; + } + + void WriteICustomAttributeNamedArguments (ICustomAttribute attribute) + { + if (attribute.HasFields) + WriteCustomAttributeNamedArguments (0x53, attribute.Fields); + + if (attribute.HasProperties) + WriteCustomAttributeNamedArguments (0x54, attribute.Properties); + } + + void WriteCustomAttributeNamedArguments (byte kind, Collection named_arguments) + { + for (int i = 0; i < named_arguments.Count; i++) + WriteCustomAttributeNamedArgument (kind, named_arguments [i]); + } + + void WriteCustomAttributeNamedArgument (byte kind, CustomAttributeNamedArgument named_argument) + { + var argument = named_argument.Argument; + + WriteByte (kind); + WriteCustomAttributeFieldOrPropType (argument.Type); + WriteUTF8String (named_argument.Name); + WriteCustomAttributeFixedArgument (argument.Type, argument); + } + + void WriteSecurityAttribute (SecurityAttribute attribute) + { + WriteTypeReference (attribute.AttributeType); + + var count = GetNamedArgumentCount (attribute); + + if (count == 0) { + WriteCompressedUInt32 (1); // length + WriteCompressedUInt32 (0); // count + return; + } + + var buffer = new SignatureWriter (metadata); + buffer.WriteCompressedUInt32 ((uint) count); + buffer.WriteICustomAttributeNamedArguments (attribute); + + WriteCompressedUInt32 ((uint) buffer.length); + WriteBytes (buffer); + } + + public void WriteSecurityDeclaration (SecurityDeclaration declaration) + { + WriteByte ((byte) '.'); + + var attributes = declaration.security_attributes; + if (attributes == null) + throw new NotSupportedException (); + + WriteCompressedUInt32 ((uint) attributes.Count); + + for (int i = 0; i < attributes.Count; i++) + WriteSecurityAttribute (attributes [i]); + } + + public void WriteXmlSecurityDeclaration (SecurityDeclaration declaration) + { + var xml = GetXmlSecurityDeclaration (declaration); + if (xml == null) + throw new NotSupportedException (); + + WriteBytes (Encoding.Unicode.GetBytes (xml)); + } + + static string GetXmlSecurityDeclaration (SecurityDeclaration declaration) + { + if (declaration.security_attributes == null || declaration.security_attributes.Count != 1) + return null; + + var attribute = declaration.security_attributes [0]; + + if (!attribute.AttributeType.IsTypeOf ("System.Security.Permissions", "PermissionSetAttribute")) + return null; + + if (attribute.properties == null || attribute.properties.Count != 1) + return null; + + var property = attribute.properties [0]; + if (property.Name != "XML") + return null; + + return (string) property.Argument.Value; + } + + void WriteTypeReference (TypeReference type) + { + WriteUTF8String (TypeParser.ToParseable (type, top_level: false)); + } + + public void WriteMarshalInfo (MarshalInfo marshal_info) + { + WriteNativeType (marshal_info.native); + + switch (marshal_info.native) { + case NativeType.Array: { + var array = (ArrayMarshalInfo) marshal_info; + if (array.element_type != NativeType.None) + WriteNativeType (array.element_type); + if (array.size_parameter_index > -1) + WriteCompressedUInt32 ((uint) array.size_parameter_index); + if (array.size > -1) + WriteCompressedUInt32 ((uint) array.size); + if (array.size_parameter_multiplier > -1) + WriteCompressedUInt32 ((uint) array.size_parameter_multiplier); + return; + } + case NativeType.SafeArray: { + var array = (SafeArrayMarshalInfo) marshal_info; + if (array.element_type != VariantType.None) + WriteVariantType (array.element_type); + return; + } + case NativeType.FixedArray: { + var array = (FixedArrayMarshalInfo) marshal_info; + if (array.size > -1) + WriteCompressedUInt32 ((uint) array.size); + if (array.element_type != NativeType.None) + WriteNativeType (array.element_type); + return; + } + case NativeType.FixedSysString: + var sys_string = (FixedSysStringMarshalInfo) marshal_info; + if (sys_string.size > -1) + WriteCompressedUInt32 ((uint) sys_string.size); + return; + case NativeType.CustomMarshaler: + var marshaler = (CustomMarshalInfo) marshal_info; + WriteUTF8String (marshaler.guid != Guid.Empty ? marshaler.guid.ToString () : string.Empty); + WriteUTF8String (marshaler.unmanaged_type); + WriteTypeReference (marshaler.managed_type); + WriteUTF8String (marshaler.cookie); + return; + } + } + + void WriteNativeType (NativeType native) + { + WriteByte ((byte) native); + } + + void WriteVariantType (VariantType variant) + { + WriteByte ((byte) variant); + } + + public void WriteSequencePoints (MethodDebugInformation info) + { + var start_line = -1; + var start_column = -1; + + WriteCompressedUInt32 (info.local_var_token.RID); + + Document previous_document; + if (!info.TryGetUniqueDocument (out previous_document)) + previous_document = null; + + for (int i = 0; i < info.SequencePoints.Count; i++) { + var sequence_point = info.SequencePoints [i]; + + var document = sequence_point.Document; + if (previous_document != document) { + var document_token = metadata.GetDocumentToken (document); + + if (previous_document != null) + WriteCompressedUInt32 (0); + + WriteCompressedUInt32 (document_token.RID); + previous_document = document; + } + + if (i > 0) + WriteCompressedUInt32 ((uint) (sequence_point.Offset - info.SequencePoints [i - 1].Offset)); + else + WriteCompressedUInt32 ((uint) sequence_point.Offset); + + if (sequence_point.IsHidden) { + WriteInt16 (0); + continue; + } + + var delta_lines = sequence_point.EndLine - sequence_point.StartLine; + var delta_columns = sequence_point.EndColumn - sequence_point.StartColumn; + + WriteCompressedUInt32 ((uint) delta_lines); + + if (delta_lines == 0) + WriteCompressedUInt32((uint) delta_columns); + else + WriteCompressedInt32 (delta_columns); + + if (start_line < 0) { + WriteCompressedUInt32 ((uint) sequence_point.StartLine); + WriteCompressedUInt32 ((uint) sequence_point.StartColumn); + } else { + WriteCompressedInt32 (sequence_point.StartLine - start_line); + WriteCompressedInt32 (sequence_point.StartColumn - start_column); + } + + start_line = sequence_point.StartLine; + start_column = sequence_point.StartColumn; + } + } + } + + static partial class Mixin { + + public static bool TryGetUniqueDocument (this MethodDebugInformation info, out Document document) + { + document = info.SequencePoints [0].Document; + + for (int i = 1; i < info.SequencePoints.Count; i++) { + var sequence_point = info.SequencePoints [i]; + if (sequence_point.Document != document) + return false; + } + + return true; + } + } +} diff --git a/cecil-master/Mono.Cecil/BaseAssemblyResolver.cs b/cecil-master/Mono.Cecil/BaseAssemblyResolver.cs new file mode 100644 index 000000000..fd9e5c968 --- /dev/null +++ b/cecil-master/Mono.Cecil/BaseAssemblyResolver.cs @@ -0,0 +1,407 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +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; + } + } + +#if !NET_CORE + [Serializable] +#endif + public sealed class AssemblyResolutionException : FileNotFoundException { + + readonly AssemblyNameReference reference; + + public AssemblyNameReference AssemblyReference { + get { return reference; } + } + + public AssemblyResolutionException (AssemblyNameReference reference) + : this (reference, null) + { + } + + public AssemblyResolutionException (AssemblyNameReference reference, Exception innerException) + : base (string.Format ("Failed to resolve assembly: '{0}'", reference), innerException) + { + this.reference = reference; + } + +#if !NET_CORE + AssemblyResolutionException ( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base (info, context) + { + } +#endif + } + + public abstract class BaseAssemblyResolver : IAssemblyResolver { + + static readonly bool on_mono = Type.GetType ("Mono.Runtime") != null; + + readonly Collection directories; + +#if NET_CORE + // Maps file names of available trusted platform assemblies to their full paths. + // Internal for testing. + internal static readonly Lazy> TrustedPlatformAssemblies = new Lazy> (CreateTrustedPlatformAssemblyMap); +#else + Collection gac_paths; +#endif + + 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 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) + { + Mixin.CheckName (name); + Mixin.CheckParameters (parameters); + + var assembly = SearchDirectory (name, directories, parameters); + if (assembly != null) + return assembly; + + if (name.IsRetargetable) { + // if the reference is retargetable, zero it + name = new AssemblyNameReference (name.Name, Mixin.ZeroVersion) { + PublicKeyToken = Empty.Array, + }; + } + +#if NET_CORE + assembly = SearchTrustedPlatformAssemblies (name, parameters); + if (assembly != null) + return assembly; +#else + var framework_dir = Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName); + var framework_dirs = on_mono + ? new [] { framework_dir, Path.Combine (framework_dir, "Facades") } + : new [] { framework_dir }; + + if (IsZero (name.Version)) { + assembly = SearchDirectory (name, framework_dirs, parameters); + if (assembly != null) + return assembly; + } + + if (name.Name == "mscorlib") { + assembly = GetCorlib (name, parameters); + if (assembly != null) + return assembly; + } + + assembly = GetAssemblyInGac (name, parameters); + if (assembly != null) + return assembly; + + assembly = SearchDirectory (name, framework_dirs, parameters); + if (assembly != null) + return assembly; +#endif + if (ResolveFailure != null) { + assembly = ResolveFailure (this, name); + if (assembly != null) + return assembly; + } + + throw new AssemblyResolutionException (name); + } + +#if NET_CORE + AssemblyDefinition SearchTrustedPlatformAssemblies (AssemblyNameReference name, ReaderParameters parameters) + { + if (name.IsWindowsRuntime) + return null; + + if (TrustedPlatformAssemblies.Value.TryGetValue (name.Name, out string path)) + return GetAssembly (path, parameters); + + return null; + } + + static Dictionary CreateTrustedPlatformAssemblyMap () + { + var result = new Dictionary (StringComparer.OrdinalIgnoreCase); + + string paths; + + try { + paths = (string) AppDomain.CurrentDomain.GetData ("TRUSTED_PLATFORM_ASSEMBLIES"); + } catch { + paths = null; + } + + if (paths == null) + return result; + + foreach (var path in paths.Split (Path.PathSeparator)) + if (string.Equals (Path.GetExtension (path), ".dll", StringComparison.OrdinalIgnoreCase)) + result [Path.GetFileNameWithoutExtension (path)] = path; + + return result; + } +#endif + + protected virtual AssemblyDefinition SearchDirectory (AssemblyNameReference name, IEnumerable directories, ReaderParameters parameters) + { + var extensions = name.IsWindowsRuntime ? new [] { ".winmd", ".dll" } : 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)) + continue; + try { + return GetAssembly (file, parameters); + } catch (System.BadImageFormatException) { + continue; + } + } + } + + return null; + } + + static bool IsZero (Version version) + { + return version.Major == 0 && version.Minor == 0 && version.Build == 0 && version.Revision == 0; + } + +#if !NET_CORE + AssemblyDefinition GetCorlib (AssemblyNameReference reference, ReaderParameters parameters) + { + var version = reference.Version; + var corlib = typeof (object).Assembly.GetName (); + if (corlib.Version == version || IsZero (version)) + return GetAssembly (typeof (object).Module.FullyQualifiedName, parameters); + + var path = Directory.GetParent ( + Directory.GetParent ( + typeof (object).Module.FullyQualifiedName).FullName + ).FullName; + + if (on_mono) { + if (version.Major == 1) + path = Path.Combine (path, "1.0"); + else if (version.Major == 2) { + if (version.MajorRevision == 5) + path = Path.Combine (path, "2.1"); + else + path = Path.Combine (path, "2.0"); + } else if (version.Major == 4) + path = Path.Combine (path, "4.0"); + else + throw new NotSupportedException ("Version not supported: " + version); + } else { + switch (version.Major) { + case 1: + if (version.MajorRevision == 3300) + path = Path.Combine (path, "v1.0.3705"); + else + path = Path.Combine (path, "v1.1.4322"); + break; + case 2: + path = Path.Combine (path, "v2.0.50727"); + break; + case 4: + path = Path.Combine (path, "v4.0.30319"); + break; + default: + throw new NotSupportedException ("Version not supported: " + version); + } + } + + var file = Path.Combine (path, "mscorlib.dll"); + if (File.Exists (file)) + return GetAssembly (file, parameters); + + if (on_mono && Directory.Exists (path + "-api")) { + file = Path.Combine (path + "-api", "mscorlib.dll"); + if (File.Exists (file)) + return GetAssembly (file, parameters); + } + + return null; + } + + static Collection GetGacPaths () + { + if (on_mono) + return GetDefaultMonoGacPaths (); + + var paths = new Collection (2); + var windir = Environment.GetEnvironmentVariable ("WINDIR"); + if (windir == null) + return paths; + + paths.Add (Path.Combine (windir, "assembly")); + paths.Add (Path.Combine (windir, Path.Combine ("Microsoft.NET", "assembly"))); + return paths; + } + + static Collection GetDefaultMonoGacPaths () + { + var paths = new Collection (1); + var gac = GetCurrentMonoGac (); + if (gac != null) + paths.Add (gac); + + var gac_paths_env = Environment.GetEnvironmentVariable ("MONO_GAC_PREFIX"); + if (string.IsNullOrEmpty (gac_paths_env)) + return paths; + + var prefixes = gac_paths_env.Split (Path.PathSeparator); + foreach (var prefix in prefixes) { + if (string.IsNullOrEmpty (prefix)) + continue; + + var gac_path = Path.Combine (Path.Combine (Path.Combine (prefix, "lib"), "mono"), "gac"); + if (Directory.Exists (gac_path) && !paths.Contains (gac)) + paths.Add (gac_path); + } + + return paths; + } + + static string GetCurrentMonoGac () + { + return Path.Combine ( + Directory.GetParent ( + Path.GetDirectoryName (typeof (object).Module.FullyQualifiedName)).FullName, + "gac"); + } + + AssemblyDefinition GetAssemblyInGac (AssemblyNameReference reference, ReaderParameters parameters) + { + if (reference.PublicKeyToken == null || reference.PublicKeyToken.Length == 0) + return null; + + if (gac_paths == null) + gac_paths = GetGacPaths (); + + if (on_mono) + return GetAssemblyInMonoGac (reference, parameters); + + return GetAssemblyInNetGac (reference, parameters); + } + + AssemblyDefinition GetAssemblyInMonoGac (AssemblyNameReference reference, ReaderParameters parameters) + { + for (int i = 0; i < gac_paths.Count; i++) { + var gac_path = gac_paths [i]; + var file = GetAssemblyFile (reference, string.Empty, gac_path); + if (File.Exists (file)) + return GetAssembly (file, parameters); + } + + return null; + } + + AssemblyDefinition GetAssemblyInNetGac (AssemblyNameReference reference, ReaderParameters parameters) + { + var gacs = new [] { "GAC_MSIL", "GAC_32", "GAC_64", "GAC" }; + var prefixes = new [] { string.Empty, "v4.0_" }; + + for (int i = 0; i < gac_paths.Count; i++) { + for (int j = 0; j < gacs.Length; j++) { + var gac = Path.Combine (gac_paths [i], gacs [j]); + var file = GetAssemblyFile (reference, prefixes [i], gac); + if (Directory.Exists (gac) && File.Exists (file)) + return GetAssembly (file, parameters); + } + } + + return null; + } + + static string GetAssemblyFile (AssemblyNameReference reference, string prefix, string gac) + { + var gac_folder = new StringBuilder () + .Append (prefix) + .Append (reference.Version) + .Append ("__"); + + for (int i = 0; i < reference.PublicKeyToken.Length; i++) + gac_folder.Append (reference.PublicKeyToken [i].ToString ("x2")); + + return Path.Combine ( + Path.Combine ( + Path.Combine (gac, reference.Name), gac_folder.ToString ()), + reference.Name + ".dll"); + } +#endif + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + + protected virtual void Dispose (bool disposing) + { + } + } +} diff --git a/cecil-master/Mono.Cecil/CallSite.cs b/cecil-master/Mono.Cecil/CallSite.cs new file mode 100644 index 000000000..ebb108f29 --- /dev/null +++ b/cecil-master/Mono.Cecil/CallSite.cs @@ -0,0 +1,106 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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); + this.MethodSignatureFullName (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/cecil-master/Mono.Cecil/Consts.cs b/cecil-master/Mono.Cecil/Consts.cs new file mode 100644 index 000000000..3b80461c5 --- /dev/null +++ b/cecil-master/Mono.Cecil/Consts.cs @@ -0,0 +1,5 @@ +static class Consts +{ + public const string AssemblyName = "Mono.Cecil"; + public const string PublicKey = "00240000048000009400000006020000002400005253413100040000010001002b5c9f7f04346c324a3176f8d3ee823bbf2d60efdbc35f86fd9e65ea3e6cd11bcdcba3a353e55133c8ac5c4caaba581b2c6dfff2cc2d0edc43959ddb86b973300a479a82419ef489c3225f1fe429a708507bd515835160e10bc743d20ca33ab9570cfd68d479fcf0bc797a763bec5d1000f0159ef619e709d915975e87beebaf"; +} \ No newline at end of file diff --git a/cecil-master/Mono.Cecil/CustomAttribute.cs b/cecil-master/Mono.Cecil/CustomAttribute.cs new file mode 100644 index 000000000..c9cad8e5d --- /dev/null +++ b/cecil-master/Mono.Cecil/CustomAttribute.cs @@ -0,0 +1,220 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Diagnostics; +using System.Threading; +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; } + bool HasConstructorArguments { get; } + Collection Fields { get; } + Collection Properties { get; } + Collection ConstructorArguments { get; } + } + + [DebuggerDisplay ("{AttributeType}")] + public sealed class CustomAttribute : ICustomAttribute { + + internal CustomAttributeValueProjection projection; + 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 !arguments.IsNullOrEmpty (); + } + } + + public Collection ConstructorArguments { + get { + Resolve (); + + if (arguments == null) + Interlocked.CompareExchange (ref arguments, new Collection (), null); + + return arguments; + } + } + + public bool HasFields { + get { + Resolve (); + + return !fields.IsNullOrEmpty (); + } + } + + public Collection Fields { + get { + Resolve (); + + if (fields == null) + Interlocked.CompareExchange (ref fields, new Collection (), null); + + return fields; + } + } + + public bool HasProperties { + get { + Resolve (); + + return !properties.IsNullOrEmpty (); + } + } + + public Collection Properties { + get { + Resolve (); + + if (properties == null) + Interlocked.CompareExchange (ref properties, new Collection (), null); + + return properties; + } + } + + 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; + + lock (Module.SyncRoot) { + if (resolved) + 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; + } + }); + } + } + } +} diff --git a/cecil-master/Mono.Cecil/DefaultAssemblyResolver.cs b/cecil-master/Mono.Cecil/DefaultAssemblyResolver.cs new file mode 100644 index 000000000..755071ea4 --- /dev/null +++ b/cecil-master/Mono.Cecil/DefaultAssemblyResolver.cs @@ -0,0 +1,61 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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) + { + Mixin.CheckName (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; + } + + protected override void Dispose (bool disposing) + { + foreach (var assembly in cache.Values) + assembly.Dispose (); + + cache.Clear (); + + base.Dispose (disposing); + } + } +} diff --git a/cecil-master/Mono.Cecil/EmbeddedResource.cs b/cecil-master/Mono.Cecil/EmbeddedResource.cs new file mode 100644 index 000000000..6b5f86a12 --- /dev/null +++ b/cecil-master/Mono.Cecil/EmbeddedResource.cs @@ -0,0 +1,98 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 new MemoryStream (reader.GetManagedResource (offset.Value)); + + throw new InvalidOperationException (); + } + + public byte [] GetResourceData () + { + if (stream != null) + return ReadStream (stream); + + if (data != null) + return data; + + if (offset.HasValue) + return reader.GetManagedResource (offset.Value); + + throw new InvalidOperationException (); + } + + static byte [] ReadStream (Stream stream) + { + int read; + + if (stream.CanSeek) { + var length = (int) stream.Length; + var data = new byte [length]; + int offset = 0; + + while ((read = stream.Read (data, offset, length - offset)) > 0) + offset += read; + + return data; + } + + var buffer = new byte [1024 * 8]; + var memory = new MemoryStream (); + while ((read = stream.Read (buffer, 0, buffer.Length)) > 0) + memory.Write (buffer, 0, read); + + return memory.ToArray (); + } + } +} diff --git a/cecil-master/Mono.Cecil/EventAttributes.cs b/cecil-master/Mono.Cecil/EventAttributes.cs new file mode 100644 index 000000000..9f823fd1e --- /dev/null +++ b/cecil-master/Mono.Cecil/EventAttributes.cs @@ -0,0 +1,21 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/EventDefinition.cs b/cecil-master/Mono.Cecil/EventDefinition.cs new file mode 100644 index 000000000..457ff4c7f --- /dev/null +++ b/cecil-master/Mono.Cecil/EventDefinition.cs @@ -0,0 +1,156 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System.Threading; +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 !other_methods.IsNullOrEmpty (); + } + } + + public Collection OtherMethods { + get { + if (other_methods != null) + return other_methods; + + InitializeMethods (); + + if (other_methods == null) + Interlocked.CompareExchange (ref other_methods, new Collection (), null); + + return other_methods; + } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } + } + + #region EventAttributes + + public bool IsSpecialName { + get { return attributes.GetAttributes ((ushort) EventAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((ushort) EventAttributes.SpecialName, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((ushort) EventAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((ushort) EventAttributes.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; + if (module == null) + return; + + lock (module.SyncRoot) { + if (add_method != null + || invoke_method != null + || remove_method != null) + return; + + if (!module.HasImage ()) + return; + + module.Read (this, (@event, reader) => reader.ReadMethods (@event)); + } + } + + public override EventDefinition Resolve () + { + return this; + } + } +} diff --git a/cecil-master/Mono.Cecil/EventReference.cs b/cecil-master/Mono.Cecil/EventReference.cs new file mode 100644 index 000000000..d4df72b4d --- /dev/null +++ b/cecil-master/Mono.Cecil/EventReference.cs @@ -0,0 +1,42 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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) + { + Mixin.CheckType (eventType, Mixin.Argument.eventType); + event_type = eventType; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new abstract EventDefinition Resolve (); + } +} diff --git a/cecil-master/Mono.Cecil/ExportedType.cs b/cecil-master/Mono.Cecil/ExportedType.cs new file mode 100644 index 000000000..8238a0c6d --- /dev/null +++ b/cecil-master/Mono.Cecil/ExportedType.cs @@ -0,0 +1,240 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil { + + public sealed 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; + } + set { + if (declaring_type != null) { + declaring_type.Scope = value; + return; + } + + scope = value; + } + } + + 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 attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } + } + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } + } + + public bool IsNestedPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } + } + + public bool IsNestedPrivate { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } + } + + public bool IsNestedFamily { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } + } + + public bool IsNestedAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } + } + + public bool IsNestedFamilyAndAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } + } + + public bool IsNestedFamilyOrAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } + } + + public bool IsAutoLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } + } + + public bool IsSequentialLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } + } + + public bool IsExplicitLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } + } + + public bool IsClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } + } + + public bool IsInterface { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } + } + + public bool IsAbstract { + get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); } + } + + public bool IsSealed { + get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); } + } + + public bool IsSpecialName { + get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); } + } + + public bool IsImport { + get { return attributes.GetAttributes ((uint) TypeAttributes.Import); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); } + } + + public bool IsSerializable { + get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); } + } + + public bool IsAnsiClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } + } + + public bool IsUnicodeClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } + } + + public bool IsAutoClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } + } + + public bool IsBeforeFieldInit { + get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); } + } + + public bool HasSecurity { + get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); } + } + + #endregion + + public bool IsForwarder { + get { return attributes.GetAttributes ((uint) TypeAttributes.Forwarder); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Forwarder, value); } + } + + public string FullName { + get { + var fullname = string.IsNullOrEmpty (@namespace) + ? name + : @namespace + '.' + name; + + if (declaring_type != null) + return declaring_type.FullName + "/" + fullname; + + return fullname; + } + } + + 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/cecil-master/Mono.Cecil/FieldAttributes.cs b/cecil-master/Mono.Cecil/FieldAttributes.cs new file mode 100644 index 000000000..7d5bb544a --- /dev/null +++ b/cecil-master/Mono.Cecil/FieldAttributes.cs @@ -0,0 +1,41 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/FieldDefinition.cs b/cecil-master/Mono.Cecil/FieldDefinition.cs new file mode 100644 index 000000000..7ce8d27b5 --- /dev/null +++ b/cecil-master/Mono.Cecil/FieldDefinition.cs @@ -0,0 +1,282 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Threading; +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; + } + + lock (Module.SyncRoot) { + if (offset != Mixin.NotResolvedMarker) + 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; } + } + + internal FieldDefinitionProjection WindowsRuntimeProjection { + get { return (FieldDefinitionProjection) projection; } + set { projection = value; } + } + + void ResolveRVA () + { + if (rva != Mixin.NotResolvedMarker) + return; + + if (!HasImage) + return; + + lock (Module.SyncRoot) { + if (rva != Mixin.NotResolvedMarker) + 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; + HasFieldRVA = !initial_value.IsNullOrEmpty (); + rva = 0; + } + } + + public FieldAttributes Attributes { + get { return (FieldAttributes) attributes; } + set { + if (IsWindowsRuntimeProjection && (ushort) value != attributes) + throw new InvalidOperationException (); + + attributes = (ushort) value; + } + } + + public bool HasConstant { + get { + this.ResolveConstant (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 this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } + } + + public bool HasMarshalInfo { + get { + if (marshal_info != null) + return true; + + return this.GetHasMarshalInfo (Module); + } + } + + public MarshalInfo MarshalInfo { + get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, Module)); } + set { marshal_info = value; } + } + + #region FieldAttributes + + public bool IsCompilerControlled { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled, value); } + } + + public bool IsPrivate { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private, value); } + } + + public bool IsFamilyAndAssembly { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem, value); } + } + + public bool IsAssembly { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly, value); } + } + + public bool IsFamily { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family, value); } + } + + public bool IsFamilyOrAssembly { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem, value); } + } + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public, value); } + } + + public bool IsStatic { + get { return attributes.GetAttributes ((ushort) FieldAttributes.Static); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Static, value); } + } + + public bool IsInitOnly { + get { return attributes.GetAttributes ((ushort) FieldAttributes.InitOnly); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.InitOnly, value); } + } + + public bool IsLiteral { + get { return attributes.GetAttributes ((ushort) FieldAttributes.Literal); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Literal, value); } + } + + public bool IsNotSerialized { + get { return attributes.GetAttributes ((ushort) FieldAttributes.NotSerialized); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.NotSerialized, value); } + } + + public bool IsSpecialName { + get { return attributes.GetAttributes ((ushort) FieldAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.SpecialName, value); } + } + + public bool IsPInvokeImpl { + get { return attributes.GetAttributes ((ushort) FieldAttributes.PInvokeImpl); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.PInvokeImpl, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((ushort) FieldAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.RTSpecialName, value); } + } + + public bool HasDefault { + get { return attributes.GetAttributes ((ushort) FieldAttributes.HasDefault); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.HasDefault, value); } + } + + public bool HasFieldRVA { + get { return attributes.GetAttributes ((ushort) FieldAttributes.HasFieldRVA); } + set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.HasFieldRVA, 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/cecil-master/Mono.Cecil/FieldReference.cs b/cecil-master/Mono.Cecil/FieldReference.cs new file mode 100644 index 000000000..944c22595 --- /dev/null +++ b/cecil-master/Mono.Cecil/FieldReference.cs @@ -0,0 +1,68 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 (); } + } + + public 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) + { + Mixin.CheckType (fieldType, Mixin.Argument.fieldType); + + this.field_type = fieldType; + this.token = new MetadataToken (TokenType.MemberRef); + } + + public FieldReference (string name, TypeReference fieldType, TypeReference declaringType) + : this (name, fieldType) + { + Mixin.CheckType (declaringType, Mixin.Argument.declaringType); + + this.DeclaringType = declaringType; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new virtual FieldDefinition Resolve () + { + var module = this.Module; + if (module == null) + throw new NotSupportedException (); + + return module.Resolve (this); + } + } +} diff --git a/cecil-master/Mono.Cecil/FileAttributes.cs b/cecil-master/Mono.Cecil/FileAttributes.cs new file mode 100644 index 000000000..171f174b0 --- /dev/null +++ b/cecil-master/Mono.Cecil/FileAttributes.cs @@ -0,0 +1,17 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/FunctionPointerType.cs b/cecil-master/Mono.Cecil/FunctionPointerType.cs new file mode 100644 index 000000000..0602fcbe8 --- /dev/null +++ b/cecil-master/Mono.Cecil/FunctionPointerType.cs @@ -0,0 +1,111 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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; } + set { throw new InvalidOperationException (); } + } + + public override bool IsFunctionPointer { + get { return true; } + } + + public 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 (" *"); + this.MethodSignatureFullName (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/cecil-master/Mono.Cecil/GenericInstanceMethod.cs b/cecil-master/Mono.Cecil/GenericInstanceMethod.cs new file mode 100644 index 000000000..e3ff7db8e --- /dev/null +++ b/cecil-master/Mono.Cecil/GenericInstanceMethod.cs @@ -0,0 +1,78 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Text; +using System.Threading; +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public sealed class GenericInstanceMethod : MethodSpecification, IGenericInstance, IGenericContext { + + Collection arguments; + + public bool HasGenericArguments { + get { return !arguments.IsNullOrEmpty (); } + } + + public Collection GenericArguments { + get { + if (arguments == null) + Interlocked.CompareExchange (ref arguments, new Collection (), null); + + return arguments; + } + } + + public override bool IsGenericInstance { + get { return true; } + } + + IGenericParameterProvider IGenericContext.Method { + get { return ElementMethod; } + } + + IGenericParameterProvider IGenericContext.Type { + get { return ElementMethod.DeclaringType; } + } + + public override bool ContainsGenericParameter { + get { return this.ContainsGenericParameter () || 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); + this.GenericInstanceFullName (signature); + this.MethodSignatureFullName (signature); + return signature.ToString (); + + } + } + + public GenericInstanceMethod (MethodReference method) + : base (method) + { + } + + internal GenericInstanceMethod (MethodReference method, int arity) + : this (method) + { + this.arguments = new Collection (arity); + } + } +} diff --git a/cecil-master/Mono.Cecil/GenericInstanceType.cs b/cecil-master/Mono.Cecil/GenericInstanceType.cs new file mode 100644 index 000000000..745acd866 --- /dev/null +++ b/cecil-master/Mono.Cecil/GenericInstanceType.cs @@ -0,0 +1,76 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Text; +using System.Threading; +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 !arguments.IsNullOrEmpty (); } + } + + public Collection GenericArguments { + get { + if (arguments == null) + Interlocked.CompareExchange (ref arguments, new Collection (), null); + + return arguments; + } + } + + 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); + this.GenericInstanceFullName (name); + return name.ToString (); + } + } + + public override bool IsGenericInstance { + get { return true; } + } + + public override bool ContainsGenericParameter { + get { return this.ContainsGenericParameter () || base.ContainsGenericParameter; } + } + + IGenericParameterProvider IGenericContext.Type { + get { return ElementType; } + } + + public GenericInstanceType (TypeReference type) + : base (type) + { + base.IsValueType = type.IsValueType; + this.etype = MD.ElementType.GenericInst; + } + + internal GenericInstanceType (TypeReference type, int arity) + : this (type) + { + this.arguments = new Collection (arity); + } + } +} diff --git a/cecil-master/Mono.Cecil/GenericParameter.cs b/cecil-master/Mono.Cecil/GenericParameter.cs new file mode 100644 index 000000000..30dd73382 --- /dev/null +++ b/cecil-master/Mono.Cecil/GenericParameter.cs @@ -0,0 +1,362 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Threading; +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; + GenericParameterConstraintCollection 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; + + return HasImage && Module.Read (this, (generic_parameter, reader) => reader.HasGenericConstraints (generic_parameter)); + } + } + + public Collection Constraints { + get { + if (constraints != null) + return constraints; + + if (HasImage) + return Module.Read (ref constraints, this, (generic_parameter, reader) => reader.ReadGenericConstraints (generic_parameter)); + + Interlocked.CompareExchange (ref constraints, new GenericParameterConstraintCollection (this), null); + return constraints; + } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (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; + } + set { throw new InvalidOperationException (); } + } + + public override TypeReference DeclaringType { + get { return owner as TypeReference; } + set { throw new InvalidOperationException (); } + } + + public MethodReference DeclaringMethod { + get { return owner as MethodReference; } + } + + 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; } + } + + public override bool ContainsGenericParameter { + get { return true; } + } + + public override MetadataType MetadataType { + get { return (MetadataType) etype; } + } + + #region GenericParameterAttributes + + public bool IsNonVariant { + get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant); } + set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.NonVariant, value); } + } + + public bool IsCovariant { + get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant); } + set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Covariant, value); } + } + + public bool IsContravariant { + get { return attributes.GetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant); } + set { attributes = attributes.SetMaskedAttributes ((ushort) GenericParameterAttributes.VarianceMask, (ushort) GenericParameterAttributes.Contravariant, value); } + } + + public bool HasReferenceTypeConstraint { + get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint); } + set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.ReferenceTypeConstraint, value); } + } + + public bool HasNotNullableValueTypeConstraint { + get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint); } + set { attributes = attributes.SetAttributes ((ushort) GenericParameterAttributes.NotNullableValueTypeConstraint, value); } + } + + public bool HasDefaultConstructorConstraint { + get { return attributes.GetAttributes ((ushort) GenericParameterAttributes.DefaultConstructorConstraint); } + set { attributes = attributes.SetAttributes ((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); + this.token = new MetadataToken (TokenType.GenericParam); + + } + + internal GenericParameter (int position, GenericParameterType type, ModuleDefinition module) + : base (string.Empty, string.Empty) + { + Mixin.CheckModule (module); + + this.position = position; + this.type = type; + this.etype = ConvertGenericParameterType (type); + this.module = module; + this.token = new MetadataToken (TokenType.GenericParam); + } + + 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; + } + } + + public sealed class GenericParameterConstraint : ICustomAttributeProvider { + + internal GenericParameter generic_parameter; + internal MetadataToken token; + + TypeReference constraint_type; + Collection custom_attributes; + + public TypeReference ConstraintType { + get { return constraint_type; } + set { constraint_type = value; } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + if (generic_parameter == null) + return false; + + return this.GetHasCustomAttributes (generic_parameter.Module); + } + } + + public Collection CustomAttributes { + get { + if (generic_parameter == null) { + if (custom_attributes == null) + Interlocked.CompareExchange (ref custom_attributes, new Collection (), null); + return custom_attributes; + } + + return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, generic_parameter.Module)); + } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal GenericParameterConstraint (TypeReference constraintType, MetadataToken token) + { + this.constraint_type = constraintType; + this.token = token; + } + + public GenericParameterConstraint (TypeReference constraintType) + { + Mixin.CheckType (constraintType, Mixin.Argument.constraintType); + + this.constraint_type = constraintType; + this.token = new MetadataToken (TokenType.GenericParamConstraint); + } + } + + class GenericParameterConstraintCollection : Collection + { + readonly GenericParameter generic_parameter; + + internal GenericParameterConstraintCollection (GenericParameter genericParameter) + { + this.generic_parameter = genericParameter; + } + + internal GenericParameterConstraintCollection (GenericParameter genericParameter, int length) + : base (length) + { + this.generic_parameter = genericParameter; + } + + protected override void OnAdd (GenericParameterConstraint item, int index) + { + item.generic_parameter = generic_parameter; + } + + protected override void OnInsert (GenericParameterConstraint item, int index) + { + item.generic_parameter = generic_parameter; + } + + protected override void OnSet (GenericParameterConstraint item, int index) + { + item.generic_parameter = generic_parameter; + } + + protected override void OnRemove (GenericParameterConstraint item, int index) + { + item.generic_parameter = null; + } + } +} diff --git a/cecil-master/Mono.Cecil/GenericParameterAttributes.cs b/cecil-master/Mono.Cecil/GenericParameterAttributes.cs new file mode 100644 index 000000000..149582cdb --- /dev/null +++ b/cecil-master/Mono.Cecil/GenericParameterAttributes.cs @@ -0,0 +1,27 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/GenericParameterResolver.cs b/cecil-master/Mono.Cecil/GenericParameterResolver.cs new file mode 100644 index 000000000..86525c59e --- /dev/null +++ b/cecil-master/Mono.Cecil/GenericParameterResolver.cs @@ -0,0 +1,175 @@ +using Mono.Cecil.Cil; +using System; + +namespace Mono.Cecil { + internal sealed class GenericParameterResolver { + internal static TypeReference ResolveReturnTypeIfNeeded (MethodReference methodReference) + { + if (methodReference.DeclaringType.IsArray && methodReference.Name == "Get") + return methodReference.ReturnType; + + var genericInstanceMethod = methodReference as GenericInstanceMethod; + var declaringGenericInstanceType = methodReference.DeclaringType as GenericInstanceType; + + if (genericInstanceMethod == null && declaringGenericInstanceType == null) + return methodReference.ReturnType; + + return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, methodReference.ReturnType); + } + + internal static TypeReference ResolveFieldTypeIfNeeded (FieldReference fieldReference) + { + return ResolveIfNeeded (null, fieldReference.DeclaringType as GenericInstanceType, fieldReference.FieldType); + } + + internal static TypeReference ResolveParameterTypeIfNeeded (MethodReference method, ParameterReference parameter) + { + var genericInstanceMethod = method as GenericInstanceMethod; + var declaringGenericInstanceType = method.DeclaringType as GenericInstanceType; + + if (genericInstanceMethod == null && declaringGenericInstanceType == null) + return parameter.ParameterType; + + return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, parameter.ParameterType); + } + + internal static TypeReference ResolveVariableTypeIfNeeded (MethodReference method, VariableReference variable) + { + var genericInstanceMethod = method as GenericInstanceMethod; + var declaringGenericInstanceType = method.DeclaringType as GenericInstanceType; + + if (genericInstanceMethod == null && declaringGenericInstanceType == null) + return variable.VariableType; + + return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, variable.VariableType); + } + + private static TypeReference ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance declaringGenericInstanceType, TypeReference parameterType) + { + var byRefType = parameterType as ByReferenceType; + if (byRefType != null) + return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, byRefType); + + var arrayType = parameterType as ArrayType; + if (arrayType != null) + return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, arrayType); + + var genericInstanceType = parameterType as GenericInstanceType; + if (genericInstanceType != null) + return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, genericInstanceType); + + var genericParameter = parameterType as GenericParameter; + if (genericParameter != null) + return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, genericParameter); + + var requiredModifierType = parameterType as RequiredModifierType; + if (requiredModifierType != null && ContainsGenericParameters (requiredModifierType)) + return ResolveIfNeeded (genericInstanceMethod, declaringGenericInstanceType, requiredModifierType.ElementType); + + if (ContainsGenericParameters (parameterType)) + throw new Exception ("Unexpected generic parameter."); + + return parameterType; + } + + private static TypeReference ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, GenericParameter genericParameterElement) + { + return (genericParameterElement.MetadataType == MetadataType.MVar) + ? (genericInstanceMethod != null ? genericInstanceMethod.GenericArguments[genericParameterElement.Position] : genericParameterElement) + : genericInstanceType.GenericArguments[genericParameterElement.Position]; + } + + private static ArrayType ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, ArrayType arrayType) + { + return new ArrayType (ResolveIfNeeded (genericInstanceMethod, genericInstanceType, arrayType.ElementType), arrayType.Rank); + } + + private static ByReferenceType ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, ByReferenceType byReferenceType) + { + return new ByReferenceType (ResolveIfNeeded (genericInstanceMethod, genericInstanceType, byReferenceType.ElementType)); + } + + private static GenericInstanceType ResolveIfNeeded (IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, GenericInstanceType genericInstanceType1) + { + if (!ContainsGenericParameters (genericInstanceType1)) + return genericInstanceType1; + + var newGenericInstance = new GenericInstanceType (genericInstanceType1.ElementType); + + foreach (var genericArgument in genericInstanceType1.GenericArguments) { + if (!genericArgument.IsGenericParameter) { + newGenericInstance.GenericArguments.Add (ResolveIfNeeded (genericInstanceMethod, genericInstanceType, genericArgument)); + continue; + } + + var genParam = (GenericParameter)genericArgument; + + switch (genParam.Type) { + case GenericParameterType.Type: { + if (genericInstanceType == null) + throw new NotSupportedException (); + + newGenericInstance.GenericArguments.Add (genericInstanceType.GenericArguments[genParam.Position]); + } + break; + + case GenericParameterType.Method: { + if (genericInstanceMethod == null) + newGenericInstance.GenericArguments.Add (genParam); + else + newGenericInstance.GenericArguments.Add (genericInstanceMethod.GenericArguments[genParam.Position]); + } + break; + } + } + + return newGenericInstance; + } + + private static bool ContainsGenericParameters (TypeReference typeReference) + { + var genericParameter = typeReference as GenericParameter; + if (genericParameter != null) + return true; + + var arrayType = typeReference as ArrayType; + if (arrayType != null) + return ContainsGenericParameters (arrayType.ElementType); + + var pointerType = typeReference as PointerType; + if (pointerType != null) + return ContainsGenericParameters (pointerType.ElementType); + + var byRefType = typeReference as ByReferenceType; + if (byRefType != null) + return ContainsGenericParameters (byRefType.ElementType); + + var sentinelType = typeReference as SentinelType; + if (sentinelType != null) + return ContainsGenericParameters (sentinelType.ElementType); + + var pinnedType = typeReference as PinnedType; + if (pinnedType != null) + return ContainsGenericParameters (pinnedType.ElementType); + + var requiredModifierType = typeReference as RequiredModifierType; + if (requiredModifierType != null) + return ContainsGenericParameters (requiredModifierType.ElementType); + + var genericInstance = typeReference as GenericInstanceType; + if (genericInstance != null) { + foreach (var genericArgument in genericInstance.GenericArguments) { + if (ContainsGenericParameters (genericArgument)) + return true; + } + + return false; + } + + if (typeReference is TypeSpecification) + throw new NotSupportedException (); + + return false; + } + } +} diff --git a/cecil-master/Mono.Cecil/IConstantProvider.cs b/cecil-master/Mono.Cecil/IConstantProvider.cs new file mode 100644 index 000000000..178b66511 --- /dev/null +++ b/cecil-master/Mono.Cecil/IConstantProvider.cs @@ -0,0 +1,44 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 ( + this IConstantProvider self, + ref object constant, + ModuleDefinition module) + { + if (module == null) { + constant = Mixin.NoValue; + return; + } + + lock (module.SyncRoot) { + if (constant != Mixin.NotResolved) + return; + if (module.HasImage ()) + constant = module.Read (self, (provider, reader) => reader.ReadConstant (provider)); + else + constant = Mixin.NoValue; + } + } + } +} diff --git a/cecil-master/Mono.Cecil/ICustomAttributeProvider.cs b/cecil-master/Mono.Cecil/ICustomAttributeProvider.cs new file mode 100644 index 000000000..894253098 --- /dev/null +++ b/cecil-master/Mono.Cecil/ICustomAttributeProvider.cs @@ -0,0 +1,45 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Threading; +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 ( + this ICustomAttributeProvider self, + ModuleDefinition module) + { + return module.HasImage () && module.Read (self, (provider, reader) => reader.HasCustomAttributes (provider)); + } + + public static Collection GetCustomAttributes ( + this ICustomAttributeProvider self, + ref Collection variable, + ModuleDefinition module) + { + if (module.HasImage ()) + return module.Read (ref variable, self, (provider, reader) => reader.ReadCustomAttributes (provider)); + + Interlocked.CompareExchange (ref variable, new Collection (), null); + return variable; + } + } +} diff --git a/cecil-master/Mono.Cecil/IGenericInstance.cs b/cecil-master/Mono.Cecil/IGenericInstance.cs new file mode 100644 index 000000000..e98d8189b --- /dev/null +++ b/cecil-master/Mono.Cecil/IGenericInstance.cs @@ -0,0 +1,48 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 (this 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 (this 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/cecil-master/Mono.Cecil/IGenericParameterProvider.cs b/cecil-master/Mono.Cecil/IGenericParameterProvider.cs new file mode 100644 index 000000000..b79169ed9 --- /dev/null +++ b/cecil-master/Mono.Cecil/IGenericParameterProvider.cs @@ -0,0 +1,58 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System.Threading; +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 ( + this IGenericParameterProvider self, + ModuleDefinition module) + { + return module.HasImage () && module.Read (self, (provider, reader) => reader.HasGenericParameters (provider)); + } + + public static Collection GetGenericParameters ( + this IGenericParameterProvider self, + ref Collection collection, + ModuleDefinition module) + { + if (module.HasImage ()) + return module.Read (ref collection, self, (provider, reader) => reader.ReadGenericParameters (provider)); + + Interlocked.CompareExchange (ref collection, new GenericParameterCollection (self), null); + return collection; + } + } +} diff --git a/cecil-master/Mono.Cecil/IMarshalInfoProvider.cs b/cecil-master/Mono.Cecil/IMarshalInfoProvider.cs new file mode 100644 index 000000000..a1b9e8834 --- /dev/null +++ b/cecil-master/Mono.Cecil/IMarshalInfoProvider.cs @@ -0,0 +1,38 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public interface IMarshalInfoProvider : IMetadataTokenProvider { + + bool HasMarshalInfo { get; } + MarshalInfo MarshalInfo { get; set; } + } + + static partial class Mixin { + + public static bool GetHasMarshalInfo ( + this IMarshalInfoProvider self, + ModuleDefinition module) + { + return module.HasImage () && module.Read (self, (provider, reader) => reader.HasMarshalInfo (provider)); + } + + public static MarshalInfo GetMarshalInfo ( + this IMarshalInfoProvider self, + ref MarshalInfo variable, + ModuleDefinition module) + { + return module.HasImage () + ? module.Read (ref variable, self, (provider, reader) => reader.ReadMarshalInfo (provider)) + : null; + } + } +} diff --git a/cecil-master/Mono.Cecil/IMemberDefinition.cs b/cecil-master/Mono.Cecil/IMemberDefinition.cs new file mode 100644 index 000000000..ad747002b --- /dev/null +++ b/cecil-master/Mono.Cecil/IMemberDefinition.cs @@ -0,0 +1,82 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 (this uint self, uint attributes) + { + return (self & attributes) != 0; + } + + public static uint SetAttributes (this uint self, uint attributes, bool value) + { + if (value) + return self | attributes; + + return self & ~attributes; + } + + public static bool GetMaskedAttributes (this uint self, uint mask, uint attributes) + { + return (self & mask) == attributes; + } + + public static uint SetMaskedAttributes (this uint self, uint mask, uint attributes, bool value) + { + if (value) { + self &= ~mask; + return self | attributes; + } + + return self & ~(mask & attributes); + } + + public static bool GetAttributes (this ushort self, ushort attributes) + { + return (self & attributes) != 0; + } + + public static ushort SetAttributes (this ushort self, ushort attributes, bool value) + { + if (value) + return (ushort) (self | attributes); + + return (ushort) (self & ~attributes); + } + + public static bool GetMaskedAttributes (this ushort self, ushort mask, uint attributes) + { + return (self & mask) == attributes; + } + + public static ushort SetMaskedAttributes (this 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/cecil-master/Mono.Cecil/IMetadataScope.cs b/cecil-master/Mono.Cecil/IMetadataScope.cs new file mode 100644 index 000000000..2e56e758c --- /dev/null +++ b/cecil-master/Mono.Cecil/IMetadataScope.cs @@ -0,0 +1,23 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum MetadataScopeType { + AssemblyNameReference, + ModuleReference, + ModuleDefinition, + } + + public interface IMetadataScope : IMetadataTokenProvider { + MetadataScopeType MetadataScopeType { get; } + string Name { get; set; } + } +} diff --git a/cecil-master/Mono.Cecil/IMetadataTokenProvider.cs b/cecil-master/Mono.Cecil/IMetadataTokenProvider.cs new file mode 100644 index 000000000..dcd678b03 --- /dev/null +++ b/cecil-master/Mono.Cecil/IMetadataTokenProvider.cs @@ -0,0 +1,17 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public interface IMetadataTokenProvider { + + MetadataToken MetadataToken { get; set; } + } +} diff --git a/cecil-master/Mono.Cecil/IMethodSignature.cs b/cecil-master/Mono.Cecil/IMethodSignature.cs new file mode 100644 index 000000000..4d7766e45 --- /dev/null +++ b/cecil-master/Mono.Cecil/IMethodSignature.cs @@ -0,0 +1,57 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 (this IMethodSignature self) + { + return self.HasThis && !self.ExplicitThis; + } + + public static void MethodSignatureFullName (this 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/cecil-master/Mono.Cecil/Import.cs b/cecil-master/Mono.Cecil/Import.cs new file mode 100644 index 000000000..272e96076 --- /dev/null +++ b/cecil-master/Mono.Cecil/Import.cs @@ -0,0 +1,812 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using Mono.Collections.Generic; +using SR = System.Reflection; + +using Mono.Cecil.Metadata; + +namespace Mono.Cecil { + + public interface IMetadataImporterProvider { + IMetadataImporter GetMetadataImporter (ModuleDefinition module); + } + + public interface IMetadataImporter { + AssemblyNameReference ImportReference (AssemblyNameReference reference); + TypeReference ImportReference (TypeReference type, IGenericParameterProvider context); + FieldReference ImportReference (FieldReference field, IGenericParameterProvider context); + MethodReference ImportReference (MethodReference method, IGenericParameterProvider context); + } + + public interface IReflectionImporterProvider { + IReflectionImporter GetReflectionImporter (ModuleDefinition module); + } + + public interface IReflectionImporter { + AssemblyNameReference ImportReference (SR.AssemblyName reference); + TypeReference ImportReference (Type type, IGenericParameterProvider context); + FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context); + MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context); + } + + struct ImportGenericContext { + + Collection stack; + + public bool IsEmpty { get { return stack == null; } } + + public ImportGenericContext (IGenericParameterProvider provider) + { + if (provider == null) + throw new ArgumentNullException ("provider"); + + stack = null; + + Push (provider); + } + + public void Push (IGenericParameterProvider provider) + { + if (stack == null) + stack = new Collection (1) { provider }; + else + stack.Add (provider); + } + + public void Pop () + { + stack.RemoveAt (stack.Count - 1); + } + + public TypeReference MethodParameter (string method, int position) + { + for (int i = stack.Count - 1; i >= 0; i--) { + var candidate = stack [i] as MethodReference; + if (candidate == null) + continue; + + if (method != NormalizeMethodName (candidate)) + continue; + + return candidate.GenericParameters [position]; + } + + throw new InvalidOperationException (); + } + + public string NormalizeMethodName (MethodReference method) + { + return method.DeclaringType.GetElementType ().FullName + "." + method.Name; + } + + public TypeReference TypeParameter (string type, int position) + { + for (int i = stack.Count - 1; i >= 0; i--) { + var candidate = GenericTypeFor (stack [i]); + + if (candidate.FullName != type) + continue; + + return candidate.GenericParameters [position]; + } + + throw new InvalidOperationException (); + } + + static TypeReference GenericTypeFor (IGenericParameterProvider context) + { + var type = context as TypeReference; + if (type != null) + return type.GetElementType (); + + var method = context as MethodReference; + if (method != null) + return method.DeclaringType.GetElementType (); + + throw new InvalidOperationException (); + } + + public static ImportGenericContext For (IGenericParameterProvider context) + { + return context != null ? new ImportGenericContext (context) : default (ImportGenericContext); + } + } + + public class DefaultReflectionImporter : IReflectionImporter { + + readonly protected ModuleDefinition module; + + public DefaultReflectionImporter (ModuleDefinition module) + { + Mixin.CheckModule (module); + + this.module = module; + } + + enum ImportGenericKind { + Definition, + Open, + } + + static readonly Dictionary type_etype_mapping = new Dictionary (18) { + { typeof (void), ElementType.Void }, + { typeof (bool), ElementType.Boolean }, + { typeof (char), ElementType.Char }, + { typeof (sbyte), ElementType.I1 }, + { typeof (byte), ElementType.U1 }, + { typeof (short), ElementType.I2 }, + { typeof (ushort), ElementType.U2 }, + { typeof (int), ElementType.I4 }, + { typeof (uint), ElementType.U4 }, + { typeof (long), ElementType.I8 }, + { typeof (ulong), ElementType.U8 }, + { typeof (float), ElementType.R4 }, + { typeof (double), ElementType.R8 }, + { typeof (string), ElementType.String }, + { typeof (TypedReference), ElementType.TypedByRef }, + { typeof (IntPtr), ElementType.I }, + { typeof (UIntPtr), ElementType.U }, + { typeof (object), ElementType.Object }, + }; + + TypeReference ImportType (Type type, ImportGenericContext context) + { + return ImportType (type, context, ImportGenericKind.Open); + } + + TypeReference ImportType (Type type, ImportGenericContext context, ImportGenericKind import_kind) + { + if (IsTypeSpecification (type) || ImportOpenGenericType (type, import_kind)) + return ImportTypeSpecification (type, context); + + var reference = new TypeReference ( + string.Empty, + type.Name, + module, + ImportScope (type), + type.IsValueType); + + reference.etype = ImportElementType (type); + + if (IsNestedType (type)) + reference.DeclaringType = ImportType (type.DeclaringType, context, import_kind); + else + reference.Namespace = type.Namespace ?? string.Empty; + + if (type.IsGenericType) + ImportGenericParameters (reference, type.GetGenericArguments ()); + + return reference; + } + + protected virtual IMetadataScope ImportScope (Type type) + { + return ImportScope (type.Assembly); + } + + static bool ImportOpenGenericType (Type type, ImportGenericKind import_kind) + { + return type.IsGenericType && type.IsGenericTypeDefinition && import_kind == ImportGenericKind.Open; + } + + static bool ImportOpenGenericMethod (SR.MethodBase method, ImportGenericKind import_kind) + { + return method.IsGenericMethod && method.IsGenericMethodDefinition && import_kind == ImportGenericKind.Open; + } + + static bool IsNestedType (Type type) + { + return type.IsNested; + } + + TypeReference ImportTypeSpecification (Type type, ImportGenericContext context) + { + if (type.IsByRef) + return new ByReferenceType (ImportType (type.GetElementType (), context)); + + if (type.IsPointer) + return new PointerType (ImportType (type.GetElementType (), context)); + + if (type.IsArray) + return new ArrayType (ImportType (type.GetElementType (), context), type.GetArrayRank ()); + + if (type.IsGenericType) + return ImportGenericInstance (type, context); + + if (type.IsGenericParameter) + return ImportGenericParameter (type, context); + + throw new NotSupportedException (type.FullName); + } + + static TypeReference ImportGenericParameter (Type type, ImportGenericContext context) + { + if (context.IsEmpty) + throw new InvalidOperationException (); + + if (type.DeclaringMethod != null) + return context.MethodParameter (NormalizeMethodName (type.DeclaringMethod), type.GenericParameterPosition); + + if (type.DeclaringType != null) + return context.TypeParameter (NormalizeTypeFullName (type.DeclaringType), type.GenericParameterPosition); + + throw new InvalidOperationException(); + } + + static string NormalizeMethodName (SR.MethodBase method) + { + return NormalizeTypeFullName (method.DeclaringType) + "." + method.Name; + } + + static string NormalizeTypeFullName (Type type) + { + if (IsNestedType (type)) + return NormalizeTypeFullName (type.DeclaringType) + "/" + type.Name; + + return type.FullName; + } + + TypeReference ImportGenericInstance (Type type, ImportGenericContext context) + { + var element_type = ImportType (type.GetGenericTypeDefinition (), context, ImportGenericKind.Definition); + var arguments = type.GetGenericArguments (); + var instance = new GenericInstanceType (element_type, arguments.Length); + var instance_arguments = instance.GenericArguments; + + context.Push (element_type); + try { + for (int i = 0; i < arguments.Length; i++) + instance_arguments.Add (ImportType (arguments [i], context)); + + return instance; + } finally { + context.Pop (); + } + } + + static bool IsTypeSpecification (Type type) + { + return type.HasElementType + || IsGenericInstance (type) + || type.IsGenericParameter; + } + + static bool IsGenericInstance (Type type) + { + return type.IsGenericType && !type.IsGenericTypeDefinition; + } + + static ElementType ImportElementType (Type type) + { + ElementType etype; + if (!type_etype_mapping.TryGetValue (type, out etype)) + return ElementType.None; + + return etype; + } + + protected AssemblyNameReference ImportScope (SR.Assembly assembly) + { + return ImportReference (assembly.GetName ()); + } + + public virtual AssemblyNameReference ImportReference (SR.AssemblyName name) + { + Mixin.CheckName (name); + + AssemblyNameReference reference; + if (TryGetAssemblyNameReference (name, out reference)) + return reference; + + reference = new AssemblyNameReference (name.Name, name.Version) + { + PublicKeyToken = name.GetPublicKeyToken (), + Culture = name.CultureInfo.Name, + HashAlgorithm = (AssemblyHashAlgorithm) name.HashAlgorithm, + }; + + module.AssemblyReferences.Add (reference); + + return reference; + } + + bool TryGetAssemblyNameReference (SR.AssemblyName name, out AssemblyNameReference assembly_reference) + { + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; + if (name.FullName != reference.FullName) // TODO compare field by field + continue; + + assembly_reference = reference; + return true; + } + + assembly_reference = null; + return false; + } + + FieldReference ImportField (SR.FieldInfo field, ImportGenericContext context) + { + var declaring_type = ImportType (field.DeclaringType, context); + + if (IsGenericInstance (field.DeclaringType)) + field = ResolveFieldDefinition (field); + + context.Push (declaring_type); + try { + return new FieldReference { + Name = field.Name, + DeclaringType = declaring_type, + FieldType = ImportType (field.FieldType, context), + }; + } finally { + context.Pop (); + } + } + + static SR.FieldInfo ResolveFieldDefinition (SR.FieldInfo field) + { + return field.Module.ResolveField (field.MetadataToken); + } + + static SR.MethodBase ResolveMethodDefinition (SR.MethodBase method) + { + return method.Module.ResolveMethod (method.MetadataToken); + } + + MethodReference ImportMethod (SR.MethodBase method, ImportGenericContext context, ImportGenericKind import_kind) + { + if (IsMethodSpecification (method) || ImportOpenGenericMethod (method, import_kind)) + return ImportMethodSpecification (method, context); + + var declaring_type = ImportType (method.DeclaringType, context); + + if (IsGenericInstance (method.DeclaringType)) + method = ResolveMethodDefinition (method); + + var reference = new MethodReference { + Name = method.Name, + HasThis = HasCallingConvention (method, SR.CallingConventions.HasThis), + ExplicitThis = HasCallingConvention (method, SR.CallingConventions.ExplicitThis), + DeclaringType = ImportType (method.DeclaringType, context, ImportGenericKind.Definition), + }; + + if (HasCallingConvention (method, SR.CallingConventions.VarArgs)) + reference.CallingConvention &= MethodCallingConvention.VarArg; + + if (method.IsGenericMethod) + ImportGenericParameters (reference, method.GetGenericArguments ()); + + context.Push (reference); + try { + var method_info = method as SR.MethodInfo; + reference.ReturnType = method_info != null + ? ImportType (method_info.ReturnType, context) + : ImportType (typeof (void), default (ImportGenericContext)); + + var parameters = method.GetParameters (); + var reference_parameters = reference.Parameters; + + for (int i = 0; i < parameters.Length; i++) + reference_parameters.Add ( + new ParameterDefinition (ImportType (parameters [i].ParameterType, context))); + + reference.DeclaringType = declaring_type; + + return reference; + } finally { + context.Pop (); + } + } + + static void ImportGenericParameters (IGenericParameterProvider provider, Type [] arguments) + { + var provider_parameters = provider.GenericParameters; + + for (int i = 0; i < arguments.Length; i++) + provider_parameters.Add (new GenericParameter (arguments [i].Name, provider)); + } + + static bool IsMethodSpecification (SR.MethodBase method) + { + return method.IsGenericMethod && !method.IsGenericMethodDefinition; + } + + MethodReference ImportMethodSpecification (SR.MethodBase method, ImportGenericContext context) + { + var method_info = method as SR.MethodInfo; + if (method_info == null) + throw new InvalidOperationException (); + + var element_method = ImportMethod (method_info.GetGenericMethodDefinition (), context, ImportGenericKind.Definition); + var instance = new GenericInstanceMethod (element_method); + var arguments = method.GetGenericArguments (); + var instance_arguments = instance.GenericArguments; + + context.Push (element_method); + try { + for (int i = 0; i < arguments.Length; i++) + instance_arguments.Add (ImportType (arguments [i], context)); + + return instance; + } finally { + context.Pop (); + } + } + + static bool HasCallingConvention (SR.MethodBase method, SR.CallingConventions conventions) + { + return (method.CallingConvention & conventions) != 0; + } + + public virtual TypeReference ImportReference (Type type, IGenericParameterProvider context) + { + Mixin.CheckType (type); + return ImportType ( + type, + ImportGenericContext.For (context), + context != null ? ImportGenericKind.Open : ImportGenericKind.Definition); + } + + public virtual FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context) + { + Mixin.CheckField (field); + return ImportField (field, ImportGenericContext.For (context)); + } + + public virtual MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context) + { + Mixin.CheckMethod (method); + return ImportMethod (method, + ImportGenericContext.For (context), + context != null ? ImportGenericKind.Open : ImportGenericKind.Definition); + } + } + + public class DefaultMetadataImporter : IMetadataImporter { + + readonly protected ModuleDefinition module; + + public DefaultMetadataImporter (ModuleDefinition module) + { + Mixin.CheckModule (module); + + this.module = module; + } + + TypeReference ImportType (TypeReference type, ImportGenericContext context) + { + if (type.IsTypeSpecification ()) + return ImportTypeSpecification (type, context); + + var reference = new TypeReference ( + type.Namespace, + type.Name, + module, + ImportScope (type), + type.IsValueType); + + MetadataSystem.TryProcessPrimitiveTypeReference (reference); + + if (type.IsNested) + reference.DeclaringType = ImportType (type.DeclaringType, context); + + if (type.HasGenericParameters) + ImportGenericParameters (reference, type); + + return reference; + } + + protected virtual IMetadataScope ImportScope (TypeReference type) + { + return ImportScope (type.Scope); + } + + protected IMetadataScope ImportScope (IMetadataScope scope) + { + switch (scope.MetadataScopeType) { + case MetadataScopeType.AssemblyNameReference: + return ImportReference ((AssemblyNameReference) scope); + case MetadataScopeType.ModuleDefinition: + if (scope == module) return scope; + return ImportReference (((ModuleDefinition) scope).Assembly.Name); + case MetadataScopeType.ModuleReference: + throw new NotImplementedException (); + } + + throw new NotSupportedException (); + } + + public virtual AssemblyNameReference ImportReference (AssemblyNameReference name) + { + Mixin.CheckName (name); + + AssemblyNameReference reference; + if (module.TryGetAssemblyNameReference (name, out reference)) + return reference; + + reference = new AssemblyNameReference (name.Name, name.Version) { + Culture = name.Culture, + HashAlgorithm = name.HashAlgorithm, + IsRetargetable = name.IsRetargetable, + IsWindowsRuntime = name.IsWindowsRuntime, + }; + + var pk_token = !name.PublicKeyToken.IsNullOrEmpty () + ? 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; + } + + 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, ImportGenericContext 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.FnPtr: + var fnptr = (FunctionPointerType) type; + var imported_fnptr = new FunctionPointerType () { + HasThis = fnptr.HasThis, + ExplicitThis = fnptr.ExplicitThis, + CallingConvention = fnptr.CallingConvention, + ReturnType = ImportType (fnptr.ReturnType, context), + }; + + if (!fnptr.HasParameters) + return imported_fnptr; + + for (int i = 0; i < fnptr.Parameters.Count; i++) + imported_fnptr.Parameters.Add (new ParameterDefinition ( + ImportType (fnptr.Parameters [i].ParameterType, context))); + + return imported_fnptr; + 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 arguments = instance.GenericArguments; + var imported_instance = new GenericInstanceType (element_type, arguments.Count); + 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: + var var_parameter = (GenericParameter) type; + if (var_parameter.DeclaringType == null) + throw new InvalidOperationException (); + return context.TypeParameter (var_parameter.DeclaringType.FullName, var_parameter.Position); + case ElementType.MVar: + var mvar_parameter = (GenericParameter) type; + if (mvar_parameter.DeclaringMethod == null) + throw new InvalidOperationException (); + return context.MethodParameter (context.NormalizeMethodName (mvar_parameter.DeclaringMethod), mvar_parameter.Position); + } + + throw new NotSupportedException (type.etype.ToString ()); + } + + FieldReference ImportField (FieldReference field, ImportGenericContext context) + { + var declaring_type = ImportType (field.DeclaringType, context); + + context.Push (declaring_type); + try { + return new FieldReference { + Name = field.Name, + DeclaringType = declaring_type, + FieldType = ImportType (field.FieldType, context), + }; + } finally { + context.Pop (); + } + } + + MethodReference ImportMethod (MethodReference method, ImportGenericContext 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, + CallingConvention = method.CallingConvention, + }; + + if (method.HasGenericParameters) + ImportGenericParameters (reference, method); + + context.Push (reference); + try { + reference.ReturnType = ImportType (method.ReturnType, context); + + if (!method.HasParameters) + return reference; + + var parameters = method.Parameters; + var reference_parameters = reference.parameters = new ParameterDefinitionCollection (reference, parameters.Count); + for (int i = 0; i < parameters.Count; i++) + reference_parameters.Add ( + new ParameterDefinition (ImportType (parameters [i].ParameterType, context))); + + return reference; + } finally { + context.Pop(); + } + } + + MethodSpecification ImportMethodSpecification (MethodReference method, ImportGenericContext 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; + } + + public virtual TypeReference ImportReference (TypeReference type, IGenericParameterProvider context) + { + Mixin.CheckType (type); + return ImportType (type, ImportGenericContext.For (context)); + } + + public virtual FieldReference ImportReference (FieldReference field, IGenericParameterProvider context) + { + Mixin.CheckField (field); + return ImportField (field, ImportGenericContext.For (context)); + } + + public virtual MethodReference ImportReference (MethodReference method, IGenericParameterProvider context) + { + Mixin.CheckMethod (method); + return ImportMethod (method, ImportGenericContext.For (context)); + } + } + + static partial class Mixin { + + public static void CheckModule (ModuleDefinition module) + { + if (module == null) + throw new ArgumentNullException (Argument.module.ToString ()); + } + + public static bool TryGetAssemblyNameReference (this ModuleDefinition module, AssemblyNameReference name_reference, out AssemblyNameReference assembly_reference) + { + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) { + var reference = references [i]; + if (!Equals (name_reference, reference)) + continue; + + assembly_reference = reference; + return true; + } + + assembly_reference = null; + return false; + } + + static bool Equals (byte [] a, byte [] b) + { + if (ReferenceEquals (a, b)) + return true; + if (a == null) + return false; + if (a.Length != b.Length) + return false; + for (int i = 0; i < a.Length; i++) + if (a [i] != b [i]) + return false; + return true; + } + + static bool Equals (T a, T b) where T : class, IEquatable + { + if (ReferenceEquals (a, b)) + return true; + if (a == null) + return false; + return a.Equals (b); + } + + static bool Equals (AssemblyNameReference a, AssemblyNameReference b) + { + if (ReferenceEquals (a, b)) + return true; + if (a.Name != b.Name) + return false; + if (!Equals (a.Version, b.Version)) + return false; + if (a.Culture != b.Culture) + return false; + if (!Equals (a.PublicKeyToken, b.PublicKeyToken)) + return false; + return true; + } + } +} diff --git a/cecil-master/Mono.Cecil/LinkedResource.cs b/cecil-master/Mono.Cecil/LinkedResource.cs new file mode 100644 index 000000000..e53430eca --- /dev/null +++ b/cecil-master/Mono.Cecil/LinkedResource.cs @@ -0,0 +1,42 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/ManifestResourceAttributes.cs b/cecil-master/Mono.Cecil/ManifestResourceAttributes.cs new file mode 100644 index 000000000..03ccb6b4c --- /dev/null +++ b/cecil-master/Mono.Cecil/ManifestResourceAttributes.cs @@ -0,0 +1,21 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/MarshalInfo.cs b/cecil-master/Mono.Cecil/MarshalInfo.cs new file mode 100644 index 000000000..47d935e2c --- /dev/null +++ b/cecil-master/Mono.Cecil/MarshalInfo.cs @@ -0,0 +1,153 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/MemberDefinitionCollection.cs b/cecil-master/Mono.Cecil/MemberDefinitionCollection.cs new file mode 100644 index 000000000..3872b2a97 --- /dev/null +++ b/cecil-master/Mono.Cecil/MemberDefinitionCollection.cs @@ -0,0 +1,74 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + sealed 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/cecil-master/Mono.Cecil/MemberReference.cs b/cecil-master/Mono.Cecil/MemberReference.cs new file mode 100644 index 000000000..8276a66f1 --- /dev/null +++ b/cecil-master/Mono.Cecil/MemberReference.cs @@ -0,0 +1,102 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil { + + public abstract class MemberReference : IMetadataTokenProvider { + + string name; + TypeReference declaring_type; + + internal MetadataToken token; + internal object projection; + + public virtual string Name { + get { return name; } + set { + if (IsWindowsRuntimeProjection && value != name) + throw new InvalidOperationException (); + + 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; } + } + + public bool IsWindowsRuntimeProjection { + get { return projection != null; } + } + + 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; } + } + + public 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 IMemberDefinition Resolve () + { + return ResolveDefinition (); + } + + protected abstract IMemberDefinition ResolveDefinition (); + + public override string ToString () + { + return FullName; + } + } +} diff --git a/cecil-master/Mono.Cecil/MetadataResolver.cs b/cecil-master/Mono.Cecil/MetadataResolver.cs new file mode 100644 index 000000000..29b786293 --- /dev/null +++ b/cecil-master/Mono.Cecil/MetadataResolver.cs @@ -0,0 +1,442 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + public interface IAssemblyResolver : IDisposable { + AssemblyDefinition Resolve (AssemblyNameReference name); + AssemblyDefinition Resolve (AssemblyNameReference name, ReaderParameters parameters); + } + + public interface IMetadataResolver { + TypeDefinition Resolve (TypeReference type); + FieldDefinition Resolve (FieldReference field); + MethodDefinition Resolve (MethodReference method); + } + +#if !NET_CORE + [Serializable] +#endif + public sealed class ResolutionException : Exception { + + readonly MemberReference member; + + public MemberReference Member { + get { return member; } + } + + public IMetadataScope Scope { + get { + var type = member as TypeReference; + if (type != null) + return type.Scope; + + var declaring_type = member.DeclaringType; + if (declaring_type != null) + return declaring_type.Scope; + + throw new NotSupportedException (); + } + } + + public ResolutionException (MemberReference member) + : base ("Failed to resolve " + member.FullName) + { + if (member == null) + throw new ArgumentNullException ("member"); + + this.member = member; + } + + public ResolutionException (MemberReference member, Exception innerException) + : base ("Failed to resolve " + member.FullName, innerException) + { + if (member == null) + throw new ArgumentNullException ("member"); + + this.member = member; + } + +#if !NET_CORE + ResolutionException ( + System.Runtime.Serialization.SerializationInfo info, + System.Runtime.Serialization.StreamingContext context) + : base (info, context) + { + } +#endif + } + + 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) + { + Mixin.CheckType (type); + + type = type.GetElementType (); + + var scope = type.Scope; + + if (scope == null) + return null; + + 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: + if (type.Module.Assembly == null) + return null; + + 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 declaring_type.GetNestedType (type.TypeFullName ()); + } + + public virtual FieldDefinition Resolve (FieldReference field) + { + Mixin.CheckField (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) + { + Mixin.CheckMethod (method); + + var type = Resolve (method.DeclaringType); + if (type == null) + return null; + + method = method.GetElementMethod (); + + if (!type.HasMethods) + return null; + + // This is here to handle privatescope. Aka CompilerControlled. + // GetMethod cannot correctly resolve a privatescope method when the method name is the same as another method in the type. + // because GetMethod operates on a MethodReference which doesn't have access to the MethodAttributes. + // privatescope methods are always private. There should also never be a MethodReference to a privatescope method. + // in other words, privatescope methods should always be referenced by their MethodDefinition. + // + // privatescope methods aside, if method is ever a MethodDefinition we don't need to go searching all of the methods on the type + // we can return the method directly. This avoids the cost of a linear search. + // + // So we have this optimization opportunity here. + // And we need to handle privatescope methods somehow, because GetMethod can't. + // + // and 2 birds one stone. This if check covers the optimization and privatescope handling. + if (method is MethodDefinition definition) + return definition; + + 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.HasThis != reference.HasThis) + continue; + + if (method.IsVarArg () != reference.IsVarArg ()) + continue; + + if (method.IsVarArg () && IsVarArgCallTo (method, reference)) + return method; + + 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 IsVarArgCallTo (MethodDefinition method, MethodReference reference) + { + if (method.Parameters.Count >= reference.Parameters.Count) + return false; + + if (reference.GetSentinelPosition () != method.Parameters.Count) + return false; + + for (int i = 0; i < method.Parameters.Count; i++) + if (!AreSame (method.Parameters [i].ParameterType, reference.Parameters [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); + + if (a.IsFunctionPointer) + return AreSame ((FunctionPointerType) a, (FunctionPointerType) b); + + return true; + } + + static bool AreSame (FunctionPointerType a, FunctionPointerType b) + { + if (a.HasThis != b.HasThis) + return false; + + if (a.CallingConvention != b.CallingConvention) + return false; + + if (!AreSame (a.ReturnType, b.ReturnType)) + return false; + + if (a.ContainsGenericParameter != b.ContainsGenericParameter) + return false; + + if (a.HasParameters != b.HasParameters) + return false; + + if (!a.HasParameters) + return true; + + if (!AreSame (a.Parameters, b.Parameters)) + return false; + + 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 (a.IsTypeSpecification ()) + 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/cecil-master/Mono.Cecil/MetadataSystem.cs b/cecil-master/Mono.Cecil/MetadataSystem.cs new file mode 100644 index 000000000..a8777716d --- /dev/null +++ b/cecil-master/Mono.Cecil/MetadataSystem.cs @@ -0,0 +1,382 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Threading; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Collections.Generic; + +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; + + internal Document [] Documents; + internal Dictionary>> LocalScopes; + internal ImportDebugInformation [] ImportScopes; + internal Dictionary StateMachineMethods; + internal Dictionary []> CustomDebugInformations; + + static Dictionary> primitive_value_types; + + static void InitializePrimitives () + { + var 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) }, + }; + + Interlocked.CompareExchange (ref primitive_value_types, types, null); + } + + 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)) { + 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 = new Dictionary> (capacity: 0); + if (ReverseNestedTypes != null) ReverseNestedTypes = new Dictionary (capacity: 0); + if (Interfaces != null) Interfaces = new Dictionary>> (capacity: 0); + if (ClassLayouts != null) ClassLayouts = new Dictionary> (capacity: 0); + if (FieldLayouts != null) FieldLayouts = new Dictionary (capacity: 0); + if (FieldRVAs != null) FieldRVAs = new Dictionary (capacity: 0); + if (FieldMarshals != null) FieldMarshals = new Dictionary (capacity: 0); + if (Constants != null) Constants = new Dictionary> (capacity: 0); + if (Overrides != null) Overrides = new Dictionary> (capacity: 0); + if (CustomAttributes != null) CustomAttributes = new Dictionary (capacity: 0); + if (SecurityDeclarations != null) SecurityDeclarations = new Dictionary (capacity: 0); + if (Events != null) Events = new Dictionary (capacity: 0); + if (Properties != null) Properties = new Dictionary (capacity: 0); + if (Semantics != null) Semantics = new Dictionary> (capacity: 0); + if (PInvokes != null) PInvokes = new Dictionary> (capacity: 0); + if (GenericParameters != null) GenericParameters = new Dictionary (capacity: 0); + if (GenericConstraints != null) GenericConstraints = new Dictionary>> (capacity: 0); + + Documents = Empty.Array; + ImportScopes = Empty.Array; + if (LocalScopes != null) LocalScopes = new Dictionary>> (capacity: 0); + if (StateMachineMethods != null) StateMachineMethods = new Dictionary (capacity: 0); + } + + public AssemblyNameReference GetAssemblyNameReference (uint rid) + { + if (rid < 1 || rid > AssemblyReferences.Length) + return null; + + return AssemblyReferences [rid - 1]; + } + + 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 Collection mapping) + { + return NestedTypes.TryGetValue (type.token.RID, out mapping); + } + + public void SetNestedTypeMapping (uint type_rid, Collection mapping) + { + NestedTypes [type_rid] = mapping; + } + + public bool TryGetReverseNestedTypeMapping (TypeDefinition type, out uint declaring) + { + return ReverseNestedTypes.TryGetValue (type.token.RID, out declaring); + } + + public void SetReverseNestedTypeMapping (uint nested, uint declaring) + { + ReverseNestedTypes [nested] = declaring; + } + + public bool TryGetInterfaceMapping (TypeDefinition type, out Collection> mapping) + { + return Interfaces.TryGetValue (type.token.RID, out mapping); + } + + public void SetInterfaceMapping (uint type_rid, Collection> mapping) + { + Interfaces [type_rid] = mapping; + } + + 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 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 bool TryGetGenericParameterRanges (IGenericParameterProvider owner, out Range [] ranges) + { + return GenericParameters.TryGetValue (owner.MetadataToken, out ranges); + } + + public bool TryGetCustomAttributeRanges (ICustomAttributeProvider owner, out Range [] ranges) + { + return CustomAttributes.TryGetValue (owner.MetadataToken, out ranges); + } + + public bool TryGetSecurityDeclarationRanges (ISecurityDeclarationProvider owner, out Range [] ranges) + { + return SecurityDeclarations.TryGetValue (owner.MetadataToken, out ranges); + } + + public bool TryGetGenericConstraintMapping (GenericParameter generic_parameter, out Collection> mapping) + { + return GenericConstraints.TryGetValue (generic_parameter.token.RID, out mapping); + } + + public void SetGenericConstraintMapping (uint gp_rid, Collection> mapping) + { + GenericConstraints [gp_rid] = mapping; + } + + public bool TryGetOverrideMapping (MethodDefinition method, out Collection mapping) + { + return Overrides.TryGetValue (method.token.RID, out mapping); + } + + public void SetOverrideMapping (uint rid, Collection mapping) + { + Overrides [rid] = mapping; + } + + public Document GetDocument (uint rid) + { + if (rid < 1 || rid > Documents.Length) + return null; + + return Documents [rid - 1]; + } + + public bool TryGetLocalScopes (MethodDefinition method, out Collection> scopes) + { + return LocalScopes.TryGetValue (method.MetadataToken.RID, out scopes); + } + + public void SetLocalScopes (uint method_rid, Collection> records) + { + LocalScopes [method_rid] = records; + } + + public ImportDebugInformation GetImportScope (uint rid) + { + if (rid < 1 || rid > ImportScopes.Length) + return null; + + return ImportScopes [rid - 1]; + } + + public bool TryGetStateMachineKickOffMethod (MethodDefinition method, out uint rid) + { + return StateMachineMethods.TryGetValue (method.MetadataToken.RID, out 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/cecil-master/Mono.Cecil/MethodAttributes.cs b/cecil-master/Mono.Cecil/MethodAttributes.cs new file mode 100644 index 000000000..1bd7d1288 --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodAttributes.cs @@ -0,0 +1,48 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/MethodCallingConvention.cs b/cecil-master/Mono.Cecil/MethodCallingConvention.cs new file mode 100644 index 000000000..80f3e9773 --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodCallingConvention.cs @@ -0,0 +1,23 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum MethodCallingConvention : byte { + Default = 0x0, + C = 0x1, + StdCall = 0x2, + ThisCall = 0x3, + FastCall = 0x4, + VarArg = 0x5, + Unmanaged = 0x9, + Generic = 0x10, + } +} diff --git a/cecil-master/Mono.Cecil/MethodDefinition.cs b/cecil-master/Mono.Cecil/MethodDefinition.cs new file mode 100644 index 000000000..b4e43766b --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodDefinition.cs @@ -0,0 +1,564 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Threading; +using Mono.Cecil.Cil; +using Mono.Collections.Generic; + +using RVA = System.UInt32; + +namespace Mono.Cecil { + + public sealed class MethodDefinition : MethodReference, IMemberDefinition, ISecurityDeclarationProvider, ICustomDebugInformationProvider { + + 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; + internal MethodDebugInformation debug_info; + internal Collection custom_infos; + + public override string Name { + get { return base.Name; } + set { + if (IsWindowsRuntimeProjection && value != base.Name) + throw new InvalidOperationException (); + + base.Name = value; + } + } + + public MethodAttributes Attributes { + get { return (MethodAttributes) attributes; } + set { + if (IsWindowsRuntimeProjection && (ushort) value != attributes) + throw new InvalidOperationException (); + + attributes = (ushort) value; + } + } + + public MethodImplAttributes ImplAttributes { + get { return (MethodImplAttributes) impl_attributes; } + set { + if (IsWindowsRuntimeProjection && (ushort) value != impl_attributes) + throw new InvalidOperationException (); + + 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 MethodDefinitionProjection WindowsRuntimeProjection { + get { return (MethodDefinitionProjection) projection; } + set { projection = value; } + } + + internal void ReadSemantics () + { + if (sem_attrs_ready) + return; + + var module = this.Module; + if (module == null) + return; + + if (!module.HasImage) + return; + + lock (module.SyncRoot) { + if (sem_attrs_ready) + return; + + module.Read (this, (method, reader) => reader.ReadAllSemantics (method)); + } + } + + public bool HasSecurityDeclarations { + get { + if (security_declarations != null) + return security_declarations.Count > 0; + + return this.GetHasSecurityDeclarations (Module); + } + } + + public Collection SecurityDeclarations { + get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (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 { + var local = this.body; + if (local != null) + return local; + + if (!HasBody) + return null; + + if (HasImage && rva != 0) + return Module.Read (ref body, this, (method, reader) => reader.ReadMethodBody (method)); + + Interlocked.CompareExchange (ref body, new MethodBody (this) , null); + + return body; + } + set { + var module = this.Module; + if (module == null) { + body = value; + return; + } + + // we reset Body to null in ILSpy to save memory; so we need that operation to be thread-safe + lock (module.SyncRoot) { + body = value; + if (value == null) + this.debug_info = null; + } + } + } + + public MethodDebugInformation DebugInformation { + get { + Mixin.Read (Body); + + if (debug_info == null) { + Interlocked.CompareExchange (ref debug_info, new MethodDebugInformation (this), null); + } + + return debug_info; + } + set { + debug_info = 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; + + return HasImage && Module.Read (this, (method, reader) => reader.HasOverrides (method)); + } + } + + public Collection Overrides { + get { + if (overrides != null) + return overrides; + + if (HasImage) + return Module.Read (ref overrides, this, (method, reader) => reader.ReadOverrides (method)); + + Interlocked.CompareExchange (ref overrides, new Collection (), null); + + return overrides; + } + } + + public override bool HasGenericParameters { + get { + if (generic_parameters != null) + return generic_parameters.Count > 0; + + return this.GetHasGenericParameters (Module); + } + } + + public override Collection GenericParameters { + get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); } + } + + public bool HasCustomDebugInformations { + get { + Mixin.Read (Body); + + return !custom_infos.IsNullOrEmpty (); + } + } + + public Collection CustomDebugInformations { + get { + Mixin.Read (Body); + + if (custom_infos == null) + Interlocked.CompareExchange (ref custom_infos, new Collection (), null); + + return custom_infos; + } + } + + #region MethodAttributes + + public bool IsCompilerControlled { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.CompilerControlled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.CompilerControlled, value); } + } + + public bool IsPrivate { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Private); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Private, value); } + } + + public bool IsFamilyAndAssembly { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamANDAssem); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamANDAssem, value); } + } + + public bool IsAssembly { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Assembly); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Assembly, value); } + } + + public bool IsFamily { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Family); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Family, value); } + } + + public bool IsFamilyOrAssembly { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamORAssem); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.FamORAssem, value); } + } + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.MemberAccessMask, (ushort) MethodAttributes.Public, value); } + } + + public bool IsStatic { + get { return attributes.GetAttributes ((ushort) MethodAttributes.Static); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Static, value); } + } + + public bool IsFinal { + get { return attributes.GetAttributes ((ushort) MethodAttributes.Final); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Final, value); } + } + + public bool IsVirtual { + get { return attributes.GetAttributes ((ushort) MethodAttributes.Virtual); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Virtual, value); } + } + + public bool IsHideBySig { + get { return attributes.GetAttributes ((ushort) MethodAttributes.HideBySig); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.HideBySig, value); } + } + + public bool IsReuseSlot { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.ReuseSlot); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.ReuseSlot, value); } + } + + public bool IsNewSlot { + get { return attributes.GetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.NewSlot); } + set { attributes = attributes.SetMaskedAttributes ((ushort) MethodAttributes.VtableLayoutMask, (ushort) MethodAttributes.NewSlot, value); } + } + + public bool IsCheckAccessOnOverride { + get { return attributes.GetAttributes ((ushort) MethodAttributes.CheckAccessOnOverride); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.CheckAccessOnOverride, value); } + } + + public bool IsAbstract { + get { return attributes.GetAttributes ((ushort) MethodAttributes.Abstract); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.Abstract, value); } + } + + public bool IsSpecialName { + get { return attributes.GetAttributes ((ushort) MethodAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.SpecialName, value); } + } + + public bool IsPInvokeImpl { + get { return attributes.GetAttributes ((ushort) MethodAttributes.PInvokeImpl); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.PInvokeImpl, value); } + } + + public bool IsUnmanagedExport { + get { return attributes.GetAttributes ((ushort) MethodAttributes.UnmanagedExport); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.UnmanagedExport, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((ushort) MethodAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.RTSpecialName, value); } + } + + public bool HasSecurity { + get { return attributes.GetAttributes ((ushort) MethodAttributes.HasSecurity); } + set { attributes = attributes.SetAttributes ((ushort) MethodAttributes.HasSecurity, value); } + } + + #endregion + + #region MethodImplAttributes + + public bool IsIL { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.IL, value); } + } + + public bool IsNative { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Native); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Native, value); } + } + + public bool IsRuntime { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Runtime); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.CodeTypeMask, (ushort) MethodImplAttributes.Runtime, value); } + } + + public bool IsUnmanaged { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Unmanaged); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Unmanaged, value); } + } + + public bool IsManaged { + get { return impl_attributes.GetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Managed); } + set { impl_attributes = impl_attributes.SetMaskedAttributes ((ushort) MethodImplAttributes.ManagedMask, (ushort) MethodImplAttributes.Managed, value); } + } + + public bool IsForwardRef { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.ForwardRef); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.ForwardRef, value); } + } + + public bool IsPreserveSig { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.PreserveSig); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.PreserveSig, value); } + } + + public bool IsInternalCall { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.InternalCall); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.InternalCall, value); } + } + + public bool IsSynchronized { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.Synchronized); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.Synchronized, value); } + } + + public bool NoInlining { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.NoInlining); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.NoInlining, value); } + } + + public bool NoOptimization { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.NoOptimization); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.NoOptimization, value); } + } + + public bool AggressiveInlining { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.AggressiveInlining); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.AggressiveInlining, value); } + } + + public bool AggressiveOptimization { + get { return impl_attributes.GetAttributes ((ushort) MethodImplAttributes.AggressiveOptimization); } + set { impl_attributes = impl_attributes.SetAttributes ((ushort) MethodImplAttributes.AggressiveOptimization, value); } + } + + #endregion + + #region MethodSemanticsAttributes + + public bool IsSetter { + get { return this.GetSemantics (MethodSemanticsAttributes.Setter); } + set { this.SetSemantics (MethodSemanticsAttributes.Setter, value); } + } + + public bool IsGetter { + get { return this.GetSemantics (MethodSemanticsAttributes.Getter); } + set { this.SetSemantics (MethodSemanticsAttributes.Getter, value); } + } + + public bool IsOther { + get { return this.GetSemantics (MethodSemanticsAttributes.Other); } + set { this.SetSemantics (MethodSemanticsAttributes.Other, value); } + } + + public bool IsAddOn { + get { return this.GetSemantics (MethodSemanticsAttributes.AddOn); } + set { this.SetSemantics (MethodSemanticsAttributes.AddOn, value); } + } + + public bool IsRemoveOn { + get { return this.GetSemantics (MethodSemanticsAttributes.RemoveOn); } + set { this.SetSemantics (MethodSemanticsAttributes.RemoveOn, value); } + } + + public bool IsFire { + get { return this.GetSemantics (MethodSemanticsAttributes.Fire); } + set { this.SetSemantics (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 (this 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 (this MethodBody self, int index) + { + var variables = self.Variables; + + if (index < 0 || index >= variables.size) + return null; + + return variables [index]; + } + + public static bool GetSemantics (this MethodDefinition self, MethodSemanticsAttributes semantics) + { + return (self.SemanticsAttributes & semantics) != 0; + } + + public static void SetSemantics (this MethodDefinition self, MethodSemanticsAttributes semantics, bool value) + { + if (value) + self.SemanticsAttributes |= semantics; + else + self.SemanticsAttributes &= ~semantics; + } + } +} diff --git a/cecil-master/Mono.Cecil/MethodImplAttributes.cs b/cecil-master/Mono.Cecil/MethodImplAttributes.cs new file mode 100644 index 000000000..23e857bc2 --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodImplAttributes.cs @@ -0,0 +1,37 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 + + ForwardRef = 0x0010, // The method is declared, but its implementation is provided elsewhere. + PreserveSig = 0x0080, // The method signature is exported exactly as declared. + InternalCall = 0x1000, // The call is internal, that is, it calls a method that's implemented within the CLR. + Synchronized = 0x0020, // The method can be executed by only one thread at a time. + // Static methods lock on the type, whereas instance methods lock on the instance. + NoOptimization = 0x0040, // The method is not optimized by the just-in-time (JIT) compiler or by native codegen. + NoInlining = 0x0008, // The method cannot be inlined. + AggressiveInlining = 0x0100, // The method should be inlined if possible. + AggressiveOptimization = 0x0200, // The method contains code that should always be optimized by the JIT compiler. + } +} diff --git a/cecil-master/Mono.Cecil/MethodReference.cs b/cecil-master/Mono.Cecil/MethodReference.cs new file mode 100644 index 000000000..cc4391543 --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodReference.cs @@ -0,0 +1,202 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Text; +using System.Threading; +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 !parameters.IsNullOrEmpty (); } + } + + public virtual Collection Parameters { + get { + if (parameters == null) + Interlocked.CompareExchange (ref parameters, new ParameterDefinitionCollection (this), null); + + 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 !generic_parameters.IsNullOrEmpty (); } + } + + public virtual Collection GenericParameters { + get { + if (generic_parameters == null) + Interlocked.CompareExchange (ref generic_parameters, new GenericParameterCollection (this), null); + + return generic_parameters; + } + } + + 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 ()); + this.MethodSignatureFullName (builder); + return builder.ToString (); + } + } + + public virtual bool IsGenericInstance { + get { return false; } + } + + public override bool ContainsGenericParameter { + get { + if (this.ReturnType.ContainsGenericParameter || base.ContainsGenericParameter) + return true; + + if (!HasParameters) + return false; + + 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) + { + Mixin.CheckType (returnType, Mixin.Argument.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) + { + Mixin.CheckType (declaringType, Mixin.Argument.declaringType); + + this.DeclaringType = declaringType; + } + + public virtual MethodReference GetElementMethod () + { + return this; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new 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 (this IMethodSignature self) + { + return self.CallingConvention == MethodCallingConvention.VarArg; + } + + public static int GetSentinelPosition (this 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/cecil-master/Mono.Cecil/MethodReferenceComparer.cs b/cecil-master/Mono.Cecil/MethodReferenceComparer.cs new file mode 100644 index 000000000..3bf2c6eca --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodReferenceComparer.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; + +namespace Mono.Cecil { + internal sealed class MethodReferenceComparer : EqualityComparer { + // Initialized lazily for each thread + [ThreadStatic] + static List xComparisonStack = null; + + [ThreadStatic] + static List yComparisonStack = null; + + public override bool Equals (MethodReference x, MethodReference y) + { + return AreEqual (x, y); + } + + public override int GetHashCode (MethodReference obj) + { + return GetHashCodeFor (obj); + } + + public static bool AreEqual (MethodReference x, MethodReference y) + { + if (ReferenceEquals (x, y)) + return true; + + if (x.HasThis != y.HasThis) + return false; + + if (x.HasParameters != y.HasParameters) + return false; + + if (x.HasGenericParameters != y.HasGenericParameters) + return false; + + if (x.Parameters.Count != y.Parameters.Count) + return false; + + if (x.Name != y.Name) + return false; + + if (!TypeReferenceEqualityComparer.AreEqual (x.DeclaringType, y.DeclaringType)) + return false; + + var xGeneric = x as GenericInstanceMethod; + var yGeneric = y as GenericInstanceMethod; + if (xGeneric != null || yGeneric != null) { + if (xGeneric == null || yGeneric == null) + return false; + + if (xGeneric.GenericArguments.Count != yGeneric.GenericArguments.Count) + return false; + + for (int i = 0; i < xGeneric.GenericArguments.Count; i++) + if (!TypeReferenceEqualityComparer.AreEqual (xGeneric.GenericArguments[i], yGeneric.GenericArguments[i])) + return false; + } + + var xResolved = x.Resolve (); + var yResolved = y.Resolve (); + + if (xResolved != yResolved) + return false; + + if (xResolved == null) + { + // We couldn't resolve either method. In order for them to be equal, their parameter types _must_ match. But wait, there's a twist! + // There exists a situation where we might get into a recursive state: parameter type comparison might lead to comparing the same + // methods again if the parameter types are generic parameters whose owners are these methods. We guard against these by using a + // thread static list of all our comparisons carried out in the stack so far, and if we're in progress of comparing them already, + // we'll just say that they match. + + if (xComparisonStack == null) + xComparisonStack = new List (); + + if (yComparisonStack == null) + yComparisonStack = new List (); + + for (int i = 0; i < xComparisonStack.Count; i++) { + if (xComparisonStack[i] == x && yComparisonStack[i] == y) + return true; + } + + xComparisonStack.Add (x); + + try { + yComparisonStack.Add (y); + + try { + for (int i = 0; i < x.Parameters.Count; i++) { + if (!TypeReferenceEqualityComparer.AreEqual (x.Parameters[i].ParameterType, y.Parameters[i].ParameterType)) + return false; + } + } finally { + yComparisonStack.RemoveAt (yComparisonStack.Count - 1); + } + } finally { + xComparisonStack.RemoveAt (xComparisonStack.Count - 1); + } + } + + return true; + } + + public static bool AreSignaturesEqual (MethodReference x, MethodReference y, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact) + { + if (x.HasThis != y.HasThis) + return false; + + if (x.Parameters.Count != y.Parameters.Count) + return false; + + if (x.GenericParameters.Count != y.GenericParameters.Count) + return false; + + for (var i = 0; i < x.Parameters.Count; i++) + if (!TypeReferenceEqualityComparer.AreEqual (x.Parameters[i].ParameterType, y.Parameters[i].ParameterType, comparisonMode)) + return false; + + if (!TypeReferenceEqualityComparer.AreEqual (x.ReturnType, y.ReturnType, comparisonMode)) + return false; + + return true; + } + + public static int GetHashCodeFor (MethodReference obj) + { + // a very good prime number + const int hashCodeMultiplier = 486187739; + + var genericInstanceMethod = obj as GenericInstanceMethod; + if (genericInstanceMethod != null) { + var hashCode = GetHashCodeFor (genericInstanceMethod.ElementMethod); + for (var i = 0; i < genericInstanceMethod.GenericArguments.Count; i++) + hashCode = hashCode * hashCodeMultiplier + TypeReferenceEqualityComparer.GetHashCodeFor (genericInstanceMethod.GenericArguments[i]); + return hashCode; + } + + return TypeReferenceEqualityComparer.GetHashCodeFor (obj.DeclaringType) * hashCodeMultiplier + obj.Name.GetHashCode (); + } + } +} diff --git a/cecil-master/Mono.Cecil/MethodReturnType.cs b/cecil-master/Mono.Cecil/MethodReturnType.cs new file mode 100644 index 000000000..71a78de1b --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodReturnType.cs @@ -0,0 +1,98 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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) + Interlocked.CompareExchange (ref parameter, new ParameterDefinition (return_type, method), null); + + 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 string Name { + get { return Parameter.Name; } + set { Parameter.Name = 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/cecil-master/Mono.Cecil/MethodSemanticsAttributes.cs b/cecil-master/Mono.Cecil/MethodSemanticsAttributes.cs new file mode 100644 index 000000000..274dfd044 --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodSemanticsAttributes.cs @@ -0,0 +1,25 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/MethodSpecification.cs b/cecil-master/Mono.Cecil/MethodSpecification.cs new file mode 100644 index 000000000..040be6ed5 --- /dev/null +++ b/cecil-master/Mono.Cecil/MethodSpecification.cs @@ -0,0 +1,84 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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; } + } + + public override bool ContainsGenericParameter { + get { return method.ContainsGenericParameter; } + } + + internal MethodSpecification (MethodReference method) + { + Mixin.CheckMethod (method); + + this.method = method; + this.token = new MetadataToken (TokenType.MethodSpec); + } + + public sealed override MethodReference GetElementMethod () + { + return method.GetElementMethod (); + } + } +} diff --git a/cecil-master/Mono.Cecil/Modifiers.cs b/cecil-master/Mono.Cecil/Modifiers.cs new file mode 100644 index 000000000..9c50f0e4e --- /dev/null +++ b/cecil-master/Mono.Cecil/Modifiers.cs @@ -0,0 +1,112 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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; } + } + + public override bool ContainsGenericParameter { + get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; } + } + + public OptionalModifierType (TypeReference modifierType, TypeReference type) + : base (type) + { + if (modifierType == null) + throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ()); + Mixin.CheckType (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; } + } + + public override bool ContainsGenericParameter { + get { return modifier_type.ContainsGenericParameter || base.ContainsGenericParameter; } + } + + public RequiredModifierType (TypeReference modifierType, TypeReference type) + : base (type) + { + if (modifierType == null) + throw new ArgumentNullException (Mixin.Argument.modifierType.ToString ()); + Mixin.CheckType (type); + this.modifier_type = modifierType; + this.etype = MD.ElementType.CModReqD; + } + + } +} diff --git a/cecil-master/Mono.Cecil/ModuleDefinition.cs b/cecil-master/Mono.Cecil/ModuleDefinition.cs new file mode 100644 index 000000000..b17f7c466 --- /dev/null +++ b/cecil-master/Mono.Cecil/ModuleDefinition.cs @@ -0,0 +1,1353 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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; + internal IAssemblyResolver assembly_resolver; + internal IMetadataResolver metadata_resolver; + internal IMetadataImporterProvider metadata_importer_provider; + internal IReflectionImporterProvider reflection_importer_provider; + Stream symbol_stream; + ISymbolReaderProvider symbol_reader_provider; + bool read_symbols; + bool throw_symbols_mismatch; + bool projections; + bool in_memory; + bool read_write; + + public ReadingMode ReadingMode { + get { return reading_mode; } + set { reading_mode = value; } + } + + public bool InMemory { + get { return in_memory; } + set { in_memory = value; } + } + + public IAssemblyResolver AssemblyResolver { + get { return assembly_resolver; } + set { assembly_resolver = value; } + } + + public IMetadataResolver MetadataResolver { + get { return metadata_resolver; } + set { metadata_resolver = value; } + } + + public IMetadataImporterProvider MetadataImporterProvider { + get { return metadata_importer_provider; } + set { metadata_importer_provider = value; } + } + + public IReflectionImporterProvider ReflectionImporterProvider { + get { return reflection_importer_provider; } + set { reflection_importer_provider = 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 bool ThrowIfSymbolsAreNotMatching { + get { return throw_symbols_mismatch; } + set { throw_symbols_mismatch = value; } + } + + public bool ReadWrite { + get { return read_write; } + set { read_write = value; } + } + + public bool ApplyWindowsRuntimeProjections { + get { return projections; } + set { projections = value; } + } + + public ReaderParameters () + : this (ReadingMode.Deferred) + { + } + + public ReaderParameters (ReadingMode readingMode) + { + this.reading_mode = readingMode; + this.throw_symbols_mismatch = true; + } + } + + public sealed class ModuleParameters { + + ModuleKind kind; + TargetRuntime runtime; + uint? timestamp; + TargetArchitecture architecture; + IAssemblyResolver assembly_resolver; + IMetadataResolver metadata_resolver; + IMetadataImporterProvider metadata_importer_provider; + IReflectionImporterProvider reflection_importer_provider; + + public ModuleKind Kind { + get { return kind; } + set { kind = value; } + } + + public TargetRuntime Runtime { + get { return runtime; } + set { runtime = value; } + } + + public uint? Timestamp { + get { return timestamp; } + set { timestamp = value; } + } + + public TargetArchitecture Architecture { + get { return architecture; } + set { architecture = value; } + } + + public IAssemblyResolver AssemblyResolver { + get { return assembly_resolver; } + set { assembly_resolver = value; } + } + + public IMetadataResolver MetadataResolver { + get { return metadata_resolver; } + set { metadata_resolver = value; } + } + + public IMetadataImporterProvider MetadataImporterProvider { + get { return metadata_importer_provider; } + set { metadata_importer_provider = value; } + } + + public IReflectionImporterProvider ReflectionImporterProvider { + get { return reflection_importer_provider; } + set { reflection_importer_provider = value; } + } + + public ModuleParameters () + { + this.kind = ModuleKind.Dll; + this.Runtime = GetCurrentRuntime (); + this.architecture = TargetArchitecture.I386; + } + + static TargetRuntime GetCurrentRuntime () + { + return typeof (object).Assembly.ImageRuntimeVersion.ParseRuntime (); + } + } + + public sealed class WriterParameters { + + uint? timestamp; + Stream symbol_stream; + ISymbolWriterProvider symbol_writer_provider; + bool write_symbols; + byte [] key_blob; + string key_container; + SR.StrongNameKeyPair key_pair; + + public uint? Timestamp { + get { return timestamp; } + set { timestamp = value; } + } + + public Stream SymbolStream { + get { return symbol_stream; } + set { symbol_stream = value; } + } + + public ISymbolWriterProvider SymbolWriterProvider { + get { return symbol_writer_provider; } + set { symbol_writer_provider = value; } + } + + public bool WriteSymbols { + get { return write_symbols; } + set { write_symbols = value; } + } + + public bool HasStrongNameKey { + get { return key_pair != null || key_blob != null || key_container != null; } + } + + public byte [] StrongNameKeyBlob { + get { return key_blob; } + set { key_blob = value; } + } + + public string StrongNameKeyContainer { + get { return key_container; } + set { key_container = value; } + } + + public SR.StrongNameKeyPair StrongNameKeyPair { + get { return key_pair; } + set { key_pair = value; } + } + + public bool DeterministicMvid { get; set; } + } + + public sealed class ModuleDefinition : ModuleReference, ICustomAttributeProvider, ICustomDebugInformationProvider, IDisposable { + + internal Image Image; + internal MetadataSystem MetadataSystem; + internal ReadingMode ReadingMode; + internal ISymbolReaderProvider SymbolReaderProvider; + + internal ISymbolReader symbol_reader; + internal Disposable assembly_resolver; + internal IMetadataResolver metadata_resolver; + internal TypeSystem type_system; + internal readonly MetadataReader reader; + readonly string file_name; + + internal string runtime_version; + internal ModuleKind kind; + WindowsRuntimeProjections projections; + MetadataKind metadata_kind; + TargetRuntime runtime; + TargetArchitecture architecture; + ModuleAttributes attributes; + ModuleCharacteristics characteristics; + Guid mvid; + + internal ushort linker_version = 8; + internal ushort subsystem_major = 4; + internal ushort subsystem_minor = 0; + internal uint timestamp; + + internal AssemblyDefinition assembly; + MethodDefinition entry_point; + bool entry_point_set; + + internal IReflectionImporter reflection_importer; + internal IMetadataImporter metadata_importer; + + Collection custom_attributes; + Collection references; + Collection modules; + Collection resources; + Collection exported_types; + TypeDefinitionCollection types; + + internal Collection custom_infos; + + internal MetadataBuilder metadata_builder; + + public bool IsMain { + get { return kind != ModuleKind.NetModule; } + } + + public ModuleKind Kind { + get { return kind; } + set { kind = value; } + } + + public MetadataKind MetadataKind { + get { return metadata_kind; } + set { metadata_kind = value; } + } + + internal WindowsRuntimeProjections Projections { + get { + if (projections == null) + Interlocked.CompareExchange (ref projections, new WindowsRuntimeProjections (this), null); + + return projections; + } + } + + public TargetRuntime Runtime { + get { return runtime; } + set { + runtime = value; + runtime_version = runtime.RuntimeVersionString (); + } + } + + public string RuntimeVersion { + get { return runtime_version; } + set { + runtime_version = value; + runtime = runtime_version.ParseRuntime (); + } + } + + 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; } + } + + [Obsolete ("Use FileName")] + public string FullyQualifiedName { + get { return file_name; } + } + + public string FileName { + get { return file_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; } + } + + internal IReflectionImporter ReflectionImporter { + get { + if (reflection_importer == null) + Interlocked.CompareExchange (ref reflection_importer, new DefaultReflectionImporter (this), null); + + return reflection_importer; + } + } + + internal IMetadataImporter MetadataImporter { + get { + if (metadata_importer == null) + Interlocked.CompareExchange (ref metadata_importer, new DefaultMetadataImporter (this), null); + + return metadata_importer; + } + } + + public IAssemblyResolver AssemblyResolver { + get { + if (assembly_resolver.value == null) { + lock (module_lock) { + assembly_resolver = Disposable.Owned (new DefaultAssemblyResolver () as IAssemblyResolver); + } + } + + return assembly_resolver.value; + } + } + + public IMetadataResolver MetadataResolver { + get { + if (metadata_resolver == null) + Interlocked.CompareExchange (ref metadata_resolver, new MetadataResolver (this.AssemblyResolver), null); + + return metadata_resolver; + } + } + + public TypeSystem TypeSystem { + get { + if (type_system == null) + Interlocked.CompareExchange (ref type_system, TypeSystem.CreateTypeSystem (this), null); + + 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 ()); + + Interlocked.CompareExchange (ref references, new Collection (), null); + return references; + } + } + + 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 ()); + + Interlocked.CompareExchange (ref modules, new Collection (), null); + return modules; + } + } + + 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 ()); + + Interlocked.CompareExchange (ref resources, new Collection (), null); + return resources; + } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (this); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (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 ()); + + Interlocked.CompareExchange (ref types, new TypeDefinitionCollection (this), null); + return types; + } + } + + 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 ()); + + Interlocked.CompareExchange (ref exported_types, new Collection (), null); + return exported_types; + } + } + + public MethodDefinition EntryPoint { + get { + if (entry_point_set) + return entry_point; + + if (HasImage) + Read (ref entry_point, this, (_, reader) => reader.ReadEntryPoint ()); + else + entry_point = null; + + entry_point_set = true; + return entry_point; + } + set { + entry_point = value; + entry_point_set = true; + } + } + + public bool HasCustomDebugInformations { + get { + return custom_infos != null && custom_infos.Count > 0; + } + } + + public Collection CustomDebugInformations { + get { + if (custom_infos == null) + Interlocked.CompareExchange (ref custom_infos, new Collection (), null); + + return custom_infos; + } + } + + 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.RuntimeVersion = image.RuntimeVersion; + this.architecture = image.Architecture; + this.attributes = image.Attributes; + this.characteristics = image.DllCharacteristics; + this.linker_version = image.LinkerVersion; + this.subsystem_major = image.SubSystemMajor; + this.subsystem_minor = image.SubSystemMinor; + this.file_name = image.FileName; + this.timestamp = image.Timestamp; + + this.reader = new MetadataReader (this); + } + + public void Dispose () + { + if (Image != null) + Image.Dispose (); + + if (symbol_reader != null) + symbol_reader.Dispose (); + + if (assembly_resolver.value != null) + assembly_resolver.Dispose (); + } + + public bool HasTypeReference (string fullName) + { + return HasTypeReference (string.Empty, fullName); + } + + public bool HasTypeReference (string scope, string fullName) + { + Mixin.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) + { + Mixin.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 IEnumerable GetCustomAttributes () + { + if (!HasImage) + return Empty.Array; + + return Read (this, (_, reader) => reader.GetCustomAttributes ()); + } + + public TypeReference GetType (string fullName, bool runtimeName) + { + return runtimeName + ? TypeParser.ParseType (this, fullName, typeDefinitionOnly: true) + : GetType (fullName); + } + + public TypeDefinition GetType (string fullName) + { + Mixin.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; + } + } + + 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 = type.GetNestedType (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); + } + + static void CheckContext (IGenericParameterProvider context, ModuleDefinition module) + { + if (context == null) + return; + + if (context.Module != module) + throw new ArgumentException (); + } + + [Obsolete ("Use ImportReference", error: false)] + public TypeReference Import (Type type) + { + return ImportReference (type, null); + } + + public TypeReference ImportReference (Type type) + { + return ImportReference (type, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public TypeReference Import (Type type, IGenericParameterProvider context) + { + return ImportReference (type, context); + } + + public TypeReference ImportReference (Type type, IGenericParameterProvider context) + { + Mixin.CheckType (type); + CheckContext (context, this); + + return ReflectionImporter.ImportReference (type, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public FieldReference Import (SR.FieldInfo field) + { + return ImportReference (field, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public FieldReference Import (SR.FieldInfo field, IGenericParameterProvider context) + { + return ImportReference (field, context); + } + + public FieldReference ImportReference (SR.FieldInfo field) + { + return ImportReference (field, null); + } + + public FieldReference ImportReference (SR.FieldInfo field, IGenericParameterProvider context) + { + Mixin.CheckField (field); + CheckContext (context, this); + + return ReflectionImporter.ImportReference (field, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public MethodReference Import (SR.MethodBase method) + { + return ImportReference (method, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public MethodReference Import (SR.MethodBase method, IGenericParameterProvider context) + { + return ImportReference (method, context); + } + + public MethodReference ImportReference (SR.MethodBase method) + { + return ImportReference (method, null); + } + + public MethodReference ImportReference (SR.MethodBase method, IGenericParameterProvider context) + { + Mixin.CheckMethod (method); + CheckContext (context, this); + + return ReflectionImporter.ImportReference (method, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public TypeReference Import (TypeReference type) + { + return ImportReference (type, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public TypeReference Import (TypeReference type, IGenericParameterProvider context) + { + return ImportReference (type, context); + } + + public TypeReference ImportReference (TypeReference type) + { + return ImportReference (type, null); + } + + public TypeReference ImportReference (TypeReference type, IGenericParameterProvider context) + { + Mixin.CheckType (type); + + if (type.Module == this) + return type; + + CheckContext (context, this); + + return MetadataImporter.ImportReference (type, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public FieldReference Import (FieldReference field) + { + return ImportReference (field, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public FieldReference Import (FieldReference field, IGenericParameterProvider context) + { + return ImportReference (field, context); + } + + public FieldReference ImportReference (FieldReference field) + { + return ImportReference (field, null); + } + + public FieldReference ImportReference (FieldReference field, IGenericParameterProvider context) + { + Mixin.CheckField (field); + + if (field.Module == this) + return field; + + CheckContext (context, this); + + return MetadataImporter.ImportReference (field, context); + } + + [Obsolete ("Use ImportReference", error: false)] + public MethodReference Import (MethodReference method) + { + return ImportReference (method, null); + } + + [Obsolete ("Use ImportReference", error: false)] + public MethodReference Import (MethodReference method, IGenericParameterProvider context) + { + return ImportReference (method, context); + } + + public MethodReference ImportReference (MethodReference method) + { + return ImportReference (method, null); + } + + public MethodReference ImportReference (MethodReference method, IGenericParameterProvider context) + { + Mixin.CheckMethod (method); + + if (method.Module == this) + return method; + + CheckContext (context, this); + + return MetadataImporter.ImportReference (method, context); + } + + public IMetadataTokenProvider LookupToken (int token) + { + return LookupToken (new MetadataToken ((uint) token)); + } + + public IMetadataTokenProvider LookupToken (MetadataToken token) + { + return Read (token, (t, reader) => reader.LookupToken (t)); + } + + public void ImmediateRead () + { + if (!HasImage) + return; + ReadingMode = ReadingMode.Immediate; + var moduleReader = new ImmediateModuleReader (Image); + moduleReader.ReadModule (this, resolve_attributes: true); + } + + readonly object module_lock = new object(); + + internal object SyncRoot { + get { return module_lock; } + } + + internal void Read (TItem item, Action read) + { + lock (module_lock) { + var position = reader.position; + var context = reader.context; + + read (item, reader); + + reader.position = position; + reader.context = context; + } + } + + 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.DebugHeader != null; } + } + + public ImageDebugHeader GetDebugHeader () + { + return Image.DebugHeader ?? new ImageDebugHeader (); + } + + public static ModuleDefinition CreateModule (string name, ModuleKind kind) + { + return CreateModule (name, new ModuleParameters { Kind = kind }); + } + + public static ModuleDefinition CreateModule (string name, ModuleParameters parameters) + { + Mixin.CheckName (name); + Mixin.CheckParameters (parameters); + + var module = new ModuleDefinition { + Name = name, + kind = parameters.Kind, + timestamp = parameters.Timestamp ?? Mixin.GetTimestamp (), + Runtime = parameters.Runtime, + architecture = parameters.Architecture, + mvid = Guid.NewGuid (), + Attributes = ModuleAttributes.ILOnly, + Characteristics = (ModuleCharacteristics) 0x8540, + }; + + if (parameters.AssemblyResolver != null) + module.assembly_resolver = Disposable.NotOwned (parameters.AssemblyResolver); + + if (parameters.MetadataResolver != null) + module.metadata_resolver = parameters.MetadataResolver; + + if (parameters.MetadataImporterProvider != null) + module.metadata_importer = parameters.MetadataImporterProvider.GetMetadataImporter (module); + + if (parameters.ReflectionImporterProvider != null) + module.reflection_importer = parameters.ReflectionImporterProvider.GetReflectionImporter (module); + + if (parameters.Kind != ModuleKind.NetModule) { + var assembly = new AssemblyDefinition (); + module.assembly = assembly; + module.assembly.Name = CreateAssemblyName (name); + assembly.main_module = module; + } + + module.Types.Add (new TypeDefinition (string.Empty, "", TypeAttributes.NotPublic)); + + return module; + } + + static AssemblyNameDefinition CreateAssemblyName (string name) + { + if (name.EndsWith (".dll") || name.EndsWith (".exe")) + name = name.Substring (0, name.Length - 4); + + return new AssemblyNameDefinition (name, Mixin.ZeroVersion); + } + + public void ReadSymbols () + { + if (string.IsNullOrEmpty (file_name)) + throw new InvalidOperationException (); + + var provider = new DefaultSymbolReaderProvider (throwIfNoSymbol: true); + ReadSymbols (provider.GetSymbolReader (this, file_name), throwIfSymbolsAreNotMaching: true); + } + + public void ReadSymbols (ISymbolReader reader) + { + ReadSymbols(reader, throwIfSymbolsAreNotMaching: true); + } + + public void ReadSymbols (ISymbolReader reader, bool throwIfSymbolsAreNotMaching) + { + if (reader == null) + throw new ArgumentNullException ("reader"); + + symbol_reader = reader; + + if (!symbol_reader.ProcessDebugHeader (GetDebugHeader ())) { + symbol_reader = null; + + if (throwIfSymbolsAreNotMaching) + throw new SymbolsNotMatchingException ("Symbols were found but are not matching the assembly"); + + return; + } + + if (HasImage && ReadingMode == ReadingMode.Immediate) { + var immediate_reader = new ImmediateModuleReader (Image); + immediate_reader.ReadSymbols (this); + } + } + + public static ModuleDefinition ReadModule (string fileName) + { + return ReadModule (fileName, new ReaderParameters (ReadingMode.Deferred)); + } + + public static ModuleDefinition ReadModule (string fileName, ReaderParameters parameters) + { + var stream = GetFileStream (fileName, FileMode.Open, parameters.ReadWrite ? FileAccess.ReadWrite : FileAccess.Read, FileShare.Read); + + if (parameters.InMemory) { + var memory = new MemoryStream (stream.CanSeek ? (int) stream.Length : 0); + using (stream) + stream.CopyTo (memory); + + memory.Position = 0; + stream = memory; + } + + try { + return ReadModule (Disposable.Owned (stream), fileName, parameters); + } catch (Exception) { + stream.Dispose (); + throw; + } + } + + static Stream GetFileStream (string fileName, FileMode mode, FileAccess access, FileShare share) + { + Mixin.CheckFileName (fileName); + + return new FileStream (fileName, mode, access, share); + } + + public static ModuleDefinition ReadModule (Stream stream) + { + return ReadModule (stream, new ReaderParameters (ReadingMode.Deferred)); + } + + public static ModuleDefinition ReadModule (Stream stream, ReaderParameters parameters) + { + Mixin.CheckStream (stream); + Mixin.CheckReadSeek (stream); + + return ReadModule (Disposable.NotOwned (stream), stream.GetFileName (), parameters); + } + + static ModuleDefinition ReadModule (Disposable stream, string fileName, ReaderParameters parameters) + { + Mixin.CheckParameters (parameters); + + return ModuleReader.CreateModule ( + ImageReader.ReadImage (stream, fileName), + parameters); + } + + public void Write (string fileName) + { + Write (fileName, new WriterParameters ()); + } + + public void Write (string fileName, WriterParameters parameters) + { + Mixin.CheckParameters (parameters); + var file = GetFileStream (fileName, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); + ModuleWriter.WriteModule (this, Disposable.Owned (file), parameters); + } + + public void Write () + { + Write (new WriterParameters ()); + } + + public void Write (WriterParameters parameters) + { + if (!HasImage) + throw new InvalidOperationException (); + + Write (Image.Stream.value, parameters); + } + + public void Write (Stream stream) + { + Write (stream, new WriterParameters ()); + } + + public void Write (Stream stream, WriterParameters parameters) + { + Mixin.CheckStream (stream); + Mixin.CheckWriteSeek (stream); + Mixin.CheckParameters (parameters); + + ModuleWriter.WriteModule (this, Disposable.NotOwned (stream), parameters); + } + } + + static partial class Mixin { + + public enum Argument { + name, + fileName, + fullName, + stream, + type, + method, + field, + parameters, + module, + modifierType, + eventType, + fieldType, + declaringType, + returnType, + propertyType, + interfaceType, + constraintType, + } + + public static void CheckName (object name) + { + if (name == null) + throw new ArgumentNullException (Argument.name.ToString ()); + } + + public static void CheckName (string name) + { + if (string.IsNullOrEmpty (name)) + throw new ArgumentNullOrEmptyException (Argument.name.ToString ()); + } + + public static void CheckFileName (string fileName) + { + if (string.IsNullOrEmpty (fileName)) + throw new ArgumentNullOrEmptyException (Argument.fileName.ToString ()); + } + + public static void CheckFullName (string fullName) + { + if (string.IsNullOrEmpty (fullName)) + throw new ArgumentNullOrEmptyException (Argument.fullName.ToString ()); + } + + public static void CheckStream (object stream) + { + if (stream == null) + throw new ArgumentNullException (Argument.stream.ToString ()); + } + + public static void CheckWriteSeek (Stream stream) + { + if (!stream.CanWrite || !stream.CanSeek) + throw new ArgumentException ("Stream must be writable and seekable."); + } + + public static void CheckReadSeek (Stream stream) + { + if (!stream.CanRead || !stream.CanSeek) + throw new ArgumentException ("Stream must be readable and seekable."); + } + + public static void CheckType (object type) + { + if (type == null) + throw new ArgumentNullException (Argument.type.ToString ()); + } + + public static void CheckType (object type, Argument argument) + { + if (type == null) + throw new ArgumentNullException (argument.ToString ()); + } + + public static void CheckField (object field) + { + if (field == null) + throw new ArgumentNullException (Argument.field.ToString ()); + } + + public static void CheckMethod (object method) + { + if (method == null) + throw new ArgumentNullException (Argument.method.ToString ()); + } + + public static void CheckParameters (object parameters) + { + if (parameters == null) + throw new ArgumentNullException (Argument.parameters.ToString ()); + } + + public static uint GetTimestamp () + { + return (uint) DateTime.UtcNow.Subtract (new DateTime (1970, 1, 1)).TotalSeconds; + } + + public static bool HasImage (this ModuleDefinition self) + { + return self != null && self.HasImage; + } + + public static string GetFileName (this Stream self) + { + var file_stream = self as FileStream; + if (file_stream == null) + return string.Empty; + + return Path.GetFullPath (file_stream.Name); + } + + public static TargetRuntime ParseRuntime (this string self) + { + if (string.IsNullOrEmpty (self)) + return TargetRuntime.Net_4_0; + + 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; + } + } + + public static string RuntimeVersionString (this TargetRuntime runtime) + { + switch (runtime) { + case TargetRuntime.Net_1_0: + return "v1.0.3705"; + case TargetRuntime.Net_1_1: + return "v1.1.4322"; + case TargetRuntime.Net_2_0: + return "v2.0.50727"; + case TargetRuntime.Net_4_0: + default: + return "v4.0.30319"; + } + } + + public static bool IsWindowsMetadata (this ModuleDefinition module) + { + return module.MetadataKind != MetadataKind.Ecma335; + } + + public static byte [] ReadAll (this Stream self) + { + int read; + var memory = new MemoryStream ((int) self.Length); + var buffer = new byte [1024]; + + while ((read = self.Read (buffer, 0, buffer.Length)) != 0) + memory.Write (buffer, 0, read); + + return memory.ToArray (); + } + + public static void Read (object o) + { + } + } +} diff --git a/cecil-master/Mono.Cecil/ModuleKind.cs b/cecil-master/Mono.Cecil/ModuleKind.cs new file mode 100644 index 000000000..2cd084db5 --- /dev/null +++ b/cecil-master/Mono.Cecil/ModuleKind.cs @@ -0,0 +1,55 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil { + + public enum ModuleKind { + Dll, + Console, + Windows, + NetModule, + } + + public enum MetadataKind { + Ecma335, + WindowsMetadata, + ManagedWindowsMetadata, + } + + public enum TargetArchitecture { + I386 = 0x014c, + AMD64 = 0x8664, + IA64 = 0x0200, + ARM = 0x01c0, + ARMv7 = 0x01c4, + ARM64 = 0xaa64, + } + + [Flags] + public enum ModuleAttributes { + ILOnly = 1, + Required32Bit = 2, + ILLibrary = 4, + StrongNameSigned = 8, + Preferred32Bit = 0x00020000, + } + + [Flags] + public enum ModuleCharacteristics { + HighEntropyVA = 0x0020, + DynamicBase = 0x0040, + NoSEH = 0x0400, + NXCompat = 0x0100, + AppContainer = 0x1000, + TerminalServerAware = 0x8000, + } +} diff --git a/cecil-master/Mono.Cecil/ModuleReference.cs b/cecil-master/Mono.Cecil/ModuleReference.cs new file mode 100644 index 000000000..43c618f4c --- /dev/null +++ b/cecil-master/Mono.Cecil/ModuleReference.cs @@ -0,0 +1,49 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/NativeType.cs b/cecil-master/Mono.Cecil/NativeType.cs new file mode 100644 index 000000000..02174db6f --- /dev/null +++ b/cecil-master/Mono.Cecil/NativeType.cs @@ -0,0 +1,55 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/PInvokeAttributes.cs b/cecil-master/Mono.Cecil/PInvokeAttributes.cs new file mode 100644 index 000000000..11e96d20d --- /dev/null +++ b/cecil-master/Mono.Cecil/PInvokeAttributes.cs @@ -0,0 +1,44 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/PInvokeInfo.cs b/cecil-master/Mono.Cecil/PInvokeInfo.cs new file mode 100644 index 000000000..8efc01081 --- /dev/null +++ b/cecil-master/Mono.Cecil/PInvokeInfo.cs @@ -0,0 +1,120 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 attributes.GetAttributes ((ushort) PInvokeAttributes.NoMangle); } + set { attributes = attributes.SetAttributes ((ushort) PInvokeAttributes.NoMangle, value); } + } + + public bool IsCharSetNotSpec { + get { return attributes.GetMaskedAttributes((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetNotSpec, value); } + } + + public bool IsCharSetAnsi { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAnsi, value); } + } + + public bool IsCharSetUnicode { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetUnicode, value); } + } + + public bool IsCharSetAuto { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CharSetMask, (ushort) PInvokeAttributes.CharSetAuto, value); } + } + + public bool SupportsLastError { + get { return attributes.GetAttributes ((ushort) PInvokeAttributes.SupportsLastError); } + set { attributes = attributes.SetAttributes ((ushort) PInvokeAttributes.SupportsLastError, value); } + } + + public bool IsCallConvWinapi { + get { return attributes.GetMaskedAttributes((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvWinapi, value); } + } + + public bool IsCallConvCdecl { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvCdecl, value); } + } + + public bool IsCallConvStdCall { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvStdCall, value); } + } + + public bool IsCallConvThiscall { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvThiscall, value); } + } + + public bool IsCallConvFastcall { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.CallConvMask, (ushort) PInvokeAttributes.CallConvFastcall, value); } + } + + public bool IsBestFitEnabled { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitEnabled, value); } + } + + public bool IsBestFitDisabled { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.BestFitMask, (ushort) PInvokeAttributes.BestFitDisabled, value); } + } + + public bool IsThrowOnUnmappableCharEnabled { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled); } + set { attributes = attributes.SetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharEnabled, value); } + } + + public bool IsThrowOnUnmappableCharDisabled { + get { return attributes.GetMaskedAttributes ((ushort) PInvokeAttributes.ThrowOnUnmappableCharMask, (ushort) PInvokeAttributes.ThrowOnUnmappableCharDisabled); } + set { attributes = attributes.SetMaskedAttributes ((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/cecil-master/Mono.Cecil/ParameterAttributes.cs b/cecil-master/Mono.Cecil/ParameterAttributes.cs new file mode 100644 index 000000000..9a0e35e07 --- /dev/null +++ b/cecil-master/Mono.Cecil/ParameterAttributes.cs @@ -0,0 +1,27 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/ParameterDefinition.cs b/cecil-master/Mono.Cecil/ParameterDefinition.cs new file mode 100644 index 000000000..59bafe2c8 --- /dev/null +++ b/cecil-master/Mono.Cecil/ParameterDefinition.cs @@ -0,0 +1,146 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 method.HasImplicitThis () ? index + 1 : index; + } + } + + public bool HasConstant { + get { + this.ResolveConstant (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 this.GetHasCustomAttributes (parameter_type.Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, parameter_type.Module)); } + } + + public bool HasMarshalInfo { + get { + if (marshal_info != null) + return true; + + return this.GetHasMarshalInfo (parameter_type.Module); + } + } + + public MarshalInfo MarshalInfo { + get { return marshal_info ?? (this.GetMarshalInfo (ref marshal_info, parameter_type.Module)); } + set { marshal_info = value; } + } + + #region ParameterAttributes + + public bool IsIn { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.In); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.In, value); } + } + + public bool IsOut { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.Out); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Out, value); } + } + + public bool IsLcid { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.Lcid); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Lcid, value); } + } + + public bool IsReturnValue { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.Retval); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Retval, value); } + } + + public bool IsOptional { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.Optional); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.Optional, value); } + } + + public bool HasDefault { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.HasDefault); } + set { attributes = attributes.SetAttributes ((ushort) ParameterAttributes.HasDefault, value); } + } + + public bool HasFieldMarshal { + get { return attributes.GetAttributes ((ushort) ParameterAttributes.HasFieldMarshal); } + set { attributes = attributes.SetAttributes ((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/cecil-master/Mono.Cecil/ParameterDefinitionCollection.cs b/cecil-master/Mono.Cecil/ParameterDefinitionCollection.cs new file mode 100644 index 000000000..1a9764c50 --- /dev/null +++ b/cecil-master/Mono.Cecil/ParameterDefinitionCollection.cs @@ -0,0 +1,62 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/ParameterReference.cs b/cecil-master/Mono.Cecil/ParameterReference.cs new file mode 100644 index 000000000..4670a562b --- /dev/null +++ b/cecil-master/Mono.Cecil/ParameterReference.cs @@ -0,0 +1,57 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/PinnedType.cs b/cecil-master/Mono.Cecil/PinnedType.cs new file mode 100644 index 000000000..fa89af514 --- /dev/null +++ b/cecil-master/Mono.Cecil/PinnedType.cs @@ -0,0 +1,35 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/PointerType.cs b/cecil-master/Mono.Cecil/PointerType.cs new file mode 100644 index 000000000..4b21164a3 --- /dev/null +++ b/cecil-master/Mono.Cecil/PointerType.cs @@ -0,0 +1,43 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/PropertyAttributes.cs b/cecil-master/Mono.Cecil/PropertyAttributes.cs new file mode 100644 index 000000000..4d1ce8c8b --- /dev/null +++ b/cecil-master/Mono.Cecil/PropertyAttributes.cs @@ -0,0 +1,23 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/PropertyDefinition.cs b/cecil-master/Mono.Cecil/PropertyDefinition.cs new file mode 100644 index 000000000..06b7bfdf7 --- /dev/null +++ b/cecil-master/Mono.Cecil/PropertyDefinition.cs @@ -0,0 +1,245 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System.Text; +using System.Threading; +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 this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (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 !other_methods.IsNullOrEmpty (); + } + } + + public Collection OtherMethods { + get { + if (other_methods != null) + return other_methods; + + InitializeMethods (); + + if (other_methods != null) + return other_methods; + + Interlocked.CompareExchange (ref other_methods, new Collection (), null); + return other_methods; + } + } + + 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 { + this.ResolveConstant (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 attributes.GetAttributes ((ushort) PropertyAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.SpecialName, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((ushort) PropertyAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((ushort) PropertyAttributes.RTSpecialName, value); } + } + + public bool HasDefault { + get { return attributes.GetAttributes ((ushort) PropertyAttributes.HasDefault); } + set { attributes = attributes.SetAttributes ((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; + if (module == null) + return; + + lock (module.SyncRoot) { + if (get_method != null || set_method != null) + return; + + if (!module.HasImage ()) + return; + + module.Read (this, (property, reader) => reader.ReadMethods (property)); + } + } + + public override PropertyDefinition Resolve () + { + return this; + } + } +} diff --git a/cecil-master/Mono.Cecil/PropertyReference.cs b/cecil-master/Mono.Cecil/PropertyReference.cs new file mode 100644 index 000000000..2434d0f8c --- /dev/null +++ b/cecil-master/Mono.Cecil/PropertyReference.cs @@ -0,0 +1,45 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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) + { + Mixin.CheckType (propertyType, Mixin.Argument.propertyType); + + property_type = propertyType; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new abstract PropertyDefinition Resolve (); + } +} diff --git a/cecil-master/Mono.Cecil/ReferenceType.cs b/cecil-master/Mono.Cecil/ReferenceType.cs new file mode 100644 index 000000000..67686fbff --- /dev/null +++ b/cecil-master/Mono.Cecil/ReferenceType.cs @@ -0,0 +1,43 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/Resource.cs b/cecil-master/Mono.Cecil/Resource.cs new file mode 100644 index 000000000..cee75f9e4 --- /dev/null +++ b/cecil-master/Mono.Cecil/Resource.cs @@ -0,0 +1,58 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 attributes.GetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Public, value); } + } + + public bool IsPrivate { + get { return attributes.GetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private); } + set { attributes = attributes.SetMaskedAttributes ((uint) ManifestResourceAttributes.VisibilityMask, (uint) ManifestResourceAttributes.Private, value); } + } + + #endregion + + internal Resource (string name, ManifestResourceAttributes attributes) + { + this.name = name; + this.attributes = (uint) attributes; + } + } +} diff --git a/cecil-master/Mono.Cecil/SecurityDeclaration.cs b/cecil-master/Mono.Cecil/SecurityDeclaration.cs new file mode 100644 index 000000000..99a66ee10 --- /dev/null +++ b/cecil-master/Mono.Cecil/SecurityDeclaration.cs @@ -0,0 +1,201 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Diagnostics; +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; } + } + + [DebuggerDisplay ("{AttributeType}")] + 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 !fields.IsNullOrEmpty (); } + } + + public Collection Fields { + get { + if (fields == null) + Interlocked.CompareExchange (ref fields, new Collection (), null); + + return fields; + } + } + + public bool HasProperties { + get { return !properties.IsNullOrEmpty (); } + } + + public Collection Properties { + get { + if (properties == null) + Interlocked.CompareExchange (ref properties, new Collection (), null); + + return properties; + } + } + + public SecurityAttribute (TypeReference attributeType) + { + this.attribute_type = attributeType; + } + + bool ICustomAttribute.HasConstructorArguments { + get { return false; } + } + + Collection ICustomAttribute.ConstructorArguments { + get { throw new NotSupportedException (); } + } + } + + 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 !security_attributes.IsNullOrEmpty (); + } + } + + public Collection SecurityAttributes { + get { + Resolve (); + + if (security_attributes == null) + Interlocked.CompareExchange (ref security_attributes, new Collection (), null); + + return security_attributes; + } + } + + 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 module.Read (ref blob, this, (declaration, reader) => reader.ReadSecurityDeclarationBlob (declaration.signature)); + } + + void Resolve () + { + if (resolved || !HasImage) + return; + + lock (module.SyncRoot) { + + if (resolved) + return; + + module.Read (this, (declaration, reader) => reader.ReadSecurityDeclarationSignature (declaration)); + resolved = true; + } + } + } + + static partial class Mixin { + + public static bool GetHasSecurityDeclarations ( + this ISecurityDeclarationProvider self, + ModuleDefinition module) + { + return module.HasImage () && module.Read (self, (provider, reader) => reader.HasSecurityDeclarations (provider)); + } + + public static Collection GetSecurityDeclarations ( + this ISecurityDeclarationProvider self, + ref Collection variable, + ModuleDefinition module) + { + if (module.HasImage) + return module.Read (ref variable, self, (provider, reader) => reader.ReadSecurityDeclarations (provider)); + + Interlocked.CompareExchange (ref variable, new Collection (), null); + return variable; + } + } +} diff --git a/cecil-master/Mono.Cecil/SentinelType.cs b/cecil-master/Mono.Cecil/SentinelType.cs new file mode 100644 index 000000000..b603cc3c0 --- /dev/null +++ b/cecil-master/Mono.Cecil/SentinelType.cs @@ -0,0 +1,35 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/TargetRuntime.cs b/cecil-master/Mono.Cecil/TargetRuntime.cs new file mode 100644 index 000000000..c1cd0269f --- /dev/null +++ b/cecil-master/Mono.Cecil/TargetRuntime.cs @@ -0,0 +1,19 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +namespace Mono.Cecil { + + public enum TargetRuntime { + Net_1_0, + Net_1_1, + Net_2_0, + Net_4_0, + } +} diff --git a/cecil-master/Mono.Cecil/Treatments.cs b/cecil-master/Mono.Cecil/Treatments.cs new file mode 100644 index 000000000..21c176842 --- /dev/null +++ b/cecil-master/Mono.Cecil/Treatments.cs @@ -0,0 +1,61 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono.Cecil { + + [Flags] + enum TypeDefinitionTreatment { + None = 0x0, + + KindMask = 0xf, + NormalType = 0x1, + NormalAttribute = 0x2, + UnmangleWindowsRuntimeName = 0x3, + PrefixWindowsRuntimeName = 0x4, + RedirectToClrType = 0x5, + RedirectToClrAttribute = 0x6, + RedirectImplementedMethods = 0x7, + + Abstract = 0x10, + Internal = 0x20, + } + + enum TypeReferenceTreatment { + None = 0x0, + SystemDelegate = 0x1, + SystemAttribute = 0x2, + UseProjectionInfo = 0x3, + } + + [Flags] + enum MethodDefinitionTreatment { + None = 0x0, + Abstract = 0x2, + Private = 0x4, + Public = 0x8, + Runtime = 0x10, + InternalCall = 0x20, + } + + enum FieldDefinitionTreatment { + None = 0x0, + Public = 0x1, + } + + enum CustomAttributeValueTreatment { + None = 0x0, + AllowSingle = 0x1, + AllowMultiple = 0x2, + VersionAttribute = 0x3, + DeprecatedAttribute = 0x4, + } +} diff --git a/cecil-master/Mono.Cecil/TypeAttributes.cs b/cecil-master/Mono.Cecil/TypeAttributes.cs new file mode 100644 index 000000000..92a71aca4 --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeAttributes.cs @@ -0,0 +1,63 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/TypeComparisonMode.cs b/cecil-master/Mono.Cecil/TypeComparisonMode.cs new file mode 100644 index 000000000..f69d98a99 --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeComparisonMode.cs @@ -0,0 +1,12 @@ +namespace Mono.Cecil +{ + internal enum TypeComparisonMode { + Exact, + SignatureOnly, + + /// + /// Types can be in different assemblies, as long as the module, assembly, and type names match they will be considered equal + /// + SignatureOnlyLoose + } +} diff --git a/cecil-master/Mono.Cecil/TypeDefinition.cs b/cecil-master/Mono.Cecil/TypeDefinition.cs new file mode 100644 index 000000000..872e4c253 --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeDefinition.cs @@ -0,0 +1,620 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Threading; +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; + + InterfaceImplementationCollection 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 { + if (IsWindowsRuntimeProjection && (ushort) value != attributes) + throw new InvalidOperationException (); + + attributes = (uint) value; + } + } + + public TypeReference BaseType { + get { return base_type; } + set { base_type = value; } + } + + public override string Name { + get { return base.Name; } + set { + if (IsWindowsRuntimeProjection && value != base.Name) + throw new InvalidOperationException (); + + base.Name = value; + } + } + + void ResolveLayout () + { + if (!HasImage) { + packing_size = Mixin.NoDataMarker; + class_size = Mixin.NoDataMarker; + return; + } + + lock (Module.SyncRoot) { + if (packing_size != Mixin.NotResolvedMarker || class_size != Mixin.NotResolvedMarker) + 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; + + return HasImage && Module.Read (this, (type, reader) => reader.HasInterfaces (type)); + } + } + + public Collection Interfaces { + get { + if (interfaces != null) + return interfaces; + + if (HasImage) + return Module.Read (ref interfaces, this, (type, reader) => reader.ReadInterfaces (type)); + + Interlocked.CompareExchange (ref interfaces, new InterfaceImplementationCollection (this), null); + return interfaces; + } + } + + public bool HasNestedTypes { + get { + if (nested_types != null) + return nested_types.Count > 0; + + return HasImage && Module.Read (this, (type, reader) => reader.HasNestedTypes (type)); + } + } + + 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)); + + Interlocked.CompareExchange (ref nested_types, new MemberDefinitionCollection (this), null); + return nested_types; + } + } + + public bool HasMethods { + get { + if (methods != null) + return methods.Count > 0; + + return HasImage && methods_range.Length > 0; + } + } + + public Collection Methods { + get { + if (methods != null) + return methods; + + if (HasImage) + return Module.Read (ref methods, this, (type, reader) => reader.ReadMethods (type)); + + Interlocked.CompareExchange (ref methods, new MemberDefinitionCollection (this) , null); + return methods; + } + } + + public bool HasFields { + get { + if (fields != null) + return fields.Count > 0; + + return HasImage && fields_range.Length > 0; + } + } + + public Collection Fields { + get { + if (fields != null) + return fields; + + if (HasImage) + return Module.Read (ref fields, this, (type, reader) => reader.ReadFields (type)); + + Interlocked.CompareExchange (ref fields, new MemberDefinitionCollection (this), null); + return fields; + } + } + + public bool HasEvents { + get { + if (events != null) + return events.Count > 0; + + return HasImage && Module.Read (this, (type, reader) => reader.HasEvents (type)); + } + } + + public Collection Events { + get { + if (events != null) + return events; + + if (HasImage) + return Module.Read (ref events, this, (type, reader) => reader.ReadEvents (type)); + + Interlocked.CompareExchange (ref events, new MemberDefinitionCollection (this), null); + return events; + } + } + + public bool HasProperties { + get { + if (properties != null) + return properties.Count > 0; + + return HasImage && Module.Read (this, (type, reader) => reader.HasProperties (type)); + } + } + + public Collection Properties { + get { + if (properties != null) + return properties; + + if (HasImage) + return Module.Read (ref properties, this, (type, reader) => reader.ReadProperties (type)); + + Interlocked.CompareExchange (ref properties, new MemberDefinitionCollection (this), null); + return properties; + } + } + + public bool HasSecurityDeclarations { + get { + if (security_declarations != null) + return security_declarations.Count > 0; + + return this.GetHasSecurityDeclarations (Module); + } + } + + public Collection SecurityDeclarations { + get { return security_declarations ?? (this.GetSecurityDeclarations (ref security_declarations, Module)); } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + return this.GetHasCustomAttributes (Module); + } + } + + public Collection CustomAttributes { + get { return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, Module)); } + } + + public override bool HasGenericParameters { + get { + if (generic_parameters != null) + return generic_parameters.Count > 0; + + return this.GetHasGenericParameters (Module); + } + } + + public override Collection GenericParameters { + get { return generic_parameters ?? (this.GetGenericParameters (ref generic_parameters, Module)); } + } + + #region TypeAttributes + + public bool IsNotPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NotPublic, value); } + } + + public bool IsPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.Public, value); } + } + + public bool IsNestedPublic { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPublic, value); } + } + + public bool IsNestedPrivate { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedPrivate, value); } + } + + public bool IsNestedFamily { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamily, value); } + } + + public bool IsNestedAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedAssembly, value); } + } + + public bool IsNestedFamilyAndAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamANDAssem, value); } + } + + public bool IsNestedFamilyOrAssembly { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.VisibilityMask, (uint) TypeAttributes.NestedFamORAssem, value); } + } + + public bool IsAutoLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.AutoLayout, value); } + } + + public bool IsSequentialLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.SequentialLayout, value); } + } + + public bool IsExplicitLayout { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.LayoutMask, (uint) TypeAttributes.ExplicitLayout, value); } + } + + public bool IsClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Class, value); } + } + + public bool IsInterface { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.ClassSemanticMask, (uint) TypeAttributes.Interface, value); } + } + + public bool IsAbstract { + get { return attributes.GetAttributes ((uint) TypeAttributes.Abstract); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Abstract, value); } + } + + public bool IsSealed { + get { return attributes.GetAttributes ((uint) TypeAttributes.Sealed); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Sealed, value); } + } + + public bool IsSpecialName { + get { return attributes.GetAttributes ((uint) TypeAttributes.SpecialName); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.SpecialName, value); } + } + + public bool IsImport { + get { return attributes.GetAttributes ((uint) TypeAttributes.Import); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Import, value); } + } + + public bool IsSerializable { + get { return attributes.GetAttributes ((uint) TypeAttributes.Serializable); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.Serializable, value); } + } + + public bool IsWindowsRuntime { + get { return attributes.GetAttributes ((uint) TypeAttributes.WindowsRuntime); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.WindowsRuntime, value); } + } + + public bool IsAnsiClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AnsiClass, value); } + } + + public bool IsUnicodeClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.UnicodeClass, value); } + } + + public bool IsAutoClass { + get { return attributes.GetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass); } + set { attributes = attributes.SetMaskedAttributes ((uint) TypeAttributes.StringFormatMask, (uint) TypeAttributes.AutoClass, value); } + } + + public bool IsBeforeFieldInit { + get { return attributes.GetAttributes ((uint) TypeAttributes.BeforeFieldInit); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.BeforeFieldInit, value); } + } + + public bool IsRuntimeSpecialName { + get { return attributes.GetAttributes ((uint) TypeAttributes.RTSpecialName); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.RTSpecialName, value); } + } + + public bool HasSecurity { + get { return attributes.GetAttributes ((uint) TypeAttributes.HasSecurity); } + set { attributes = attributes.SetAttributes ((uint) TypeAttributes.HasSecurity, value); } + } + + #endregion + + public bool IsEnum { + get { return base_type != null && base_type.IsTypeOf ("System", "Enum"); } + } + + public override bool IsValueType { + get { + if (base_type == null) + return false; + + return base_type.IsTypeOf ("System", "Enum") || (base_type.IsTypeOf ("System", "ValueType") && !this.IsTypeOf ("System", "Enum")); + } + set { + throw new NotSupportedException (); + } + } + + public override bool IsPrimitive { + get { + ElementType primitive_etype; + return MetadataSystem.TryGetPrimitiveElementType (this, out primitive_etype) && primitive_etype.IsPrimitive (); + } + } + + 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; } + } + + internal new TypeDefinitionProjection WindowsRuntimeProjection { + get { return (TypeDefinitionProjection) projection; } + set { projection = 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; + } + + protected override void ClearFullName () + { + base.ClearFullName (); + + if (!HasNestedTypes) + return; + + var nested_types = this.NestedTypes; + + for (int i = 0; i < nested_types.Count; i++) + nested_types [i].ClearFullName (); + } + + public override TypeDefinition Resolve () + { + return this; + } + } + + public sealed class InterfaceImplementation : ICustomAttributeProvider + { + internal TypeDefinition type; + internal MetadataToken token; + + TypeReference interface_type; + Collection custom_attributes; + + public TypeReference InterfaceType { + get { return interface_type; } + set { interface_type = value; } + } + + public bool HasCustomAttributes { + get { + if (custom_attributes != null) + return custom_attributes.Count > 0; + + if (type == null) + return false; + + return this.GetHasCustomAttributes (type.Module); + } + } + + public Collection CustomAttributes { + get { + if (type == null) { + if (custom_attributes == null) + Interlocked.CompareExchange (ref custom_attributes, new Collection (), null); + return custom_attributes; + } + + return custom_attributes ?? (this.GetCustomAttributes (ref custom_attributes, type.Module)); + } + } + + public MetadataToken MetadataToken { + get { return token; } + set { token = value; } + } + + internal InterfaceImplementation (TypeReference interfaceType, MetadataToken token) + { + this.interface_type = interfaceType; + this.token = token; + } + + public InterfaceImplementation (TypeReference interfaceType) + { + Mixin.CheckType (interfaceType, Mixin.Argument.interfaceType); + + this.interface_type = interfaceType; + this.token = new MetadataToken (TokenType.InterfaceImpl); + } + } + + class InterfaceImplementationCollection : Collection + { + readonly TypeDefinition type; + + internal InterfaceImplementationCollection (TypeDefinition type) + { + this.type = type; + } + + internal InterfaceImplementationCollection (TypeDefinition type, int length) + : base (length) + { + this.type = type; + } + + protected override void OnAdd (InterfaceImplementation item, int index) + { + item.type = type; + } + + protected override void OnInsert (InterfaceImplementation item, int index) + { + item.type = type; + } + + protected override void OnSet (InterfaceImplementation item, int index) + { + item.type = type; + } + + protected override void OnRemove (InterfaceImplementation item, int index) + { + item.type = null; + } + } + + static partial class Mixin { + + public static TypeReference GetEnumUnderlyingType (this 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 (this TypeDefinition self, string fullname) + { + 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.TypeFullName () == fullname) + return nested_type; + } + + return null; + } + } +} diff --git a/cecil-master/Mono.Cecil/TypeDefinitionCollection.cs b/cecil-master/Mono.Cecil/TypeDefinitionCollection.cs new file mode 100644 index 000000000..95e39b9a6 --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeDefinitionCollection.cs @@ -0,0 +1,100 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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/cecil-master/Mono.Cecil/TypeParser.cs b/cecil-master/Mono.Cecil/TypeParser.cs new file mode 100644 index 000000000..a4ebd6954 --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeParser.cs @@ -0,0 +1,532 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 (!nested_names.IsNullOrEmpty ()) { + 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) + { + return int.TryParse (value, out result); + } + + static void TryAddArity (string name, ref int arity) + { + int type_arity; + if (!TryGetArity (name, out type_arity)) + return; + + arity += type_arity; + } + + string ParsePart () + { + var part = new StringBuilder (); + while (position < length && !IsDelimiter (fullname [position])) { + if (fullname [position] == '\\') + position++; + + part.Append (fullname [position++]); + } + + return part.ToString (); + } + + 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) + { + array = array.Add (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, bool typeDefinitionOnly = false) + { + if (string.IsNullOrEmpty (fullname)) + return null; + + var parser = new TypeParser (fullname); + return GetTypeReference (module, parser.ParseType (true), typeDefinitionOnly); + } + + static TypeReference GetTypeReference (ModuleDefinition module, Type type_info, bool type_def_only) + { + TypeReference type; + if (!TryGetDefinition (module, type_info, out type)) { + if (type_def_only) + return null; + + 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 (specs.IsNullOrEmpty ()) + 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 (generic_arguments.IsNullOrEmpty ()) + return type; + + var instance = new GenericInstanceType (type, generic_arguments.Length); + var instance_arguments = instance.GenericArguments; + + for (int i = 0; i < generic_arguments.Length; i++) + instance_arguments.Add (GetTypeReference (type.Module, generic_arguments [i], false)); + + 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 (nested_names.IsNullOrEmpty ()) + 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.CoreLibrary; + + AssemblyNameReference match; + var reference = AssemblyNameReference.Parse (type_info.assembly); + + return module.TryGetAssemblyNameReference (reference, out match) + ? match + : reference; + } + + 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 (!nested_names.IsNullOrEmpty ()) { + for (int i = 0; i < nested_names.Length; i++) { + var nested_type = typedef.GetNestedType (nested_names [i]); + if (nested_type == null) + return false; + + typedef = nested_type; + } + } + + 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, bool top_level = true) + { + if (type == null) + return null; + + var name = new StringBuilder (); + AppendType (type, name, true, top_level); + return name.ToString (); + } + + static void AppendNamePart (string part, StringBuilder name) + { + foreach (var c in part) { + if (IsDelimiter (c)) + name.Append ('\\'); + + name.Append (c); + } + } + + static void AppendType (TypeReference type, StringBuilder name, bool fq_name, bool top_level) + { + var element_type = type.GetElementType (); + + var declaring_type = element_type.DeclaringType; + if (declaring_type != null) { + AppendType (declaring_type, name, false, top_level); + name.Append ('+'); + } + + var @namespace = type.Namespace; + if (!string.IsNullOrEmpty (@namespace)) { + AppendNamePart (@namespace, name); + name.Append ('.'); + } + + AppendNamePart (element_type.Name, name); + + if (!fq_name) + return; + + if (type.IsTypeSpecification ()) + 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 (type.ElementType.IsTypeSpecification ()) + 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/cecil-master/Mono.Cecil/TypeReference.cs b/cecil-master/Mono.Cecil/TypeReference.cs new file mode 100644 index 000000000..701f83b8f --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeReference.cs @@ -0,0 +1,352 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Threading; +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 { + if (IsWindowsRuntimeProjection && value != base.Name) + throw new InvalidOperationException ("Projected type reference name can't be changed."); + base.Name = value; + ClearFullName (); + } + } + + public virtual string Namespace { + get { return @namespace; } + set { + if (IsWindowsRuntimeProjection && value != @namespace) + throw new InvalidOperationException ("Projected type reference namespace can't be changed."); + @namespace = value; + ClearFullName (); + } + } + + 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; + } + } + + internal TypeReferenceProjection WindowsRuntimeProjection { + get { return (TypeReferenceProjection) projection; } + set { projection = value; } + } + + 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 !generic_parameters.IsNullOrEmpty (); } + } + + public virtual Collection GenericParameters { + get { + if (generic_parameters == null) + Interlocked.CompareExchange (ref generic_parameters, new GenericParameterCollection (this), null); + + return generic_parameters; + } + } + + public virtual IMetadataScope Scope { + get { + var declaring_type = this.DeclaringType; + if (declaring_type != null) + return declaring_type.Scope; + + return scope; + } + set { + var declaring_type = this.DeclaringType; + if (declaring_type != null) { + if (IsWindowsRuntimeProjection && value != declaring_type.Scope) + throw new InvalidOperationException ("Projected type scope can't be changed."); + declaring_type.Scope = value; + return; + } + + if (IsWindowsRuntimeProjection && value != scope) + throw new InvalidOperationException ("Projected type scope can't be changed."); + scope = value; + } + } + + public bool IsNested { + get { return this.DeclaringType != null; } + } + + public override TypeReference DeclaringType { + get { return base.DeclaringType; } + set { + if (IsWindowsRuntimeProjection && value != base.DeclaringType) + throw new InvalidOperationException ("Projected type declaring type can't be changed."); + base.DeclaringType = value; + ClearFullName (); + } + } + + public override string FullName { + get { + if (fullname != null) + return fullname; + + var new_fullname = this.TypeFullName (); + + if (IsNested) + new_fullname = DeclaringType.FullName + "/" + new_fullname; + Interlocked.CompareExchange (ref fullname, new_fullname, null); + return fullname; + } + } + + 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 etype.IsPrimitive (); } + } + + 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; + } + + protected virtual void ClearFullName () + { + this.fullname = null; + } + + public virtual TypeReference GetElementType () + { + return this; + } + + protected override IMemberDefinition ResolveDefinition () + { + return this.Resolve (); + } + + public new 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 (this 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 string TypeFullName (this TypeReference self) + { + return string.IsNullOrEmpty (self.Namespace) + ? self.Name + : self.Namespace + '.' + self.Name; + } + + public static bool IsTypeOf (this TypeReference self, string @namespace, string name) + { + return self.Name == name + && self.Namespace == @namespace; + } + + public static bool IsTypeSpecification (this 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 (this TypeReference self) + { + var type = self.Resolve (); + if (type == null) + throw new ResolutionException (self); + + return type; + } + } +} diff --git a/cecil-master/Mono.Cecil/TypeReferenceEqualityComparer.cs b/cecil-master/Mono.Cecil/TypeReferenceEqualityComparer.cs new file mode 100644 index 000000000..29c2ee2e9 --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeReferenceEqualityComparer.cs @@ -0,0 +1,253 @@ +using System; +using System.Collections.Generic; + +namespace Mono.Cecil { + internal sealed class TypeReferenceEqualityComparer : EqualityComparer { + public override bool Equals (TypeReference x, TypeReference y) + { + return AreEqual (x, y); + } + + public override int GetHashCode (TypeReference obj) + { + return GetHashCodeFor (obj); + } + + public static bool AreEqual (TypeReference a, TypeReference b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact) + { + if (ReferenceEquals (a, b)) + return true; + + if (a == null || b == null) + return false; + + var aMetadataType = a.MetadataType; + var bMetadataType = b.MetadataType; + + if (aMetadataType == MetadataType.GenericInstance || bMetadataType == MetadataType.GenericInstance) { + if (aMetadataType != bMetadataType) + return false; + + return AreEqual ((GenericInstanceType)a, (GenericInstanceType)b, comparisonMode); + } + + if (aMetadataType == MetadataType.Array || bMetadataType == MetadataType.Array) { + if (aMetadataType != bMetadataType) + return false; + + var a1 = (ArrayType)a; + var b1 = (ArrayType)b; + if (a1.Rank != b1.Rank) + return false; + + return AreEqual (a1.ElementType, b1.ElementType, comparisonMode); + } + + if (aMetadataType == MetadataType.Var || bMetadataType == MetadataType.Var) { + if (aMetadataType != bMetadataType) + return false; + + return AreEqual ((GenericParameter)a, (GenericParameter)b, comparisonMode); + } + + if (aMetadataType == MetadataType.MVar || bMetadataType == MetadataType.MVar) { + if (aMetadataType != bMetadataType) + return false; + + return AreEqual ((GenericParameter)a, (GenericParameter)b, comparisonMode); + } + + if (aMetadataType == MetadataType.ByReference || bMetadataType == MetadataType.ByReference) { + if (aMetadataType != bMetadataType) + return false; + + return AreEqual (((ByReferenceType)a).ElementType, ((ByReferenceType)b).ElementType, comparisonMode); + } + + if (aMetadataType == MetadataType.Pointer || bMetadataType == MetadataType.Pointer) { + if (aMetadataType != bMetadataType) + return false; + + return AreEqual (((PointerType)a).ElementType, ((PointerType)b).ElementType, comparisonMode); + } + + if (aMetadataType == MetadataType.RequiredModifier || bMetadataType == MetadataType.RequiredModifier) { + if (aMetadataType != bMetadataType) + return false; + + var a1 = (RequiredModifierType)a; + var b1 = (RequiredModifierType)b; + + return AreEqual (a1.ModifierType, b1.ModifierType, comparisonMode) && AreEqual (a1.ElementType, b1.ElementType, comparisonMode); + } + + if (aMetadataType == MetadataType.OptionalModifier || bMetadataType == MetadataType.OptionalModifier) { + if (aMetadataType != bMetadataType) + return false; + + var a1 = (OptionalModifierType)a; + var b1 = (OptionalModifierType)b; + + return AreEqual (a1.ModifierType, b1.ModifierType, comparisonMode) && AreEqual (a1.ElementType, b1.ElementType, comparisonMode); + } + + if (aMetadataType == MetadataType.Pinned || bMetadataType == MetadataType.Pinned) { + if (aMetadataType != bMetadataType) + return false; + + return AreEqual (((PinnedType)a).ElementType, ((PinnedType)b).ElementType, comparisonMode); + } + + if (aMetadataType == MetadataType.Sentinel || bMetadataType == MetadataType.Sentinel) { + if (aMetadataType != bMetadataType) + return false; + + return AreEqual (((SentinelType)a).ElementType, ((SentinelType)b).ElementType, comparisonMode); + } + + if (!a.Name.Equals (b.Name) || !a.Namespace.Equals (b.Namespace)) + return false; + + var xDefinition = a.Resolve (); + var yDefinition = b.Resolve (); + + // For loose signature the types could be in different assemblies, as long as the type names match we will consider them equal + if (comparisonMode == TypeComparisonMode.SignatureOnlyLoose) { + if (xDefinition.Module.Name != yDefinition.Module.Name) + return false; + + if (xDefinition.Module.Assembly.Name.Name != yDefinition.Module.Assembly.Name.Name) + return false; + + return xDefinition.FullName == yDefinition.FullName; + } + + return xDefinition == yDefinition; + } + + static bool AreEqual (GenericParameter a, GenericParameter b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact) + { + if (ReferenceEquals (a, b)) + return true; + + if (a.Position != b.Position) + return false; + + if (a.Type != b.Type) + return false; + + var aOwnerType = a.Owner as TypeReference; + if (aOwnerType != null && AreEqual (aOwnerType, b.Owner as TypeReference, comparisonMode)) + return true; + + var aOwnerMethod = a.Owner as MethodReference; + if (aOwnerMethod != null && comparisonMode != TypeComparisonMode.SignatureOnlyLoose && MethodReferenceComparer.AreEqual (aOwnerMethod, b.Owner as MethodReference)) + return true; + + return comparisonMode == TypeComparisonMode.SignatureOnly || comparisonMode == TypeComparisonMode.SignatureOnlyLoose; + } + + static bool AreEqual (GenericInstanceType a, GenericInstanceType b, TypeComparisonMode comparisonMode = TypeComparisonMode.Exact) + { + if (ReferenceEquals (a, b)) + return true; + + var aGenericArgumentsCount = a.GenericArguments.Count; + if (aGenericArgumentsCount != b.GenericArguments.Count) + return false; + + if (!AreEqual (a.ElementType, b.ElementType, comparisonMode)) + return false; + + for (int i = 0; i < aGenericArgumentsCount; i++) + if (!AreEqual (a.GenericArguments[i], b.GenericArguments[i], comparisonMode)) + return false; + + return true; + } + + public static int GetHashCodeFor (TypeReference obj) + { + // a very good prime number + const int hashCodeMultiplier = 486187739; + // prime numbers + const int genericInstanceTypeMultiplier = 31; + const int byReferenceMultiplier = 37; + const int pointerMultiplier = 41; + const int requiredModifierMultiplier = 43; + const int optionalModifierMultiplier = 47; + const int pinnedMultiplier = 53; + const int sentinelMultiplier = 59; + + var metadataType = obj.MetadataType; + + if (metadataType == MetadataType.GenericInstance) { + var genericInstanceType = (GenericInstanceType)obj; + var hashCode = GetHashCodeFor (genericInstanceType.ElementType) * hashCodeMultiplier + genericInstanceTypeMultiplier; + for (var i = 0; i < genericInstanceType.GenericArguments.Count; i++) + hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor (genericInstanceType.GenericArguments[i]); + return hashCode; + } + + if (metadataType == MetadataType.Array) { + var arrayType = (ArrayType)obj; + return GetHashCodeFor (arrayType.ElementType) * hashCodeMultiplier + arrayType.Rank.GetHashCode (); + } + + if (metadataType == MetadataType.Var || metadataType == MetadataType.MVar) { + var genericParameter = (GenericParameter)obj; + var hashCode = genericParameter.Position.GetHashCode () * hashCodeMultiplier + ((int)metadataType).GetHashCode (); + + var ownerTypeReference = genericParameter.Owner as TypeReference; + if (ownerTypeReference != null) + return hashCode * hashCodeMultiplier + GetHashCodeFor (ownerTypeReference); + + var ownerMethodReference = genericParameter.Owner as MethodReference; + if (ownerMethodReference != null) + return hashCode * hashCodeMultiplier + MethodReferenceComparer.GetHashCodeFor (ownerMethodReference); + + throw new InvalidOperationException ("Generic parameter encountered with invalid owner"); + } + + if (metadataType == MetadataType.ByReference) { + var byReferenceType = (ByReferenceType)obj; + return GetHashCodeFor (byReferenceType.ElementType) * hashCodeMultiplier * byReferenceMultiplier; + } + + if (metadataType == MetadataType.Pointer) { + var pointerType = (PointerType)obj; + return GetHashCodeFor (pointerType.ElementType) * hashCodeMultiplier * pointerMultiplier; + } + + if (metadataType == MetadataType.RequiredModifier) { + var requiredModifierType = (RequiredModifierType)obj; + var hashCode = GetHashCodeFor (requiredModifierType.ElementType) * requiredModifierMultiplier; + hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor (requiredModifierType.ModifierType); + return hashCode; + } + + if (metadataType == MetadataType.OptionalModifier) { + var optionalModifierType = (OptionalModifierType)obj; + var hashCode = GetHashCodeFor (optionalModifierType.ElementType) * optionalModifierMultiplier; + hashCode = hashCode * hashCodeMultiplier + GetHashCodeFor (optionalModifierType.ModifierType); + return hashCode; + } + + if (metadataType == MetadataType.Pinned) { + var pinnedType = (PinnedType)obj; + return GetHashCodeFor (pinnedType.ElementType) * hashCodeMultiplier * pinnedMultiplier; + } + + if (metadataType == MetadataType.Sentinel) { + var sentinelType = (SentinelType)obj; + return GetHashCodeFor (sentinelType.ElementType) * hashCodeMultiplier * sentinelMultiplier; + } + + if (metadataType == MetadataType.FunctionPointer) { + throw new NotImplementedException ("We currently don't handle function pointer types."); + } + + return obj.Namespace.GetHashCode () * hashCodeMultiplier + obj.FullName.GetHashCode (); + } + } +} diff --git a/cecil-master/Mono.Cecil/TypeResolver.cs b/cecil-master/Mono.Cecil/TypeResolver.cs new file mode 100644 index 000000000..95b0f3a71 --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeResolver.cs @@ -0,0 +1,220 @@ +using Mono.Cecil.Cil; +using System; + +namespace Mono.Cecil { + internal sealed class TypeResolver { + private readonly IGenericInstance _typeDefinitionContext; + private readonly IGenericInstance _methodDefinitionContext; + + public static TypeResolver For (TypeReference typeReference) + { + return typeReference.IsGenericInstance ? new TypeResolver ((GenericInstanceType)typeReference) : new TypeResolver (); + } + + public static TypeResolver For (TypeReference typeReference, MethodReference methodReference) + { + return new TypeResolver (typeReference as GenericInstanceType, methodReference as GenericInstanceMethod); + } + + public TypeResolver () + { + + } + + public TypeResolver (GenericInstanceType typeDefinitionContext) + { + _typeDefinitionContext = typeDefinitionContext; + } + + public TypeResolver (GenericInstanceMethod methodDefinitionContext) + { + _methodDefinitionContext = methodDefinitionContext; + } + + public TypeResolver (GenericInstanceType typeDefinitionContext, GenericInstanceMethod methodDefinitionContext) + { + _typeDefinitionContext = typeDefinitionContext; + _methodDefinitionContext = methodDefinitionContext; + } + + public MethodReference Resolve (MethodReference method) + { + var methodReference = method; + if (IsDummy ()) + return methodReference; + + var declaringType = Resolve (method.DeclaringType); + + var genericInstanceMethod = method as GenericInstanceMethod; + if (genericInstanceMethod != null) { + methodReference = new MethodReference (method.Name, method.ReturnType, declaringType); + + foreach (var p in method.Parameters) + methodReference.Parameters.Add (new ParameterDefinition (p.Name, p.Attributes, p.ParameterType)); + + foreach (var gp in genericInstanceMethod.ElementMethod.GenericParameters) + methodReference.GenericParameters.Add (new GenericParameter (gp.Name, methodReference)); + + methodReference.HasThis = method.HasThis; + + var m = new GenericInstanceMethod (methodReference); + foreach (var ga in genericInstanceMethod.GenericArguments) { + m.GenericArguments.Add (Resolve (ga)); + } + + methodReference = m; + } else { + methodReference = new MethodReference (method.Name, method.ReturnType, declaringType); + + foreach (var gp in method.GenericParameters) + methodReference.GenericParameters.Add (new GenericParameter (gp.Name, methodReference)); + + foreach (var p in method.Parameters) + methodReference.Parameters.Add (new ParameterDefinition (p.Name, p.Attributes, p.ParameterType)); + + methodReference.HasThis = method.HasThis; + } + + + return methodReference; + } + + public FieldReference Resolve (FieldReference field) + { + var declaringType = Resolve (field.DeclaringType); + + if (declaringType == field.DeclaringType) + return field; + + return new FieldReference (field.Name, field.FieldType, declaringType); + } + + public TypeReference ResolveReturnType (MethodReference method) + { + return Resolve (GenericParameterResolver.ResolveReturnTypeIfNeeded (method)); + } + + public TypeReference ResolveParameterType (MethodReference method, ParameterReference parameter) + { + return Resolve (GenericParameterResolver.ResolveParameterTypeIfNeeded (method, parameter)); + } + + public TypeReference ResolveVariableType (MethodReference method, VariableReference variable) + { + return Resolve (GenericParameterResolver.ResolveVariableTypeIfNeeded (method, variable)); + } + + public TypeReference ResolveFieldType (FieldReference field) + { + return Resolve (GenericParameterResolver.ResolveFieldTypeIfNeeded (field)); + } + + public TypeReference Resolve (TypeReference typeReference) + { + return Resolve (typeReference, true); + } + + public TypeReference Resolve (TypeReference typeReference, bool includeTypeDefinitions) + { + if (IsDummy ()) + return typeReference; + + if (_typeDefinitionContext != null && _typeDefinitionContext.GenericArguments.Contains (typeReference)) + return typeReference; + if (_methodDefinitionContext != null && _methodDefinitionContext.GenericArguments.Contains (typeReference)) + return typeReference; + + var genericParameter = typeReference as GenericParameter; + if (genericParameter != null) { + if (_typeDefinitionContext != null && _typeDefinitionContext.GenericArguments.Contains (genericParameter)) + return genericParameter; + if (_methodDefinitionContext != null && _methodDefinitionContext.GenericArguments.Contains (genericParameter)) + return genericParameter; + return ResolveGenericParameter (genericParameter); + } + + var arrayType = typeReference as ArrayType; + if (arrayType != null) + return new ArrayType (Resolve (arrayType.ElementType), arrayType.Rank); + + var pointerType = typeReference as PointerType; + if (pointerType != null) + return new PointerType (Resolve (pointerType.ElementType)); + + var byReferenceType = typeReference as ByReferenceType; + if (byReferenceType != null) + return new ByReferenceType (Resolve (byReferenceType.ElementType)); + + var pinnedType = typeReference as PinnedType; + if (pinnedType != null) + return new PinnedType (Resolve (pinnedType.ElementType)); + + var genericInstanceType = typeReference as GenericInstanceType; + if (genericInstanceType != null) { + var newGenericInstanceType = new GenericInstanceType (genericInstanceType.ElementType); + foreach (var genericArgument in genericInstanceType.GenericArguments) + newGenericInstanceType.GenericArguments.Add (Resolve (genericArgument)); + return newGenericInstanceType; + } + + var requiredModType = typeReference as RequiredModifierType; + if (requiredModType != null) + return Resolve (requiredModType.ElementType, includeTypeDefinitions); + + + if (includeTypeDefinitions) { + var typeDefinition = typeReference as TypeDefinition; + if (typeDefinition != null && typeDefinition.HasGenericParameters) { + var newGenericInstanceType = new GenericInstanceType (typeDefinition); + foreach (var gp in typeDefinition.GenericParameters) + newGenericInstanceType.GenericArguments.Add (Resolve (gp)); + return newGenericInstanceType; + } + } + + if (typeReference is TypeSpecification) + throw new NotSupportedException (string.Format ("The type {0} cannot be resolved correctly.", typeReference.FullName)); + + return typeReference; + } + + internal TypeResolver Nested (GenericInstanceMethod genericInstanceMethod) + { + return new TypeResolver (_typeDefinitionContext as GenericInstanceType, genericInstanceMethod); + } + + private TypeReference ResolveGenericParameter (GenericParameter genericParameter) + { + if (genericParameter.Owner == null) + return HandleOwnerlessInvalidILCode (genericParameter); + + var memberReference = genericParameter.Owner as MemberReference; + if (memberReference == null) + throw new NotSupportedException (); + + return genericParameter.Type == GenericParameterType.Type + ? _typeDefinitionContext.GenericArguments[genericParameter.Position] + : (_methodDefinitionContext != null ? _methodDefinitionContext.GenericArguments[genericParameter.Position] : genericParameter); + } + + private TypeReference HandleOwnerlessInvalidILCode (GenericParameter genericParameter) + { + // NOTE: If owner is null and we have a method parameter, then we'll assume that the method parameter + // is actually a type parameter, and we'll use the type parameter from the corresponding position. I think + // this assumption is valid, but if you're visiting this code then I might have been proven wrong. + if (genericParameter.Type == GenericParameterType.Method && (_typeDefinitionContext != null && genericParameter.Position < _typeDefinitionContext.GenericArguments.Count)) + return _typeDefinitionContext.GenericArguments[genericParameter.Position]; + + // NOTE: Owner cannot be null, but sometimes the Mono compiler generates invalid IL and we + // end up in this situation. + // When we do, we assume that the runtime doesn't care about the resolved type of the GenericParameter, + // thus we return a reference to System.Object. + return genericParameter.Module.TypeSystem.Object; + } + + private bool IsDummy () + { + return _typeDefinitionContext == null && _methodDefinitionContext == null; + } + } +} diff --git a/cecil-master/Mono.Cecil/TypeSpecification.cs b/cecil-master/Mono.Cecil/TypeSpecification.cs new file mode 100644 index 000000000..16e0cab81 --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeSpecification.cs @@ -0,0 +1,68 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 InvalidOperationException (); } + } + + public override string Namespace { + get { return element_type.Namespace; } + set { throw new InvalidOperationException (); } + } + + public override IMetadataScope Scope { + get { return element_type.Scope; } + set { throw new InvalidOperationException (); } + } + + public override ModuleDefinition Module { + get { return element_type.Module; } + } + + public override string FullName { + get { return element_type.FullName; } + } + + public 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 (); + } + } +} diff --git a/cecil-master/Mono.Cecil/TypeSystem.cs b/cecil-master/Mono.Cecil/TypeSystem.cs new file mode 100644 index 000000000..e16ec6f3b --- /dev/null +++ b/cecil-master/Mono.Cecil/TypeSystem.cs @@ -0,0 +1,331 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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 core_library; + + public CommonTypeSystem (ModuleDefinition module) + : base (module) + { + } + + internal override TypeReference LookupType (string @namespace, string name) + { + return CreateTypeReference (@namespace, name); + } + + public AssemblyNameReference GetCoreLibraryReference () + { + if (core_library != null) + return core_library; + + if (module.TryGetCoreLibraryReference (out core_library)) + return core_library; + + core_library = new AssemblyNameReference { + Name = Mixin.mscorlib, + Version = GetCorlibVersion (), + PublicKeyToken = new byte [] { 0xb7, 0x7a, 0x5c, 0x56, 0x19, 0x34, 0xe0, 0x89 }, + }; + + module.AssemblyReferences.Add (core_library); + + return core_library; + } + + 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, GetCoreLibraryReference ()); + } + } + + 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 (module.IsCoreLibrary ()) + return new CoreTypeSystem (module); + + return new CommonTypeSystem (module); + } + + internal abstract TypeReference LookupType (string @namespace, string name); + + TypeReference LookupSystemType (ref TypeReference reference, string name, ElementType element_type) + { + lock (module.SyncRoot) { + if (reference != null) + return reference; + var type = LookupType ("System", name); + type.etype = element_type; + return reference = 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.KnownValueType (); + return typeRef = type; + } + } + + [Obsolete ("Use CoreLibrary")] + public IMetadataScope Corlib { + get { return CoreLibrary; } + } + + public IMetadataScope CoreLibrary { + get { + var common = this as CommonTypeSystem; + if (common == null) + return module; + + return common.GetCoreLibraryReference (); + } + } + + 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)); } + } + } + + static partial class Mixin { + + public const string mscorlib = "mscorlib"; + public const string system_runtime = "System.Runtime"; + public const string system_private_corelib = "System.Private.CoreLib"; + public const string netstandard = "netstandard"; + + public static bool TryGetCoreLibraryReference (this ModuleDefinition module, out AssemblyNameReference reference) + { + var references = module.AssemblyReferences; + + for (int i = 0; i < references.Count; i++) { + reference = references [i]; + if (IsCoreLibrary (reference)) + return true; + } + + reference = null; + return false; + + } + + public static bool IsCoreLibrary (this ModuleDefinition module) + { + if (module.Assembly == null) + return false; + + if (!IsCoreLibrary (module.Assembly.Name)) + return false; + + if (module.HasImage && module.Read (module, (m, reader) => reader.image.GetTableLength (Table.AssemblyRef) > 0)) + return false; + + return true; + } + + public static void KnownValueType (this TypeReference type) + { + if (!type.IsDefinition) + type.IsValueType = true; + } + + static bool IsCoreLibrary (AssemblyNameReference reference) + { + var name = reference.Name; + return name == mscorlib + || name == system_runtime + || name == system_private_corelib + || name == netstandard; + } + } +} diff --git a/cecil-master/Mono.Cecil/VariantType.cs b/cecil-master/Mono.Cecil/VariantType.cs new file mode 100644 index 000000000..c5e222df4 --- /dev/null +++ b/cecil-master/Mono.Cecil/VariantType.cs @@ -0,0 +1,37 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +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, + I8 = 20, + UI8 = 21, + Int = 22, + UInt = 23 + } +} diff --git a/cecil-master/Mono.Cecil/WindowsRuntimeProjections.cs b/cecil-master/Mono.Cecil/WindowsRuntimeProjections.cs new file mode 100644 index 000000000..b96a891b2 --- /dev/null +++ b/cecil-master/Mono.Cecil/WindowsRuntimeProjections.cs @@ -0,0 +1,971 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; +using System.Threading; +using Mono.Collections.Generic; + +namespace Mono.Cecil { + + sealed class TypeDefinitionProjection { + + public readonly TypeAttributes Attributes; + public readonly string Name; + public readonly TypeDefinitionTreatment Treatment; + public readonly Collection RedirectedMethods; + public readonly Collection> RedirectedInterfaces; + + public TypeDefinitionProjection (TypeDefinition type, TypeDefinitionTreatment treatment, Collection redirectedMethods, Collection> redirectedInterfaces) + { + Attributes = type.Attributes; + Name = type.Name; + Treatment = treatment; + RedirectedMethods = redirectedMethods; + RedirectedInterfaces = redirectedInterfaces; + } + } + + sealed class TypeReferenceProjection { + + public readonly string Name; + public readonly string Namespace; + public readonly IMetadataScope Scope; + public readonly TypeReferenceTreatment Treatment; + + public TypeReferenceProjection (TypeReference type, TypeReferenceTreatment treatment) + { + Name = type.Name; + Namespace = type.Namespace; + Scope = type.Scope; + Treatment = treatment; + } + } + + sealed class MethodDefinitionProjection { + + public readonly MethodAttributes Attributes; + public readonly MethodImplAttributes ImplAttributes; + public readonly string Name; + public readonly MethodDefinitionTreatment Treatment; + + public MethodDefinitionProjection (MethodDefinition method, MethodDefinitionTreatment treatment) + { + Attributes = method.Attributes; + ImplAttributes = method.ImplAttributes; + Name = method.Name; + Treatment = treatment; + } + } + + sealed class FieldDefinitionProjection { + + public readonly FieldAttributes Attributes; + public readonly FieldDefinitionTreatment Treatment; + + public FieldDefinitionProjection (FieldDefinition field, FieldDefinitionTreatment treatment) + { + Attributes = field.Attributes; + Treatment = treatment; + } + } + + sealed class CustomAttributeValueProjection { + + public readonly AttributeTargets Targets; + public readonly CustomAttributeValueTreatment Treatment; + + public CustomAttributeValueProjection (AttributeTargets targets, CustomAttributeValueTreatment treatment) + { + Targets = targets; + Treatment = treatment; + } + } + + sealed class WindowsRuntimeProjections { + + struct ProjectionInfo { + + public readonly string WinRTNamespace; + public readonly string ClrNamespace; + public readonly string ClrName; + public readonly string ClrAssembly; + public readonly bool Attribute; + + public ProjectionInfo (string winrt_namespace, string clr_namespace, string clr_name, string clr_assembly, bool attribute = false) + { + WinRTNamespace = winrt_namespace; + ClrNamespace = clr_namespace; + ClrName = clr_name; + ClrAssembly = clr_assembly; + Attribute = attribute; + } + } + + static readonly Version version = new Version (4, 0, 0, 0); + + static readonly byte[] contract_pk_token = { + 0xB0, 0x3F, 0x5F, 0x7F, 0x11, 0xD5, 0x0A, 0x3A + }; + + static readonly byte[] contract_pk = { + 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x52, 0x53, 0x41, 0x31, 0x00, 0x04, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x07, 0xD1, 0xFA, 0x57, 0xC4, 0xAE, 0xD9, 0xF0, 0xA3, 0x2E, 0x84, 0xAA, 0x0F, 0xAE, 0xFD, 0x0D, + 0xE9, 0xE8, 0xFD, 0x6A, 0xEC, 0x8F, 0x87, 0xFB, 0x03, 0x76, 0x6C, 0x83, 0x4C, 0x99, 0x92, 0x1E, + 0xB2, 0x3B, 0xE7, 0x9A, 0xD9, 0xD5, 0xDC, 0xC1, 0xDD, 0x9A, 0xD2, 0x36, 0x13, 0x21, 0x02, 0x90, + 0x0B, 0x72, 0x3C, 0xF9, 0x80, 0x95, 0x7F, 0xC4, 0xE1, 0x77, 0x10, 0x8F, 0xC6, 0x07, 0x77, 0x4F, + 0x29, 0xE8, 0x32, 0x0E, 0x92, 0xEA, 0x05, 0xEC, 0xE4, 0xE8, 0x21, 0xC0, 0xA5, 0xEF, 0xE8, 0xF1, + 0x64, 0x5C, 0x4C, 0x0C, 0x93, 0xC1, 0xAB, 0x99, 0x28, 0x5D, 0x62, 0x2C, 0xAA, 0x65, 0x2C, 0x1D, + 0xFA, 0xD6, 0x3D, 0x74, 0x5D, 0x6F, 0x2D, 0xE5, 0xF1, 0x7E, 0x5E, 0xAF, 0x0F, 0xC4, 0x96, 0x3D, + 0x26, 0x1C, 0x8A, 0x12, 0x43, 0x65, 0x18, 0x20, 0x6D, 0xC0, 0x93, 0x34, 0x4D, 0x5A, 0xD2, 0x93 + }; + + static Dictionary projections; + + static Dictionary Projections + { + get { + if (projections != null) + return projections; + + + var new_projections = new Dictionary { + { "AttributeTargets", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeTargets", "System.Runtime") }, + { "AttributeUsageAttribute", new ProjectionInfo ("Windows.Foundation.Metadata", "System", "AttributeUsageAttribute", "System.Runtime", attribute: true) }, + { "Color", new ProjectionInfo ("Windows.UI", "Windows.UI", "Color", "System.Runtime.WindowsRuntime") }, + { "CornerRadius", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "CornerRadius", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "DateTime", new ProjectionInfo ("Windows.Foundation", "System", "DateTimeOffset", "System.Runtime") }, + { "Duration", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "Duration", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "DurationType", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "DurationType", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "EventHandler`1", new ProjectionInfo ("Windows.Foundation", "System", "EventHandler`1", "System.Runtime") }, + { "EventRegistrationToken", new ProjectionInfo ("Windows.Foundation", "System.Runtime.InteropServices.WindowsRuntime", "EventRegistrationToken", "System.Runtime.InteropServices.WindowsRuntime") }, + { "GeneratorPosition", new ProjectionInfo ("Windows.UI.Xaml.Controls.Primitives", "Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "GridLength", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "GridLength", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "GridUnitType", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "GridUnitType", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "HResult", new ProjectionInfo ("Windows.Foundation", "System", "Exception", "System.Runtime") }, + { "IBindableIterable", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections", "IEnumerable", "System.Runtime") }, + { "IBindableVector", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections", "IList", "System.Runtime") }, + { "IClosable", new ProjectionInfo ("Windows.Foundation", "System", "IDisposable", "System.Runtime") }, + { "ICommand", new ProjectionInfo ("Windows.UI.Xaml.Input", "System.Windows.Input", "ICommand", "System.ObjectModel") }, + { "IIterable`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IEnumerable`1", "System.Runtime") }, + { "IKeyValuePair`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "KeyValuePair`2", "System.Runtime") }, + { "IMapView`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IReadOnlyDictionary`2", "System.Runtime") }, + { "IMap`2", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IDictionary`2", "System.Runtime") }, + { "INotifyCollectionChanged", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "INotifyCollectionChanged", "System.ObjectModel") }, + { "INotifyPropertyChanged", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "INotifyPropertyChanged", "System.ObjectModel") }, + { "IReference`1", new ProjectionInfo ("Windows.Foundation", "System", "Nullable`1", "System.Runtime") }, + { "IVectorView`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IReadOnlyList`1", "System.Runtime") }, + { "IVector`1", new ProjectionInfo ("Windows.Foundation.Collections", "System.Collections.Generic", "IList`1", "System.Runtime") }, + { "KeyTime", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "KeyTime", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "Matrix", new ProjectionInfo ("Windows.UI.Xaml.Media", "Windows.UI.Xaml.Media", "Matrix", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "Matrix3D", new ProjectionInfo ("Windows.UI.Xaml.Media.Media3D", "Windows.UI.Xaml.Media.Media3D", "Matrix3D", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "Matrix3x2", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Matrix3x2", "System.Numerics.Vectors") }, + { "Matrix4x4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Matrix4x4", "System.Numerics.Vectors") }, + { "NotifyCollectionChangedAction", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedAction", "System.ObjectModel") }, + { "NotifyCollectionChangedEventArgs", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedEventArgs", "System.ObjectModel") }, + { "NotifyCollectionChangedEventHandler", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System.Collections.Specialized", "NotifyCollectionChangedEventHandler", "System.ObjectModel") }, + { "Plane", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Plane", "System.Numerics.Vectors") }, + { "Point", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Point", "System.Runtime.WindowsRuntime") }, + { "PropertyChangedEventArgs", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "PropertyChangedEventArgs", "System.ObjectModel") }, + { "PropertyChangedEventHandler", new ProjectionInfo ("Windows.UI.Xaml.Data", "System.ComponentModel", "PropertyChangedEventHandler", "System.ObjectModel") }, + { "Quaternion", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Quaternion", "System.Numerics.Vectors") }, + { "Rect", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Rect", "System.Runtime.WindowsRuntime") }, + { "RepeatBehavior", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "RepeatBehavior", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "RepeatBehaviorType", new ProjectionInfo ("Windows.UI.Xaml.Media.Animation", "Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "Size", new ProjectionInfo ("Windows.Foundation", "Windows.Foundation", "Size", "System.Runtime.WindowsRuntime") }, + { "Thickness", new ProjectionInfo ("Windows.UI.Xaml", "Windows.UI.Xaml", "Thickness", "System.Runtime.WindowsRuntime.UI.Xaml") }, + { "TimeSpan", new ProjectionInfo ("Windows.Foundation", "System", "TimeSpan", "System.Runtime") }, + { "TypeName", new ProjectionInfo ("Windows.UI.Xaml.Interop", "System", "Type", "System.Runtime") }, + { "Uri", new ProjectionInfo ("Windows.Foundation", "System", "Uri", "System.Runtime") }, + { "Vector2", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector2", "System.Numerics.Vectors") }, + { "Vector3", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector3", "System.Numerics.Vectors") }, + { "Vector4", new ProjectionInfo ("Windows.Foundation.Numerics", "System.Numerics", "Vector4", "System.Numerics.Vectors") }, + }; + + Interlocked.CompareExchange (ref projections, new_projections, null); + return projections; + } + } + + readonly ModuleDefinition module; + Version corlib_version = new Version (255, 255, 255, 255); + AssemblyNameReference[] virtual_references; + + AssemblyNameReference[] VirtualReferences { + get { + if (virtual_references == null) { + // force module to read its assembly references. that will in turn initialize virtual_references + Mixin.Read (module.AssemblyReferences); + } + + return virtual_references; + } + } + + public WindowsRuntimeProjections (ModuleDefinition module) + { + this.module = module; + } + + public static void Project (TypeDefinition type) + { + var treatment = TypeDefinitionTreatment.None; + var metadata_kind = type.Module.MetadataKind; + Collection redirectedMethods = null; + Collection> redirectedInterfaces = null; + + if (type.IsWindowsRuntime) { + if (metadata_kind == MetadataKind.WindowsMetadata) { + treatment = GetWellKnownTypeDefinitionTreatment (type); + if (treatment != TypeDefinitionTreatment.None) { + ApplyProjection (type, new TypeDefinitionProjection (type, treatment, redirectedMethods, redirectedInterfaces)); + return; + } + + var base_type = type.BaseType; + if (base_type != null && IsAttribute (base_type)) { + treatment = TypeDefinitionTreatment.NormalAttribute; + } else { + treatment = GenerateRedirectionInformation (type, out redirectedMethods, out redirectedInterfaces); + } + } + else if (metadata_kind == MetadataKind.ManagedWindowsMetadata && NeedsWindowsRuntimePrefix (type)) + treatment = TypeDefinitionTreatment.PrefixWindowsRuntimeName; + + if (treatment == TypeDefinitionTreatment.PrefixWindowsRuntimeName || treatment == TypeDefinitionTreatment.NormalType) + if (!type.IsInterface && HasAttribute (type.CustomAttributes, "Windows.UI.Xaml", "TreatAsAbstractComposableClassAttribute")) + treatment |= TypeDefinitionTreatment.Abstract; + } + else if (metadata_kind == MetadataKind.ManagedWindowsMetadata && IsClrImplementationType (type)) + treatment = TypeDefinitionTreatment.UnmangleWindowsRuntimeName; + + if (treatment != TypeDefinitionTreatment.None) + ApplyProjection (type, new TypeDefinitionProjection (type, treatment, redirectedMethods, redirectedInterfaces)); + } + + static TypeDefinitionTreatment GetWellKnownTypeDefinitionTreatment (TypeDefinition type) + { + ProjectionInfo info; + if (!Projections.TryGetValue (type.Name, out info)) + return TypeDefinitionTreatment.None; + + var treatment = info.Attribute ? TypeDefinitionTreatment.RedirectToClrAttribute : TypeDefinitionTreatment.RedirectToClrType; + + if (type.Namespace == info.ClrNamespace) + return treatment; + + if (type.Namespace == info.WinRTNamespace) + return treatment | TypeDefinitionTreatment.Internal; + + return TypeDefinitionTreatment.None; + } + + private static TypeDefinitionTreatment GenerateRedirectionInformation (TypeDefinition type, out Collection redirectedMethods, out Collection> redirectedInterfaces) + { + bool implementsProjectedInterface = false; + redirectedMethods = null; + redirectedInterfaces = null; + + foreach (var implementedInterface in type.Interfaces) { + if (IsRedirectedType (implementedInterface.InterfaceType)) { + implementsProjectedInterface = true; + break; + } + } + + if (!implementsProjectedInterface) + return TypeDefinitionTreatment.NormalType; + + var allImplementedInterfaces = new HashSet (new TypeReferenceEqualityComparer ()); + redirectedMethods = new Collection (); + redirectedInterfaces = new Collection> (); + + foreach (var @interface in type.Interfaces) { + var interfaceType = @interface.InterfaceType; + + if (IsRedirectedType (interfaceType)) { + allImplementedInterfaces.Add (interfaceType); + CollectImplementedInterfaces (interfaceType, allImplementedInterfaces); + } + } + + foreach (var implementedInterface in type.Interfaces) { + var interfaceType = implementedInterface.InterfaceType; + if (IsRedirectedType (implementedInterface.InterfaceType)) { + var etype = interfaceType.GetElementType (); + var unprojectedType = new TypeReference (etype.Namespace, etype.Name, etype.Module, etype.Scope) { + DeclaringType = etype.DeclaringType, + projection = etype.projection + }; + + RemoveProjection (unprojectedType); + + var genericInstanceType = interfaceType as GenericInstanceType; + if (genericInstanceType != null) { + var genericUnprojectedType = new GenericInstanceType (unprojectedType); + foreach (var genericArgument in genericInstanceType.GenericArguments) + genericUnprojectedType.GenericArguments.Add (genericArgument); + + unprojectedType = genericUnprojectedType; + } + + var unprojectedInterface = new InterfaceImplementation (unprojectedType); + redirectedInterfaces.Add (new KeyValuePair (implementedInterface, unprojectedInterface)); + } + } + + // Interfaces don't inherit methods of the interfaces they implement + if (!type.IsInterface) { + foreach (var implementedInterface in allImplementedInterfaces) { + RedirectInterfaceMethods (implementedInterface, redirectedMethods); + } + } + + return TypeDefinitionTreatment.RedirectImplementedMethods; + } + + private static void CollectImplementedInterfaces (TypeReference type, HashSet results) + { + var typeResolver = TypeResolver.For (type); + var typeDef = type.Resolve (); + + foreach (var implementedInterface in typeDef.Interfaces) { + var interfaceType = typeResolver.Resolve (implementedInterface.InterfaceType); + results.Add (interfaceType); + CollectImplementedInterfaces (interfaceType, results); + } + } + + private static void RedirectInterfaceMethods (TypeReference interfaceType, Collection redirectedMethods) + { + var typeResolver = TypeResolver.For (interfaceType); + var typeDef = interfaceType.Resolve (); + + foreach (var method in typeDef.Methods) { + var redirectedMethod = new MethodDefinition (method.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot, typeResolver.Resolve (method.ReturnType)); + redirectedMethod.ImplAttributes = MethodImplAttributes.Runtime; + + foreach (var parameter in method.Parameters) { + redirectedMethod.Parameters.Add (new ParameterDefinition (parameter.Name, parameter.Attributes, typeResolver.Resolve (parameter.ParameterType))); + } + + redirectedMethod.Overrides.Add (typeResolver.Resolve (method)); + redirectedMethods.Add (redirectedMethod); + } + } + + private static bool IsRedirectedType (TypeReference type) + { + var typeRefProjection = type.GetElementType ().projection as TypeReferenceProjection; + return typeRefProjection != null && typeRefProjection.Treatment == TypeReferenceTreatment.UseProjectionInfo; + } + + static bool NeedsWindowsRuntimePrefix (TypeDefinition type) + { + if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.Interface)) != TypeAttributes.Public) + return false; + + var base_type = type.BaseType; + if (base_type == null || base_type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + + if (base_type.Namespace == "System") + switch (base_type.Name) + { + case "Attribute": + case "MulticastDelegate": + case "ValueType": + return false; + } + + return true; + } + + public static bool IsClrImplementationType (TypeDefinition type) + { + if ((type.Attributes & (TypeAttributes.VisibilityMask | TypeAttributes.SpecialName)) != TypeAttributes.SpecialName) + return false; + return type.Name.StartsWith (""); + } + + public static void ApplyProjection (TypeDefinition type, TypeDefinitionProjection projection) + { + if (projection == null) + return; + + var treatment = projection.Treatment; + + switch (treatment & TypeDefinitionTreatment.KindMask) { + case TypeDefinitionTreatment.NormalType: + type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Import; + break; + + case TypeDefinitionTreatment.NormalAttribute: + type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Sealed; + break; + + case TypeDefinitionTreatment.UnmangleWindowsRuntimeName: + type.Attributes = type.Attributes & ~TypeAttributes.SpecialName | TypeAttributes.Public; + type.Name = type.Name.Substring ("".Length); + break; + + case TypeDefinitionTreatment.PrefixWindowsRuntimeName: + type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import; + type.Name = "" + type.Name; + break; + + case TypeDefinitionTreatment.RedirectToClrType: + type.Attributes = type.Attributes & ~TypeAttributes.Public | TypeAttributes.Import; + break; + + case TypeDefinitionTreatment.RedirectToClrAttribute: + type.Attributes = type.Attributes & ~TypeAttributes.Public; + break; + + case TypeDefinitionTreatment.RedirectImplementedMethods: { + type.Attributes |= TypeAttributes.WindowsRuntime | TypeAttributes.Import; + + foreach (var redirectedInterfacePair in projection.RedirectedInterfaces) { + type.Interfaces.Add (redirectedInterfacePair.Value); + + foreach (var customAttribute in redirectedInterfacePair.Key.CustomAttributes) + redirectedInterfacePair.Value.CustomAttributes.Add (customAttribute); + + redirectedInterfacePair.Key.CustomAttributes.Clear (); + + foreach (var method in type.Methods) { + foreach (var @override in method.Overrides) { + if (TypeReferenceEqualityComparer.AreEqual (@override.DeclaringType, redirectedInterfacePair.Key.InterfaceType)) { + @override.DeclaringType = redirectedInterfacePair.Value.InterfaceType; + } + } + } + } + + foreach (var method in projection.RedirectedMethods) { + type.Methods.Add (method); + } + } + break; + } + + if ((treatment & TypeDefinitionTreatment.Abstract) != 0) + type.Attributes |= TypeAttributes.Abstract; + + if ((treatment & TypeDefinitionTreatment.Internal) != 0) + type.Attributes &= ~TypeAttributes.Public; + + type.WindowsRuntimeProjection = projection; + } + + public static TypeDefinitionProjection RemoveProjection (TypeDefinition type) + { + if (!type.IsWindowsRuntimeProjection) + return null; + + var projection = type.WindowsRuntimeProjection; + type.WindowsRuntimeProjection = null; + + type.Attributes = projection.Attributes; + type.Name = projection.Name; + + if (projection.Treatment == TypeDefinitionTreatment.RedirectImplementedMethods) { + foreach (var method in projection.RedirectedMethods) { + type.Methods.Remove (method); + } + + foreach (var redirectedInterfacePair in projection.RedirectedInterfaces) { + foreach (var method in type.Methods) { + foreach (var @override in method.Overrides) { + if (TypeReferenceEqualityComparer.AreEqual (@override.DeclaringType, redirectedInterfacePair.Value.InterfaceType)) { + @override.DeclaringType = redirectedInterfacePair.Key.InterfaceType; + } + } + } + + foreach (var customAttribute in redirectedInterfacePair.Value.CustomAttributes) + redirectedInterfacePair.Key.CustomAttributes.Add (customAttribute); + + redirectedInterfacePair.Value.CustomAttributes.Clear (); + type.Interfaces.Remove (redirectedInterfacePair.Value); + } + } + + return projection; + } + + public static void Project (TypeReference type) + { + TypeReferenceTreatment treatment; + + ProjectionInfo info; + if (Projections.TryGetValue (type.Name, out info) && info.WinRTNamespace == type.Namespace) + treatment = TypeReferenceTreatment.UseProjectionInfo; + else + treatment = GetSpecialTypeReferenceTreatment (type); + + if (treatment != TypeReferenceTreatment.None) + ApplyProjection (type, new TypeReferenceProjection (type, treatment)); + } + + static TypeReferenceTreatment GetSpecialTypeReferenceTreatment (TypeReference type) + { + if (type.Namespace == "System") { + if (type.Name == "MulticastDelegate") + return TypeReferenceTreatment.SystemDelegate; + if (type.Name == "Attribute") + return TypeReferenceTreatment.SystemAttribute; + } + + return TypeReferenceTreatment.None; + } + + static bool IsAttribute (TypeReference type) + { + if (type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + return type.Name == "Attribute" && type.Namespace == "System"; + } + + static bool IsEnum (TypeReference type) + { + if (type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + return type.Name == "Enum" && type.Namespace == "System"; + } + + public static void ApplyProjection (TypeReference type, TypeReferenceProjection projection) + { + if (projection == null) + return; + + switch (projection.Treatment) + { + case TypeReferenceTreatment.SystemDelegate: + case TypeReferenceTreatment.SystemAttribute: + type.Scope = type.Module.Projections.GetAssemblyReference ("System.Runtime"); + break; + + case TypeReferenceTreatment.UseProjectionInfo: + var info = Projections [type.Name]; + type.Name = info.ClrName; + type.Namespace = info.ClrNamespace; + type.Scope = type.Module.Projections.GetAssemblyReference (info.ClrAssembly); + break; + } + + type.WindowsRuntimeProjection = projection; + } + + public static TypeReferenceProjection RemoveProjection (TypeReference type) + { + if (!type.IsWindowsRuntimeProjection) + return null; + + var projection = type.WindowsRuntimeProjection; + type.WindowsRuntimeProjection = null; + + type.Name = projection.Name; + type.Namespace = projection.Namespace; + type.Scope = projection.Scope; + + return projection; + } + + public static void Project (MethodDefinition method) + { + var treatment = MethodDefinitionTreatment.None; + var other = false; + var declaring_type = method.DeclaringType; + + if (declaring_type.IsWindowsRuntime) + { + if (IsClrImplementationType (declaring_type)) + treatment = MethodDefinitionTreatment.None; + else if (declaring_type.IsNested) + treatment = MethodDefinitionTreatment.None; + else if (declaring_type.IsInterface) + treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall; + else if (declaring_type.Module.MetadataKind == MetadataKind.ManagedWindowsMetadata && !method.IsPublic) + treatment = MethodDefinitionTreatment.None; + else + { + other = true; + + var base_type = declaring_type.BaseType; + if (base_type != null && base_type.MetadataToken.TokenType == TokenType.TypeRef) + { + switch (GetSpecialTypeReferenceTreatment(base_type)) + { + case TypeReferenceTreatment.SystemDelegate: + treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.Public; + other = false; + break; + + case TypeReferenceTreatment.SystemAttribute: + treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall; + other = false; + break; + } + } + } + } + + if (other) + { + var seen_redirected = false; + var seen_non_redirected = false; + + foreach (var @override in method.Overrides) { + if (@override.MetadataToken.TokenType == TokenType.MemberRef && ImplementsRedirectedInterface (@override)) { + seen_redirected = true; + } else { + seen_non_redirected = true; + } + } + + if (seen_redirected && !seen_non_redirected) { + treatment = MethodDefinitionTreatment.Runtime | MethodDefinitionTreatment.InternalCall | MethodDefinitionTreatment.Private; + other = false; + } + } + + if (other) + treatment |= GetMethodDefinitionTreatmentFromCustomAttributes(method); + + if (treatment != MethodDefinitionTreatment.None) + ApplyProjection (method, new MethodDefinitionProjection (method, treatment)); + } + + static MethodDefinitionTreatment GetMethodDefinitionTreatmentFromCustomAttributes(MethodDefinition method) + { + var treatment = MethodDefinitionTreatment.None; + + foreach (var attribute in method.CustomAttributes) + { + var type = attribute.AttributeType; + if (type.Namespace != "Windows.UI.Xaml") + continue; + if (type.Name == "TreatAsPublicMethodAttribute") + treatment |= MethodDefinitionTreatment.Public; + else if (type.Name == "TreatAsAbstractMethodAttribute") + treatment |= MethodDefinitionTreatment.Abstract; + } + + return treatment; + } + + public static void ApplyProjection (MethodDefinition method, MethodDefinitionProjection projection) + { + if (projection == null) + return; + + var treatment = projection.Treatment; + + if ((treatment & MethodDefinitionTreatment.Abstract) != 0) + method.Attributes |= MethodAttributes.Abstract; + + if ((treatment & MethodDefinitionTreatment.Private) != 0) + method.Attributes = (method.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Private; + + if ((treatment & MethodDefinitionTreatment.Public) != 0) + method.Attributes = (method.Attributes & ~MethodAttributes.MemberAccessMask) | MethodAttributes.Public; + + if ((treatment & MethodDefinitionTreatment.Runtime) != 0) + method.ImplAttributes |= MethodImplAttributes.Runtime; + + if ((treatment & MethodDefinitionTreatment.InternalCall) != 0) + method.ImplAttributes |= MethodImplAttributes.InternalCall; + + method.WindowsRuntimeProjection = projection; + } + + public static MethodDefinitionProjection RemoveProjection (MethodDefinition method) + { + if (!method.IsWindowsRuntimeProjection) + return null; + + var projection = method.WindowsRuntimeProjection; + method.WindowsRuntimeProjection = null; + + method.Attributes = projection.Attributes; + method.ImplAttributes = projection.ImplAttributes; + method.Name = projection.Name; + + return projection; + } + + public static void Project (FieldDefinition field) + { + var treatment = FieldDefinitionTreatment.None; + var declaring_type = field.DeclaringType; + + if (declaring_type.Module.MetadataKind == MetadataKind.WindowsMetadata && field.IsRuntimeSpecialName && field.Name == "value__") { + var base_type = declaring_type.BaseType; + if (base_type != null && IsEnum (base_type)) + treatment = FieldDefinitionTreatment.Public; + } + + if (treatment != FieldDefinitionTreatment.None) + ApplyProjection (field, new FieldDefinitionProjection (field, treatment)); + } + + public static void ApplyProjection (FieldDefinition field, FieldDefinitionProjection projection) + { + if (projection == null) + return; + + if (projection.Treatment == FieldDefinitionTreatment.Public) + field.Attributes = (field.Attributes & ~FieldAttributes.FieldAccessMask) | FieldAttributes.Public; + + field.WindowsRuntimeProjection = projection; + } + + public static FieldDefinitionProjection RemoveProjection (FieldDefinition field) + { + if (!field.IsWindowsRuntimeProjection) + return null; + + var projection = field.WindowsRuntimeProjection; + field.WindowsRuntimeProjection = null; + + field.Attributes = projection.Attributes; + + return projection; + } + + static bool ImplementsRedirectedInterface (MemberReference member) + { + var declaring_type = member.DeclaringType; + TypeReference type; + switch (declaring_type.MetadataToken.TokenType) { + case TokenType.TypeRef: + type = declaring_type; + break; + + case TokenType.TypeSpec: + if (!declaring_type.IsGenericInstance) + return false; + + type = ((TypeSpecification) declaring_type).ElementType; + if (type.MetadataType != MetadataType.Class || type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + + break; + + default: + return false; + } + + var projection = RemoveProjection (type); + + var found = false; + + ProjectionInfo info; + if (Projections.TryGetValue (type.Name, out info) && type.Namespace == info.WinRTNamespace) { + found = true; + } + + ApplyProjection (type, projection); + + return found; + } + + + public void AddVirtualReferences (Collection references) + { + var corlib = GetCoreLibrary (references); + corlib_version = corlib.Version; + corlib.Version = version; + + if (virtual_references == null) { + var winrt_references = GetAssemblyReferences (corlib); + Interlocked.CompareExchange (ref virtual_references, winrt_references, null); + } + + foreach (var reference in virtual_references) + references.Add (reference); + } + + public void RemoveVirtualReferences (Collection references) + { + var corlib = GetCoreLibrary (references); + corlib.Version = corlib_version; + + foreach (var reference in VirtualReferences) + references.Remove (reference); + } + + static AssemblyNameReference[] GetAssemblyReferences (AssemblyNameReference corlib) + { + var system_runtime = new AssemblyNameReference ("System.Runtime", version); + var system_runtime_interopservices_windowsruntime = new AssemblyNameReference ("System.Runtime.InteropServices.WindowsRuntime", version); + var system_objectmodel = new AssemblyNameReference ("System.ObjectModel", version); + var system_runtime_windowsruntime = new AssemblyNameReference ("System.Runtime.WindowsRuntime", version); + var system_runtime_windowsruntime_ui_xaml = new AssemblyNameReference ("System.Runtime.WindowsRuntime.UI.Xaml", version); + var system_numerics_vectors = new AssemblyNameReference ("System.Numerics.Vectors", version); + + if (corlib.HasPublicKey) { + system_runtime_windowsruntime.PublicKey = + system_runtime_windowsruntime_ui_xaml.PublicKey = corlib.PublicKey; + + system_runtime.PublicKey = + system_runtime_interopservices_windowsruntime.PublicKey = + system_objectmodel.PublicKey = + system_numerics_vectors.PublicKey = contract_pk; + } + else { + system_runtime_windowsruntime.PublicKeyToken = + system_runtime_windowsruntime_ui_xaml.PublicKeyToken = corlib.PublicKeyToken; + + system_runtime.PublicKeyToken = + system_runtime_interopservices_windowsruntime.PublicKeyToken = + system_objectmodel.PublicKeyToken = + system_numerics_vectors.PublicKeyToken = contract_pk_token; + } + + return new[] { + system_runtime, + system_runtime_interopservices_windowsruntime, + system_objectmodel, + system_runtime_windowsruntime, + system_runtime_windowsruntime_ui_xaml, + system_numerics_vectors, + }; + } + + static AssemblyNameReference GetCoreLibrary (Collection references) + { + foreach (var reference in references) + if (reference.Name == "mscorlib") + return reference; + + throw new BadImageFormatException ("Missing mscorlib reference in AssemblyRef table."); + } + + AssemblyNameReference GetAssemblyReference (string name) + { + foreach (var assembly in VirtualReferences) + if (assembly.Name == name) + return assembly; + + throw new Exception (); + } + + public static void Project (ICustomAttributeProvider owner, Collection owner_attributes, CustomAttribute attribute) + { + if (!IsWindowsAttributeUsageAttribute (owner, attribute)) + return; + + var treatment = CustomAttributeValueTreatment.None; + var type = (TypeDefinition) owner; + + if (type.Namespace == "Windows.Foundation.Metadata") { + if (type.Name == "VersionAttribute") + treatment = CustomAttributeValueTreatment.VersionAttribute; + else if (type.Name == "DeprecatedAttribute") + treatment = CustomAttributeValueTreatment.DeprecatedAttribute; + } + + if (treatment == CustomAttributeValueTreatment.None) { + var multiple = HasAttribute (owner_attributes, "Windows.Foundation.Metadata", "AllowMultipleAttribute"); + treatment = multiple ? CustomAttributeValueTreatment.AllowMultiple : CustomAttributeValueTreatment.AllowSingle; + } + + if (treatment != CustomAttributeValueTreatment.None) { + var attribute_targets = (AttributeTargets) attribute.ConstructorArguments [0].Value; + ApplyProjection (attribute, new CustomAttributeValueProjection (attribute_targets, treatment)); + } + } + + static bool IsWindowsAttributeUsageAttribute (ICustomAttributeProvider owner, CustomAttribute attribute) + { + if (owner.MetadataToken.TokenType != TokenType.TypeDef) + return false; + + var constructor = attribute.Constructor; + + if (constructor.MetadataToken.TokenType != TokenType.MemberRef) + return false; + + var declaring_type = constructor.DeclaringType; + + if (declaring_type.MetadataToken.TokenType != TokenType.TypeRef) + return false; + + // declaring type is already projected + return declaring_type.Name == "AttributeUsageAttribute" && declaring_type.Namespace == /*"Windows.Foundation.Metadata"*/"System"; + } + + static bool HasAttribute (Collection attributes, string @namespace, string name) + { + foreach (var attribute in attributes) { + var attribute_type = attribute.AttributeType; + if (attribute_type.Name == name && attribute_type.Namespace == @namespace) + return true; + } + return false; + } + + public static void ApplyProjection (CustomAttribute attribute, CustomAttributeValueProjection projection) + { + if (projection == null) + return; + + bool version_or_deprecated; + bool multiple; + + switch (projection.Treatment) { + case CustomAttributeValueTreatment.AllowSingle: + version_or_deprecated = false; + multiple = false; + break; + + case CustomAttributeValueTreatment.AllowMultiple: + version_or_deprecated = false; + multiple = true; + break; + + case CustomAttributeValueTreatment.VersionAttribute: + case CustomAttributeValueTreatment.DeprecatedAttribute: + version_or_deprecated = true; + multiple = true; + break; + + default: + throw new ArgumentException (); + } + + var attribute_targets = (AttributeTargets) attribute.ConstructorArguments [0].Value; + if (version_or_deprecated) + attribute_targets |= AttributeTargets.Constructor | AttributeTargets.Property; + attribute.ConstructorArguments [0] = new CustomAttributeArgument (attribute.ConstructorArguments [0].Type, attribute_targets); + + attribute.Properties.Add (new CustomAttributeNamedArgument ("AllowMultiple", new CustomAttributeArgument (attribute.Module.TypeSystem.Boolean, multiple))); + + attribute.projection = projection; + } + + public static CustomAttributeValueProjection RemoveProjection (CustomAttribute attribute) + { + if (attribute.projection == null) + return null; + + var projection = attribute.projection; + attribute.projection = null; + + attribute.ConstructorArguments [0] = new CustomAttributeArgument (attribute.ConstructorArguments [0].Type, projection.Targets); + attribute.Properties.Clear (); + + return projection; + } + } +} diff --git a/cecil-master/Mono.Collections.Generic/Collection.cs b/cecil-master/Mono.Collections.Generic/Collection.cs new file mode 100644 index 000000000..86c14298d --- /dev/null +++ b/cecil-master/Mono.Collections.Generic/Collection.cs @@ -0,0 +1,418 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections; +using System.Collections.Generic; + +using Mono.Cecil; + +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; + } + } + + public int Capacity { + get { return items.Length; } + set { + if (value < 0 || value < size) + throw new ArgumentOutOfRangeException (); + + Resize (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 = capacity == 0 + ? Empty.Array + : 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); + version++; + } + + public bool Remove (T item) + { + var index = IndexOf (item); + if (index == -1) + return false; + + OnRemove (item, index); + + Shift (index, -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); + + Resize (new_size); + } + + protected void Resize (int new_size) + { + if (new_size == size) + return; + if (new_size < size) + throw new ArgumentOutOfRangeException (); + + items = items.Resize (new_size); + } + + 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/cecil-master/Mono.Collections.Generic/ReadOnlyCollection.cs b/cecil-master/Mono.Collections.Generic/ReadOnlyCollection.cs new file mode 100644 index 000000000..0ff232020 --- /dev/null +++ b/cecil-master/Mono.Collections.Generic/ReadOnlyCollection.cs @@ -0,0 +1,101 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections; +using System.Collections.Generic; +using System.Threading; + +namespace Mono.Collections.Generic { + + public sealed class ReadOnlyCollection : Collection, ICollection, IList { + + static ReadOnlyCollection empty; + + public static ReadOnlyCollection Empty { + get { + if (empty != null) + return empty; + + Interlocked.CompareExchange (ref empty, new ReadOnlyCollection (), null); + return empty; + } + } + + bool ICollection.IsReadOnly { + get { return true; } + } + + bool IList.IsFixedSize { + get { return true; } + } + + bool IList.IsReadOnly { + get { return true; } + } + + 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/cecil-master/Mono.Security.Cryptography/CryptoConvert.cs b/cecil-master/Mono.Security.Cryptography/CryptoConvert.cs new file mode 100644 index 000000000..cd68f99e2 --- /dev/null +++ b/cecil-master/Mono.Security.Cryptography/CryptoConvert.cs @@ -0,0 +1,290 @@ +// +// CryptoConvert.cs - Crypto Convertion Routines +// +// Author: +// Sebastien Pouliot +// +// (C) 2003 Motus Technologies Inc. (http://www.motus.com) +// Copyright (C) 2004-2006 Novell Inc. (http://www.novell.com) +// +// 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.Security.Cryptography; + +namespace Mono.Security.Cryptography { + + static class CryptoConvert { + + static private int ToInt32LE (byte [] bytes, int offset) + { + return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]; + } + + static private uint ToUInt32LE (byte [] bytes, int offset) + { + return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]); + } + + static private byte [] GetBytesLE (int val) + { + return new byte [] { + (byte) (val & 0xff), + (byte) ((val >> 8) & 0xff), + (byte) ((val >> 16) & 0xff), + (byte) ((val >> 24) & 0xff) + }; + } + + static private byte[] Trim (byte[] array) + { + for (int i=0; i < array.Length; i++) { + if (array [i] != 0x00) { + byte[] result = new byte [array.Length - i]; + Buffer.BlockCopy (array, i, result, 0, result.Length); + return result; + } + } + return null; + } + + static RSA FromCapiPrivateKeyBlob (byte[] blob, int offset) + { + RSAParameters rsap = new RSAParameters (); + try { + if ((blob [offset] != 0x07) || // PRIVATEKEYBLOB (0x07) + (blob [offset+1] != 0x02) || // Version (0x02) + (blob [offset+2] != 0x00) || // Reserved (word) + (blob [offset+3] != 0x00) || + (ToUInt32LE (blob, offset+8) != 0x32415352)) // DWORD magic = RSA2 + throw new CryptographicException ("Invalid blob header"); + + // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) + // int algId = ToInt32LE (blob, offset+4); + + // DWORD bitlen + int bitLen = ToInt32LE (blob, offset+12); + + // DWORD public exponent + byte[] exp = new byte [4]; + Buffer.BlockCopy (blob, offset+16, exp, 0, 4); + Array.Reverse (exp); + rsap.Exponent = Trim (exp); + + int pos = offset+20; + // BYTE modulus[rsapubkey.bitlen/8]; + int byteLen = (bitLen >> 3); + rsap.Modulus = new byte [byteLen]; + Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); + Array.Reverse (rsap.Modulus); + pos += byteLen; + + // BYTE prime1[rsapubkey.bitlen/16]; + int byteHalfLen = (byteLen >> 1); + rsap.P = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen); + Array.Reverse (rsap.P); + pos += byteHalfLen; + + // BYTE prime2[rsapubkey.bitlen/16]; + rsap.Q = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen); + Array.Reverse (rsap.Q); + pos += byteHalfLen; + + // BYTE exponent1[rsapubkey.bitlen/16]; + rsap.DP = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen); + Array.Reverse (rsap.DP); + pos += byteHalfLen; + + // BYTE exponent2[rsapubkey.bitlen/16]; + rsap.DQ = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen); + Array.Reverse (rsap.DQ); + pos += byteHalfLen; + + // BYTE coefficient[rsapubkey.bitlen/16]; + rsap.InverseQ = new byte [byteHalfLen]; + Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen); + Array.Reverse (rsap.InverseQ); + pos += byteHalfLen; + + // ok, this is hackish but CryptoAPI support it so... + // note: only works because CRT is used by default + // http://bugzilla.ximian.com/show_bug.cgi?id=57941 + rsap.D = new byte [byteLen]; // must be allocated + if (pos + byteLen + offset <= blob.Length) { + // BYTE privateExponent[rsapubkey.bitlen/8]; + Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen); + Array.Reverse (rsap.D); + } + } + catch (Exception e) { + throw new CryptographicException ("Invalid blob.", e); + } + + RSA rsa = null; + try { + rsa = RSA.Create (); + rsa.ImportParameters (rsap); + } + catch (CryptographicException) { + // this may cause problem when this code is run under + // the SYSTEM identity on Windows (e.g. ASP.NET). See + // http://bugzilla.ximian.com/show_bug.cgi?id=77559 + bool throws = false; + try { + CspParameters csp = new CspParameters (); + csp.Flags = CspProviderFlags.UseMachineKeyStore; + rsa = new RSACryptoServiceProvider (csp); + rsa.ImportParameters (rsap); + } + catch { + throws = true; + } + + if (throws) { + // rethrow original, not the latter, exception if this fails + throw; + } + } + return rsa; + } + + static RSA FromCapiPublicKeyBlob (byte[] blob, int offset) + { + try { + if ((blob [offset] != 0x06) || // PUBLICKEYBLOB (0x06) + (blob [offset+1] != 0x02) || // Version (0x02) + (blob [offset+2] != 0x00) || // Reserved (word) + (blob [offset+3] != 0x00) || + (ToUInt32LE (blob, offset+8) != 0x31415352)) // DWORD magic = RSA1 + throw new CryptographicException ("Invalid blob header"); + + // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...) + // int algId = ToInt32LE (blob, offset+4); + + // DWORD bitlen + int bitLen = ToInt32LE (blob, offset+12); + + // DWORD public exponent + RSAParameters rsap = new RSAParameters (); + rsap.Exponent = new byte [3]; + rsap.Exponent [0] = blob [offset+18]; + rsap.Exponent [1] = blob [offset+17]; + rsap.Exponent [2] = blob [offset+16]; + + int pos = offset+20; + // BYTE modulus[rsapubkey.bitlen/8]; + int byteLen = (bitLen >> 3); + rsap.Modulus = new byte [byteLen]; + Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen); + Array.Reverse (rsap.Modulus); + + RSA rsa = null; + try { + rsa = RSA.Create (); + rsa.ImportParameters (rsap); + } + catch (CryptographicException) { + // this may cause problem when this code is run under + // the SYSTEM identity on Windows (e.g. ASP.NET). See + // http://bugzilla.ximian.com/show_bug.cgi?id=77559 + CspParameters csp = new CspParameters (); + csp.Flags = CspProviderFlags.UseMachineKeyStore; + rsa = new RSACryptoServiceProvider (csp); + rsa.ImportParameters (rsap); + } + return rsa; + } + catch (Exception e) { + throw new CryptographicException ("Invalid blob.", e); + } + } + + // PRIVATEKEYBLOB + // PUBLICKEYBLOB + static public RSA FromCapiKeyBlob (byte[] blob) + { + return FromCapiKeyBlob (blob, 0); + } + + static public RSA FromCapiKeyBlob (byte[] blob, int offset) + { + if (blob == null) + throw new ArgumentNullException ("blob"); + if (offset >= blob.Length) + throw new ArgumentException ("blob is too small."); + + switch (blob [offset]) { + case 0x00: + // this could be a public key inside an header + // like "sn -e" would produce + if (blob [offset + 12] == 0x06) { + return FromCapiPublicKeyBlob (blob, offset + 12); + } + break; + case 0x06: + return FromCapiPublicKeyBlob (blob, offset); + case 0x07: + return FromCapiPrivateKeyBlob (blob, offset); + } + throw new CryptographicException ("Unknown blob format."); + } + + static public byte[] ToCapiPublicKeyBlob (RSA rsa) + { + RSAParameters p = rsa.ExportParameters (false); + int keyLength = p.Modulus.Length; // in bytes + byte[] blob = new byte [20 + keyLength]; + + blob [0] = 0x06; // Type - PUBLICKEYBLOB (0x06) + blob [1] = 0x02; // Version - Always CUR_BLOB_VERSION (0x02) + // [2], [3] // RESERVED - Always 0 + blob [5] = 0x24; // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN) + blob [8] = 0x52; // Magic - RSA1 (ASCII in hex) + blob [9] = 0x53; + blob [10] = 0x41; + blob [11] = 0x31; + + byte[] bitlen = GetBytesLE (keyLength << 3); + blob [12] = bitlen [0]; // bitlen + blob [13] = bitlen [1]; + blob [14] = bitlen [2]; + blob [15] = bitlen [3]; + + // public exponent (DWORD) + int pos = 16; + int n = p.Exponent.Length; + while (n > 0) + blob [pos++] = p.Exponent [--n]; + // modulus + pos = 20; + byte[] part = p.Modulus; + int len = part.Length; + Array.Reverse (part, 0, len); + Buffer.BlockCopy (part, 0, blob, pos, len); + pos += len; + return blob; + } + } +} diff --git a/cecil-master/Mono.Security.Cryptography/CryptoService.cs b/cecil-master/Mono.Security.Cryptography/CryptoService.cs new file mode 100644 index 000000000..3877debfa --- /dev/null +++ b/cecil-master/Mono.Security.Cryptography/CryptoService.cs @@ -0,0 +1,204 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.IO; +using System.Reflection; +using System.Security.Cryptography; +using System.Runtime.Serialization; + +using Mono.Security.Cryptography; + +using Mono.Cecil.PE; + +namespace Mono.Cecil { + + // Most of this code has been adapted + // from Jeroen Frijters' fantastic work + // in IKVM.Reflection.Emit. Thanks! + + static class CryptoService { + + public static byte [] GetPublicKey (WriterParameters parameters) + { + using (var rsa = parameters.CreateRSA ()) { + var cspBlob = CryptoConvert.ToCapiPublicKeyBlob (rsa); + var publicKey = new byte [12 + cspBlob.Length]; + Buffer.BlockCopy (cspBlob, 0, publicKey, 12, cspBlob.Length); + // The first 12 bytes are documented at: + // http://msdn.microsoft.com/library/en-us/cprefadd/html/grfungethashfromfile.asp + // ALG_ID - Signature + publicKey [1] = 36; + // ALG_ID - Hash + publicKey [4] = 4; + publicKey [5] = 128; + // Length of Public Key (in bytes) + publicKey [8] = (byte) (cspBlob.Length >> 0); + publicKey [9] = (byte) (cspBlob.Length >> 8); + publicKey [10] = (byte) (cspBlob.Length >> 16); + publicKey [11] = (byte) (cspBlob.Length >> 24); + return publicKey; + } + } + + public static void StrongName (Stream stream, ImageWriter writer, WriterParameters parameters) + { + int strong_name_pointer; + + var strong_name = CreateStrongName (parameters, HashStream (stream, writer, out strong_name_pointer)); + PatchStrongName (stream, strong_name_pointer, strong_name); + } + + static void PatchStrongName (Stream stream, int strong_name_pointer, byte [] strong_name) + { + stream.Seek (strong_name_pointer, SeekOrigin.Begin); + stream.Write (strong_name, 0, strong_name.Length); + } + + static byte [] CreateStrongName (WriterParameters parameters, byte [] hash) + { + const string hash_algo = "SHA1"; + + using (var rsa = parameters.CreateRSA ()) { + var formatter = new RSAPKCS1SignatureFormatter (rsa); + formatter.SetHashAlgorithm (hash_algo); + + byte [] signature = formatter.CreateSignature (hash); + Array.Reverse (signature); + + return signature; + } + } + + static byte [] HashStream (Stream stream, ImageWriter writer, out int strong_name_pointer) + { + const int buffer_size = 8192; + + var text = writer.text; + var header_size = (int) writer.GetHeaderSize (); + var text_section_pointer = (int) text.PointerToRawData; + var strong_name_directory = writer.GetStrongNameSignatureDirectory (); + + if (strong_name_directory.Size == 0) + throw new InvalidOperationException (); + + strong_name_pointer = (int) (text_section_pointer + + (strong_name_directory.VirtualAddress - text.VirtualAddress)); + var strong_name_length = (int) strong_name_directory.Size; + + var sha1 = new SHA1Managed (); + var buffer = new byte [buffer_size]; + using (var crypto_stream = new CryptoStream (Stream.Null, sha1, CryptoStreamMode.Write)) { + stream.Seek (0, SeekOrigin.Begin); + CopyStreamChunk (stream, crypto_stream, buffer, header_size); + + stream.Seek (text_section_pointer, SeekOrigin.Begin); + CopyStreamChunk (stream, crypto_stream, buffer, (int) strong_name_pointer - text_section_pointer); + + stream.Seek (strong_name_length, SeekOrigin.Current); + CopyStreamChunk (stream, crypto_stream, buffer, (int) (stream.Length - (strong_name_pointer + strong_name_length))); + } + + return sha1.Hash; + } + + public static void CopyStreamChunk (Stream stream, Stream dest_stream, byte [] buffer, int length) + { + while (length > 0) { + int read = stream.Read (buffer, 0, System.Math.Min (buffer.Length, length)); + dest_stream.Write (buffer, 0, read); + length -= read; + } + } + + public static byte [] ComputeHash (string file) + { + if (!File.Exists (file)) + return Empty.Array; + + using (var stream = new FileStream (file, FileMode.Open, FileAccess.Read, FileShare.Read)) + return ComputeHash (stream); + } + + public static byte [] ComputeHash (Stream stream) + { + const int buffer_size = 8192; + + var sha1 = new SHA1Managed (); + var buffer = new byte [buffer_size]; + + using (var crypto_stream = new CryptoStream (Stream.Null, sha1, CryptoStreamMode.Write)) + CopyStreamChunk (stream, crypto_stream, buffer, (int) stream.Length); + + return sha1.Hash; + } + + public static byte [] ComputeHash (params ByteBuffer [] buffers) + { + var sha1 = new SHA1Managed (); + + using (var crypto_stream = new CryptoStream (Stream.Null, sha1, CryptoStreamMode.Write)) { + for (int i = 0; i < buffers.Length; i++) { + crypto_stream.Write (buffers [i].buffer, 0, buffers [i].length); + } + } + + return sha1.Hash; + } + + public static Guid ComputeGuid (byte [] hash) + { + // From corefx/src/System.Reflection.Metadata/src/System/Reflection/Metadata/BlobContentId.cs + var guid = new byte [16]; + Buffer.BlockCopy (hash, 0, guid, 0, 16); + + // modify the guid data so it decodes to the form of a "random" guid ala rfc4122 + guid [7] = (byte) ((guid [7] & 0x0f) | (4 << 4)); + guid [8] = (byte) ((guid [8] & 0x3f) | (2 << 6)); + + return new Guid (guid); + } + } + + static partial class Mixin { + + public static RSA CreateRSA (this WriterParameters writer_parameters) + { + byte [] key; + string key_container; + + if (writer_parameters.StrongNameKeyBlob != null) + return CryptoConvert.FromCapiKeyBlob (writer_parameters.StrongNameKeyBlob); + + if (writer_parameters.StrongNameKeyContainer != null) + key_container = writer_parameters.StrongNameKeyContainer; + else if (!TryGetKeyContainer (writer_parameters.StrongNameKeyPair, out key, out key_container)) + return CryptoConvert.FromCapiKeyBlob (key); + + var parameters = new CspParameters { + Flags = CspProviderFlags.UseMachineKeyStore, + KeyContainerName = key_container, + KeyNumber = 2, + }; + + return new RSACryptoServiceProvider (parameters); + } + + static bool TryGetKeyContainer (ISerializable key_pair, out byte [] key, out string key_container) + { + var info = new SerializationInfo (typeof (StrongNameKeyPair), new FormatterConverter ()); + key_pair.GetObjectData (info, new StreamingContext ()); + + key = (byte []) info.GetValue ("_keyPairArray", typeof (byte [])); + key_container = info.GetString ("_keyPairContainer"); + return key_container != null; + } + } +} diff --git a/cecil-master/Mono/Disposable.cs b/cecil-master/Mono/Disposable.cs new file mode 100644 index 000000000..dc2b1a3d1 --- /dev/null +++ b/cecil-master/Mono/Disposable.cs @@ -0,0 +1,45 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; + +namespace Mono { + + static class Disposable { + + public static Disposable Owned (T value) where T : class, IDisposable + { + return new Disposable (value, owned: true); + } + + public static Disposable NotOwned (T value) where T : class, IDisposable + { + return new Disposable (value, owned: false); + } + } + + struct Disposable : IDisposable where T : class, IDisposable { + + internal readonly T value; + readonly bool owned; + + public Disposable (T value, bool owned) + { + this.value = value; + this.owned = owned; + } + + public void Dispose () + { + if (value != null && owned) + value.Dispose (); + } + } +} diff --git a/cecil-master/Mono/Empty.cs b/cecil-master/Mono/Empty.cs new file mode 100644 index 000000000..de28e6561 --- /dev/null +++ b/cecil-master/Mono/Empty.cs @@ -0,0 +1,62 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using Mono.Collections.Generic; + +namespace Mono { + + static class Empty { + + public static readonly T [] Array = new T [0]; + } + + class ArgumentNullOrEmptyException : ArgumentException { + + public ArgumentNullOrEmptyException (string paramName) + : base ("Argument null or empty", paramName) + { + } + } +} + +namespace Mono.Cecil { + + static partial class Mixin { + + public static bool IsNullOrEmpty (this T [] self) + { + return self == null || self.Length == 0; + } + + public static bool IsNullOrEmpty (this Collection self) + { + return self == null || self.size == 0; + } + + public static T [] Resize (this T [] self, int length) + { + Array.Resize (ref self, length); + return self; + } + + public static T [] Add (this T [] self, T item) + { + if (self == null) { + self = new [] { item }; + return self; + } + + self = self.Resize (self.Length + 1); + self [self.Length - 1] = item; + return self; + } + } +} diff --git a/cecil-master/Mono/MergeSort.cs b/cecil-master/Mono/MergeSort.cs new file mode 100644 index 000000000..5d856eaf0 --- /dev/null +++ b/cecil-master/Mono/MergeSort.cs @@ -0,0 +1,66 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// Copyright (c) 2008 - 2011 Novell, Inc. +// +// Licensed under the MIT/X11 license. +// + +using System; +using System.Collections.Generic; + +namespace Mono { + + class MergeSort { + private readonly T [] elements; + private readonly T [] buffer; + private readonly IComparer comparer; + + private MergeSort (T [] elements, IComparer comparer) + { + this.elements = elements; + this.buffer = new T [elements.Length]; + Array.Copy (this.elements, this.buffer, elements.Length); + this.comparer = comparer; + } + + public static void Sort (T [] source, IComparer comparer) + { + Sort (source, 0, source.Length, comparer); + } + + public static void Sort (T [] source, int start, int length, IComparer comparer) + { + new MergeSort (source, comparer).Sort (start, length); + } + + private void Sort (int start, int length) + { + TopDownSplitMerge (this.buffer, this.elements, start, length); + } + + private void TopDownSplitMerge (T [] a, T [] b, int start, int end) + { + if (end - start < 2) + return; + + int middle = (end + start) / 2; + TopDownSplitMerge (b, a, start, middle); + TopDownSplitMerge (b, a, middle, end); + TopDownMerge (a, b, start, middle, end); + } + + private void TopDownMerge (T [] a, T [] b, int start, int middle, int end) + { + for (int i = start, j = middle, k = start; k < end; k++) { + if (i < middle && (j >= end || comparer.Compare (a [i], a [j]) <= 0)) { + b [k] = a [i++]; + } else { + b [k] = a [j++]; + } + } + } + } +} diff --git a/cecil-master/ProjectInfo.cs b/cecil-master/ProjectInfo.cs new file mode 100644 index 000000000..c7ffe5f04 --- /dev/null +++ b/cecil-master/ProjectInfo.cs @@ -0,0 +1,20 @@ +// +// Author: +// Jb Evain (jbevain@gmail.com) +// +// Copyright (c) 2008 - 2015 Jb Evain +// +// Licensed under the MIT/X11 license. +// + +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyProduct (Consts.AssemblyName)] +[assembly: AssemblyCopyright ("Copyright © 2008 - 2018 Jb Evain")] + +[assembly: ComVisible (false)] + +[assembly: AssemblyVersion ("0.11.5.0")] +[assembly: AssemblyFileVersion ("0.11.5.0")] +[assembly: AssemblyInformationalVersion ("0.11.5.0")] diff --git a/cecil-master/README.md b/cecil-master/README.md new file mode 100644 index 000000000..eaa363733 --- /dev/null +++ b/cecil-master/README.md @@ -0,0 +1,15 @@ +Cecil +===== + +Mono.Cecil is a library to generate and inspect programs and libraries in the ECMA CIL form. + +To put it simply, you can use Cecil to: + +* Analyze .NET binaries using a simple and powerful object model, without having to load assemblies to use Reflection. +* Modify .NET binaries, add new metadata structures and alter the IL code. + +Cecil has been around since 2004 and is [widely used](https://github.com/jbevain/cecil/wiki/Users) in the .NET community. If you're using Cecil, or depend on a framework, project, or product using it, please consider [sponsoring Cecil](https://github.com/sponsors/jbevain/). + +To discuss Cecil, the best place is the [mono-cecil](https://groups.google.com/group/mono-cecil) Google Group. + +Cecil is a project under the benevolent umbrella of the [.NET Foundation](http://www.dotnetfoundation.org/). diff --git a/cecil-master/Test/Mono.Cecil.Tests.csproj b/cecil-master/Test/Mono.Cecil.Tests.csproj new file mode 100644 index 000000000..f7762e3f0 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests.csproj @@ -0,0 +1,29 @@ + + + + netcoreapp3.1;net40 + + + + 2.10.0 + + + + + Mono.Cecil + + + Mono.Cecil.Mdb + + + Mono.Cecil.Pdb + + + + + + + + + + diff --git a/cecil-master/Test/Mono.Cecil.Tests/AssemblyInfo.cs b/cecil-master/Test/Mono.Cecil.Tests/AssemblyInfo.cs new file mode 100644 index 000000000..f4a938ac4 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/AssemblyInfo.cs @@ -0,0 +1,6 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle ("Mono.Cecil.Tests")] + +[assembly: Guid ("da96c202-696a-457e-89af-5fa74e6bda0d")] diff --git a/cecil-master/Test/Mono.Cecil.Tests/AssemblyTests.cs b/cecil-master/Test/Mono.Cecil.Tests/AssemblyTests.cs new file mode 100644 index 000000000..649dca185 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/AssemblyTests.cs @@ -0,0 +1,109 @@ +using System; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class AssemblyTests : BaseTestFixture { + + [Test] + public void Name () + { + TestModule ("hello.exe", module => { + var name = module.Assembly.Name; + + Assert.IsNotNull (name); + + Assert.AreEqual ("hello", name.Name); + Assert.AreEqual ("", name.Culture); + Assert.AreEqual (new Version (0, 0, 0, 0), name.Version); + Assert.AreEqual (AssemblyHashAlgorithm.SHA1, name.HashAlgorithm); + }); + } + + [Test] + public void ParseLowerCaseNameParts () + { + var name = AssemblyNameReference.Parse ("Foo, version=2.0.0.0, culture=fr-FR"); + Assert.AreEqual ("Foo", name.Name); + Assert.AreEqual (2, name.Version.Major); + Assert.AreEqual (0, name.Version.Minor); + Assert.AreEqual ("fr-FR", name.Culture); + } + + [Test] + public void ZeroVersion () + { + var name = new AssemblyNameReference ("Foo", null); + Assert.AreEqual ("0.0.0.0", name.Version.ToString (fieldCount: 4)); + Assert.AreEqual ("Foo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", name.FullName); + + name = new AssemblyNameReference ("Foo", new Version (0, 0, 0, 0)); + Assert.AreEqual ("0.0.0.0", name.Version.ToString (fieldCount: 4)); + Assert.AreEqual ("Foo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", name.FullName); + } + + [Test] + public void NoBuildOrMajor () + { + var name = new AssemblyNameReference ("Foo", new Version (0, 0)); + Assert.AreEqual ("Foo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", name.FullName); + + name = new AssemblyNameReference ("Foo", new Version (0, 0, 0)); + Assert.AreEqual ("Foo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", name.FullName); + } + + [Test] + public void Retargetable () + { + if (Platform.OnCoreClr) + return; + + TestModule ("RetargetableExample.dll", module => { + var type = module.Types [1]; + var property = type.Properties [0]; + var attribute = property.CustomAttributes [0]; + + var argumentType = ((CustomAttributeArgument) attribute.ConstructorArguments [0].Value).Type; + var reference = (AssemblyNameReference) argumentType.Scope; + + Assert.AreEqual ( + "System.Data, Version=3.5.0.0, Culture=neutral, PublicKeyToken=969db8053d3322ac, Retargetable=Yes", + reference.FullName); + }, verify: !Platform.OnMono); + } + + [Test] + public void SystemRuntime () + { + if (Platform.OnCoreClr) + return; + + TestModule ("System.Runtime.dll", module => { + Assert.AreEqual ("System.Runtime", module.Assembly.Name.Name); + Assert.AreEqual (1, module.AssemblyReferences.Count); + Assert.AreNotEqual (module, module.TypeSystem.CoreLibrary); + Assert.AreEqual (module.AssemblyReferences [0], module.TypeSystem.CoreLibrary); + }, verify: !Platform.OnMono); + } + + [Test] + public void MismatchedLibraryAndSymbols () + { + // SQLite-net.dll (from nuget) shiped with mismatched symbol files, but throwIfNoSymbol did not prevent it from throwing + var parameters = new ReaderParameters { + ReadSymbols = true, + SymbolReaderProvider = new DefaultSymbolReaderProvider (throwIfNoSymbol: false), + ThrowIfSymbolsAreNotMatching = false, + }; + + using (var module = GetResourceModule ("SQLite-net.dll", parameters)) { + Assert.Null (module.SymbolReader); + } + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/BaseTestFixture.cs b/cecil-master/Test/Mono.Cecil.Tests/BaseTestFixture.cs new file mode 100644 index 000000000..046791bfa --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/BaseTestFixture.cs @@ -0,0 +1,357 @@ +using System; +using System.IO; +using System.Runtime.CompilerServices; +using Mono.Cecil.Cil; +using NUnit.Framework; + +using Mono.Cecil.PE; + +#if !NET_CORE +namespace System.Runtime.CompilerServices { + + [AttributeUsage (AttributeTargets.Parameter, Inherited = false)] + public sealed class CallerFilePathAttribute : Attribute { + } + + [AttributeUsage (AttributeTargets.Parameter, Inherited = false)] + public sealed class CallerMemberNameAttribute : Attribute { + } +} +#endif + +namespace Mono.Cecil.Tests { + + public abstract class BaseTestFixture { + + protected static void IgnoreOnMono () + { + if (Platform.OnMono) + Assert.Ignore (); + } + + protected static void IgnoreOnCoreClr () + { + if (Platform.OnCoreClr) + Assert.Ignore (); + } + + protected static void OnlyOnWindows () + { + if (!Platform.OnWindows) + Assert.Ignore (); + } + + public static string GetResourcePath (string name, string sourceFilePath) + { + return Path.Combine (FindResourcesDirectory (sourceFilePath), name); + } + + public static string GetAssemblyResourcePath (string name, [CallerFilePath] string sourceFilePath = "") + { + return GetResourcePath (Path.Combine ("assemblies", name), sourceFilePath); + } + + public static string GetCSharpResourcePath (string name, [CallerFilePath] string sourceFilePath = "") + { + return GetResourcePath (Path.Combine ("cs", name), sourceFilePath); + } + + public static string GetILResourcePath (string name, [CallerFilePath] string sourceFilePath = "") + { + return GetResourcePath (Path.Combine ("il", name), sourceFilePath); + } + + public ModuleDefinition GetResourceModule (string name, [CallerFilePath] string sourceFilePath = "") + { + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, sourceFilePath)); + } + + public ModuleDefinition GetResourceModule (string name, ReaderParameters parameters, [CallerFilePath] string sourceFilePath = "") + { + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, sourceFilePath), parameters); + } + + public ModuleDefinition GetResourceModule (string name, ReadingMode mode, [CallerFilePath] string sourceFilePath = "") + { + return ModuleDefinition.ReadModule (GetAssemblyResourcePath (name, sourceFilePath), new ReaderParameters (mode)); + } + + public Stream GetResourceStream (string name, [CallerFilePath] string sourceFilePath = "") + { + return new FileStream (GetAssemblyResourcePath (name, sourceFilePath), FileMode.Open, FileAccess.Read); + } + + internal Image GetResourceImage (string name, [CallerFilePath] string sourceFilePath = "") + { + var file = new FileStream (GetAssemblyResourcePath (name, sourceFilePath), FileMode.Open, FileAccess.Read); + return ImageReader.ReadImage (Disposable.Owned (file as Stream), file.Name); + } + + public ModuleDefinition GetCurrentModule () + { + return ModuleDefinition.ReadModule (GetType ().Module.FullyQualifiedName); + } + + public ModuleDefinition GetCurrentModule (ReaderParameters parameters) + { + return ModuleDefinition.ReadModule (GetType ().Module.FullyQualifiedName, parameters); + } + + public static string FindResourcesDirectory (string sourceFilePath) + { + var path = Path.GetDirectoryName (sourceFilePath); + while (!Directory.Exists (Path.Combine (path, "Resources"))) { + var old = path; + path = Path.GetDirectoryName (path); + Assert.AreNotEqual (old, path); + } + + return Path.Combine (path, "Resources"); + } + + public static void AssertCode (string expected, MethodDefinition method) + { + Assert.IsTrue (method.HasBody); + Assert.IsNotNull (method.Body); + + Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method))); + } + + public static string Normalize (string str) + { + return str.Trim ().Replace ("\r\n", "\n"); + } + + public static void TestModule (string file, Action test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null, IAssemblyResolver assemblyResolver = null, bool applyWindowsRuntimeProjections = false, [CallerFilePath] string sourceFilePath = "") + { + Run (new ModuleTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections, sourceFilePath)); + } + + public static void TestCSharp (string file, Action test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null, IAssemblyResolver assemblyResolver = null, bool applyWindowsRuntimeProjections = false, [CallerFilePath] string sourceFilePath = "") + { + Run (new CSharpTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections, sourceFilePath)); + } + + public static void TestIL (string file, Action test, bool verify = true, bool readOnly = false, Type symbolReaderProvider = null, Type symbolWriterProvider = null, IAssemblyResolver assemblyResolver = null, bool applyWindowsRuntimeProjections = false, [CallerFilePath] string sourceFilePath = "") + { + Run (new ILTestCase (file, test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections, sourceFilePath)); + } + + static void Run (TestCase testCase) + { + using (var runner = new TestRunner (testCase, TestCaseType.ReadDeferred)) + runner.RunTest (); + + using (var runner = new TestRunner (testCase, TestCaseType.ReadImmediate)) + runner.RunTest (); + + if (testCase.ReadOnly) + return; + + using (var runner = new TestRunner (testCase, TestCaseType.WriteFromDeferred)) + runner.RunTest (); + + using (var runner = new TestRunner (testCase, TestCaseType.WriteFromImmediate)) + runner.RunTest (); + } + } + + abstract class TestCase { + + public readonly bool Verify; + public readonly bool ReadOnly; + public readonly Type SymbolReaderProvider; + public readonly Type SymbolWriterProvider; + public readonly IAssemblyResolver AssemblyResolver; + public readonly Action Test; + public readonly bool ApplyWindowsRuntimeProjections; + public readonly string SourceFilePath; + + public abstract string ModuleLocation { get; } + + protected TestCase (Action test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections, string sourceFilePath = "") + { + Test = test; + Verify = verify; + ReadOnly = readOnly; + SymbolReaderProvider = symbolReaderProvider; + SymbolWriterProvider = symbolWriterProvider; + AssemblyResolver = assemblyResolver; + ApplyWindowsRuntimeProjections = applyWindowsRuntimeProjections; + SourceFilePath = sourceFilePath; + } + } + + class ModuleTestCase : TestCase { + + public readonly string Module; + + public ModuleTestCase (string module, Action test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections, string sourceFilePath = "") + : base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections, sourceFilePath) + { + Module = module; + } + + public override string ModuleLocation + { + get { return BaseTestFixture.GetAssemblyResourcePath (Module, SourceFilePath); } + } + } + + class CSharpTestCase : TestCase { + + public readonly string File; + + public CSharpTestCase (string file, Action test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections, string sourceFilePath = "") + : base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections, sourceFilePath) + { + File = file; + } + + public override string ModuleLocation + { + get + { + return CompilationService.CompileResource (BaseTestFixture.GetCSharpResourcePath (File, SourceFilePath)); + } + } + } + + class ILTestCase : TestCase { + + public readonly string File; + + public ILTestCase (string file, Action test, bool verify, bool readOnly, Type symbolReaderProvider, Type symbolWriterProvider, IAssemblyResolver assemblyResolver, bool applyWindowsRuntimeProjections, string sourceFilePath = "") + : base (test, verify, readOnly, symbolReaderProvider, symbolWriterProvider, assemblyResolver, applyWindowsRuntimeProjections, sourceFilePath) + { + File = file; + } + + public override string ModuleLocation + { + get + { + return CompilationService.CompileResource (BaseTestFixture.GetILResourcePath (File, SourceFilePath)); ; + } + } + } + + class TestRunner : IDisposable { + + readonly TestCase test_case; + readonly TestCaseType type; + + ModuleDefinition test_module; + DefaultAssemblyResolver test_resolver; + + public TestRunner (TestCase testCase, TestCaseType type) + { + this.test_case = testCase; + this.type = type; + } + + ModuleDefinition GetModule () + { + var location = test_case.ModuleLocation; + + var parameters = new ReaderParameters { + SymbolReaderProvider = GetSymbolReaderProvider (), + AssemblyResolver = GetAssemblyResolver (), + ApplyWindowsRuntimeProjections = test_case.ApplyWindowsRuntimeProjections + }; + + switch (type) { + case TestCaseType.ReadImmediate: + parameters.ReadingMode = ReadingMode.Immediate; + return ModuleDefinition.ReadModule (location, parameters); + case TestCaseType.ReadDeferred: + parameters.ReadingMode = ReadingMode.Deferred; + return ModuleDefinition.ReadModule (location, parameters); + case TestCaseType.WriteFromImmediate: + parameters.ReadingMode = ReadingMode.Immediate; + return RoundTrip (location, parameters, "cecil-irt"); + case TestCaseType.WriteFromDeferred: + parameters.ReadingMode = ReadingMode.Deferred; + return RoundTrip (location, parameters, "cecil-drt"); + default: + return null; + } + } + + ISymbolReaderProvider GetSymbolReaderProvider () + { + if (test_case.SymbolReaderProvider == null) + return null; + + return (ISymbolReaderProvider) Activator.CreateInstance (test_case.SymbolReaderProvider); + } + + ISymbolWriterProvider GetSymbolWriterProvider () + { + if (test_case.SymbolReaderProvider == null) + return null; + + return (ISymbolWriterProvider) Activator.CreateInstance (test_case.SymbolWriterProvider); + } + + IAssemblyResolver GetAssemblyResolver () + { + if (test_case.AssemblyResolver != null) + return test_case.AssemblyResolver; + + test_resolver = new DefaultAssemblyResolver (); + var directory = Path.GetDirectoryName (test_case.ModuleLocation); + test_resolver.AddSearchDirectory (directory); + return test_resolver; + } + + ModuleDefinition RoundTrip (string location, ReaderParameters reader_parameters, string folder) + { + var rt_folder = Path.Combine (Path.GetTempPath (), folder); + if (!Directory.Exists (rt_folder)) + Directory.CreateDirectory (rt_folder); + var rt_module = Path.Combine (rt_folder, Path.GetFileName (location)); + + using (var module = ModuleDefinition.ReadModule (location, reader_parameters)) { + var writer_parameters = new WriterParameters { + SymbolWriterProvider = GetSymbolWriterProvider (), + }; + + test_case.Test (module); + + module.Write (rt_module, writer_parameters); + } + + if (test_case.Verify) + CompilationService.Verify (rt_module); + + return ModuleDefinition.ReadModule (rt_module, reader_parameters); + } + + public void RunTest () + { + var module = GetModule (); + if (module == null) + return; + + test_module = module; + test_case.Test (module); + } + + public void Dispose () + { + if (test_module != null) + test_module.Dispose (); + + if (test_resolver != null) + test_resolver.Dispose (); + } + } + + enum TestCaseType { + ReadImmediate, + ReadDeferred, + WriteFromImmediate, + WriteFromDeferred, + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/CompilationService.cs b/cecil-master/Test/Mono.Cecil.Tests/CompilationService.cs new file mode 100644 index 000000000..f7ecc4c29 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/CompilationService.cs @@ -0,0 +1,385 @@ +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Text; +using System.Reflection; +using NUnit.Framework; + +#if NET_CORE +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Emit; +using CS = Microsoft.CodeAnalysis.CSharp; +#endif + +namespace Mono.Cecil.Tests { + + struct CompilationResult { + internal DateTime source_write_time; + internal string result_file; + + public CompilationResult (DateTime write_time, string result_file) + { + this.source_write_time = write_time; + this.result_file = result_file; + } + } + + public static class Platform { + + public static bool OnMono { + get { return TryGetType ("Mono.Runtime") != null; } + } + + public static bool OnCoreClr { + get { return TryGetType ("System.Runtime.Loader.AssemblyLoadContext, System.Runtime.Loader, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a") != null; } + } + + public static bool OnWindows { + get { return Environment.OSVersion.Platform == PlatformID.Win32NT; } + } + + public static bool HasNativePdbSupport { + get { return OnWindows && !OnMono; } + } + + static Type TryGetType (string assemblyQualifiedName) + { + try { + // Note that throwOnError=false only suppresses some exceptions, not all. + return Type.GetType(assemblyQualifiedName, throwOnError: false); + } catch { + return null; + } + } + } + + abstract class CompilationService { + + Dictionary files = new Dictionary (); + + bool TryGetResult (string name, out string file_result) + { + file_result = null; + CompilationResult result; + if (!files.TryGetValue (name, out result)) + return false; + + if (result.source_write_time != File.GetLastWriteTime (name)) + return false; + + file_result = result.result_file; + return true; + } + + public string Compile (string name) + { + string result_file; + if (TryGetResult (name, out result_file)) + return result_file; + + result_file = CompileFile (name); + RegisterFile (name, result_file); + return result_file; + } + + void RegisterFile (string name, string result_file) + { + files [name] = new CompilationResult (File.GetLastWriteTime (name), result_file); + } + + protected abstract string CompileFile (string name); + + public static string CompileResource (string name) + { + var extension = Path.GetExtension (name); + if (extension == ".il") + return IlasmCompilationService.Instance.Compile (name); + + if (extension == ".cs") +#if NET_CORE + return RoslynCompilationService.Instance.Compile (name); +#else + return CodeDomCompilationService.Instance.Compile (name); +#endif + throw new NotSupportedException (extension); + } + + protected static string GetCompiledFilePath (string file_name) + { + var tmp_cecil = Path.Combine (Path.GetTempPath (), "cecil"); + if (!Directory.Exists (tmp_cecil)) + Directory.CreateDirectory (tmp_cecil); + + return Path.Combine (tmp_cecil, Path.GetFileName (file_name) + ".dll"); + } + + public static void Verify (string name) + { +#if !NET_CORE + var output = Platform.OnMono ? ShellService.PEDump (name) : ShellService.PEVerify (name); + if (output.ExitCode != 0) + Assert.Fail (output.ToString ()); +#endif + } + } + + class IlasmCompilationService : CompilationService { + + public static readonly IlasmCompilationService Instance = new IlasmCompilationService (); + + protected override string CompileFile (string name) + { + string file = GetCompiledFilePath (name); + + var output = ShellService.ILAsm (name, file); + + AssertAssemblerResult (output); + + return file; + } + + static void AssertAssemblerResult (ShellService.ProcessOutput output) + { + if (output.ExitCode != 0) + Assert.Fail (output.ToString ()); + } + } + +#if NET_CORE + + class RoslynCompilationService : CompilationService { + + public static readonly RoslynCompilationService Instance = new RoslynCompilationService (); + + protected override string CompileFile (string name) + { + var compilation = GetCompilation (name); + var outputName = GetCompiledFilePath (name); + + var result = compilation.Emit (outputName); + Assert.IsTrue (result.Success, GetErrorMessage (result)); + + return outputName; + } + + static Compilation GetCompilation (string name) + { + var assemblyName = Path.GetFileNameWithoutExtension (name); + var source = File.ReadAllText (name); + + var tpa = BaseAssemblyResolver.TrustedPlatformAssemblies.Value; + + var references = new [] + { + MetadataReference.CreateFromFile (tpa ["netstandard"]), + MetadataReference.CreateFromFile (tpa ["mscorlib"]), + MetadataReference.CreateFromFile (tpa ["System.Private.CoreLib"]), + MetadataReference.CreateFromFile (tpa ["System.Runtime"]), + MetadataReference.CreateFromFile (tpa ["System.Console"]), + MetadataReference.CreateFromFile (tpa ["System.Security.AccessControl"]), + }; + + var extension = Path.GetExtension (name); + switch (extension) { + case ".cs": + return CS.CSharpCompilation.Create ( + assemblyName, + new [] { CS.SyntaxFactory.ParseSyntaxTree (source, new CS.CSharpParseOptions (preprocessorSymbols: new string [] { "NET_CORE" })) }, + references, + new CS.CSharpCompilationOptions (OutputKind.DynamicallyLinkedLibrary, optimizationLevel: OptimizationLevel.Release)); + default: + throw new NotSupportedException (); + } + } + + static string GetErrorMessage (EmitResult result) + { + if (result.Success) + return string.Empty; + + var builder = new StringBuilder (); + foreach (var diagnostic in result.Diagnostics) + builder.AppendLine (diagnostic.ToString ()); + + return builder.ToString (); + } + } + +#else + + class CodeDomCompilationService : CompilationService { + + public static readonly CodeDomCompilationService Instance = new CodeDomCompilationService (); + + protected override string CompileFile (string name) + { + string file = GetCompiledFilePath (name); + + using (var provider = GetProvider (name)) { + var parameters = GetDefaultParameters (name); + parameters.IncludeDebugInformation = false; + parameters.GenerateExecutable = false; + parameters.OutputAssembly = file; + + var results = provider.CompileAssemblyFromFile (parameters, name); + AssertCompilerResults (results); + } + + return file; + } + + static void AssertCompilerResults (CompilerResults results) + { + Assert.IsFalse (results.Errors.HasErrors, GetErrorMessage (results)); + } + + static string GetErrorMessage (CompilerResults results) + { + if (!results.Errors.HasErrors) + return string.Empty; + + var builder = new StringBuilder (); + foreach (CompilerError error in results.Errors) + builder.AppendLine (error.ToString ()); + return builder.ToString (); + } + + static CompilerParameters GetDefaultParameters (string name) + { + return GetCompilerInfo (name).CreateDefaultCompilerParameters (); + } + + static CodeDomProvider GetProvider (string name) + { + return GetCompilerInfo (name).CreateProvider (); + } + + static CompilerInfo GetCompilerInfo (string name) + { + return CodeDomProvider.GetCompilerInfo ( + CodeDomProvider.GetLanguageFromExtension (Path.GetExtension (name))); + } + } + +#endif + + class ShellService { + + public class ProcessOutput { + + public int ExitCode; + public string StdOut; + public string StdErr; + + public ProcessOutput (int exitCode, string stdout, string stderr) + { + ExitCode = exitCode; + StdOut = stdout; + StdErr = stderr; + } + + public override string ToString () + { + return StdOut + StdErr; + } + } + + static ProcessOutput RunProcess (string target, params string [] arguments) + { + var stdout = new StringWriter (); + var stderr = new StringWriter (); + + var process = new Process { + StartInfo = new ProcessStartInfo { + FileName = target, + Arguments = string.Join (" ", arguments), + CreateNoWindow = true, + UseShellExecute = false, + RedirectStandardError = true, + RedirectStandardInput = true, + RedirectStandardOutput = true, + }, + }; + + process.Start (); + + process.OutputDataReceived += (_, args) => stdout.Write (args.Data); + process.ErrorDataReceived += (_, args) => stderr.Write (args.Data); + + process.BeginOutputReadLine (); + process.BeginErrorReadLine (); + + process.WaitForExit (); + + return new ProcessOutput (process.ExitCode, stdout.ToString (), stderr.ToString ()); + } + + public static ProcessOutput ILAsm (string source, string output) + { + var ilasm = "ilasm"; + if (Platform.OnWindows) + ilasm = NetFrameworkTool ("ilasm"); + + return RunProcess (ilasm, "/nologo", "/dll", "/out:" + Quote (output), Quote (source)); + } + + static string Quote (string file) + { + return "\"" + file + "\""; + } + + public static ProcessOutput PEVerify (string source) + { + return RunProcess (WinSdkTool ("peverify"), "/nologo", Quote (source)); + } + + public static ProcessOutput PEDump (string source) + { + return RunProcess ("pedump", "--verify code,metadata", Quote (source)); + } + + static string NetFrameworkTool (string tool) + { +#if NET_CORE + return Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Windows), "Microsoft.NET", "Framework", "v4.0.30319", tool + ".exe"); +#else + return Path.Combine ( + Path.GetDirectoryName (typeof (object).Assembly.Location), + tool + ".exe"); +#endif + } + + static string WinSdkTool (string tool) + { + var sdks = new [] { + @"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools", + @"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.2 Tools", + @"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7.1 Tools", + @"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.7 Tools", + @"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.2 Tools", + @"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools", + @"Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6 Tools", + @"Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools", + @"Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools", + @"Microsoft SDKs\Windows\v7.0A\Bin", + }; + + foreach (var sdk in sdks) { + var pgf = IntPtr.Size == 8 + ? Environment.GetEnvironmentVariable("ProgramFiles(x86)") + : Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles); + + var exe = Path.Combine ( + Path.Combine (pgf, sdk), + tool + ".exe"); + + if (File.Exists(exe)) + return exe; + } + + return tool; + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/CustomAttributesTests.cs b/cecil-master/Test/Mono.Cecil.Tests/CustomAttributesTests.cs new file mode 100644 index 000000000..00f00ca47 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/CustomAttributesTests.cs @@ -0,0 +1,852 @@ +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + +using Mono.Cecil; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class CustomAttributesTests : BaseTestFixture { + + [Test] + public void StringArgumentOnType () + { + TestCSharp ("CustomAttributes.cs", module => { + var hamster = module.GetType ("Hamster"); + + Assert.IsTrue (hamster.HasCustomAttributes); + Assert.AreEqual (1, hamster.CustomAttributes.Count); + + var attribute = hamster.CustomAttributes [0]; + Assert.AreEqual ("System.Void FooAttribute::.ctor(System.String)", + attribute.Constructor.FullName); + + Assert.IsTrue (attribute.HasConstructorArguments); + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + AssertArgument ("bar", attribute.ConstructorArguments [0]); + }); + } + + [Test] + public void NullString () + { + TestCSharp ("CustomAttributes.cs", module => { + var dentist = module.GetType ("Dentist"); + + var attribute = GetAttribute (dentist, "Foo"); + Assert.IsNotNull (attribute); + + AssertArgument (null, attribute.ConstructorArguments [0]); + }); + } + + [Test] + public void Primitives1 () + { + TestCSharp ("CustomAttributes.cs", module => { + var steven = module.GetType ("Steven"); + + var attribute = GetAttribute (steven, "Foo"); + Assert.IsNotNull (attribute); + + AssertArgument (-12, attribute.ConstructorArguments [0]); + AssertArgument (242, attribute.ConstructorArguments [1]); + AssertArgument (true, attribute.ConstructorArguments [2]); + AssertArgument (false, attribute.ConstructorArguments [3]); + AssertArgument (4242, attribute.ConstructorArguments [4]); + AssertArgument (-1983, attribute.ConstructorArguments [5]); + AssertArgument ('c', attribute.ConstructorArguments [6]); + }); + } + + [Test] + public void Primitives2 () + { + TestCSharp ("CustomAttributes.cs", module => { + var seagull = module.GetType ("Seagull"); + + var attribute = GetAttribute (seagull, "Foo"); + Assert.IsNotNull (attribute); + + AssertArgument (-100000, attribute.ConstructorArguments [0]); + AssertArgument (200000, attribute.ConstructorArguments [1]); + AssertArgument (12.12f, attribute.ConstructorArguments [2]); + AssertArgument (long.MaxValue, attribute.ConstructorArguments [3]); + AssertArgument (ulong.MaxValue, attribute.ConstructorArguments [4]); + AssertArgument (64.646464, attribute.ConstructorArguments [5]); + }); + } + + [Test] + public void StringArgumentOnAssembly () + { + TestCSharp ("CustomAttributes.cs", module => { + var assembly = module.Assembly; + + var attribute = GetAttribute (assembly, "Foo"); + Assert.IsNotNull (attribute); + + AssertArgument ("bingo", attribute.ConstructorArguments [0]); + }); + } + + [Test] + public void CharArray () + { + TestCSharp ("CustomAttributes.cs", module => { + var rifle = module.GetType ("Rifle"); + + var attribute = GetAttribute (rifle, "Foo"); + Assert.IsNotNull (attribute); + + var argument = attribute.ConstructorArguments [0]; + + Assert.AreEqual ("System.Char[]", argument.Type.FullName); + + var array = argument.Value as CustomAttributeArgument []; + Assert.IsNotNull (array); + + var str = "cecil"; + + Assert.AreEqual (array.Length, str.Length); + + for (int i = 0; i < str.Length; i++) + AssertArgument (str [i], array [i]); + }); + } + + [Test] + public void BoxedArguments () + { + TestCSharp ("CustomAttributes.cs", module => { + var worm = module.GetType ("Worm"); + + var attribute = GetAttribute (worm, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (".ctor ((Object:(String:\"2\")), (Object:(I4:2)))", PrettyPrint (attribute)); + }); + } + + [Test] + public void BoxedArraysArguments () + { + TestCSharp ("CustomAttributes.cs", module => { + var sheep = module.GetType ("Sheep"); + + var attribute = GetAttribute (sheep, "Foo"); + Assert.IsNotNull (attribute); + + // [Foo (new object [] { "2", 2, 'c' }, new object [] { new object [] { 1, 2, 3}, null })] + AssertCustomAttribute (".ctor ((Object:(Object[]:{(Object:(String:\"2\")), (Object:(I4:2)), (Object:(Char:'c'))})), (Object:(Object[]:{(Object:(Object[]:{(Object:(I4:1)), (Object:(I4:2)), (Object:(I4:3))})), (Object:(String:null))})))", attribute); + }); + } + + [Test] + public void FieldsAndProperties () + { + TestCSharp ("CustomAttributes.cs", module => { + var angola = module.GetType ("Angola"); + + var attribute = GetAttribute (angola, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (2, attribute.Fields.Count); + + var argument = attribute.Fields.Where (a => a.Name == "Pan").First (); + AssertCustomAttributeArgument ("(Object:(Object[]:{(Object:(I4:1)), (Object:(String:\"2\")), (Object:(Char:'3'))}))", argument); + + argument = attribute.Fields.Where (a => a.Name == "PanPan").First (); + AssertCustomAttributeArgument ("(String[]:{(String:\"yo\"), (String:\"yo\")})", argument); + + Assert.AreEqual (2, attribute.Properties.Count); + + argument = attribute.Properties.Where (a => a.Name == "Bang").First (); + AssertArgument (42, argument); + + argument = attribute.Properties.Where (a => a.Name == "Fiou").First (); + AssertArgument (null, argument); + }); + } + + [Test] + public void BoxedStringField () + { + TestCSharp ("CustomAttributes.cs", module => { + var type = module.GetType ("BoxedStringField"); + + var attribute = GetAttribute (type, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (1, attribute.Fields.Count); + + var argument = attribute.Fields.Where (a => a.Name == "Pan").First (); + AssertCustomAttributeArgument ("(Object:(String:\"fiouuu\"))", argument); + }); + } + + [Test] + public void TypeDefinitionEnum () + { + TestCSharp ("CustomAttributes.cs", module => { + var zero = module.GetType ("Zero"); + + var attribute = GetAttribute (zero, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + Assert.AreEqual ((short) 2, attribute.ConstructorArguments [0].Value); + Assert.AreEqual ("Bingo", attribute.ConstructorArguments [0].Type.FullName); + }); + } + + [Test] + public void TypeReferenceEnum () + { + TestCSharp ("CustomAttributes.cs", module => { + var ace = module.GetType ("Ace"); + + var attribute = GetAttribute (ace, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + Assert.AreEqual ((byte) 0x04, attribute.ConstructorArguments [0].Value); + Assert.AreEqual ("System.Security.AccessControl.AceFlags", attribute.ConstructorArguments [0].Type.FullName); + Assert.AreEqual (module, attribute.ConstructorArguments [0].Type.Module); + }); + } + + [Test] + public void BoxedEnumReference () + { + TestCSharp ("CustomAttributes.cs", module => { + var bzzz = module.GetType ("Bzzz"); + + var attribute = GetAttribute (bzzz, "Foo"); + Assert.IsNotNull (attribute); + + // [Foo (new object [] { Bingo.Fuel, Bingo.Binga }, null, Pan = System.Security.AccessControl.AceFlags.NoPropagateInherit)] + + Assert.AreEqual (2, attribute.ConstructorArguments.Count); + + var argument = attribute.ConstructorArguments [0]; + + AssertCustomAttributeArgument ("(Object:(Object[]:{(Object:(Bingo:2)), (Object:(Bingo:4))}))", argument); + + argument = attribute.ConstructorArguments [1]; + + AssertCustomAttributeArgument ("(Object:(String:null))", argument); + + argument = attribute.Fields.Where (a => a.Name == "Pan").First ().Argument; + + AssertCustomAttributeArgument ("(Object:(System.Security.AccessControl.AceFlags:4))", argument); + }); + } + + [Test] + public void TypeOfTypeDefinition () + { + TestCSharp ("CustomAttributes.cs", module => { + var typed = module.GetType ("Typed"); + + var attribute = GetAttribute (typed, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + var argument = attribute.ConstructorArguments [0]; + + Assert.AreEqual ("System.Type", argument.Type.FullName); + + var type = argument.Value as TypeDefinition; + Assert.IsNotNull (type); + + Assert.AreEqual ("Bingo", type.FullName); + }); + } + + [Test] + public void TypeOfNestedTypeDefinition () + { + TestCSharp ("CustomAttributes.cs", module => { + var typed = module.GetType ("NestedTyped"); + + var attribute = GetAttribute (typed, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + var argument = attribute.ConstructorArguments [0]; + + Assert.AreEqual ("System.Type", argument.Type.FullName); + + var type = argument.Value as TypeDefinition; + Assert.IsNotNull (type); + + Assert.AreEqual ("FooAttribute/Token", type.FullName); + }); + } + + [Test] + public void FieldTypeOf () + { + TestCSharp ("CustomAttributes.cs", module => { + var truc = module.GetType ("Truc"); + + var attribute = GetAttribute (truc, "Foo"); + Assert.IsNotNull (attribute); + + var argument = attribute.Fields.Where (a => a.Name == "Chose").First ().Argument; + + Assert.AreEqual ("System.Type", argument.Type.FullName); + + var type = argument.Value as TypeDefinition; + Assert.IsNotNull (type); + + Assert.AreEqual ("Typed", type.FullName); + }); + } + + [Test] + public void EscapedTypeName () + { + TestModule ("bug-185.dll", module => { + var foo = module.GetType ("Foo"); + var foo_do = foo.Methods.Where (m => !m.IsConstructor).First (); + + var attribute = foo_do.CustomAttributes.Where (ca => ca.AttributeType.Name == "AsyncStateMachineAttribute").First (); + + Assert.AreEqual (foo.NestedTypes [0], attribute.ConstructorArguments [0].Value); + + var function = module.GetType ("Function`1"); + + var apply = function.Methods.Where(m => !m.IsConstructor).First (); + + attribute = apply.CustomAttributes.Where (ca => ca.AttributeType.Name == "AsyncStateMachineAttribute").First (); + + Assert.AreEqual (function.NestedTypes [0], attribute.ConstructorArguments [0].Value); + }); + } + + [Test] + public void FieldNullTypeOf () + { + TestCSharp ("CustomAttributes.cs", module => { + var truc = module.GetType ("Machin"); + + var attribute = GetAttribute (truc, "Foo"); + Assert.IsNotNull (attribute); + + var argument = attribute.Fields.Where (a => a.Name == "Chose").First ().Argument; + + Assert.AreEqual ("System.Type", argument.Type.FullName); + + Assert.IsNull (argument.Value); + }); + } + + [Test] + public void OpenGenericTypeOf () + { + TestCSharp ("CustomAttributes.cs", module => { + var open_generic = module.GetType ("OpenGeneric`2"); + Assert.IsNotNull (open_generic); + + var attribute = GetAttribute (open_generic, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + var argument = attribute.ConstructorArguments [0]; + + Assert.AreEqual ("System.Type", argument.Type.FullName); + + var type = argument.Value as TypeReference; + Assert.IsNotNull (type); + + Assert.AreEqual ("System.Collections.Generic.Dictionary`2", type.FullName); + }); + } + + [Test] + public void ClosedGenericTypeOf () + { + TestCSharp ("CustomAttributes.cs", module => { + var closed_generic = module.GetType ("ClosedGeneric"); + Assert.IsNotNull (closed_generic); + + var attribute = GetAttribute (closed_generic, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + var argument = attribute.ConstructorArguments [0]; + + Assert.AreEqual ("System.Type", argument.Type.FullName); + + var type = argument.Value as TypeReference; + Assert.IsNotNull (type); + + Assert.AreEqual ("System.Collections.Generic.Dictionary`2[,]>", type.FullName); + }); + } + + [Test] + public void TypeOfArrayOfNestedClass () + { + TestCSharp ("CustomAttributes.cs", module => { + var parent = module.GetType ("Parent"); + Assert.IsNotNull (parent); + + var attribute = GetAttribute (parent, "Foo"); + Assert.IsNotNull (attribute); + + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + var argument = attribute.ConstructorArguments [0]; + + Assert.AreEqual ("System.Type", argument.Type.FullName); + + var type = argument.Value as TypeReference; + Assert.IsNotNull (type); + + Assert.AreEqual ("Parent/Child[]", type.FullName); + }); + } + + [Test] + public void EmptyBlob () + { + TestIL ("ca-empty-blob.il", module => { + var attribute = module.GetType ("CustomAttribute"); + Assert.AreEqual (1, attribute.CustomAttributes.Count); + Assert.AreEqual (0, attribute.CustomAttributes [0].ConstructorArguments.Count); + }, verify: !Platform.OnMono); + } + + [Test] + public void InterfaceImplementation () + { + OnlyOnWindows (); // Mono's ilasm doesn't support .interfaceimpl + + TestIL ("ca-iface-impl.il", module => { + var type = module.GetType ("FooType"); + var iface = type.Interfaces.Single (i => i.InterfaceType.FullName == "IFoo"); + Assert.IsTrue (iface.HasCustomAttributes); + var attributes = iface.CustomAttributes; + Assert.AreEqual (1, attributes.Count); + Assert.AreEqual ("FooAttribute", attributes [0].AttributeType.FullName); + }); + } + + [Test] + public void GenericParameterConstraint () + { + TestModule ("GenericParameterConstraintAttributes.dll", module => { + var type = module.GetType ("Foo.Library`1"); + var gp = type.GenericParameters.Single (); + var constraint = gp.Constraints.Single (); + + Assert.IsTrue (constraint.HasCustomAttributes); + var attributes = constraint.CustomAttributes; + Assert.AreEqual (1, attributes.Count); + Assert.AreEqual ("System.Runtime.CompilerServices.NullableAttribute", attributes [0].AttributeType.FullName); + }, verify: !Platform.OnMono); + } + + [Test] + public void GenericAttributeString () + { + TestModule ("GenericAttributes.dll", module => { + var type = module.GetType ("WithGenericAttribute_OfString"); + Assert.IsTrue (type.HasCustomAttributes); + var attributes = type.CustomAttributes; + Assert.AreEqual (1, attributes.Count); + Assert.AreEqual ("GenericAttribute`1", attributes [0].AttributeType.FullName); + var attribute = attributes [0]; + // constructor arguments + Assert.AreEqual (true, attribute.HasConstructorArguments); + var argument = attribute.ConstructorArguments.Single (); + Assert.AreEqual ("System.String", argument.Type.FullName); + Assert.AreEqual ("t", argument.Value); + // named field argument + Assert.AreEqual (true, attribute.HasFields); + var field = attribute.Fields.Single (); + Assert.AreEqual ("F", field.Name); + Assert.AreEqual ("System.String", field.Argument.Type.FullName); + Assert.AreEqual ("f", field.Argument.Value); + // named property argument + Assert.AreEqual (true, attribute.HasProperties); + var property = attribute.Properties.Single (); + Assert.AreEqual ("P", property.Name); + Assert.AreEqual ("System.String", property.Argument.Type.FullName); + Assert.AreEqual ("p", property.Argument.Value); + + }, verify: !Platform.OnMono); + } + + [Test] + public void GenericAttributeInt () + { + TestModule ("GenericAttributes.dll", module => { + var type = module.GetType ("WithGenericAttribute_OfInt"); + Assert.IsTrue (type.HasCustomAttributes); + var attributes = type.CustomAttributes; + Assert.AreEqual (1, attributes.Count); + Assert.AreEqual ("GenericAttribute`1", attributes [0].AttributeType.FullName); + var attribute = attributes [0]; + // constructor arguments + Assert.AreEqual (true, attribute.HasConstructorArguments); + var argument = attribute.ConstructorArguments.Single (); + Assert.AreEqual ("System.Int32", argument.Type.FullName); + Assert.AreEqual (1, argument.Value); + // named field argument + Assert.AreEqual (true, attribute.HasFields); + var field = attribute.Fields.Single (); + Assert.AreEqual ("F", field.Name); + Assert.AreEqual ("System.Int32", field.Argument.Type.FullName); + Assert.AreEqual (2, field.Argument.Value); + // named property argument + Assert.AreEqual (true, attribute.HasProperties); + var property = attribute.Properties.Single (); + Assert.AreEqual ("P", property.Name); + Assert.AreEqual ("System.Int32", property.Argument.Type.FullName); + Assert.AreEqual (3, property.Argument.Value); + }, verify: !Platform.OnMono); + } + + [Test] + public void ConstrainedGenericAttribute () + { + TestModule ("GenericAttributes.dll", module => { + var type = module.GetType ("WithConstrainedGenericAttribute"); + Assert.IsTrue (type.HasCustomAttributes); + var attributes = type.CustomAttributes; + Assert.AreEqual (1, attributes.Count); + var attribute = attributes [0]; + Assert.AreEqual ("ConstrainedGenericAttribute`1", attribute.AttributeType.FullName); + }, verify: !Platform.OnMono); + } + + [Test] + public void NullCharInString () + { + TestCSharp ("CustomAttributes.cs", module => { + var type = module.GetType ("NullCharInString"); + var attributes = type.CustomAttributes; + Assert.AreEqual (1, attributes.Count); + var attribute = attributes [0]; + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + var value = (string) attribute.ConstructorArguments [0].Value; + Assert.AreEqual (8, value.Length); + Assert.AreEqual ('\0', value [7]); + }); + } + + [Test] + public void OrderedAttributes () + { + TestModule ("ordered-attrs.exe", module => { + var type = module.GetType ("Program"); + var method = type.GetMethod ("Main"); + var attributes = method.CustomAttributes; + Assert.AreEqual (6, attributes.Count); + + Assert.AreEqual ("AAttribute", attributes [0].AttributeType.Name); + Assert.AreEqual ("Main.A1", attributes [0].Fields [0].Argument.Value as string); + + Assert.AreEqual ("AAttribute", attributes [1].AttributeType.Name); + Assert.AreEqual ("Main.A2", attributes [1].Fields [0].Argument.Value as string); + + Assert.AreEqual ("BAttribute", attributes [2].AttributeType.Name); + Assert.AreEqual ("Main.B1", attributes [2].Fields [0].Argument.Value as string); + + Assert.AreEqual ("AAttribute", attributes [3].AttributeType.Name); + Assert.AreEqual ("Main.A3", attributes [3].Fields [0].Argument.Value as string); + + Assert.AreEqual ("BAttribute", attributes [4].AttributeType.Name); + Assert.AreEqual ("Main.B2", attributes [4].Fields [0].Argument.Value as string); + + Assert.AreEqual ("BAttribute", attributes [5].AttributeType.Name); + Assert.AreEqual ("Main.B3", attributes [5].Fields [0].Argument.Value as string); + }); + } + + [Test] + public void DefineCustomAttributeFromBlob () + { + var file = Path.Combine (Path.GetTempPath (), "CaBlob.dll"); + + var module = ModuleDefinition.CreateModule ("CaBlob.dll", new ModuleParameters { Kind = ModuleKind.Dll, Runtime = TargetRuntime.Net_2_0 }); + var assembly_title_ctor = module.ImportReference (typeof (System.Reflection.AssemblyTitleAttribute).GetConstructor (new [] {typeof (string)})); + + Assert.IsNotNull (assembly_title_ctor); + + var buffer = new ByteBuffer (); + buffer.WriteUInt16 (1); // ca signature + + var title = Encoding.UTF8.GetBytes ("CaBlob"); + + buffer.WriteCompressedUInt32 ((uint) title.Length); + buffer.WriteBytes (title); + + buffer.WriteUInt16 (0); // named arguments + + var blob = new byte [buffer.length]; + Buffer.BlockCopy (buffer.buffer, 0, blob, 0, buffer.length); + + var attribute = new CustomAttribute (assembly_title_ctor, blob); + module.Assembly.CustomAttributes.Add (attribute); + + module.Write (file); + + module = ModuleDefinition.ReadModule (file); + + attribute = GetAttribute (module.Assembly, "AssemblyTitle"); + + Assert.IsNotNull (attribute); + Assert.AreEqual ("CaBlob", (string) attribute.ConstructorArguments [0].Value); + + module.Dispose (); + } + +#if NET_CORE + [Test] + public void BoxedEnumOnGenericArgumentOnType () + { + TestCSharp ("CustomAttributes.cs", module => { + var valueEnumGenericType = module.GetType ("BoxedValueEnumOnGenericType"); + + Assert.IsTrue (valueEnumGenericType.HasCustomAttributes); + Assert.AreEqual (1, valueEnumGenericType.CustomAttributes.Count); + + var attribute = valueEnumGenericType.CustomAttributes [0]; + Assert.AreEqual ("System.Void FooAttribute::.ctor(System.Object,System.Object)", + attribute.Constructor.FullName); + + Assert.IsTrue (attribute.HasConstructorArguments); + Assert.AreEqual (2, attribute.ConstructorArguments.Count); + + AssertCustomAttributeArgument ("(Object:(GenericWithEnum`1/OnGenericNumber:0))", attribute.ConstructorArguments [0]); + AssertCustomAttributeArgument ("(Object:(GenericWithEnum`1/OnGenericNumber:1))", attribute.ConstructorArguments [1]); + }); + } + + [Test] + public void EnumOnGenericArgumentOnType () + { + TestCSharp ("CustomAttributes.cs", module => { + var valueEnumGenericType = module.GetType ("ValueEnumOnGenericType"); + + Assert.IsTrue (valueEnumGenericType.HasCustomAttributes); + Assert.AreEqual (1, valueEnumGenericType.CustomAttributes.Count); + + var attribute = valueEnumGenericType.CustomAttributes [0]; + Assert.AreEqual ("System.Void FooAttribute::.ctor(GenericWithEnum`1/OnGenericNumber)", + attribute.Constructor.FullName); + + Assert.IsTrue (attribute.HasConstructorArguments); + Assert.AreEqual (1, attribute.ConstructorArguments.Count); + + AssertCustomAttributeArgument ("(GenericWithEnum`1/OnGenericNumber:1)", attribute.ConstructorArguments [0]); + }); + } + + [Test] + public void EnumOnGenericFieldOnType () + { + TestCSharp ("CustomAttributes.cs", module => { + var valueEnumGenericType = module.GetType ("FieldEnumOnGenericType"); + + Assert.IsTrue (valueEnumGenericType.HasCustomAttributes); + Assert.AreEqual (1, valueEnumGenericType.CustomAttributes.Count); + + var attribute = valueEnumGenericType.CustomAttributes [0]; + var argument = attribute.Fields.Where (a => a.Name == "NumberEnumField").First ().Argument; + + AssertCustomAttributeArgument ("(GenericWithEnum`1/OnGenericNumber:0)", argument); + }); + } + + [Test] + public void EnumOnGenericPropertyOnType () + { + TestCSharp ("CustomAttributes.cs", module => { + var valueEnumGenericType = module.GetType ("PropertyEnumOnGenericType"); + + Assert.IsTrue (valueEnumGenericType.HasCustomAttributes); + Assert.AreEqual (1, valueEnumGenericType.CustomAttributes.Count); + + var attribute = valueEnumGenericType.CustomAttributes [0]; + var argument = attribute.Properties.Where (a => a.Name == "NumberEnumProperty").First ().Argument; + + AssertCustomAttributeArgument ("(GenericWithEnum`1/OnGenericNumber:1)", argument); + }); + } + + [Test] + public void EnumDeclaredInGenericTypeArray () + { + TestCSharp ("CustomAttributes.cs", module => { + var type = module.GetType ("WithAttributeUsingNestedEnumArray"); + var attributes = type.CustomAttributes; + Assert.AreEqual (1, attributes.Count); + var attribute = attributes [0]; + Assert.AreEqual (1, attribute.Fields.Count); + var arg = attribute.Fields [0].Argument; + Assert.AreEqual ("System.Object", arg.Type.FullName); + + var argumentValue = (CustomAttributeArgument)arg.Value; + Assert.AreEqual ("GenericWithEnum`1/OnGenericNumber[]", argumentValue.Type.FullName); + var argumentValues = (CustomAttributeArgument [])argumentValue.Value; + + Assert.AreEqual ("GenericWithEnum`1/OnGenericNumber", argumentValues [0].Type.FullName); + Assert.AreEqual (0, (int)argumentValues [0].Value); + + Assert.AreEqual ("GenericWithEnum`1/OnGenericNumber", argumentValues [1].Type.FullName); + Assert.AreEqual (1, (int)argumentValues [1].Value); + }); + } +#endif + + static void AssertCustomAttribute (string expected, CustomAttribute attribute) + { + Assert.AreEqual (expected, PrettyPrint (attribute)); + } + + static void AssertCustomAttributeArgument (string expected, CustomAttributeNamedArgument named_argument) + { + AssertCustomAttributeArgument (expected, named_argument.Argument); + } + + static void AssertCustomAttributeArgument (string expected, CustomAttributeArgument argument) + { + var result = new StringBuilder (); + PrettyPrint (argument, result); + + Assert.AreEqual (expected, result.ToString ()); + } + + static string PrettyPrint (CustomAttribute attribute) + { + var signature = new StringBuilder (); + signature.Append (".ctor ("); + + for (int i = 0; i < attribute.ConstructorArguments.Count; i++) { + if (i > 0) + signature.Append (", "); + + PrettyPrint (attribute.ConstructorArguments [i], signature); + } + + signature.Append (")"); + return signature.ToString (); + } + + static void PrettyPrint (CustomAttributeArgument argument, StringBuilder signature) + { + var value = argument.Value; + + signature.Append ("("); + + PrettyPrint (argument.Type, signature); + + signature.Append (":"); + + PrettyPrintValue (argument.Value, signature); + + signature.Append (")"); + } + + static void PrettyPrintValue (object value, StringBuilder signature) + { + if (value == null) { + signature.Append ("null"); + return; + } + + var arguments = value as CustomAttributeArgument []; + if (arguments != null) { + signature.Append ("{"); + for (int i = 0; i < arguments.Length; i++) { + if (i > 0) + signature.Append (", "); + + PrettyPrint (arguments [i], signature); + } + signature.Append ("}"); + + return; + } + + switch (Type.GetTypeCode (value.GetType ())) { + case System.TypeCode.String: + signature.AppendFormat ("\"{0}\"", value); + break; + case System.TypeCode.Char: + signature.AppendFormat ("'{0}'", (char) value); + break; + default: + var formattable = value as IFormattable; + if (formattable != null) { + signature.Append (formattable.ToString (null, CultureInfo.InvariantCulture)); + return; + } + + if (value is CustomAttributeArgument) { + PrettyPrint ((CustomAttributeArgument) value, signature); + return; + } + break; + } + } + + static void PrettyPrint (TypeReference type, StringBuilder signature) + { + if (type.IsArray) { + ArrayType array = (ArrayType) type; + signature.AppendFormat ("{0}[]", array.ElementType.etype.ToString ()); + } else if (type.etype == ElementType.None || type.etype == ElementType.GenericInst) { + signature.Append (type.FullName); + } else + signature.Append (type.etype.ToString ()); + } + + static void AssertArgument (T value, CustomAttributeNamedArgument named_argument) + { + AssertArgument (value, named_argument.Argument); + } + + static void AssertArgument (T value, CustomAttributeArgument argument) + { + AssertArgument (typeof (T).FullName, (object) value, argument); + } + + static void AssertArgument (string type, object value, CustomAttributeArgument argument) + { + Assert.AreEqual (type, argument.Type.FullName); + Assert.AreEqual (value, argument.Value); + } + + static CustomAttribute GetAttribute (ICustomAttributeProvider owner, string type) + { + Assert.IsTrue (owner.HasCustomAttributes); + + foreach (var attribute in owner.CustomAttributes) + if (attribute.Constructor.DeclaringType.Name.StartsWith (type)) + return attribute; + + return null; + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/EventTests.cs b/cecil-master/Test/Mono.Cecil.Tests/EventTests.cs new file mode 100644 index 000000000..cb9064b79 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/EventTests.cs @@ -0,0 +1,79 @@ +using System; + +using Mono.Cecil; +using Mono.Cecil.Metadata; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class EventTests : BaseTestFixture { + + [Test] + public void AbstractMethod () + { + TestCSharp ("Events.cs", module => { + var type = module.GetType ("Foo"); + + Assert.IsTrue (type.HasEvents); + + var events = type.Events; + + Assert.AreEqual (1, events.Count); + + var @event = events [0]; + + Assert.IsNotNull (@event); + Assert.AreEqual ("Bar", @event.Name); + Assert.IsNotNull (@event.EventType); + Assert.AreEqual ("Pan", @event.EventType.FullName); + + Assert.IsNotNull (@event.AddMethod); + Assert.AreEqual (MethodSemanticsAttributes.AddOn, @event.AddMethod.SemanticsAttributes); + Assert.IsNotNull (@event.RemoveMethod); + Assert.AreEqual (MethodSemanticsAttributes.RemoveOn, @event.RemoveMethod.SemanticsAttributes); + }); + } + + [Test] + public void OtherMethod () + { + TestIL ("others.il", module => { + var type = module.GetType ("Others"); + + Assert.IsTrue (type.HasEvents); + + var events = type.Events; + + Assert.AreEqual (1, events.Count); + + var @event = events [0]; + + Assert.IsNotNull (@event); + Assert.AreEqual ("Handler", @event.Name); + Assert.IsNotNull (@event.EventType); + Assert.AreEqual ("System.EventHandler", @event.EventType.FullName); + + Assert.IsTrue (@event.HasOtherMethods); + + Assert.AreEqual (2, @event.OtherMethods.Count); + + var other = @event.OtherMethods [0]; + Assert.AreEqual ("dang_Handler", other.Name); + + other = @event.OtherMethods [1]; + Assert.AreEqual ("fang_Handler", other.Name); + }); + } + + [Test] + public void UnattachedEvent () + { + var int32 = typeof (int).ToDefinition (); + var evt = new EventDefinition ("Event", EventAttributes.None, int32); + + Assert.AreEqual (null, evt.AddMethod); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/Extensions.cs b/cecil-master/Test/Mono.Cecil.Tests/Extensions.cs new file mode 100644 index 000000000..b51e545ae --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/Extensions.cs @@ -0,0 +1,93 @@ +using System; +using System.IO; +using System.Linq; +using SR = System.Reflection; + +using Mono.Cecil; + +namespace Mono.Cecil.Tests { + + public static class Extensions { + + public static MethodDefinition GetMethod (this TypeDefinition self, string name) + { + return self.Methods.Where (m => m.Name == name).First (); + } + + public static FieldDefinition GetField (this TypeDefinition self, string name) + { + return self.Fields.Where (f => f.Name == name).First (); + } + + public static TypeDefinition ToDefinition (this Type self) + { + var module = ModuleDefinition.ReadModule (new MemoryStream (File.ReadAllBytes (self.Module.FullyQualifiedName))); + return (TypeDefinition) module.LookupToken (self.MetadataToken); + } + + public static MethodDefinition ToDefinition (this SR.MethodBase method) + { + var declaring_type = method.DeclaringType.ToDefinition (); + return (MethodDefinition) declaring_type.Module.LookupToken (method.MetadataToken); + } + + public static FieldDefinition ToDefinition (this SR.FieldInfo field) + { + var declaring_type = field.DeclaringType.ToDefinition (); + return (FieldDefinition) declaring_type.Module.LookupToken (field.MetadataToken); + } + + public static TypeReference MakeGenericType (this TypeReference self, params TypeReference [] arguments) + { + if (self.GenericParameters.Count != arguments.Length) + throw new ArgumentException (); + + var instance = new GenericInstanceType (self, arguments.Length); + foreach (var argument in arguments) + instance.GenericArguments.Add (argument); + + return instance; + } + + public static MethodReference MakeGenericMethod (this MethodReference self, params TypeReference [] arguments) + { + if (self.GenericParameters.Count != arguments.Length) + throw new ArgumentException (); + + var instance = new GenericInstanceMethod (self); + foreach (var argument in arguments) + instance.GenericArguments.Add (argument); + + return instance; + } + + public static MethodReference MakeGeneric (this MethodReference self, params TypeReference [] arguments) + { + var reference = new MethodReference { + Name = self.Name, + DeclaringType = self.DeclaringType.MakeGenericType (arguments), + HasThis = self.HasThis, + ExplicitThis = self.ExplicitThis, + ReturnType = self.ReturnType, + CallingConvention = self.CallingConvention, + }; + + foreach (var parameter in self.Parameters) + reference.Parameters.Add (new ParameterDefinition (parameter.ParameterType)); + + foreach (var generic_parameter in self.GenericParameters) + reference.GenericParameters.Add (new GenericParameter (generic_parameter.Name, reference)); + + return reference; + } + + public static FieldReference MakeGeneric (this FieldReference self, params TypeReference [] arguments) + { + return new FieldReference { + Name = self.Name, + DeclaringType = self.DeclaringType.MakeGenericType (arguments), + FieldType = self.FieldType, + }; + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/FieldTests.cs b/cecil-master/Test/Mono.Cecil.Tests/FieldTests.cs new file mode 100644 index 000000000..6cbbb28a7 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/FieldTests.cs @@ -0,0 +1,425 @@ +using System; +using System.IO; + +using Mono.Cecil.PE; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class FieldTests : BaseTestFixture { + + [Test] + public void TypeDefField () + { + TestCSharp ("Fields.cs", module => { + var type = module.Types [1]; + Assert.AreEqual ("Foo", type.Name); + Assert.AreEqual (1, type.Fields.Count); + + var field = type.Fields [0]; + Assert.AreEqual ("bar", field.Name); + Assert.AreEqual (1, field.MetadataToken.RID); + Assert.IsNotNull (field.FieldType); + Assert.AreEqual ("Bar", field.FieldType.FullName); + Assert.AreEqual (TokenType.Field, field.MetadataToken.TokenType); + Assert.IsFalse (field.HasConstant); + Assert.IsNull (field.Constant); + }); + } + + [Test] + public void PrimitiveTypes () + { + TestCSharp ("Fields.cs", module => { + var type = module.GetType ("Baz"); + + AssertField (type, "char", typeof (char)); + AssertField (type, "bool", typeof (bool)); + AssertField (type, "sbyte", typeof (sbyte)); + AssertField (type, "byte", typeof (byte)); + AssertField (type, "int16", typeof (short)); + AssertField (type, "uint16", typeof (ushort)); + AssertField (type, "int32", typeof (int)); + AssertField (type, "uint32", typeof (uint)); + AssertField (type, "int64", typeof (long)); + AssertField (type, "uint64", typeof (ulong)); + AssertField (type, "single", typeof (float)); + AssertField (type, "double", typeof (double)); + AssertField (type, "string", typeof (string)); + AssertField (type, "object", typeof (object)); + }); + } + + [Test] + public void VolatileField () + { + TestCSharp ("Fields.cs", module => { + var type = module.GetType ("Bar"); + + Assert.IsTrue (type.HasFields); + Assert.AreEqual (1, type.Fields.Count); + + var field = type.Fields [0]; + + Assert.AreEqual ("oiseau", field.Name); + Assert.AreEqual ("System.Int32 modreq(System.Runtime.CompilerServices.IsVolatile)", field.FieldType.FullName); + + Assert.IsFalse (field.HasConstant); + }); + } + + [Test] + public void FieldLayout () + { + TestCSharp ("Layouts.cs", module => { + var foo = module.GetType ("Foo"); + Assert.IsNotNull (foo); + + Assert.IsTrue (foo.HasFields); + + var fields = foo.Fields; + + var field = fields [0]; + + Assert.AreEqual ("Bar", field.Name); + Assert.IsTrue (field.HasLayoutInfo); + Assert.AreEqual (0, field.Offset); + + field = fields [1]; + + Assert.AreEqual ("Baz", field.Name); + Assert.IsTrue (field.HasLayoutInfo); + Assert.AreEqual (2, field.Offset); + + field = fields [2]; + + Assert.AreEqual ("Gazonk", field.Name); + Assert.IsTrue (field.HasLayoutInfo); + Assert.AreEqual (4, field.Offset); + }); + } + + [Test] + public void FieldRVA () + { + TestCSharp ("Layouts.cs", module => { + var priv_impl = GetPrivateImplementationType (module); + Assert.IsNotNull (priv_impl); + + Assert.AreEqual (1, priv_impl.Fields.Count); + + var field = priv_impl.Fields [0]; + + Assert.IsNotNull (field); + Assert.AreNotEqual (0, field.RVA); + Assert.IsNotNull (field.InitialValue); + Assert.AreEqual (16, field.InitialValue.Length); + + var buffer = new ByteBuffer (field.InitialValue); + + Assert.AreEqual (1, buffer.ReadUInt32 ()); + Assert.AreEqual (2, buffer.ReadUInt32 ()); + Assert.AreEqual (3, buffer.ReadUInt32 ()); + Assert.AreEqual (4, buffer.ReadUInt32 ()); + + var intialValue = field.InitialValue; + field.InitialValue = null; + Assert.False (field.Attributes.HasFlag (FieldAttributes.HasFieldRVA)); + + field.InitialValue = intialValue; + + Assert.True (field.Attributes.HasFlag (FieldAttributes.HasFieldRVA)); + }); + } + + int AlignmentOfInteger(int input) + { + if (input == 0) + return 0x40000000; + if (input < 0) + Assert.Fail (); + int alignment = 1; + while ((input & alignment) == 0) + alignment *= 2; + + return alignment; + } + + [Test] + public void FieldRVAAlignment () + { + TestIL ("FieldRVAAlignment.il", ilmodule => { + + var path = Path.GetTempFileName (); + + ilmodule.Write (path); + + using (var module = ModuleDefinition.ReadModule (path, new ReaderParameters { ReadWrite = true })) { + var priv_impl = GetPrivateImplementationType (module); + Assert.IsNotNull (priv_impl); + + Assert.AreEqual (8, priv_impl.Fields.Count); + + foreach (var field in priv_impl.Fields) + { + Assert.IsNotNull (field); + + Assert.AreNotEqual (0, field.RVA); + Assert.IsNotNull (field.InitialValue); + + int rvaAlignment = AlignmentOfInteger (field.RVA); + var fieldType = field.FieldType.Resolve (); + int desiredAlignment = fieldType.PackingSize; + Assert.GreaterOrEqual (rvaAlignment, desiredAlignment); + } + } + }); + } + + [Test] + public void GenericFieldDefinition () + { + TestCSharp ("Generics.cs", module => { + var bar = module.GetType ("Bar`1"); + Assert.IsNotNull (bar); + + Assert.IsTrue (bar.HasGenericParameters); + var t = bar.GenericParameters [0]; + + Assert.AreEqual ("T", t.Name); + Assert.AreEqual (t.Owner, bar); + + var bang = bar.GetField ("bang"); + + Assert.IsNotNull (bang); + + Assert.AreEqual (t, bang.FieldType); + }); + } + + [Test] + public void ArrayFields () + { + TestIL ("types.il", module => { + var types = module.GetType ("Types"); + Assert.IsNotNull (types); + + var rank_two = types.GetField ("rank_two"); + + var array = rank_two.FieldType as ArrayType; + Assert.IsNotNull (array); + + Assert.AreEqual (2, array.Rank); + Assert.IsFalse (array.Dimensions [0].IsSized); + Assert.IsFalse (array.Dimensions [1].IsSized); + + var rank_two_low_bound_zero = types.GetField ("rank_two_low_bound_zero"); + + array = rank_two_low_bound_zero.FieldType as ArrayType; + Assert.IsNotNull (array); + + Assert.AreEqual (2, array.Rank); + Assert.IsTrue (array.Dimensions [0].IsSized); + Assert.AreEqual (0, array.Dimensions [0].LowerBound); + Assert.AreEqual (null, array.Dimensions [0].UpperBound); + Assert.IsTrue (array.Dimensions [1].IsSized); + Assert.AreEqual (0, array.Dimensions [1].LowerBound); + Assert.AreEqual (null, array.Dimensions [1].UpperBound); + + var rank_one_low_bound_m1 = types.GetField ("rank_one_low_bound_m1"); + array = rank_one_low_bound_m1.FieldType as ArrayType; + Assert.IsNotNull (array); + + Assert.AreEqual (1, array.Rank); + Assert.IsTrue (array.Dimensions [0].IsSized); + Assert.AreEqual (-1, array.Dimensions [0].LowerBound); + Assert.AreEqual (4, array.Dimensions [0].UpperBound); + }); + } + + [Test] + public void EnumFieldsConstant () + { + TestCSharp ("Fields.cs", module => { + var pim = module.GetType ("Pim"); + Assert.IsNotNull (pim); + + var field = pim.GetField ("Pam"); + Assert.IsTrue (field.HasConstant); + Assert.AreEqual (1, (int) field.Constant); + + field = pim.GetField ("Poum"); + Assert.AreEqual (2, (int) field.Constant); + }); + } + + [Test] + public void StringAndClassConstant () + { + TestCSharp ("Fields.cs", module => { + var panpan = module.GetType ("PanPan"); + Assert.IsNotNull (panpan); + + var field = panpan.GetField ("Peter"); + Assert.IsTrue (field.HasConstant); + Assert.IsNull (field.Constant); + + field = panpan.GetField ("QQ"); + Assert.AreEqual ("qq", (string) field.Constant); + + field = panpan.GetField ("nil"); + Assert.AreEqual (null, (string) field.Constant); + }); + } + + [Test] + public void ObjectConstant () + { + TestCSharp ("Fields.cs", module => { + var panpan = module.GetType ("PanPan"); + Assert.IsNotNull (panpan); + + var field = panpan.GetField ("obj"); + Assert.IsTrue (field.HasConstant); + Assert.IsNull (field.Constant); + }); + } + + [Test] + public void NullPrimitiveConstant () + { + TestIL ("types.il", module => { + var fields = module.GetType ("Fields"); + + var field = fields.GetField ("int32_nullref"); + Assert.IsTrue (field.HasConstant); + Assert.AreEqual (null, field.Constant); + }); + } + + [Test] + public void ArrayConstant () + { + TestCSharp ("Fields.cs", module => { + var panpan = module.GetType ("PanPan"); + Assert.IsNotNull (panpan); + + var field = panpan.GetField ("ints"); + Assert.IsTrue (field.HasConstant); + Assert.IsNull (field.Constant); + }); + } + + [Test] + public void ConstantCoalescing () + { + TestIL ("types.il", module => { + var fields = module.GetType ("Fields"); + + var field = fields.GetField ("int32_int16"); + Assert.AreEqual ("System.Int32", field.FieldType.FullName); + Assert.IsTrue (field.HasConstant); + Assert.IsInstanceOf (typeof (short), field.Constant); + Assert.AreEqual ((short) 1, field.Constant); + + field = fields.GetField ("int16_int32"); + Assert.AreEqual ("System.Int16", field.FieldType.FullName); + Assert.IsTrue (field.HasConstant); + Assert.IsInstanceOf (typeof (int), field.Constant); + Assert.AreEqual (1, field.Constant); + + field = fields.GetField ("char_int16"); + Assert.AreEqual ("System.Char", field.FieldType.FullName); + Assert.IsTrue (field.HasConstant); + Assert.IsInstanceOf (typeof (short), field.Constant); + Assert.AreEqual ((short) 1, field.Constant); + + field = fields.GetField ("int16_char"); + Assert.AreEqual ("System.Int16", field.FieldType.FullName); + Assert.IsTrue (field.HasConstant); + Assert.IsInstanceOf (typeof (char), field.Constant); + Assert.AreEqual ('s', field.Constant); + }); + } + + [Test] + public void NestedEnumOfGenericTypeDefinition () + { + TestCSharp ("Generics.cs", module => { + var dang = module.GetType ("Bongo`1/Dang"); + Assert.IsNotNull (dang); + + var field = dang.GetField ("Ding"); + Assert.IsNotNull (field); + Assert.AreEqual (2, field.Constant); + + field = dang.GetField ("Dong"); + Assert.IsNotNull (field); + Assert.AreEqual (12, field.Constant); + }); + } + + [Test] + public void MarshalAsFixedStr () + { + TestModule ("marshal.dll", module => { + var boc = module.GetType ("Boc"); + var field = boc.GetField ("a"); + + Assert.IsNotNull (field); + + Assert.IsTrue (field.HasMarshalInfo); + + var info = (FixedSysStringMarshalInfo) field.MarshalInfo; + + Assert.AreEqual (42, info.Size); + }); + } + + [Test] + public void MarshalAsFixedArray () + { + TestModule ("marshal.dll", module => { + var boc = module.GetType ("Boc"); + var field = boc.GetField ("b"); + + Assert.IsNotNull (field); + + Assert.IsTrue (field.HasMarshalInfo); + + var info = (FixedArrayMarshalInfo) field.MarshalInfo; + + Assert.AreEqual (12, info.Size); + Assert.AreEqual (NativeType.Boolean, info.ElementType); + }); + } + + [Test] + public void UnattachedField () + { + var field = new FieldDefinition ("Field", FieldAttributes.Public, typeof (int).ToDefinition ()); + + Assert.IsFalse (field.HasConstant); + Assert.IsNull (field.Constant); + } + + static TypeDefinition GetPrivateImplementationType (ModuleDefinition module) + { + foreach (var type in module.Types) + if (type.FullName.Contains ("")) + return type; + + return null; + } + + static void AssertField (TypeDefinition type, string name, Type expected) + { + var field = type.GetField (name); + Assert.IsNotNull (field, name); + + Assert.AreEqual (expected.FullName, field.FieldType.FullName); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/Formatter.cs b/cecil-master/Test/Mono.Cecil.Tests/Formatter.cs new file mode 100644 index 000000000..8b85f2b57 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/Formatter.cs @@ -0,0 +1,193 @@ +using System; +using System.IO; +using Mono.Cecil; +using Mono.Cecil.Cil; + +namespace Mono.Cecil.Tests { + + public static class Formatter { + + public static string FormatInstruction (Instruction instruction) + { + var writer = new StringWriter (); + WriteInstruction (writer, instruction); + return writer.ToString (); + } + + public static string FormatMethodBody (MethodDefinition method) + { + var writer = new StringWriter (); + WriteMethodBody (writer, method); + return writer.ToString (); + } + + public static void WriteMethodBody (TextWriter writer, MethodDefinition method) + { + var body = method.Body; + + WriteVariables (writer, body); + + foreach (Instruction instruction in body.Instructions) { + var sequence_point = body.Method.DebugInformation.GetSequencePoint (instruction); + if (sequence_point != null) { + writer.Write ('\t'); + WriteSequencePoint (writer, sequence_point); + writer.WriteLine (); + } + + writer.Write ('\t'); + WriteInstruction (writer, instruction); + writer.WriteLine (); + } + + WriteExceptionHandlers (writer, body); + } + + static void WriteVariables (TextWriter writer, MethodBody body) + { + var variables = body.Variables; + + writer.Write ('\t'); + writer.Write (".locals {0}(", body.InitLocals ? "init " : string.Empty); + + for (int i = 0; i < variables.Count; i++) { + if (i > 0) + writer.Write (", "); + + var variable = variables [i]; + + writer.Write ("{0} {1}", variable.VariableType, GetVariableName (variable, body)); + } + writer.WriteLine (")"); + } + + static string GetVariableName (VariableDefinition variable, MethodBody body) + { + string name; + if (body.Method.DebugInformation.TryGetName (variable, out name)) + return name; + + return variable.ToString (); + } + + static void WriteInstruction (TextWriter writer, Instruction instruction) + { + writer.Write (FormatLabel (instruction.Offset)); + writer.Write (": "); + writer.Write (instruction.OpCode.Name); + if (null != instruction.Operand) { + writer.Write (' '); + WriteOperand (writer, instruction.Operand); + } + } + + static void WriteSequencePoint (TextWriter writer, SequencePoint sequence_point) + { + if (sequence_point.IsHidden) { + writer.Write (".line hidden '{0}'", sequence_point.Document.Url); + return; + } + + writer.Write (".line {0},{1}:{2},{3} '{4}'", + sequence_point.StartLine, + sequence_point.EndLine, + sequence_point.StartColumn, + sequence_point.EndColumn, + sequence_point.Document.Url); + } + + static string FormatLabel (int offset) + { + string label = "000" + offset.ToString ("x"); + return "IL_" + label.Substring (label.Length - 4); + } + + static string FormatLabel (Instruction instruction) + { + return FormatLabel (instruction.Offset); + } + + static void WriteOperand (TextWriter writer, object operand) + { + if (null == operand) throw new ArgumentNullException ("operand"); + + var target = operand as Instruction; + if (null != target) { + writer.Write (FormatLabel (target.Offset)); + return; + } + + var targets = operand as Instruction []; + if (null != targets) { + WriteLabelList (writer, targets); + return; + } + + string s = operand as string; + if (null != s) { + writer.Write ("\"" + s + "\""); + return; + } + + var parameter = operand as ParameterDefinition; + if (parameter != null) { + writer.Write (ToInvariantCultureString (parameter.Sequence)); + return; + } + + s = ToInvariantCultureString (operand); + writer.Write (s); + } + + static void WriteLabelList (TextWriter writer, Instruction [] instructions) + { + writer.Write ("("); + + for (int i = 0; i < instructions.Length; i++) { + if (i != 0) writer.Write (", "); + writer.Write (FormatLabel (instructions [i].Offset)); + } + + writer.Write (")"); + } + + static void WriteExceptionHandlers (TextWriter writer, MethodBody body) + { + if (!body.HasExceptionHandlers) + return; + + foreach (var handler in body.ExceptionHandlers) { + writer.Write ("\t"); + writer.WriteLine (".try {0} to {1} {2} handler {3} to {4}", + FormatLabel (handler.TryStart), + FormatLabel (handler.TryEnd), + FormatHandlerType (handler), + FormatLabel (handler.HandlerStart), + FormatLabel (handler.HandlerEnd)); + } + } + + static string FormatHandlerType (ExceptionHandler handler) + { + var handler_type = handler.HandlerType; + var type = handler_type.ToString ().ToLowerInvariant (); + + switch (handler_type) { + case ExceptionHandlerType.Catch: + return string.Format ("{0} {1}", type, handler.CatchType.FullName); + case ExceptionHandlerType.Filter: + throw new NotImplementedException (); + default: + return type; + } + } + + public static string ToInvariantCultureString (object value) + { + var convertible = value as IConvertible; + return (null != convertible) + ? convertible.ToString (System.Globalization.CultureInfo.InvariantCulture) + : value.ToString (); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/ILProcessorTests.cs b/cecil-master/Test/Mono.Cecil.Tests/ILProcessorTests.cs new file mode 100644 index 000000000..fd462c365 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/ILProcessorTests.cs @@ -0,0 +1,586 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Cecil.Mdb; +using Mono.Cecil.Pdb; +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class ILProcessorTests : BaseTestFixture { + + [Test] + public void Append () + { + var method = CreateTestMethod (); + var il = method.GetILProcessor (); + + var ret = il.Create (OpCodes.Ret); + il.Append (ret); + + AssertOpCodeSequence (new [] { OpCodes.Ret }, method); + } + + [Test] + public void InsertBefore () + { + var method = CreateTestMethod (OpCodes.Ldloc_0, OpCodes.Ldloc_2, OpCodes.Ldloc_3); + var il = method.GetILProcessor (); + + var ldloc_2 = method.Instructions.Where (i => i.OpCode == OpCodes.Ldloc_2).First (); + + il.InsertBefore ( + ldloc_2, + il.Create (OpCodes.Ldloc_1)); + + AssertOpCodeSequence (new [] { OpCodes.Ldloc_0, OpCodes.Ldloc_1, OpCodes.Ldloc_2, OpCodes.Ldloc_3 }, method); + } + + [Test] + public void InsertBeforeIssue697 () + { + var parameters = new ReaderParameters { SymbolReaderProvider = new MdbReaderProvider () }; + using (var module = GetResourceModule ("Issue697.dll", parameters)) + { + var pathGetterDef = module.GetTypes () + .SelectMany (t => t.Methods) + .First (m => m.Name.Equals ("get_Defer")); + + var body = pathGetterDef.Body; + var worker = body.GetILProcessor (); + var initialBody = body.Instructions.ToList (); + var head = initialBody.First (); + var opcode = worker.Create (OpCodes.Ldc_I4_1); + worker.InsertBefore (head, opcode); + worker.InsertBefore (head, worker.Create (OpCodes.Ret)); + initialBody.ForEach (worker.Remove); + AssertOpCodeSequence (new [] { OpCodes.Ldc_I4_1, OpCodes.Ret }, pathGetterDef.body); + } + } + + [Test] + public void InsertBeforeIssue697bis () + { + var parameters = new ReaderParameters { SymbolReaderProvider = new MdbReaderProvider () }; + using (var module = GetResourceModule ("Issue697.dll", parameters)) { + var pathGetterDef = module.GetTypes () + .SelectMany (t => t.Methods) + .First (m => m.Name.Equals ("get_Defer")); + + var body = pathGetterDef.Body; + var worker = body.GetILProcessor (); + var initialBody = body.Instructions.ToList (); + Console.WriteLine (initialBody.Sum (i => i.GetSize ())); + + var head = initialBody.First (); + var opcode = worker.Create (OpCodes.Ldc_I4_1); + worker.InsertBefore (head, opcode); + + Assert.That (pathGetterDef.DebugInformation.Scope.Start.IsEndOfMethod, Is.False); + foreach (var subscope in pathGetterDef.DebugInformation.Scope.Scopes) + Assert.That (subscope.Start.IsEndOfMethod, Is.False); + + // big test -- we can write w/o crashing + var unique = Guid.NewGuid ().ToString (); + var output = Path.GetTempFileName (); + var outputdll = output + ".dll"; + + var writer = new WriterParameters () { + SymbolWriterProvider = new MdbWriterProvider (), + WriteSymbols = true + }; + using (var sink = File.Open (outputdll, FileMode.Create, FileAccess.ReadWrite)) { + module.Write (sink, writer); + } + + Assert.Pass (); + } + } + + [Test] + public void InsertAfter () + { + var method = CreateTestMethod (OpCodes.Ldloc_0, OpCodes.Ldloc_2, OpCodes.Ldloc_3); + var il = method.GetILProcessor (); + + var ldloc_0 = method.Instructions.First (); + + il.InsertAfter ( + ldloc_0, + il.Create (OpCodes.Ldloc_1)); + + AssertOpCodeSequence (new [] { OpCodes.Ldloc_0, OpCodes.Ldloc_1, OpCodes.Ldloc_2, OpCodes.Ldloc_3 }, method); + } + + [Test] + public void InsertAfterUsingIndex () + { + var method = CreateTestMethod (OpCodes.Ldloc_0, OpCodes.Ldloc_2, OpCodes.Ldloc_3); + var il = method.GetILProcessor (); + + il.InsertAfter ( + 0, + il.Create (OpCodes.Ldloc_1)); + + AssertOpCodeSequence (new [] { OpCodes.Ldloc_0, OpCodes.Ldloc_1, OpCodes.Ldloc_2, OpCodes.Ldloc_3 }, method); + } + + [Test] + public void ReplaceUsingIndex () + { + var method = CreateTestMethod (OpCodes.Ldloc_0, OpCodes.Ldloc_2, OpCodes.Ldloc_3); + var il = method.GetILProcessor (); + + il.Replace (1, il.Create (OpCodes.Nop)); + + AssertOpCodeSequence (new [] { OpCodes.Ldloc_0, OpCodes.Nop, OpCodes.Ldloc_3 }, method); + } + + [Test] + public void Clear () + { + var method = CreateTestMethod (OpCodes.Ldloc_0, OpCodes.Ldloc_2, OpCodes.Ldloc_3); + var il = method.GetILProcessor (); + + il.Clear (); + + AssertOpCodeSequence (new OpCode[] { }, method); + } + + [TestCase (RoundtripType.None, false, false, false)] + [TestCase (RoundtripType.Pdb, false, false, false)] + [TestCase (RoundtripType.Pdb, true, false, false)] + [TestCase (RoundtripType.Pdb, true, false, true)] + [TestCase (RoundtripType.Pdb, true, true, false)] + [TestCase (RoundtripType.PortablePdb, false, false, false)] + [TestCase (RoundtripType.PortablePdb, true, false, false)] + [TestCase (RoundtripType.PortablePdb, true, false, true)] + [TestCase (RoundtripType.PortablePdb, true, true, false)] + public void InsertAfterWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes, bool padIL) + { + var methodBody = CreateTestMethodWithLocalScopes (roundtripType, padIL); + methodBody = RoundtripMethodBody (methodBody, roundtripType, forceUnresolved, reverseScopes); + + var il = methodBody.GetILProcessor (); + il.InsertAfter (1, il.Create (OpCodes.Ldstr, "Test")); + + methodBody = RoundtripMethodBody (methodBody, roundtripType, false, reverseScopes); + var wholeBodyScope = VerifyWholeBodyScope (methodBody); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [0], 1, 3); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1], 4, null); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1].Scopes [0], 5, 6); + AssertStateMachineScope (methodBody, 1, 7); + AssertAsyncMethodSteppingInfo (methodBody, 0, 1, 1); + AssertAsyncMethodSteppingInfo (methodBody, 1, 5, 6); + AssertAsyncMethodSteppingInfo (methodBody, 2, 7, 7); + + methodBody.Method.Module.Dispose (); + } + + [TestCase (RoundtripType.None, false, false, false)] + [TestCase (RoundtripType.Pdb, false, false, false)] + [TestCase (RoundtripType.Pdb, true, false, false)] + [TestCase (RoundtripType.Pdb, true, false, true)] + [TestCase (RoundtripType.Pdb, true, true, false)] + [TestCase (RoundtripType.PortablePdb, false, false, false)] + [TestCase (RoundtripType.PortablePdb, true, false, false)] + [TestCase (RoundtripType.PortablePdb, true, false, true)] + [TestCase (RoundtripType.PortablePdb, true, true, false)] + public void RemoveWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes, bool padIL) + { + var methodBody = CreateTestMethodWithLocalScopes (roundtripType, padIL); + methodBody = RoundtripMethodBody (methodBody, roundtripType, forceUnresolved, reverseScopes); + + var il = methodBody.GetILProcessor (); + il.RemoveAt (1); + + methodBody = RoundtripMethodBody (methodBody, roundtripType, false, reverseScopes); + var wholeBodyScope = VerifyWholeBodyScope (methodBody); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [0], 1, 1); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1], 2, null); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1].Scopes [0], 3, 4); + AssertStateMachineScope (methodBody, 1, 5); + AssertAsyncMethodSteppingInfo (methodBody, 0, 1, 1); + AssertAsyncMethodSteppingInfo (methodBody, 1, 3, 4); + AssertAsyncMethodSteppingInfo (methodBody, 2, 5, 5); + + methodBody.Method.Module.Dispose (); + } + + [TestCase (RoundtripType.None, false, false, false)] + [TestCase (RoundtripType.Pdb, false, false, false)] + [TestCase (RoundtripType.Pdb, true, false, false)] + [TestCase (RoundtripType.Pdb, true, false, true)] + [TestCase (RoundtripType.Pdb, true, true, false)] + [TestCase (RoundtripType.PortablePdb, false, false, false)] + [TestCase (RoundtripType.PortablePdb, true, false, false)] + [TestCase (RoundtripType.PortablePdb, true, false, true)] + [TestCase (RoundtripType.PortablePdb, true, true, false)] + public void ReplaceWithSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes, bool padIL) + { + var methodBody = CreateTestMethodWithLocalScopes (roundtripType, padIL); + methodBody = RoundtripMethodBody (methodBody, roundtripType, forceUnresolved, reverseScopes); + + var il = methodBody.GetILProcessor (); + il.Replace (1, il.Create (OpCodes.Ldstr, "Test")); + + methodBody = RoundtripMethodBody (methodBody, roundtripType, false, reverseScopes); + var wholeBodyScope = VerifyWholeBodyScope (methodBody); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [0], 1, 2); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1], 3, null); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1].Scopes [0], 4, 5); + AssertStateMachineScope (methodBody, 1, 6); + AssertAsyncMethodSteppingInfo (methodBody, 0, 1, 1); + AssertAsyncMethodSteppingInfo (methodBody, 1, 4, 5); + AssertAsyncMethodSteppingInfo (methodBody, 2, 6, 6); + + methodBody.Method.Module.Dispose (); + } + + [TestCase (RoundtripType.None, false, false, false)] + [TestCase (RoundtripType.Pdb, false, false, false)] + [TestCase (RoundtripType.Pdb, true, false, false)] + [TestCase (RoundtripType.Pdb, true, false, true)] + [TestCase (RoundtripType.Pdb, true, true, false)] + [TestCase (RoundtripType.PortablePdb, false, false, false)] + [TestCase (RoundtripType.PortablePdb, true, false, false)] + [TestCase (RoundtripType.PortablePdb, true, false, true)] + [TestCase (RoundtripType.PortablePdb, true, true, false)] + public void EditBodyWithScopesAndSymbolRoundtrip (RoundtripType roundtripType, bool forceUnresolved, bool reverseScopes, bool padIL) + { + var methodBody = CreateTestMethodWithLocalScopes (roundtripType, padIL); + methodBody = RoundtripMethodBody (methodBody, roundtripType, forceUnresolved, reverseScopes); + + var il = methodBody.GetILProcessor (); + il.Replace (4, il.Create (OpCodes.Ldstr, "Test")); + il.InsertAfter (5, il.Create (OpCodes.Ldloc_3)); + var tempVar3 = new VariableDefinition (methodBody.Method.Module.ImportReference (typeof (string))); + methodBody.Variables.Add (tempVar3); + methodBody.Method.DebugInformation.Scope.Scopes [reverseScopes ? 0 : 1].Scopes.Insert (reverseScopes ? 0 : 1, + new ScopeDebugInformation (methodBody.Instructions [5], methodBody.Instructions [6]) { + Variables = { new VariableDebugInformation (tempVar3, "tempVar3") } + }); + + methodBody = RoundtripMethodBody (methodBody, roundtripType, false, reverseScopes); + var wholeBodyScope = VerifyWholeBodyScope (methodBody); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [0], 1, 2); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1], 3, null); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1].Scopes [0], 4, 5); + AssertLocalScope (methodBody, wholeBodyScope.Scopes [1].Scopes [1], 5, 6); + AssertStateMachineScope (methodBody, 1, 7); + AssertAsyncMethodSteppingInfo (methodBody, 0, 1, 1); + AssertAsyncMethodSteppingInfo (methodBody, 1, 4, 5); + AssertAsyncMethodSteppingInfo (methodBody, 2, 7, 7); + + methodBody.Method.Module.Dispose (); + } + + [Test] + public void EditWithDebugInfoButNoLocalScopes() + { + var methodBody = CreateTestMethod (OpCodes.Ret); + methodBody.Method.DebugInformation = new MethodDebugInformation (methodBody.Method); + + var il = methodBody.GetILProcessor (); + il.Replace (methodBody.Instructions [0], il.Create (OpCodes.Nop)); + + Assert.AreEqual (1, methodBody.Instructions.Count); + Assert.AreEqual (Code.Nop, methodBody.Instructions [0].OpCode.Code); + Assert.Null (methodBody.Method.DebugInformation.Scope); + } + + static void AssertOpCodeSequence (OpCode [] expected, MethodBody body) + { + var opcodes = body.Instructions.Select (i => i.OpCode).ToArray (); + Assert.AreEqual (expected.Length, opcodes.Length); + + for (int i = 0; i < opcodes.Length; i++) + Assert.AreEqual (expected [i], opcodes [i]); + } + + static MethodBody CreateTestMethod (params OpCode [] opcodes) + { + var method = new MethodDefinition { + Name = "function", + Attributes = MethodAttributes.Public | MethodAttributes.Static + }; + + var il = method.Body.GetILProcessor (); + + foreach (var opcode in opcodes) + il.Emit (opcode); + + var instructions = method.Body.Instructions; + int size = 0; + for (int i = 0; i < instructions.Count; i++) { + var instruction = instructions [i]; + instruction.Offset = size; + size += instruction.GetSize (); + } + + return method.Body; + } + + static MethodDefinition CreateEmptyTestMethod (ModuleDefinition module, string name) + { + var method = new MethodDefinition { + Name = name, + Attributes = MethodAttributes.Public | MethodAttributes.Static + }; + + var il = method.Body.GetILProcessor (); + il.Emit (OpCodes.Ret); + + method.ReturnType = module.ImportReference (typeof (void)); + + return method; + } + + static ScopeDebugInformation VerifyWholeBodyScope (MethodBody body) + { + var debug_info = body.Method.DebugInformation; + Assert.IsNotNull (debug_info); + AssertLocalScope (body, debug_info.Scope, 0, null); + return debug_info.Scope; + } + + static void AssertInstructionOffset (Instruction instruction, InstructionOffset instructionOffset) + { + if (instructionOffset.IsResolved) + Assert.AreEqual (instruction, instructionOffset.ResolvedInstruction); + else + Assert.AreEqual (instruction.Offset, instructionOffset.Offset); + } + + static void AssertEndOfScopeOffset (MethodBody methodBody, InstructionOffset instructionOffset, int? index) + { + if (index.HasValue) + AssertInstructionOffset (methodBody.Instructions [index.Value], instructionOffset); + else + Assert.IsTrue (instructionOffset.IsEndOfMethod); + } + + static void AssertLocalScope (MethodBody methodBody, ScopeDebugInformation scope, int startIndex, int? endIndex) + { + Assert.IsNotNull (scope); + AssertInstructionOffset (methodBody.Instructions [startIndex], scope.Start); + AssertEndOfScopeOffset (methodBody, scope.End, endIndex); + } + + static void AssertStateMachineScope (MethodBody methodBody, int startIndex, int? endIndex) + { + var customDebugInfo = methodBody.Method.HasCustomDebugInformations ? methodBody.Method.CustomDebugInformations : methodBody.Method.DebugInformation.CustomDebugInformations; + var stateMachineScope = customDebugInfo.OfType ().SingleOrDefault (); + Assert.IsNotNull (stateMachineScope); + Assert.AreEqual (1, stateMachineScope.Scopes.Count); + AssertInstructionOffset (methodBody.Instructions [startIndex], stateMachineScope.Scopes [0].Start); + AssertEndOfScopeOffset (methodBody, stateMachineScope.Scopes [0].End, endIndex); + } + + static void AssertAsyncMethodSteppingInfo (MethodBody methodBody, int infoNumber, int yieldIndex, int resumeIndex) + { + var customDebugInfo = methodBody.Method.HasCustomDebugInformations ? methodBody.Method.CustomDebugInformations : methodBody.Method.DebugInformation.CustomDebugInformations; + var asyncMethodInfo = customDebugInfo.OfType ().SingleOrDefault (); + Assert.IsNotNull (asyncMethodInfo); + Assert.Greater (asyncMethodInfo.Yields.Count, infoNumber); + Assert.AreEqual (asyncMethodInfo.Yields.Count, asyncMethodInfo.Resumes.Count); + AssertInstructionOffset (methodBody.Instructions [yieldIndex], asyncMethodInfo.Yields [infoNumber]); + AssertInstructionOffset (methodBody.Instructions [resumeIndex], asyncMethodInfo.Resumes [infoNumber]); + } + + static MethodBody CreateTestMethodWithLocalScopes (RoundtripType roundtripType, bool padILWithNulls) + { + var module = ModuleDefinition.CreateModule ("TestILProcessor", ModuleKind.Dll); + var type = new TypeDefinition ("NS", "TestType", TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed, module.ImportReference (typeof (object))); + module.Types.Add (type); + + var methodBody = CreateTestMethod (OpCodes.Nop, OpCodes.Ldloc_0, OpCodes.Nop, OpCodes.Ldloc_1, OpCodes.Nop, OpCodes.Ldloc_2, OpCodes.Nop); + if (padILWithNulls) + methodBody.Instructions.Capacity += 10; + + var method = methodBody.Method; + method.ReturnType = module.ImportReference (typeof (void)); + type.Methods.Add (method); + + var emptyMethod = CreateEmptyTestMethod (module, "empty"); + type.Methods.Add (emptyMethod); + + methodBody.InitLocals = true; + var tempVar1 = new VariableDefinition (module.ImportReference (typeof (string))); + methodBody.Variables.Add (tempVar1); + var tempVar2 = new VariableDefinition (module.ImportReference (typeof (string))); + methodBody.Variables.Add (tempVar2); + + var debug_info = method.DebugInformation; + + // Must add a sequence point, otherwise the native PDB writer will not actually write the method's debug info + // into the PDB. + foreach (var instr in methodBody.Instructions) { + var sequence_point = new SequencePoint (instr, new Document (@"C:\test.cs")) { + StartLine = 0, + StartColumn = 0, + EndLine = 0, + EndColumn = 4, + }; + debug_info.SequencePoints.Add (sequence_point); + } + + // The method looks like this: + // Scopes + // | Scope | Scope.Scopes[0] | Scope.Scopes[1] | Scope.Scopes[1].Scopes[0] + // #0 Nop | > | | | + // #1 Ldloc_0 | . | > | | + // #2 Nop | . | < | | + // #3 Ldloc_1 | . | | > | + // #4 Nop | . | | . | > + // #5 Ldloc_2 | . | | . | < + // #6 Nop | . | | . | + // | < | | < | + // + // Async and state machine infos + // | Catch handler | Yields | Resumes | State machine | + // #0 Nop | | | | | + // #1 Ldloc_0 | | 0 | 0 | > | + // #2 Nop | | | | . | + // #3 Ldloc_1 | | | | . | + // #4 Nop | | 1 | | . | + // #5 Ldloc_2 | | | 1 | . | + // #6 Nop | * | 2 | 2 | < | + // | | | | | + + var instructions = methodBody.Instructions; + debug_info.Scope = new ScopeDebugInformation (instructions[0], null) { + Scopes = { + new ScopeDebugInformation (instructions[1], instructions[2]) { + Variables = { new VariableDebugInformation(tempVar1, "tempVar1") } + }, + new ScopeDebugInformation (instructions[3], null) { + Scopes = { + new ScopeDebugInformation (instructions[4], instructions[5]) { + Variables = { new VariableDebugInformation(tempVar2, "tempVar2") } + } + } + } + } + }; + + // For some reason the Native PDB reader/writer store the custom info on the method.DebugInfo.CustomInfo, while portable PDB stores it on method.CustomInfo. + var customDebugInfo = (roundtripType == RoundtripType.Pdb && Platform.HasNativePdbSupport) + ? method.DebugInformation.CustomDebugInformations : method.CustomDebugInformations; + customDebugInfo.Add (new StateMachineScopeDebugInformation () { + Scopes = { + new StateMachineScope(instructions[1], instructions[6]) + } + }); + customDebugInfo.Add (new AsyncMethodBodyDebugInformation () { + CatchHandler = new InstructionOffset (instructions [6]), + Yields = { + new InstructionOffset (instructions [1]), + new InstructionOffset (instructions [4]), + new InstructionOffset (instructions [6]) + }, + Resumes = { + new InstructionOffset (instructions [1]), + new InstructionOffset (instructions [5]), + new InstructionOffset (instructions [6]), + }, + ResumeMethods = { + emptyMethod, + emptyMethod, + emptyMethod + } + }); + + return methodBody; + } + + public enum RoundtripType { + None, + Pdb, + PortablePdb + } + + static MethodBody RoundtripMethodBody(MethodBody methodBody, RoundtripType roundtripType, bool forceUnresolvedScopes = false, bool reverseScopeOrder = false) + { + var newModule = RoundtripModule (methodBody.Method.Module, roundtripType); + var newMethodBody = newModule.GetType ("NS.TestType").GetMethod ("function").Body; + + if (forceUnresolvedScopes) + UnresolveScopes (newMethodBody.Method.DebugInformation.Scope); + + if (reverseScopeOrder) + ReverseScopeOrder (newMethodBody.Method.DebugInformation.Scope); + + return newMethodBody; + } + + static void UnresolveScopes(ScopeDebugInformation scope) + { + scope.Start = new InstructionOffset (scope.Start.Offset); + if (!scope.End.IsEndOfMethod) + scope.End = new InstructionOffset (scope.End.Offset); + + foreach (var subScope in scope.Scopes) + UnresolveScopes (subScope); + } + + static void ReverseScopeOrder(ScopeDebugInformation scope) + { + List subScopes = scope.Scopes.ToList (); + subScopes.Reverse (); + scope.Scopes.Clear (); + foreach (var subScope in subScopes) + scope.Scopes.Add (subScope); + + foreach (var subScope in scope.Scopes) + ReverseScopeOrder (subScope); + } + + static ModuleDefinition RoundtripModule(ModuleDefinition module, RoundtripType roundtripType) + { + if (roundtripType == RoundtripType.None) + return module; + + var file = Path.Combine (Path.GetTempPath (), "TestILProcessor.dll"); + if (File.Exists (file)) + File.Delete (file); + + ISymbolWriterProvider symbolWriterProvider; + switch (roundtripType) { + case RoundtripType.Pdb when Platform.HasNativePdbSupport: + symbolWriterProvider = new PdbWriterProvider (); + break; + case RoundtripType.PortablePdb: + default: + symbolWriterProvider = new PortablePdbWriterProvider (); + break; + } + + module.Write (file, new WriterParameters { + SymbolWriterProvider = symbolWriterProvider, + }); + module.Dispose (); + + ISymbolReaderProvider symbolReaderProvider; + switch (roundtripType) { + case RoundtripType.Pdb when Platform.HasNativePdbSupport: + symbolReaderProvider = new PdbReaderProvider (); + break; + case RoundtripType.PortablePdb: + default: + symbolReaderProvider = new PortablePdbReaderProvider (); + break; + } + + return ModuleDefinition.ReadModule (file, new ReaderParameters { + SymbolReaderProvider = symbolReaderProvider, + InMemory = true + }); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/ImageReadTests.cs b/cecil-master/Test/Mono.Cecil.Tests/ImageReadTests.cs new file mode 100644 index 000000000..fb5c558c6 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/ImageReadTests.cs @@ -0,0 +1,275 @@ +using System; +using System.IO; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Cecil.PE; +using Mono.Cecil.Metadata; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class ImageReadTests : BaseTestFixture { + + [Test] + public void ImageSections () + { + using (var image = GetResourceImage ("hello.exe")) { + Assert.AreEqual (3, image.Sections.Length); + Assert.AreEqual (".text", image.Sections [0].Name); + Assert.AreEqual (".rsrc", image.Sections [1].Name); + Assert.AreEqual (".reloc", image.Sections [2].Name); + } + } + + [Test] + public void ImageMetadataVersion () + { + using (var image = GetResourceImage ("hello.exe")) + Assert.AreEqual (TargetRuntime.Net_2_0, image.RuntimeVersion.ParseRuntime ()); + + using (var image = GetResourceImage ("hello1.exe")) + Assert.AreEqual (TargetRuntime.Net_1_1, image.RuntimeVersion.ParseRuntime ()); + } + + [Test] + public void ImageModuleKind () + { + using (var image = GetResourceImage ("hello.exe")) + Assert.AreEqual (ModuleKind.Console, image.Kind); + + using (var image = GetResourceImage ("libhello.dll")) + Assert.AreEqual (ModuleKind.Dll, image.Kind); + + using (var image = GetResourceImage ("hellow.exe")) + Assert.AreEqual (ModuleKind.Windows, image.Kind); + } + + [Test] + public void MetadataHeaps () + { + using (var image = GetResourceImage ("hello.exe")) { + Assert.IsNotNull (image.TableHeap); + + Assert.IsNotNull (image.StringHeap); + Assert.AreEqual (string.Empty, image.StringHeap.Read (0)); + Assert.AreEqual ("", image.StringHeap.Read (1)); + + Assert.IsNotNull (image.UserStringHeap); + Assert.AreEqual (string.Empty, image.UserStringHeap.Read (0)); + Assert.AreEqual ("Hello Cecil World !", image.UserStringHeap.Read (1)); + + Assert.IsNotNull (image.GuidHeap); + Assert.AreEqual (new Guid (), image.GuidHeap.Read (0)); + Assert.AreEqual (new Guid ("C3BC2BD3-2576-4D00-A80E-465B5632415F"), image.GuidHeap.Read (1)); + + Assert.IsNotNull (image.BlobHeap); + Assert.AreEqual (new byte [0], image.BlobHeap.Read (0)); + } + } + + [Test] + public void TablesHeap () + { + using (var image = GetResourceImage ("hello.exe")) { + var heap = image.TableHeap; + + Assert.IsNotNull (heap); + + Assert.AreEqual (1, heap [Table.Module].Length); + Assert.AreEqual (4, heap [Table.TypeRef].Length); + Assert.AreEqual (2, heap [Table.TypeDef].Length); + Assert.AreEqual (0, heap [Table.Field].Length); + Assert.AreEqual (2, heap [Table.Method].Length); + Assert.AreEqual (4, heap [Table.MemberRef].Length); + Assert.AreEqual (2, heap [Table.CustomAttribute].Length); + Assert.AreEqual (1, heap [Table.Assembly].Length); + Assert.AreEqual (1, heap [Table.AssemblyRef].Length); + } + } + + [Test] + public void X64Module () + { + TestModule ("hello.x64.exe", module => { + Assert.AreEqual (TargetArchitecture.AMD64, module.Image.Architecture); + Assert.AreEqual (ModuleAttributes.ILOnly, module.Image.Attributes); + }, verify: !Platform.OnMono); + } + + [Test] + public void AnyCPU32BitPreferred () + { + TestModule ("anycpu32bitpreferred.exe", module => { + Assert.AreNotEqual (0, module.Image.Characteristics & 0x0020); + }); + } + + [Test] + public void X64ModuleTextOnlySection () + { + TestModule ("hello.textonly.x64.exe", module => { + Assert.AreEqual (TargetArchitecture.AMD64, module.Image.Architecture); + Assert.AreEqual (ModuleAttributes.ILOnly, module.Image.Attributes); + }, verify: !Platform.OnMono); + } + + [Test] + public void IA64Module () + { + TestModule ("hello.ia64.exe", module => { + Assert.AreEqual (TargetArchitecture.IA64, module.Image.Architecture); + Assert.AreEqual (ModuleAttributes.ILOnly, module.Image.Attributes); + }, verify: !Platform.OnMono); + } + + [Test] + public void X86Module () + { + TestModule ("hello.x86.exe", module => { + Assert.AreEqual (TargetArchitecture.I386, module.Image.Architecture); + Assert.AreEqual (ModuleAttributes.ILOnly | ModuleAttributes.Required32Bit, module.Image.Attributes); + }); + } + + [Test] + public void AnyCpuModule () + { + TestModule ("hello.anycpu.exe", module => { + Assert.AreEqual (TargetArchitecture.I386, module.Image.Architecture); + Assert.AreEqual (ModuleAttributes.ILOnly, module.Image.Attributes); + }); + } + + [Test] + public void DelaySignedAssembly () + { + TestModule ("delay-signed.dll", module => { + Assert.IsNotNull (module.Assembly.Name.PublicKey); + Assert.AreNotEqual (0, module.Assembly.Name.PublicKey.Length); + Assert.AreNotEqual (ModuleAttributes.StrongNameSigned, module.Attributes & ModuleAttributes.StrongNameSigned); + Assert.AreNotEqual (0, module.Image.StrongName.VirtualAddress); + Assert.AreNotEqual (0, module.Image.StrongName.Size); + }); + } + + [Test] + public void WindowsPhoneNonSignedAssembly () + { + TestModule ("wp7.dll", module => { + Assert.AreEqual (0, module.Assembly.Name.PublicKey.Length); + Assert.AreNotEqual (ModuleAttributes.StrongNameSigned, module.Attributes & ModuleAttributes.StrongNameSigned); + Assert.AreEqual (0, module.Image.StrongName.VirtualAddress); + Assert.AreEqual (0, module.Image.StrongName.Size); + }, verify: false); + } + + [Test] + public void MetroAssembly () + { + if (Platform.OnMono) + return; + + TestModule ("metro.exe", module => { + Assert.AreEqual (ModuleCharacteristics.AppContainer, module.Characteristics & ModuleCharacteristics.AppContainer); + }, verify: false); + } + +#if !NET_CORE + [Test] + public void WindowsRuntimeComponentAssembly () + { + var resolver = WindowsRuntimeAssemblyResolver.CreateInstance (applyWindowsRuntimeProjections: false); + if (resolver == null) + return; + + TestModule("winrtcomp.winmd", module => { + Assert.IsTrue (module.Assembly.Name.IsWindowsRuntime); + Assert.AreEqual (6, module.Image.SubSystemMajor); + Assert.AreEqual (2, module.Image.SubSystemMinor); + }, verify: false, assemblyResolver: resolver); + } +#endif + [Test] + public void DeterministicAssembly () + { + TestModule ("Deterministic.dll", module => { + Assert.IsTrue (module.HasDebugHeader); + + var header = module.GetDebugHeader (); + + Assert.AreEqual (1, header.Entries.Length); + Assert.IsTrue (header.Entries.Any (e => e.Directory.Type == ImageDebugType.Deterministic)); + }); + } + + [Test] + public void Net471TargetingAssembly () + { + TestModule ("net471.exe", module => { + Assert.AreEqual (6, module.Image.SubSystemMajor); + Assert.AreEqual (0, module.Image.SubSystemMinor); + }); + } + + [Test] + public void LocallyScopedConstantArray () + { + TestModule ("LocallyScopedConstantArray.dll", module => { + Assert.IsTrue (module.HasDebugHeader); + var method = module.Types + .Single (x => x.Name == "TestClass") + .Methods + .Single (x => x.Name == "TestMethod"); + var debugInformation = method.DebugInformation; + Assert.IsNull (debugInformation.Scope.Constants.Single ().Value); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void ExternalPdbDeterministicAssembly () + { + TestModule ("ExternalPdbDeterministic.dll", module => { + Assert.IsTrue (module.HasDebugHeader); + + var header = module.GetDebugHeader (); + + Assert.IsTrue (header.Entries.Length >= 2); + Assert.IsTrue (header.Entries.Any (e => e.Directory.Type == ImageDebugType.CodeView)); + Assert.IsTrue (header.Entries.Any (e => e.Directory.Type == ImageDebugType.Deterministic)); + + // If read directly from a file the PdbChecksum may not be persent (in this test case it isn't) + // but when written through Cecil it will always be there. + if (header.Entries.Length > 2) { + Assert.AreEqual (3, header.Entries.Length); + Assert.IsTrue (header.Entries.Any (e => e.Directory.Type == ImageDebugType.PdbChecksum)); + } + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void EmbeddedPdbDeterministicAssembly () + { + TestModule ("EmbeddedPdbDeterministic.dll", module => { + Assert.IsTrue (module.HasDebugHeader); + + var header = module.GetDebugHeader (); + + Assert.IsTrue (header.Entries.Length >= 3); + Assert.IsTrue (header.Entries.Any (e => e.Directory.Type == ImageDebugType.CodeView)); + Assert.IsTrue (header.Entries.Any (e => e.Directory.Type == ImageDebugType.Deterministic)); + Assert.IsTrue (header.Entries.Any (e => e.Directory.Type == ImageDebugType.EmbeddedPortablePdb)); + + // If read directly from a file the PdbChecksum may not be persent (in this test case it isn't) + // but when written through Cecil it will always be there. + if (header.Entries.Length > 3) { + Assert.AreEqual (4, header.Entries.Length); + Assert.IsTrue (header.Entries.Any (e => e.Directory.Type == ImageDebugType.PdbChecksum)); + } + }, symbolReaderProvider: typeof (EmbeddedPortablePdbReaderProvider), symbolWriterProvider: typeof (EmbeddedPortablePdbWriterProvider)); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/ImportCecilTests.cs b/cecil-master/Test/Mono.Cecil.Tests/ImportCecilTests.cs new file mode 100644 index 000000000..70100eac1 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/ImportCecilTests.cs @@ -0,0 +1,368 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using SR = System.Reflection; +using System.Runtime.CompilerServices; + +using Mono.Cecil.Cil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class ImportCecilTests : BaseTestFixture { + + [Test] + public void ImportStringByRef () + { + var get_string = Compile> ((module, body) => { + var type = module.Types [1]; + + var method_by_ref = new MethodDefinition { + Name = "ModifyString", + IsPrivate = true, + IsStatic = true, + }; + + type.Methods.Add (method_by_ref); + + method_by_ref.MethodReturnType.ReturnType = module.ImportReference (typeof (void).ToDefinition ()); + + method_by_ref.Parameters.Add (new ParameterDefinition (module.ImportReference (typeof (string).ToDefinition ()))); + method_by_ref.Parameters.Add (new ParameterDefinition (module.ImportReference (new ByReferenceType (typeof (string).ToDefinition ())))); + + var m_il = method_by_ref.Body.GetILProcessor (); + m_il.Emit (OpCodes.Ldarg_1); + m_il.Emit (OpCodes.Ldarg_0); + m_il.Emit (OpCodes.Stind_Ref); + m_il.Emit (OpCodes.Ret); + + var v_0 = new VariableDefinition (module.ImportReference (typeof (string).ToDefinition ())); + body.Variables.Add (v_0); + + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldnull); + il.Emit (OpCodes.Stloc, v_0); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldloca, v_0); + il.Emit (OpCodes.Call, method_by_ref); + il.Emit (OpCodes.Ldloc_0); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual ("foo", get_string ("foo")); + } + + [Test] + public void ImportStringArray () + { + var identity = Compile> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ret); + }); + + var array = new string [2, 2]; + + Assert.AreEqual (array, identity (array)); + } + + [Test] + public void ImportFieldStringEmpty () + { + var get_empty = Compile> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldsfld, module.ImportReference (typeof (string).GetField ("Empty").ToDefinition ())); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual ("", get_empty ()); + } + + [Test] + public void ImportStringConcat () + { + var concat = Compile> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Call, module.ImportReference (typeof (string).GetMethod ("Concat", new [] { typeof (string), typeof (string) }).ToDefinition ())); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual ("FooBar", concat ("Foo", "Bar")); + } + + public class Generic { + public T Field; + + public T Method (T t) + { + return t; + } + + public TS GenericMethod (T t, TS s) + { + return s; + } + + public Generic ComplexGenericMethod (T t, TS s) + { + return new Generic { Field = s }; + } + } + + [Test] + public void ImportGenericField () + { + var get_field = Compile, string>> ((module, body) => { + var generic_def = module.ImportReference (typeof (Generic<>)).Resolve (); + var field_def = generic_def.Fields.Where (f => f.Name == "Field").First (); + + var field_string = field_def.MakeGeneric (module.ImportReference (typeof (string))); + + var field_ref = module.ImportReference (field_string); + + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldfld, field_ref); + il.Emit (OpCodes.Ret); + }); + + var generic = new Generic { + Field = "foo", + }; + + Assert.AreEqual ("foo", get_field (generic)); + } + + [Test] + public void ImportGenericMethod () + { + var generic_identity = Compile, int, int>> ((module, body) => { + var generic_def = module.ImportReference (typeof (Generic<>)).Resolve (); + var method_def = generic_def.Methods.Where (m => m.Name == "Method").First (); + + var method_int = method_def.MakeGeneric (module.ImportReference (typeof (int))); + var method_ref = module.ImportReference (method_int); + + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Callvirt, method_ref); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual (42, generic_identity (new Generic (), 42)); + } + + [Test] + public void ImportGenericMethodSpec () + { + var gen_spec_id = Compile, int, int>> ((module, body) => { + var generic_def = module.ImportReference (typeof (Generic<>)).Resolve (); + var method_def = generic_def.Methods.Where (m => m.Name == "GenericMethod").First (); + + var method_string = method_def.MakeGeneric (module.ImportReference (typeof (string))); + + var method_instance = method_string.MakeGenericMethod (module.ImportReference (typeof (int))); + + var method_ref = module.ImportReference (method_instance); + + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldnull); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Callvirt, method_ref); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual (42, gen_spec_id (new Generic (), 42)); + } + + [Test] + public void ImportComplexGenericMethodSpec () + { + var gen_spec_id = Compile, int, int>> ((module, body) => { + var generic_def = module.ImportReference (typeof (Generic<>)).Resolve (); + var method_def = generic_def.Methods.Where (m => m.Name == "ComplexGenericMethod").First (); + + var method_string = method_def.MakeGeneric (module.ImportReference (typeof (string))); + var method_instance = method_string.MakeGenericMethod (module.ImportReference (typeof (int))); + var method_ref = module.ImportReference (method_instance); + + var field_def = generic_def.Fields.Where (f => f.Name == "Field").First (); + var field_int = field_def.MakeGeneric (module.ImportReference (typeof (int))); + var field_ref = module.ImportReference (field_int); + + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldnull); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Callvirt, method_ref); + il.Emit (OpCodes.Ldfld, field_ref); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual (42, gen_spec_id (new Generic (), 42)); + } + + [Test] + public void ImportMethodOnOpenGeneric () + { + var generic = typeof (Generic<>).ToDefinition (); + + using (var module = ModuleDefinition.CreateModule ("foo", ModuleKind.Dll)) { + var method = module.ImportReference (generic.GetMethod ("Method")); + Assert.AreEqual ("T Mono.Cecil.Tests.ImportCecilTests/Generic`1::Method(T)", method.FullName); + } + } + + public class ContextGeneric1Method2 + { + public G1 GenericMethod (R1 r, S1 s) + { + return default (G1); + } + } + + public class ContextGeneric2Method1 + { + public R2 GenericMethod (G2 g, H2 h) + { + return default (R2); + } + } + + public class NestedGenericsA + { + public class NestedGenericsB + { + public class NestedGenericsC + { + public A GenericMethod (B b, C c) + { + return default (A); + } + } + } + } + + [Test] + public void ContextGenericTest () + { + if (Platform.OnCoreClr) + return; + + var module = ModuleDefinition.ReadModule (typeof (ContextGeneric1Method2<>).Module.FullyQualifiedName); + // by mixing open generics with 2 & 1 parameters, we make sure the right context is used (because otherwise, an exception will be thrown) + var type = typeof (ContextGeneric1Method2<>).MakeGenericType (typeof (ContextGeneric2Method1<,>)); + var meth = type.GetMethod ("GenericMethod"); + var imported_type = module.ImportReference (type); + var method = module.ImportReference (meth, imported_type); + Assert.AreEqual ("G1 Mono.Cecil.Tests.ImportCecilTests/ContextGeneric1Method2`1>::GenericMethod(R1,S1)", method.FullName); + + // and the other way around + type = typeof (ContextGeneric2Method1<,>).MakeGenericType (typeof (ContextGeneric1Method2<>), typeof (IList<>)); + meth = type.GetMethod ("GenericMethod"); + imported_type = module.ImportReference (type); + method = module.ImportReference (meth, imported_type); + Assert.AreEqual ("R2 Mono.Cecil.Tests.ImportCecilTests/ContextGeneric2Method1`2,System.Collections.Generic.IList`1>::GenericMethod(G2,H2)", method.FullName); + + // not sure about this one + type = typeof (NestedGenericsA.NestedGenericsB.NestedGenericsC); + meth = type.GetMethod ("GenericMethod"); + imported_type = module.ImportReference (type); + method = module.ImportReference (meth, imported_type); + Assert.AreEqual ("A Mono.Cecil.Tests.ImportCecilTests/NestedGenericsA`1/NestedGenericsB`1/NestedGenericsC`1::GenericMethod(B,C)", method.FullName); + + // We need both the method & type ! + type = typeof (Generic<>).MakeGenericType (typeof (string)); + meth = type.GetMethod ("ComplexGenericMethod"); + imported_type = module.ImportReference (type); + method = module.ImportReference (meth, imported_type); + Assert.AreEqual ("Mono.Cecil.Tests.ImportCecilTests/Generic`1 Mono.Cecil.Tests.ImportCecilTests/Generic`1::ComplexGenericMethod(T,TS)", method.FullName); + } + + delegate void Emitter (ModuleDefinition module, MethodBody body); + + static TDelegate Compile (Emitter emitter, [CallerMemberName] string testMethodName = null) + where TDelegate : class + { + var name = "ImportCecil_" + testMethodName; + + var module = CreateTestModule (name, emitter); + var assembly = LoadTestModule (module); + + return CreateRunDelegate (GetTestCase (name, assembly)); + } + + static TDelegate CreateRunDelegate (Type type) + where TDelegate : class + { + return (TDelegate) (object) Delegate.CreateDelegate (typeof (TDelegate), type.GetMethod ("Run")); + } + + static Type GetTestCase (string name, SR.Assembly assembly) + { + return assembly.GetType (name); + } + + static SR.Assembly LoadTestModule (ModuleDefinition module) + { + using (var stream = new MemoryStream ()) { + module.Write (stream); + File.WriteAllBytes (Path.Combine (Path.Combine (Path.GetTempPath (), "cecil"), module.Name + ".dll"), stream.ToArray ()); + return SR.Assembly.Load (stream.ToArray ()); + } + } + + static ModuleDefinition CreateTestModule (string name, Emitter emitter) + { + var module = CreateModule (name); + + var type = new TypeDefinition ( + "", + name, + TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract, + module.ImportReference (typeof (object))); + + module.Types.Add (type); + + var method = CreateMethod (type, typeof (TDelegate).GetMethod ("Invoke")); + + emitter (module, method.Body); + + return module; + } + + static MethodDefinition CreateMethod (TypeDefinition type, SR.MethodInfo pattern) + { + var module = type.Module; + + var method = new MethodDefinition { + Name = "Run", + IsPublic = true, + IsStatic = true, + }; + + type.Methods.Add (method); + + method.MethodReturnType.ReturnType = module.ImportReference (pattern.ReturnType); + + foreach (var parameter_pattern in pattern.GetParameters ()) + method.Parameters.Add (new ParameterDefinition (module.ImportReference (parameter_pattern.ParameterType))); + + return method; + } + + static ModuleDefinition CreateModule (string name) + { + var resolver = new DefaultAssemblyResolver (); + resolver.AddSearchDirectory (Path.GetDirectoryName (typeof (ImportCecilTests).Assembly.Location)); + return ModuleDefinition.CreateModule (name, new ModuleParameters { Kind = ModuleKind.Dll, AssemblyResolver = resolver }); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/ImportReflectionTests.cs b/cecil-master/Test/Mono.Cecil.Tests/ImportReflectionTests.cs new file mode 100644 index 000000000..33b51eedf --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/ImportReflectionTests.cs @@ -0,0 +1,428 @@ +using System; +using System.Collections.Generic; +using System.IO; +using SR = System.Reflection; +using System.Runtime.CompilerServices; + +using Mono.Cecil.Cil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class ImportReflectionTests : BaseTestFixture { + + [Test] + public void ImportString () + { + var get_string = Compile> ((_, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldstr, "yo dawg!"); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual ("yo dawg!", get_string ()); + } + + [Test] + public void ImportInt () + { + var add = Compile> ((_, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Add); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual (42, add (40, 2)); + } + + [Test] + public void ImportStringByRef () + { + var get_string = Compile> ((module, body) => { + var type = module.Types [1]; + + var method_by_ref = new MethodDefinition { + Name = "ModifyString", + IsPrivate = true, + IsStatic = true, + }; + + type.Methods.Add (method_by_ref); + + method_by_ref.MethodReturnType.ReturnType = module.ImportReference (typeof (void)); + + method_by_ref.Parameters.Add (new ParameterDefinition (module.ImportReference (typeof (string)))); + method_by_ref.Parameters.Add (new ParameterDefinition (module.ImportReference (typeof (string).MakeByRefType ()))); + + var m_il = method_by_ref.Body.GetILProcessor (); + m_il.Emit (OpCodes.Ldarg_1); + m_il.Emit (OpCodes.Ldarg_0); + m_il.Emit (OpCodes.Stind_Ref); + m_il.Emit (OpCodes.Ret); + + var v_0 = new VariableDefinition (module.ImportReference (typeof (string))); + body.Variables.Add (v_0); + + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldnull); + il.Emit (OpCodes.Stloc, v_0); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldloca, v_0); + il.Emit (OpCodes.Call, method_by_ref); + il.Emit (OpCodes.Ldloc_0); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual ("foo", get_string ("foo")); + } + + [Test] + public void ImportStringArray () + { + var identity = Compile> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ret); + }); + + var array = new string [2, 2]; + + Assert.AreEqual (array, identity (array)); + } + + [Test] + public void ImportFieldStringEmpty () + { + var get_empty = Compile> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldsfld, module.ImportReference (typeof (string).GetField ("Empty"))); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual ("", get_empty ()); + } + + [Test] + public void ImportStringConcat () + { + var concat = Compile> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Call, module.ImportReference (typeof (string).GetMethod ("Concat", new [] { typeof (string), typeof (string) }))); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual ("FooBar", concat ("Foo", "Bar")); + } + + [Test] + public void GeneratedAssemblyCulture () + { + var id = Compile> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual ("", id.Method.DeclaringType.Assembly.GetName ().CultureInfo.Name); + } + + public class Generic { + public T Field; + + public T Method (T t) + { + return t; + } + + public TS GenericMethod (T t, TS s) + { + return s; + } + + public Generic ComplexGenericMethod (T t, TS s) + { + return new Generic { Field = s }; + } + } + + [Test] + public void ImportGenericField () + { + if (Platform.OnCoreClr) + return; + + var get_field = Compile, string>> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldfld, module.ImportReference (typeof (Generic).GetField ("Field"))); + il.Emit (OpCodes.Ret); + }); + + var generic = new Generic { + Field = "foo", + }; + + Assert.AreEqual ("foo", get_field (generic)); + } + + [Test] + public void ImportGenericMethod () + { + if (Platform.OnCoreClr) + return; + + var generic_identity = Compile, int, int>> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetMethod ("Method"))); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual (42, generic_identity (new Generic (), 42)); + } + + [Test] + public void ImportGenericMethodSpec () + { + if (Platform.OnCoreClr) + return; + + var gen_spec_id = Compile, int, int>> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldnull); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetMethod ("GenericMethod").MakeGenericMethod (typeof (int)))); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual (42, gen_spec_id (new Generic (), 42)); + } + + [Test] + public void ImportComplexGenericMethodSpec () + { + if (Platform.OnCoreClr) + return; + + var gen_spec_id = Compile, int, int>> ((module, body) => { + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ldarg_0); + il.Emit (OpCodes.Ldnull); + il.Emit (OpCodes.Ldarg_1); + il.Emit (OpCodes.Callvirt, module.ImportReference (typeof (Generic).GetMethod ("ComplexGenericMethod").MakeGenericMethod (typeof (int)))); + il.Emit (OpCodes.Ldfld, module.ImportReference (typeof (Generic).GetField ("Field"))); + il.Emit (OpCodes.Ret); + }); + + Assert.AreEqual (42, gen_spec_id (new Generic (), 42)); + } + + public class Foo { + public List list; + } + + [Test] + public void ImportGenericTypeDefOrOpen () + { + using (var module = typeof (Foo<>).ToDefinition ().Module) { + var foo_def = module.ImportReference (typeof (Foo<>)); + var foo_open = module.ImportReference (typeof (Foo<>), foo_def); + + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1", foo_def.FullName); + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1", foo_open.FullName); + } + } + + [Test] + public void ImportGenericTypeFromContext () + { + var list_foo = typeof (Foo<>).GetField ("list").FieldType; + var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); + + var foo_def = typeof (Foo<>).ToDefinition (); + using (var module = foo_def.Module) { + var generic_foo = module.ImportReference (generic_list_foo_open, foo_def); + + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Generic`1>", + generic_foo.FullName); + } + } + + [Test] + public void ImportGenericTypeDefFromContext () + { + var foo_open = typeof (Foo<>).MakeGenericType (typeof (Foo<>).GetGenericArguments () [0]); + var generic_foo_open = typeof (Generic<>).MakeGenericType (foo_open); + + var foo_def = typeof (Foo<>).ToDefinition (); + using (var module = foo_def.Module) { + var generic_foo = module.ImportReference (generic_foo_open, foo_def); + + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Generic`1>", + generic_foo.FullName); + } + } + + [Test] + public void ImportArrayTypeDefFromContext () + { + var foo_open = typeof (Foo<>).MakeGenericType (typeof (Foo<>).GetGenericArguments () [0]); + var foo_open_array = foo_open.MakeArrayType (); + + var foo_def = typeof (Foo<>).ToDefinition (); + using (var module = foo_def.Module) { + var array_foo = module.ImportReference (foo_open_array, foo_def); + + Assert.AreEqual ("Mono.Cecil.Tests.ImportReflectionTests/Foo`1[]", + array_foo.FullName); + } + } + + [Test] + public void ImportGenericFieldFromContext () + { + if (Platform.OnCoreClr) + return; + + var list_foo = typeof (Foo<>).GetField ("list").FieldType; + var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); + var generic_list_foo_open_field = generic_list_foo_open.GetField ("Field"); + + var foo_def = typeof (Foo<>).ToDefinition (); + using (var module = foo_def.Module) { + var generic_field = module.ImportReference (generic_list_foo_open_field, foo_def); + + Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1>::Field", + generic_field.FullName); + } + } + + [Test] + public void ImportGenericMethodFromContext () + { + if (Platform.OnCoreClr) + return; + + var list_foo = typeof (Foo<>).GetField ("list").FieldType; + var generic_list_foo_open = typeof (Generic<>).MakeGenericType (list_foo); + var generic_list_foo_open_method = generic_list_foo_open.GetMethod ("Method"); + + var foo_def = typeof (Foo<>).ToDefinition (); + using (var module = foo_def.Module) { + var generic_method = module.ImportReference (generic_list_foo_open_method, foo_def); + + Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1>::Method(T)", + generic_method.FullName); + } + } + + [Test] + public void ImportMethodOnOpenGenericType () + { + using (var module = typeof (Generic<>).ToDefinition ().Module) { + var method = module.ImportReference (typeof (Generic<>).GetMethod ("Method")); + + Assert.AreEqual ("T Mono.Cecil.Tests.ImportReflectionTests/Generic`1::Method(T)", method.FullName); + } + } + + [Test] + public void ImportGenericMethodOnOpenGenericType () + { + using (var module = typeof (Generic<>).ToDefinition ().Module) { + var generic_method = module.ImportReference (typeof (Generic<>).GetMethod ("GenericMethod")); + + Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1::GenericMethod(T,TS)", generic_method.FullName); + + generic_method = module.ImportReference (typeof (Generic<>).GetMethod ("GenericMethod"), generic_method); + + Assert.AreEqual ("TS Mono.Cecil.Tests.ImportReflectionTests/Generic`1::GenericMethod(T,TS)", generic_method.FullName); + } + } + + delegate void Emitter (ModuleDefinition module, MethodBody body); + + static TDelegate Compile (Emitter emitter, [CallerMemberName] string testMethodName = null) + where TDelegate : class + { + var name = "ImportReflection_" + testMethodName; + + var module = CreateTestModule (name, emitter); + var assembly = LoadTestModule (module); + + return CreateRunDelegate (GetTestCase (name, assembly)); + } + + static TDelegate CreateRunDelegate (Type type) + where TDelegate : class + { + return (TDelegate) (object) Delegate.CreateDelegate (typeof (TDelegate), type.GetMethod ("Run")); + } + + static Type GetTestCase (string name, SR.Assembly assembly) + { + return assembly.GetType (name); + } + + static SR.Assembly LoadTestModule (ModuleDefinition module) + { + using (var stream = new MemoryStream ()) { + module.Write (stream); + File.WriteAllBytes (Path.Combine (Path.Combine (Path.GetTempPath (), "cecil"), module.Name + ".dll"), stream.ToArray ()); + return SR.Assembly.Load (stream.ToArray ()); + } + } + + static ModuleDefinition CreateTestModule (string name, Emitter emitter) + { + var module = CreateModule (name); + + var type = new TypeDefinition ( + "", + name, + TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.Abstract, + module.ImportReference (typeof (object))); + + module.Types.Add (type); + + var method = CreateMethod (type, typeof (TDelegate).GetMethod ("Invoke")); + + emitter (module, method.Body); + + return module; + } + + static MethodDefinition CreateMethod (TypeDefinition type, SR.MethodInfo pattern) + { + var module = type.Module; + + var method = new MethodDefinition { + Name = "Run", + IsPublic = true, + IsStatic = true, + }; + + type.Methods.Add (method); + + method.MethodReturnType.ReturnType = module.ImportReference (pattern.ReturnType); + + foreach (var parameter_pattern in pattern.GetParameters ()) + method.Parameters.Add (new ParameterDefinition (module.ImportReference (parameter_pattern.ParameterType))); + + return method; + } + + static ModuleDefinition CreateModule (string name) + { + return ModuleDefinition.CreateModule (name, ModuleKind.Dll); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/LoadAssemblyDefinitionForTestsBaseSimple.cs b/cecil-master/Test/Mono.Cecil.Tests/LoadAssemblyDefinitionForTestsBaseSimple.cs new file mode 100644 index 000000000..5c3b71385 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/LoadAssemblyDefinitionForTestsBaseSimple.cs @@ -0,0 +1,16 @@ +using System.Reflection; + +namespace Mono.Cecil.Tests { + + public class LoadAssemblyDefinitionForTestsBaseSimple { + + protected AssemblyDefinition _assembly; + protected AssemblyDefinition _mscorlib; + + public void SetupAssemblyDefinitions (Assembly testAssembly) + { + _assembly = AssemblyDefinition.ReadAssembly (testAssembly.Location); + _mscorlib = _assembly.MainModule.TypeSystem.Object.Resolve ().Module.Assembly; + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/MethodBodyTests.cs b/cecil-master/Test/Mono.Cecil.Tests/MethodBodyTests.cs new file mode 100644 index 000000000..5af097bc9 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/MethodBodyTests.cs @@ -0,0 +1,453 @@ +using System; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class MethodBodyTests : BaseTestFixture { + + [Test] + public void MultiplyMethod () + { + TestIL ("hello.il", module => { + var foo = module.GetType ("Foo"); + Assert.IsNotNull (foo); + + var bar = foo.GetMethod ("Bar"); + Assert.IsNotNull (bar); + Assert.IsTrue (bar.IsIL); + + AssertCode (@" + .locals init (System.Int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: mul + IL_0003: stloc.0 + IL_0004: ldloc.0 + IL_0005: call System.Void Foo::Baz(System.Int32) + IL_000a: ret +", bar); + }); + } + + [Test] + public void PrintStringEmpty () + { + TestIL ("hello.il", module => { + var foo = module.GetType ("Foo"); + Assert.IsNotNull (foo); + + var print_empty = foo.GetMethod ("PrintEmpty"); + Assert.IsNotNull (print_empty); + + AssertCode (@" + .locals () + IL_0000: ldsfld System.String System.String::Empty + IL_0005: call System.Void System.Console::WriteLine(System.String) + IL_000a: ret +", print_empty); + }); + } + + [Test] + public void Branch () + { + TestModule ("libhello.dll", module => { + var lib = module.GetType ("Library"); + Assert.IsNotNull (lib); + + var method = lib.GetMethod ("GetHelloString"); + Assert.IsNotNull (method); + + AssertCode (@" + .locals init (System.String V_0) + IL_0000: nop + IL_0001: ldstr ""hello world of tomorrow"" + IL_0006: stloc.0 + IL_0007: br.s IL_0009 + IL_0009: ldloc.0 + IL_000a: ret +", method); + }); + } + + [Test] + public void Switch () + { + TestModule ("switch.exe", module => { + var program = module.GetType ("Program"); + Assert.IsNotNull (program); + + var method = program.GetMethod ("Main"); + Assert.IsNotNull (method); + + AssertCode (@" + .locals init (System.Int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldlen + IL_0002: conv.i4 + IL_0003: stloc.0 + IL_0004: ldloc.0 + IL_0005: ldc.i4.8 + IL_0006: bgt.s IL_0026 + IL_0008: ldloc.0 + IL_0009: ldc.i4.1 + IL_000a: sub + IL_000b: switch (IL_0032, IL_0034, IL_0038, IL_0034) + IL_0020: ldloc.0 + IL_0021: ldc.i4.8 + IL_0022: beq.s IL_0036 + IL_0024: br.s IL_0038 + IL_0026: ldloc.0 + IL_0027: ldc.i4.s 16 + IL_0029: beq.s IL_0036 + IL_002b: ldloc.0 + IL_002c: ldc.i4.s 32 + IL_002e: beq.s IL_0036 + IL_0030: br.s IL_0038 + IL_0032: ldc.i4.0 + IL_0033: ret + IL_0034: ldc.i4.1 + IL_0035: ret + IL_0036: ldc.i4.2 + IL_0037: ret + IL_0038: ldc.i4.s 42 + IL_003a: ret +", method); + }); + } + + [Test] + public void MethodSpec () + { + TestIL ("methodspecs.il", module => { + var tamtam = module.GetType ("Tamtam"); + + var bar = tamtam.GetMethod ("Bar"); + Assert.IsNotNull (bar); + + AssertCode (@" + .locals () + IL_0000: ldc.i4.2 + IL_0001: call System.Void Tamtam::Foo(TFoo) + IL_0006: ret +", bar); + }); + } + + [Test] + public void NestedTryCatchFinally () + { + TestModule ("catch.exe", module => { + var program = module.GetType ("Program"); + var main = program.GetMethod ("Main"); + Assert.IsNotNull (main); + + AssertCode (@" + .locals () + IL_0000: call System.Void Program::Foo() + IL_0005: leave.s IL_000d + IL_0007: call System.Void Program::Baz() + IL_000c: endfinally + IL_000d: leave.s IL_001f + IL_000f: pop + IL_0010: call System.Void Program::Bar() + IL_0015: leave.s IL_001f + IL_0017: pop + IL_0018: call System.Void Program::Bar() + IL_001d: leave.s IL_001f + IL_001f: leave.s IL_0027 + IL_0021: call System.Void Program::Baz() + IL_0026: endfinally + IL_0027: ret + .try IL_0000 to IL_0007 finally handler IL_0007 to IL_000d + .try IL_0000 to IL_000f catch System.ArgumentException handler IL_000f to IL_0017 + .try IL_0000 to IL_000f catch System.Exception handler IL_0017 to IL_001f + .try IL_0000 to IL_0021 finally handler IL_0021 to IL_0027 +", main); + }); + } + + [Test] + public void FunctionPointersAndCallSites () + { + TestModule ("fptr.exe", module => { + var type = module.Types [0]; + var start = type.GetMethod ("Start"); + Assert.IsNotNull (start); + + AssertCode (@" + .locals init () + IL_0000: ldc.i4.1 + IL_0001: call method System.Int32 *(System.Int32) MakeDecision::Decide() + IL_0006: calli System.Int32(System.Int32) + IL_000b: call System.Void System.Console::WriteLine(System.Int32) + IL_0010: ldc.i4.1 + IL_0011: call method System.Int32 *(System.Int32) MakeDecision::Decide() + IL_0016: calli System.Int32(System.Int32) + IL_001b: call System.Void System.Console::WriteLine(System.Int32) + IL_0020: ldc.i4.1 + IL_0021: call method System.Int32 *(System.Int32) MakeDecision::Decide() + IL_0026: calli System.Int32(System.Int32) + IL_002b: call System.Void System.Console::WriteLine(System.Int32) + IL_0030: ret +", start); + }, verify: false); + } + + [Test] + public void ThisParameter () + { + TestIL ("hello.il", module => { + var type = module.GetType ("Foo"); + var method = type.GetMethod ("Gazonk"); + + Assert.IsNotNull (method); + + AssertCode (@" + .locals () + IL_0000: ldarg 0 + IL_0004: pop + IL_0005: ret +", method); + + Assert.AreEqual (method.Body.ThisParameter.ParameterType, type); + Assert.AreEqual (method.Body.ThisParameter, method.Body.Instructions [0].Operand); + }); + } + + [Test] + public void ThisParameterStaticMethod () + { + var static_method = typeof (ModuleDefinition).ToDefinition ().Methods.Where (m => m.IsStatic).First (); + Assert.IsNull (static_method.Body.ThisParameter); + } + + [Test] + public void ThisParameterPrimitive () + { + var int32 = typeof (int).ToDefinition (); + var int_to_string = int32.Methods.Where (m => m.Name == "ToString" && m.Parameters.Count == 0).First(); + Assert.IsNotNull (int_to_string); + + var this_parameter_type = int_to_string.Body.ThisParameter.ParameterType; + Assert.IsTrue (this_parameter_type.IsByReference); + + var element_type = ((ByReferenceType) this_parameter_type).ElementType; + Assert.AreEqual (int32, element_type); + } + + [Test] + public void ThisParameterValueType () + { + var token = typeof (MetadataToken).ToDefinition (); + var token_to_string = token.Methods.Where (m => m.Name == "ToString" && m.Parameters.Count == 0).First (); + Assert.IsNotNull (token_to_string); + + var this_parameter_type = token_to_string.Body.ThisParameter.ParameterType; + Assert.IsTrue (this_parameter_type.IsByReference); + + var element_type = ((ByReferenceType) this_parameter_type).ElementType; + Assert.AreEqual (token, element_type); + } + + [Test] + public void ThisParameterObject () + { + var module = typeof (MethodBodyTests).ToDefinition ().Module; + var @object = module.TypeSystem.Object.Resolve (); + var method = @object.Methods.Where (m => m.HasBody).First (); + + var type = method.Body.ThisParameter.ParameterType; + Assert.IsFalse (type.IsValueType); + Assert.IsFalse (type.IsPrimitive); + Assert.IsFalse (type.IsPointer); + } + + [Test] + public void FilterMaxStack () + { + TestIL ("hello.il", module => { + var type = module.GetType ("Foo"); + var method = type.GetMethod ("TestFilter"); + + Assert.IsNotNull (method); + Assert.AreEqual (2, method.Body.MaxStackSize); + }); + } + + [Test] + public void BranchOutsideMethod () + { + OnlyOnWindows (); // Mono's ilasm doesn't support branching outside of method + + TestIL ("branch-out.il", module => { + var type = module.GetType ("Foo"); + var method = type.GetMethod ("BranchOutside"); + + Assert.IsNotNull (method); + Assert.IsNotNull (method.Body); + + var leave = method.Body.Instructions [0]; + Assert.AreEqual (OpCodes.Leave, leave.OpCode); + Assert.IsNull (leave.Operand); + Assert.AreEqual ("IL_0000: leave", leave.ToString ()); + }, verify: false); + } + + [Test] + public void Iterator () + { + TestModule ("iterator.exe", module => { + var method = module.GetType ("Program").GetMethod ("GetLittleArgs"); + Assert.IsNotNull (method.Body); + }); + } + + [Test] + public void LoadString () + { + TestCSharp ("CustomAttributes.cs", module => { + var type = module.GetType ("FooAttribute"); + var get_fiou = type.GetMethod ("get_Fiou"); + Assert.IsNotNull (get_fiou); + + var ldstr = get_fiou.Body.Instructions.Where (i => i.OpCode == OpCodes.Ldstr).First (); + Assert.AreEqual ("fiou", ldstr.Operand); + }); + } + + [Test] + public void UnattachedMethodBody () + { + var system_void = typeof (void).ToDefinition (); + var method = new MethodDefinition ("NewMethod", MethodAttributes.Assembly | MethodAttributes.Static, system_void); + var body = new MethodBody (method); + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ret); + method.Body = body; + + Assert.AreEqual (body, method.Body); + } + + [Test] + public void AddInstruction () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + + var il = body.GetILProcessor (); + + var first = il.Create (OpCodes.Nop); + var second = il.Create (OpCodes.Nop); + + body.Instructions.Add (first); + body.Instructions.Add (second); + + Assert.IsNull (first.Previous); + Assert.AreEqual (second, first.Next); + Assert.AreEqual (first, second.Previous); + Assert.IsNull (second.Next); + } + + [Test] + public void InsertInstruction () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + + var il = body.GetILProcessor (); + + var first = il.Create (OpCodes.Nop); + var second = il.Create (OpCodes.Nop); + var third = il.Create (OpCodes.Nop); + + body.Instructions.Add (first); + body.Instructions.Add (third); + + Assert.IsNull (first.Previous); + Assert.AreEqual (third, first.Next); + Assert.AreEqual (first, third.Previous); + Assert.IsNull (third.Next); + + body.Instructions.Insert (1, second); + + Assert.IsNull (first.Previous); + Assert.AreEqual (second, first.Next); + Assert.AreEqual (first, second.Previous); + Assert.AreEqual (third, second.Next); + Assert.AreEqual (second, third.Previous); + Assert.IsNull (third.Next); + } + + [Test] + public void InsertAfterLastInstruction () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + + var il = body.GetILProcessor (); + + var first = il.Create (OpCodes.Nop); + var second = il.Create (OpCodes.Nop); + var third = il.Create (OpCodes.Nop); + + body.Instructions.Add (first); + body.Instructions.Add (second); + + Assert.IsNull (first.Previous); + Assert.AreEqual (second, first.Next); + Assert.AreEqual (first, second.Previous); + Assert.IsNull (second.Next); + + body.Instructions.Insert (2, third); + + Assert.IsNull (first.Previous); + Assert.AreEqual (second, first.Next); + Assert.AreEqual (first, second.Previous); + Assert.AreEqual (third, second.Next); + Assert.AreEqual (second, third.Previous); + Assert.IsNull (third.Next); + } + + [Test] + public void RemoveInstruction () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + + var il = body.GetILProcessor (); + + var first = il.Create (OpCodes.Nop); + var second = il.Create (OpCodes.Nop); + var third = il.Create (OpCodes.Nop); + + body.Instructions.Add (first); + body.Instructions.Add (second); + body.Instructions.Add (third); + + Assert.IsNull (first.Previous); + Assert.AreEqual (second, first.Next); + Assert.AreEqual (first, second.Previous); + Assert.AreEqual (third, second.Next); + Assert.AreEqual (second, third.Previous); + Assert.IsNull (third.Next); + + body.Instructions.Remove (second); + + Assert.IsNull (first.Previous); + Assert.AreEqual (third, first.Next); + Assert.AreEqual (first, third.Previous); + Assert.IsNull (third.Next); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/MethodReferenceComparerTests.cs b/cecil-master/Test/Mono.Cecil.Tests/MethodReferenceComparerTests.cs new file mode 100644 index 000000000..92e5de358 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/MethodReferenceComparerTests.cs @@ -0,0 +1,135 @@ +using NUnit.Framework; +using System; +using System.Linq; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class MethodReferenceComparerTests : LoadAssemblyDefinitionForTestsBaseSimple { + + private TypeDefinition _class1; + private TypeDefinition _class2; + + [SetUp] + public void SetUp () + { + SetupAssemblyDefinitions (typeof (MethodReferenceComparerTests).Assembly); + _class1 = TypeDefinitionUtils.TypeDefinitionFor (typeof (Class1), _assembly); + _class2 = TypeDefinitionUtils.TypeDefinitionFor (typeof (Class2), _assembly); + } + + [Test] + public void MethodReferenceEqualsMethodDefinition () + { + var typeDefinition = TypeDefinitionUtils.TypeDefinitionFor (typeof (Int32), _mscorlib); + var method = typeDefinition.Methods.Single (m => m.Name == "GetHashCode"); + var methodReference = new MethodReference (method.Name, method.ReturnType, method.DeclaringType); + methodReference.HasThis = method.HasThis; + + Assert.That (MethodReferenceComparer.AreEqual (method, methodReference), Is.True); + } + + [Test] + public void VerifyMethodSignatureMatches () + { + Assert.IsTrue (CompareSignatures ("MethodWithNoParametersOrReturn")); + Assert.IsTrue (CompareSignatures ("GenericMethodWithNoParametersOrReturn")); + Assert.IsFalse (CompareSignatures ("MethodWithNoParametersOrReturn", "GenericMethodWithNoParametersOrReturn")); + + Assert.IsTrue (CompareSignatures ("MethodWithIntParameterAndVoidReturn")); + } + + [Test] + public void VerifySignatureComparisonConsidersStatic () + { + Assert.IsTrue (CompareSignatures ("StaticMethodWithNoParametersOrReturn")); + Assert.IsTrue (CompareSignatures ("StaticMethodWithNoParametersOrReturn")); + Assert.IsFalse (CompareSignatures ("MethodWithNoParametersOrReturn", "StaticMethodWithNoParametersOrReturn")); + Assert.IsFalse (CompareSignatures ("GenericMethodWithNoParametersOrReturn", "GenericStaticMethodWithNoParametersOrReturn")); + } + + [Test] + public void VerifyMethodSignatureWithGenericParameters () + { + Assert.IsTrue (CompareSignatures ("GenericMethodWithGenericParameter")); + Assert.IsTrue (CompareSignatures ("GenericMethodWithGenericParameterArray")); + Assert.IsTrue (CompareSignatures ("GenericMethodWithByReferenceGenericParameter")); + Assert.IsTrue (CompareSignatures ("GenericMethodWithGenericInstanceGenericParameter")); + } + + [Test] + public void VerifyNonResolvableMethodReferencesWithDifferentParameterTypesAreNotEqual () + { + var method1 = new MethodReference ("TestMethod", _class1.Module.TypeSystem.Void, _class1); + method1.Parameters.Add (new ParameterDefinition (new ByReferenceType (_class1.Module.TypeSystem.Int16))); + + var method2 = new MethodReference ("TestMethod", _class1.Module.TypeSystem.Void, _class1); + method2.Parameters.Add (new ParameterDefinition (new ByReferenceType (_class1.Module.TypeSystem.Char))); + + Assert.IsFalse (MethodReferenceComparer.AreEqual (method1, method2)); + } + + [Test] + public void VerifyNonResolvableRecursiveMethodsDontStackOverflow () + { + var method1 = new MethodReference ("TestMethod", _class1.Module.TypeSystem.Void, _class1); + method1.GenericParameters.Add (new GenericParameter (method1)); + method1.Parameters.Add (new ParameterDefinition (method1.GenericParameters[0])); + + var method2 = new MethodReference ("TestMethod", _class1.Module.TypeSystem.Void, _class1); + method2.GenericParameters.Add (new GenericParameter (method2)); + method2.Parameters.Add (new ParameterDefinition (method2.GenericParameters[0])); + + Assert.IsTrue (MethodReferenceComparer.AreEqual (method1, method2)); + } + + bool CompareSignatures (string name) + { + return CompareSignatures (name, name); + } + + bool CompareSignatures (string name1, string name2) + { + return MethodReferenceComparer.AreSignaturesEqual (GetMethod (_class1, name1), GetMethod (_class2, name2), TypeComparisonMode.SignatureOnly); + } + + static MethodDefinition GetMethod (TypeDefinition type, string name) + { + return type.Methods.Single (m => m.Name == name); + } + + class GenericClass { + + } + + class Class1 { + + void MethodWithNoParametersOrReturn () {} + void GenericMethodWithNoParametersOrReturn () {} + static void StaticMethodWithNoParametersOrReturn () {} + static void GenericStaticMethodWithNoParametersOrReturn () {} + + void MethodWithIntParameterAndVoidReturn (int a) {} + + void GenericMethodWithGenericParameter (T t) {} + void GenericMethodWithGenericParameterArray (T[] t) {} + void GenericMethodWithByReferenceGenericParameter (ref T a) {} + void GenericMethodWithGenericInstanceGenericParameter (GenericClass a) {} + } + + class Class2 { + + void MethodWithNoParametersOrReturn () {} + void GenericMethodWithNoParametersOrReturn () {} + static void StaticMethodWithNoParametersOrReturn () {} + static void GenericStaticMethodWithNoParametersOrReturn () {} + + void MethodWithIntParameterAndVoidReturn (int a) {} + + void GenericMethodWithGenericParameter (T t) {} + void GenericMethodWithGenericParameterArray (T[] t) {} + void GenericMethodWithByReferenceGenericParameter (ref T a) {} + void GenericMethodWithGenericInstanceGenericParameter (GenericClass a) {} + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/MethodTests.cs b/cecil-master/Test/Mono.Cecil.Tests/MethodTests.cs new file mode 100644 index 000000000..821fb139e --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/MethodTests.cs @@ -0,0 +1,374 @@ +using System; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; +using Mono.Collections.Generic; +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class MethodTests : BaseTestFixture { + + [Test] + public void AbstractMethod () + { + TestCSharp ("Methods.cs", module => { + var type = module.Types [1]; + Assert.AreEqual ("Foo", type.Name); + Assert.AreEqual (2, type.Methods.Count); + + var method = type.GetMethod ("Bar"); + Assert.AreEqual ("Bar", method.Name); + Assert.IsTrue (method.IsAbstract); + Assert.IsNotNull (method.ReturnType); + + Assert.AreEqual (1, method.Parameters.Count); + + var parameter = method.Parameters [0]; + + Assert.AreEqual ("a", parameter.Name); + Assert.AreEqual ("System.Int32", parameter.ParameterType.FullName); + }); + } + + [Test] + public void SimplePInvoke () + { + TestCSharp ("Methods.cs", module => { + var bar = module.GetType ("Bar"); + var pan = bar.GetMethod ("Pan"); + + Assert.IsTrue (pan.IsPInvokeImpl); + Assert.IsNotNull (pan.PInvokeInfo); + + Assert.AreEqual ("Pan", pan.PInvokeInfo.EntryPoint); + Assert.IsNotNull (pan.PInvokeInfo.Module); + Assert.AreEqual ("foo.dll", pan.PInvokeInfo.Module.Name); + }); + } + + [Test] + public void GenericMethodDefinition () + { + TestCSharp ("Generics.cs", module => { + var baz = module.GetType ("Baz"); + + var gazonk = baz.GetMethod ("Gazonk"); + + Assert.IsNotNull (gazonk); + + Assert.IsTrue (gazonk.HasGenericParameters); + Assert.AreEqual (1, gazonk.GenericParameters.Count); + Assert.AreEqual ("TBang", gazonk.GenericParameters [0].Name); + }); + } + + [Test] + public void ReturnGenericInstance () + { + TestCSharp ("Generics.cs", module => { + var bar = module.GetType ("Bar`1"); + + var self = bar.GetMethod ("Self"); + Assert.IsNotNull (self); + + var bar_t = self.ReturnType; + + Assert.IsTrue (bar_t.IsGenericInstance); + + var bar_t_instance = (GenericInstanceType) bar_t; + + Assert.AreEqual (bar.GenericParameters [0], bar_t_instance.GenericArguments [0]); + + var self_str = bar.GetMethod ("SelfString"); + Assert.IsNotNull (self_str); + + var bar_str = self_str.ReturnType; + Assert.IsTrue (bar_str.IsGenericInstance); + + var bar_str_instance = (GenericInstanceType) bar_str; + + Assert.AreEqual ("System.String", bar_str_instance.GenericArguments [0].FullName); + }); + } + + [Test] + public void ReturnGenericInstanceWithMethodParameter () + { + TestCSharp ("Generics.cs", module => { + var baz = module.GetType ("Baz"); + + var gazoo = baz.GetMethod ("Gazoo"); + Assert.IsNotNull (gazoo); + + var bar_bingo = gazoo.ReturnType; + + Assert.IsTrue (bar_bingo.IsGenericInstance); + + var bar_bingo_instance = (GenericInstanceType) bar_bingo; + + Assert.AreEqual (gazoo.GenericParameters [0], bar_bingo_instance.GenericArguments [0]); + }); + } + + [Test] + public void SimpleOverrides () + { + TestCSharp ("Interfaces.cs", module => { + var ibingo = module.GetType ("IBingo"); + var ibingo_foo = ibingo.GetMethod ("Foo"); + Assert.IsNotNull (ibingo_foo); + + var ibingo_bar = ibingo.GetMethod ("Bar"); + Assert.IsNotNull (ibingo_bar); + + var bingo = module.GetType ("Bingo"); + + var foo = bingo.GetMethod ("IBingo.Foo"); + Assert.IsNotNull (foo); + + Assert.IsTrue (foo.HasOverrides); + Assert.AreEqual (ibingo_foo, foo.Overrides [0]); + + var bar = bingo.GetMethod ("IBingo.Bar"); + Assert.IsNotNull (bar); + + Assert.IsTrue (bar.HasOverrides); + Assert.AreEqual (ibingo_bar, bar.Overrides [0]); + }); + } + + [Test] + public void VarArgs () + { + TestModule ("varargs.exe", module => { + var module_type = module.Types [0]; + + Assert.AreEqual (3, module_type.Methods.Count); + + var bar = module_type.GetMethod ("Bar"); + var baz = module_type.GetMethod ("Baz"); + var foo = module_type.GetMethod ("Foo"); + + Assert.IsTrue (bar.IsVarArg ()); + Assert.IsFalse (baz.IsVarArg ()); + + Assert.IsTrue (foo.IsVarArg ()); + + var foo_reference = (MethodReference) baz.Body.Instructions.First (i => i.Offset == 0x000a).Operand; + + Assert.IsTrue (foo_reference.IsVarArg ()); + Assert.AreEqual (0, foo_reference.GetSentinelPosition ()); + + Assert.AreEqual (foo, foo_reference.Resolve ()); + + var bar_reference = (MethodReference) baz.Body.Instructions.First (i => i.Offset == 0x0023).Operand; + + Assert.IsTrue (bar_reference.IsVarArg ()); + + Assert.AreEqual (1, bar_reference.GetSentinelPosition ()); + + Assert.AreEqual (bar, bar_reference.Resolve ()); + }); + } + + [Test] + public void GenericInstanceMethod () + { + TestCSharp ("Generics.cs", module => { + var type = module.GetType ("It"); + var method = type.GetMethod ("ReadPwow"); + + GenericInstanceMethod instance = null; + + foreach (var instruction in method.Body.Instructions) { + instance = instruction.Operand as GenericInstanceMethod; + if (instance != null) + break; + } + + Assert.IsNotNull (instance); + + Assert.AreEqual (TokenType.MethodSpec, instance.MetadataToken.TokenType); + Assert.AreNotEqual (0, instance.MetadataToken.RID); + }); + } + + [Test] + public void MethodRefDeclaredOnGenerics () + { + TestCSharp ("Generics.cs", module => { + var type = module.GetType ("Tamtam"); + var beta = type.GetMethod ("Beta"); + var charlie = type.GetMethod ("Charlie"); + + // Note that the test depends on the C# compiler emitting the constructor call instruction as + // the first instruction of the method body. This requires optimizations to be enabled. + var new_list_beta = (MethodReference) beta.Body.Instructions [0].Operand; + var new_list_charlie = (MethodReference) charlie.Body.Instructions [0].Operand; + + Assert.AreEqual ("System.Collections.Generic.List`1", new_list_beta.DeclaringType.FullName); + Assert.AreEqual ("System.Collections.Generic.List`1", new_list_charlie.DeclaringType.FullName); + }); + } + + [Test] + public void ReturnParameterMethod () + { + var method = typeof (MethodTests).ToDefinition ().GetMethod ("ReturnParameterMethod"); + Assert.IsNotNull (method); + Assert.AreEqual (method, method.MethodReturnType.Parameter.Method); + } + + [Test] + public void InstanceAndStaticMethodComparison () + { + TestIL ("others.il", module => { + var others = module.GetType ("Others"); + var instance_method = others.Methods.Single (m => m.Name == "SameMethodNameInstanceStatic" && m.HasThis); + var static_method_reference = new MethodReference ("SameMethodNameInstanceStatic", instance_method.ReturnType, others) + { + HasThis = false + }; + + Assert.AreNotEqual(instance_method, static_method_reference.Resolve ()); + }); + } + + [Test] + public void FunctionPointerArgumentOverload () + { + TestIL ("others.il", module => { + var others = module.GetType ("Others"); + var overloaded_methods = others.Methods.Where (m => m.Name == "OverloadedWithFpArg").ToArray (); + // Manually create the function-pointer type so `AreSame` won't exit early due to reference equality + var overloaded_method_int_reference = new MethodReference ("OverloadedWithFpArg", module.TypeSystem.Void, others) + { + HasThis = false, + Parameters = { new ParameterDefinition ("X", ParameterAttributes.None, new FunctionPointerType () { + HasThis = false, + ReturnType = module.TypeSystem.Int32, + Parameters = { new ParameterDefinition (module.TypeSystem.Int32) } + }) } + }; + + var overloaded_method_long_reference = new MethodReference ("OverloadedWithFpArg", module.TypeSystem.Void, others) + { + HasThis = false, + Parameters = { new ParameterDefinition ("X", ParameterAttributes.None, new FunctionPointerType () { + HasThis = false, + ReturnType = module.TypeSystem.Int32, + Parameters = { new ParameterDefinition (module.TypeSystem.Int64) } + }) } + }; + + var overloaded_method_cdecl_reference = new MethodReference ("OverloadedWithFpArg", module.TypeSystem.Void, others) + { + HasThis = false, + Parameters = { new ParameterDefinition ("X", ParameterAttributes.None, new FunctionPointerType () { + CallingConvention = MethodCallingConvention.C, + HasThis = false, + ReturnType = module.TypeSystem.Int32, + Parameters = { new ParameterDefinition (module.TypeSystem.Int32) } + }) } + }; + + + Assert.AreEqual (overloaded_methods[0], overloaded_method_int_reference.Resolve ()); + Assert.AreEqual (overloaded_methods[1], overloaded_method_long_reference.Resolve ()); + Assert.AreEqual (overloaded_methods[2], overloaded_method_cdecl_reference.Resolve ()); + }); + } + + [Test] + public void PrivateScope () + { + TestIL ("privatescope.il", module => { + var foo = module.GetType ("Foo"); + var call_same_name_methods = foo.GetMethod ("CallSameNameMethods"); + var call_instructions = call_same_name_methods.Body.Instructions + .Where (ins => ins.OpCode.Code == Code.Call) + .ToArray (); + + var first_same_name_index = 2; + + // The first method will be the normal non-privatescope method. + var first_call_resolved = ((MethodReference)call_instructions [0].Operand).Resolve (); + var expected_first_call_resolved = foo.Methods [first_same_name_index]; + Assert.IsFalse(first_call_resolved.IsCompilerControlled); + Assert.AreEqual(expected_first_call_resolved, first_call_resolved); + + // This is the first privatescope method. + var second_call_resolved = ((MethodReference)call_instructions [1].Operand).Resolve(); + var expected_second_call_resolved = foo.Methods [first_same_name_index + 1]; + + // Sanity check to make sure the ordering assumptions were correct. + Assert.IsTrue(expected_second_call_resolved.IsCompilerControlled, "The expected method should have been compiler controlled."); + + // The equality failure isn't going to be very helpful since both methods will have the same ToString value, + // so before we assert equality, we'll assert that the method is compiler controlled because that is the key difference + Assert.IsTrue(second_call_resolved.IsCompilerControlled, "Expected the method reference to resolve to a compiler controlled method"); + Assert.AreEqual(expected_second_call_resolved, second_call_resolved); + + // This is the second privatescope method. + var third_call_resolved = ((MethodReference)call_instructions [2].Operand).Resolve (); + var expected_third_call_resolved = foo.Methods [first_same_name_index + 2]; + + // Sanity check to make sure the ordering assumptions were correct. + Assert.IsTrue(expected_third_call_resolved.IsCompilerControlled, "The expected method should have been compiler controlled."); + + // The equality failure isn't going to be very helpful since both methods will have the same ToString value, + // so before we assert equality, we'll assert that the method is compiler controlled because that is the key difference + Assert.IsTrue(third_call_resolved.IsCompilerControlled, "Expected the method reference to resolve to a compiler controlled method"); + Assert.AreEqual(expected_third_call_resolved, third_call_resolved); + }); + } + + [Test] + public void PrivateScopeGeneric () + { + TestIL ("privatescope.il", module => { + var foo = module.GetType ("Foo"); + var call_same_name_methods = foo.GetMethod ("CallSameNameMethodsGeneric"); + var call_instructions = call_same_name_methods.Body.Instructions + .Where (ins => ins.OpCode.Code == Code.Call) + .ToArray (); + + var first_same_name_generic_index = 6; + + // The first method will be the normal non-privatescope method. + var first_call_resolved = ((MethodReference)call_instructions [0].Operand).Resolve(); + var expected_first_call_resolved = foo.Methods [first_same_name_generic_index]; + Assert.IsFalse(first_call_resolved.IsCompilerControlled); + Assert.AreEqual(expected_first_call_resolved, first_call_resolved); + + // This is the first privatescope method. + var second_call_resolved = ((MethodReference)call_instructions [1].Operand).Resolve(); + var expected_second_call_resolved = foo.Methods [first_same_name_generic_index + 1]; + + // Sanity check to make sure the ordering assumptions were correct. + Assert.IsTrue(expected_second_call_resolved.IsCompilerControlled, "The expected method should have been compiler controlled."); + + // The equality failure isn't going to be very helpful since both methods will have the same ToString value, + // so before we assert equality, we'll assert that the method is compiler controlled because that is the key difference + Assert.IsTrue (second_call_resolved.IsCompilerControlled, "Expected the method reference to resolve to a compiler controlled method"); + Assert.AreEqual(expected_second_call_resolved, second_call_resolved); + + // This is the second privatescope method. + var third_call_resolved = ((MethodReference)call_instructions [2].Operand).Resolve(); + var expected_third_call_resolved = foo.Methods [first_same_name_generic_index + 2]; + + // Sanity check to make sure the ordering assumptions were correct. + Assert.IsTrue(expected_third_call_resolved.IsCompilerControlled, "The expected method should have been compiler controlled."); + + // The equality failure isn't going to be very helpful since both methods will have the same ToString value, + // so before we assert equality, we'll assert that the method is compiler controlled because that is the key difference + Assert.IsTrue(third_call_resolved.IsCompilerControlled, "Expected the method reference to resolve to a compiler controlled method"); + Assert.AreEqual(expected_third_call_resolved, third_call_resolved); + }); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/ModuleTests.cs b/cecil-master/Test/Mono.Cecil.Tests/ModuleTests.cs new file mode 100644 index 000000000..5af2a65d7 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/ModuleTests.cs @@ -0,0 +1,355 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; + +using Mono.Cecil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class ModuleTests : BaseTestFixture { + + [Test] + public void CreateModuleEscapesAssemblyName () + { + var module = ModuleDefinition.CreateModule ("Test.dll", ModuleKind.Dll); + Assert.AreEqual ("Test", module.Assembly.Name.Name); + + module = ModuleDefinition.CreateModule ("Test.exe", ModuleKind.Console); + Assert.AreEqual ("Test", module.Assembly.Name.Name); + } + + [Test] + public void SingleModule () + { + TestModule ("hello.exe", module => { + var assembly = module.Assembly; + + Assert.AreEqual (1, assembly.Modules.Count); + Assert.IsNotNull (assembly.MainModule); + }); + } + + [Test] + public void EntryPoint () + { + TestModule ("hello.exe", module => { + var entry_point = module.EntryPoint; + Assert.IsNotNull (entry_point); + + Assert.AreEqual ("System.Void Program::Main()", entry_point.ToString ()); + + module.EntryPoint = null; + Assert.IsNull (module.EntryPoint); + + module.EntryPoint = entry_point; + Assert.IsNotNull (module.EntryPoint); + }); + } + + [Test] + public void MultiModules () + { + IgnoreOnCoreClr (); + + TestModule("mma.exe", module => { + var assembly = module.Assembly; + + Assert.AreEqual (3, assembly.Modules.Count); + + Assert.AreEqual ("mma.exe", assembly.Modules [0].Name); + Assert.AreEqual (ModuleKind.Console, assembly.Modules [0].Kind); + + Assert.AreEqual ("moda.netmodule", assembly.Modules [1].Name); + Assert.AreEqual ("eedb4721-6c3e-4d9a-be30-49021121dd92", assembly.Modules [1].Mvid.ToString ()); + Assert.AreEqual (ModuleKind.NetModule, assembly.Modules [1].Kind); + + Assert.AreEqual ("modb.netmodule", assembly.Modules [2].Name); + Assert.AreEqual ("46c5c577-11b2-4ea0-bb3c-3c71f1331dd0", assembly.Modules [2].Mvid.ToString ()); + Assert.AreEqual (ModuleKind.NetModule, assembly.Modules [2].Kind); + }); + } + + [Test] + public void ModuleInformation () + { + TestModule ("hello.exe", module => { + Assert.IsNotNull (module); + + Assert.AreEqual ("hello.exe", module.Name); + Assert.AreEqual (new Guid ("C3BC2BD3-2576-4D00-A80E-465B5632415F"), module.Mvid); + }); + } + + [Test] + public void AssemblyReferences () + { + TestModule ("hello.exe", module => { + Assert.AreEqual (1, module.AssemblyReferences.Count); + + var reference = module.AssemblyReferences [0]; + + Assert.AreEqual ("mscorlib", reference.Name); + Assert.AreEqual (new Version (2, 0, 0, 0), reference.Version); + Assert.AreEqual (new byte [] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 }, reference.PublicKeyToken); + }); + } + + [Test] + public void ModuleReferences () + { + TestModule ("pinvoke.exe", module => { + Assert.AreEqual (2, module.ModuleReferences.Count); + Assert.AreEqual ("kernel32.dll", module.ModuleReferences [0].Name); + Assert.AreEqual ("shell32.dll", module.ModuleReferences [1].Name); + }); + } + + [Test] + public void Types () + { + TestModule ("hello.exe", module => { + Assert.AreEqual (2, module.Types.Count); + Assert.AreEqual ("", module.Types [0].FullName); + Assert.AreEqual ("", module.GetType ("").FullName); + Assert.AreEqual ("Program", module.Types [1].FullName); + Assert.AreEqual ("Program", module.GetType ("Program").FullName); + }); + } + + [Test] + public void LinkedResource () + { + TestModule ("libres.dll", module => { + var resource = module.Resources.Where (res => res.Name == "linked.txt").First () as LinkedResource; + Assert.IsNotNull (resource); + + Assert.AreEqual ("linked.txt", resource.Name); + Assert.AreEqual ("linked.txt", resource.File); + Assert.AreEqual (ResourceType.Linked, resource.ResourceType); + Assert.IsTrue (resource.IsPublic); + }); + } + + [Test] + public void EmbeddedResource () + { + TestModule ("libres.dll", module => { + var resource = module.Resources.Where (res => res.Name == "embedded1.txt").First () as EmbeddedResource; + Assert.IsNotNull (resource); + + Assert.AreEqual ("embedded1.txt", resource.Name); + Assert.AreEqual (ResourceType.Embedded, resource.ResourceType); + Assert.IsTrue (resource.IsPublic); + + using (var reader = new StreamReader (resource.GetResourceStream ())) + Assert.AreEqual ("Hello", reader.ReadToEnd ()); + + resource = module.Resources.Where (res => res.Name == "embedded2.txt").First () as EmbeddedResource; + Assert.IsNotNull (resource); + + Assert.AreEqual ("embedded2.txt", resource.Name); + Assert.AreEqual (ResourceType.Embedded, resource.ResourceType); + Assert.IsTrue (resource.IsPublic); + + using (var reader = new StreamReader (resource.GetResourceStream ())) + Assert.AreEqual ("World", reader.ReadToEnd ()); + }); + } + + [Test] + public void ExportedTypeFromNetModule () + { + IgnoreOnCoreClr (); + + TestModule ("mma.exe", module => { + Assert.IsTrue (module.HasExportedTypes); + Assert.AreEqual (2, module.ExportedTypes.Count); + + var exported_type = module.ExportedTypes [0]; + + Assert.AreEqual ("Module.A.Foo", exported_type.FullName); + Assert.AreEqual ("moda.netmodule", exported_type.Scope.Name); + + exported_type = module.ExportedTypes [1]; + + Assert.AreEqual ("Module.B.Baz", exported_type.FullName); + Assert.AreEqual ("modb.netmodule", exported_type.Scope.Name); + }); + } + + [Test] + public void NestedTypeForwarder () + { + TestCSharp ("CustomAttributes.cs", module => { + Assert.IsTrue (module.HasExportedTypes); + Assert.AreEqual (2, module.ExportedTypes.Count); + + var exported_type = module.ExportedTypes [0]; + + Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", exported_type.FullName); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", exported_type.Scope.Name); + Assert.IsTrue (exported_type.IsForwarder); + + var nested_exported_type = module.ExportedTypes [1]; + + Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", nested_exported_type.FullName); + Assert.AreEqual (exported_type, nested_exported_type.DeclaringType); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", nested_exported_type.Scope.Name); + }); + } + + [Test] + public void HasTypeReference () + { + TestCSharp ("CustomAttributes.cs", module => { + Assert.IsTrue (module.HasTypeReference ("System.Attribute")); + Assert.IsTrue (module.HasTypeReference (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", "System.Attribute")); + + Assert.IsFalse (module.HasTypeReference ("System.Core", "System.Attribute")); + Assert.IsFalse (module.HasTypeReference ("System.Linq.Enumerable")); + }); + } + + [Test] + public void Win32FileVersion () + { + IgnoreOnCoreClr (); + + TestModule ("libhello.dll", module => { + var version = FileVersionInfo.GetVersionInfo (module.FileName); + + Assert.AreEqual ("0.0.0.0", version.FileVersion); + }); + } + + [Test] + public void ModuleWithoutBlob () + { + TestModule ("noblob.dll", module => { + Assert.IsNull (module.Image.BlobHeap); + }); + } + + [Test] + public void MixedModeModule () + { + using (var module = GetResourceModule ("cppcli.dll")) { + Assert.AreEqual (1, module.ModuleReferences.Count); + Assert.AreEqual (string.Empty, module.ModuleReferences [0].Name); + } + } + + [Test] + public void OpenIrrelevantFile () + { + Assert.Throws (() => GetResourceModule ("text_file.txt")); + } + + [Test] + public void GetTypeNamespacePlusName () + { + using (var module = GetResourceModule ("moda.netmodule")) { + var type = module.GetType ("Module.A", "Foo"); + Assert.IsNotNull (type); + } + } + + [Test] + public void GetNonExistentTypeRuntimeName () + { + using (var module = GetResourceModule ("libhello.dll")) { + var type = module.GetType ("DoesNotExist", runtimeName: true); + Assert.IsNull (type); + } + } + + [Test] + public void OpenModuleImmediate () + { + using (var module = GetResourceModule ("hello.exe", ReadingMode.Immediate)) { + Assert.AreEqual (ReadingMode.Immediate, module.ReadingMode); + } + } + + [Test] + public void OpenModuleDeferred () + { + using (var module = GetResourceModule ("hello.exe", ReadingMode.Deferred)) { + Assert.AreEqual (ReadingMode.Deferred, module.ReadingMode); + } + } + + + [Test] + public void OpenModuleDeferredAndThenPerformImmediateRead () + { + using (var module = GetResourceModule ("hello.exe", ReadingMode.Deferred)) { + Assert.AreEqual (ReadingMode.Deferred, module.ReadingMode); + module.ImmediateRead (); + Assert.AreEqual (ReadingMode.Immediate, module.ReadingMode); + } + } + + [Test] + public void ImmediateReadDoesNothingForModuleWithNoImage () + { + using (var module = new ModuleDefinition ()) { + var initialReadingMode = module.ReadingMode; + module.ImmediateRead (); + Assert.AreEqual (initialReadingMode, module.ReadingMode); + } + } + + [Test] + public void OwnedStreamModuleFileName () + { + var path = GetAssemblyResourcePath ("hello.exe"); + using (var file = File.Open (path, FileMode.Open)) + { + using (var module = ModuleDefinition.ReadModule (file)) + { + Assert.IsNotNull (module.FileName); + Assert.IsNotEmpty (module.FileName); + Assert.AreEqual (path, module.FileName); + } + } + } + + [Test] + public void ReadAndWriteFile () + { + var path = Path.GetTempFileName (); + + var original = ModuleDefinition.CreateModule ("FooFoo", ModuleKind.Dll); + var type = new TypeDefinition ("Foo", "Foo", TypeAttributes.Abstract | TypeAttributes.Sealed); + original.Types.Add (type); + original.Write (path); + + using (var module = ModuleDefinition.ReadModule (path, new ReaderParameters { ReadWrite = true })) { + module.Write (); + } + + using (var module = ModuleDefinition.ReadModule (path)) + Assert.AreEqual ("Foo.Foo", module.Types [1].FullName); + } + + [Test] + public void ExceptionInWriteDoesNotKeepLockOnFile () + { + var path = Path.GetTempFileName (); + + var module = ModuleDefinition.CreateModule ("FooFoo", ModuleKind.Dll); + // Mixed mode module that Cecil can not write + module.Attributes = (ModuleAttributes) 0; + + Assert.Throws(() => module.Write (path)); + + // Ensure you can still delete the file + File.Delete (path); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/NestedTypesTests.cs b/cecil-master/Test/Mono.Cecil.Tests/NestedTypesTests.cs new file mode 100644 index 000000000..38ae14668 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/NestedTypesTests.cs @@ -0,0 +1,91 @@ +using System; + +using Mono.Cecil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class NestedTypesTests : BaseTestFixture { + + [Test] + public void NestedTypes () + { + TestCSharp ("NestedTypes.cs", module => { + var foo = module.GetType ("Foo"); + + Assert.AreEqual ("Foo", foo.Name); + Assert.AreEqual ("Foo", foo.FullName); + Assert.AreEqual (module, foo.Module); + Assert.AreEqual (1, foo.NestedTypes.Count); + + var bar = foo.NestedTypes [0]; + + Assert.AreEqual ("Bar", bar.Name); + Assert.AreEqual ("Foo/Bar", bar.FullName); + Assert.AreEqual (module, bar.Module); + Assert.AreEqual (1, bar.NestedTypes.Count); + + var baz = bar.NestedTypes [0]; + + Assert.AreEqual ("Baz", baz.Name); + Assert.AreEqual ("Foo/Bar/Baz", baz.FullName); + Assert.AreEqual (module, baz.Module); + }); + } + + [Test] + public void DirectNestedType () + { + TestCSharp ("NestedTypes.cs", module => { + var bingo = module.GetType ("Bingo"); + var get_fuel = bingo.GetMethod ("GetFuel"); + + Assert.AreEqual ("Bingo/Fuel", get_fuel.ReturnType.FullName); + }); + } + + [Test] + public void NestedTypeWithOwnNamespace () + { + TestModule ("bug-185.dll", module => { + var foo = module.GetType ("Foo"); + var foo_child = foo.NestedTypes [0]; + + Assert.AreEqual ("", foo_child.Namespace); + Assert.AreEqual ("Do>d__0", foo_child.Name); + + Assert.AreEqual ("Foo/.Do>d__0", foo_child.FullName); + }); + } + + [Test] + public void NestedTypeFullName () + { + var foo = new TypeDefinition (null, "Foo", TypeAttributes.Class); + var bar = new TypeDefinition (null, "Bar", TypeAttributes.Class); + var baz = new TypeDefinition (null, "Baz", TypeAttributes.Class); + + foo.NestedTypes.Add (bar); + bar.NestedTypes.Add (baz); + + Assert.AreEqual ("Foo/Bar/Baz", baz.FullName); + + foo.Namespace = "Change"; + + Assert.AreEqual ("Change.Foo/Bar", bar.FullName); + Assert.AreEqual ("Change.Foo/Bar/Baz", baz.FullName); + + bar.Namespace = "AnotherChange"; + + Assert.AreEqual ("Change.Foo/AnotherChange.Bar", bar.FullName); + Assert.AreEqual ("Change.Foo/AnotherChange.Bar/Baz", baz.FullName); + + foo.Name = "FooFoo"; + + Assert.AreEqual ("Change.FooFoo/AnotherChange.Bar", bar.FullName); + Assert.AreEqual ("Change.FooFoo/AnotherChange.Bar/Baz", baz.FullName); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/ParameterTests.cs b/cecil-master/Test/Mono.Cecil.Tests/ParameterTests.cs new file mode 100644 index 000000000..5ec3e0637 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/ParameterTests.cs @@ -0,0 +1,274 @@ +using System; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class ParameterTests : BaseTestFixture { + + [Test] + public void MarshalAsI4 () + { + TestModule ("marshal.dll", module => { + var bar = module.GetType ("Bar"); + var pan = bar.GetMethod ("Pan"); + + Assert.AreEqual (1, pan.Parameters.Count); + + var parameter = pan.Parameters [0]; + + Assert.IsTrue (parameter.HasMarshalInfo); + var info = parameter.MarshalInfo; + + Assert.AreEqual (typeof (MarshalInfo), info.GetType ()); + Assert.AreEqual (NativeType.I4, info.NativeType); + }); + } + + [Test] + public void CustomMarshaler () + { + TestModule ("marshal.dll", module => { + var bar = module.GetType ("Bar"); + var pan = bar.GetMethod ("PanPan"); + + var parameter = pan.Parameters [0]; + + Assert.IsTrue (parameter.HasMarshalInfo); + + var info = (CustomMarshalInfo) parameter.MarshalInfo; + + Assert.AreEqual (Guid.Empty, info.Guid); + Assert.AreEqual (string.Empty, info.UnmanagedType); + Assert.AreEqual (NativeType.CustomMarshaler, info.NativeType); + Assert.AreEqual ("nomnom", info.Cookie); + + Assert.AreEqual ("Boc", info.ManagedType.FullName); + Assert.AreEqual (module, info.ManagedType.Scope); + }); + } + + [Test] + public void SafeArrayMarshaler () + { + TestModule ("marshal.dll", module => { + var bar = module.GetType ("Bar"); + var pan = bar.GetMethod ("PanPan"); + + Assert.IsTrue (pan.MethodReturnType.HasMarshalInfo); + + var info = (SafeArrayMarshalInfo) pan.MethodReturnType.MarshalInfo; + + Assert.AreEqual (VariantType.Dispatch, info.ElementType); + }); + } + + [Test] + public void ArrayMarshaler () + { + TestModule ("marshal.dll", module => { + var bar = module.GetType ("Bar"); + var pan = bar.GetMethod ("PanPan"); + + var parameter = pan.Parameters [1]; + + Assert.IsTrue (parameter.HasMarshalInfo); + + var info = (ArrayMarshalInfo) parameter.MarshalInfo; + + Assert.AreEqual (NativeType.I8, info.ElementType); + Assert.AreEqual (66, info.Size); + Assert.AreEqual (2, info.SizeParameterIndex); + + parameter = pan.Parameters [3]; + + Assert.IsTrue (parameter.HasMarshalInfo); + + info = (ArrayMarshalInfo) parameter.MarshalInfo; + + Assert.AreEqual (NativeType.I2, info.ElementType); + Assert.AreEqual (-1, info.Size); + Assert.AreEqual (-1, info.SizeParameterIndex); + }); + } + + [Test] + public void ArrayMarshalerSized () + { + TestModule ("marshal.dll", module => { + var delegate_type = module.GetType ("SomeMethod"); + var parameter = delegate_type.GetMethod ("Invoke").Parameters [1]; + + Assert.IsTrue (parameter.HasMarshalInfo); + var array_info = (ArrayMarshalInfo) parameter.MarshalInfo; + + Assert.IsNotNull (array_info); + + Assert.AreEqual (0, array_info.SizeParameterMultiplier); + }); + } + + [Test] + public void NullableConstant () + { + TestModule ("nullable-constant.exe", module => { + var type = module.GetType ("Program"); + var method = type.GetMethod ("Foo"); + + Assert.IsTrue (method.Parameters [0].HasConstant); + Assert.IsTrue (method.Parameters [1].HasConstant); + Assert.IsTrue (method.Parameters [2].HasConstant); + + Assert.AreEqual (1234, method.Parameters [0].Constant); + Assert.AreEqual (null, method.Parameters [1].Constant); + Assert.AreEqual (12, method.Parameters [2].Constant); + }); + } + + [Test] + public void BoxedDefaultArgumentValue () + { + TestModule ("boxedoptarg.dll", module => { + var foo = module.GetType ("Foo"); + var bar = foo.GetMethod ("Bar"); + var baz = bar.Parameters [0]; + + Assert.IsTrue (baz.HasConstant); + Assert.AreEqual (-1, baz.Constant); + }); + } + + [Test] + public void AddParameterIndex () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + + var x = new ParameterDefinition ("x", ParameterAttributes.None, object_ref); + var y = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); + + method.Parameters.Add (x); + method.Parameters.Add (y); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (1, y.Index); + + Assert.AreEqual (method, x.Method); + Assert.AreEqual (method, y.Method); + } + + [Test] + public void RemoveAtParameterIndex () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + + var x = new ParameterDefinition ("x", ParameterAttributes.None, object_ref); + var y = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); + var z = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); + + method.Parameters.Add (x); + method.Parameters.Add (y); + method.Parameters.Add (z); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (1, y.Index); + Assert.AreEqual (2, z.Index); + + method.Parameters.RemoveAt (1); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (-1, y.Index); + Assert.AreEqual (1, z.Index); + } + + [Test] + public void RemoveParameterIndex () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + + var x = new ParameterDefinition ("x", ParameterAttributes.None, object_ref); + var y = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); + var z = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); + + method.Parameters.Add (x); + method.Parameters.Add (y); + method.Parameters.Add (z); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (1, y.Index); + Assert.AreEqual (2, z.Index); + + method.Parameters.Remove (y); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (-1, y.Index); + Assert.AreEqual (1, z.Index); + } + + [Test] + public void InsertParameterIndex () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + + var x = new ParameterDefinition ("x", ParameterAttributes.None, object_ref); + var y = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); + var z = new ParameterDefinition ("y", ParameterAttributes.None, object_ref); + + method.Parameters.Add (x); + method.Parameters.Add (z); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (-1, y.Index); + Assert.AreEqual (1, z.Index); + + method.Parameters.Insert (1, y); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (1, y.Index); + Assert.AreEqual (2, z.Index); + } + + [Test] + public void GenericParameterConstant () + { + TestIL ("hello.il", module => { + var foo = module.GetType ("Foo"); + var method = foo.GetMethod ("GetState"); + + Assert.IsNotNull (method); + + var parameter = method.Parameters [1]; + + Assert.IsTrue (parameter.HasConstant); + Assert.IsNull (parameter.Constant); + }); + } + + [Test] + public void NullablePrimitiveParameterConstant () + { + TestModule ("nullable-parameter.dll", module => { + var test = module.GetType ("Test"); + var method = test.GetMethod ("Foo"); + + Assert.IsNotNull (method); + + var param = method.Parameters [0]; + Assert.IsTrue (param.HasConstant); + Assert.AreEqual (1234, param.Constant); + + param = method.Parameters [1]; + Assert.IsTrue (param.HasConstant); + Assert.AreEqual (null, param.Constant); + + param = method.Parameters [2]; + Assert.IsTrue (param.HasConstant); + Assert.AreEqual (12, param.Constant); + }); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/PortablePdbTests.cs b/cecil-master/Test/Mono.Cecil.Tests/PortablePdbTests.cs new file mode 100644 index 000000000..a89f79d83 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/PortablePdbTests.cs @@ -0,0 +1,1152 @@ +using System; +using System.IO; +using System.IO.Compression; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using NUnit.Framework; + +using Mono.Cecil.Cil; +using Mono.Cecil.Pdb; +using Mono.Cecil.PE; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class PortablePdbTests : BaseTestFixture { + + [Test] + public void SequencePoints () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var main = type.GetMethod ("Main"); + + AssertCode (@" + .locals init (System.Int32 a, System.String[] V_1, System.Int32 V_2, System.String arg) + .line 21,21:3,4 'C:\sources\PdbTarget\Program.cs' + IL_0000: nop + .line 22,22:4,11 'C:\sources\PdbTarget\Program.cs' + IL_0001: nop + .line 22,22:24,28 'C:\sources\PdbTarget\Program.cs' + IL_0002: ldarg.0 + IL_0003: stloc.1 + IL_0004: ldc.i4.0 + IL_0005: stloc.2 + .line hidden 'C:\sources\PdbTarget\Program.cs' + IL_0006: br.s IL_0017 + .line 22,22:13,20 'C:\sources\PdbTarget\Program.cs' + IL_0008: ldloc.1 + IL_0009: ldloc.2 + IL_000a: ldelem.ref + IL_000b: stloc.3 + .line 23,23:5,20 'C:\sources\PdbTarget\Program.cs' + IL_000c: ldloc.3 + IL_000d: call System.Void System.Console::WriteLine(System.String) + IL_0012: nop + .line hidden 'C:\sources\PdbTarget\Program.cs' + IL_0013: ldloc.2 + IL_0014: ldc.i4.1 + IL_0015: add + IL_0016: stloc.2 + .line 22,22:21,23 'C:\sources\PdbTarget\Program.cs' + IL_0017: ldloc.2 + IL_0018: ldloc.1 + IL_0019: ldlen + IL_001a: conv.i4 + IL_001b: blt.s IL_0008 + .line 25,25:4,22 'C:\sources\PdbTarget\Program.cs' + IL_001d: ldc.i4.1 + IL_001e: ldc.i4.2 + IL_001f: call System.Int32 System.Math::Min(System.Int32,System.Int32) + IL_0024: stloc.0 + .line 26,26:3,4 'C:\sources\PdbTarget\Program.cs' + IL_0025: ret +", main); + }); + } + + [Test] + public void SequencePointsMultipleDocument () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.B"); + var main = type.GetMethod (".ctor"); + + AssertCode (@" + .locals () + .line 7,7:3,25 'C:\sources\PdbTarget\B.cs' + IL_0000: ldarg.0 + IL_0001: ldstr """" + IL_0006: stfld System.String PdbTarget.B::s + .line 110,110:3,21 'C:\sources\PdbTarget\Program.cs' + IL_000b: ldarg.0 + IL_000c: ldc.i4.2 + IL_000d: stfld System.Int32 PdbTarget.B::a + .line 111,111:3,21 'C:\sources\PdbTarget\Program.cs' + IL_0012: ldarg.0 + IL_0013: ldc.i4.3 + IL_0014: stfld System.Int32 PdbTarget.B::b + .line 9,9:3,13 'C:\sources\PdbTarget\B.cs' + IL_0019: ldarg.0 + IL_001a: call System.Void System.Object::.ctor() + IL_001f: nop + .line 10,10:3,4 'C:\sources\PdbTarget\B.cs' + IL_0020: nop + .line 11,11:4,19 'C:\sources\PdbTarget\B.cs' + IL_0021: ldstr ""B"" + IL_0026: call System.Void System.Console::WriteLine(System.String) + IL_002b: nop + .line 12,12:3,4 'C:\sources\PdbTarget\B.cs' + IL_002c: ret +", main); + }); + } + + [Test] + public void LocalVariables () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasScopes); + Assert.AreEqual (2, debug_info.Scope.Scopes.Count); + + var scope = debug_info.Scope.Scopes [0]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + var variable = scope.Variables [0]; + + Assert.AreEqual ("s", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (2, variable.Index); + + scope = debug_info.Scope.Scopes [1]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + variable = scope.Variables [0]; + + Assert.AreEqual ("s", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (3, variable.Index); + + Assert.IsTrue (scope.HasScopes); + Assert.AreEqual (1, scope.Scopes.Count); + + scope = scope.Scopes [0]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasVariables); + Assert.AreEqual (1, scope.Variables.Count); + + variable = scope.Variables [0]; + + Assert.AreEqual ("u", variable.Name); + Assert.IsFalse (variable.IsDebuggerHidden); + Assert.AreEqual (5, variable.Index); + }); + } + + [Test] + public void LocalConstants () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasScopes); + Assert.AreEqual (2, debug_info.Scope.Scopes.Count); + + var scope = debug_info.Scope.Scopes [1]; + + Assert.IsNotNull (scope); + Assert.IsTrue (scope.HasConstants); + Assert.AreEqual (2, scope.Constants.Count); + + var constant = scope.Constants [0]; + + Assert.AreEqual ("b", constant.Name); + Assert.AreEqual (12, constant.Value); + Assert.AreEqual (MetadataType.Int32, constant.ConstantType.MetadataType); + + constant = scope.Constants [1]; + Assert.AreEqual ("c", constant.Name); + Assert.AreEqual ((decimal) 74, constant.Value); + Assert.AreEqual (MetadataType.ValueType, constant.ConstantType.MetadataType); + + method = type.GetMethod ("Foo"); + debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + Assert.IsTrue (debug_info.Scope.HasConstants); + Assert.AreEqual (4, debug_info.Scope.Constants.Count); + + constant = debug_info.Scope.Constants [0]; + Assert.AreEqual ("s", constant.Name); + Assert.AreEqual ("const string", constant.Value); + Assert.AreEqual (MetadataType.String, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [1]; + Assert.AreEqual ("f", constant.Name); + Assert.AreEqual (1, constant.Value); + Assert.AreEqual (MetadataType.Int32, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [2]; + Assert.AreEqual ("o", constant.Name); + Assert.AreEqual (null, constant.Value); + Assert.AreEqual (MetadataType.Object, constant.ConstantType.MetadataType); + + constant = debug_info.Scope.Constants [3]; + Assert.AreEqual ("u", constant.Name); + Assert.AreEqual (null, constant.Value); + Assert.AreEqual (MetadataType.String, constant.ConstantType.MetadataType); + }); + } + + [Test] + public void ImportScope () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var method = type.GetMethod ("Bar"); + var debug_info = method.DebugInformation; + + Assert.IsNotNull (debug_info.Scope); + + var import = debug_info.Scope.Import; + Assert.IsNotNull (import); + + Assert.IsFalse (import.HasTargets); + Assert.IsNotNull (import.Parent); + + import = import.Parent; + + Assert.IsTrue (import.HasTargets); + Assert.AreEqual (9, import.Targets.Count); + var target = import.Targets [0]; + + Assert.AreEqual (ImportTargetKind.ImportAlias, target.Kind); + Assert.AreEqual ("XML", target.Alias); + + target = import.Targets [1]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System", target.Namespace); + + target = import.Targets [2]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System.Collections.Generic", target.Namespace); + + target = import.Targets [3]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System.IO", target.Namespace); + + target = import.Targets [4]; + + Assert.AreEqual (ImportTargetKind.ImportNamespace, target.Kind); + Assert.AreEqual ("System.Threading.Tasks", target.Namespace); + + target = import.Targets [5]; + + Assert.AreEqual (ImportTargetKind.ImportNamespaceInAssembly, target.Kind); + Assert.AreEqual ("System.Xml.Resolvers", target.Namespace); + Assert.AreEqual ("System.Xml", target.AssemblyReference.Name); + + + target = import.Targets [6]; + + Assert.AreEqual (ImportTargetKind.ImportType, target.Kind); + Assert.AreEqual ("System.Console", target.Type.FullName); + + target = import.Targets [7]; + + Assert.AreEqual (ImportTargetKind.ImportType, target.Kind); + Assert.AreEqual ("System.Math", target.Type.FullName); + + target = import.Targets [8]; + + Assert.AreEqual (ImportTargetKind.DefineTypeAlias, target.Kind); + Assert.AreEqual ("Foo", target.Alias); + Assert.AreEqual ("System.Xml.XmlDocumentType", target.Type.FullName); + + Assert.IsNotNull (import.Parent); + + import = import.Parent; + + Assert.IsTrue (import.HasTargets); + Assert.AreEqual (1, import.Targets.Count); + Assert.IsNull (import.Parent); + + target = import.Targets [0]; + + Assert.AreEqual (ImportTargetKind.DefineAssemblyAlias, target.Kind); + Assert.AreEqual ("XML", target.Alias); + Assert.AreEqual ("System.Xml", target.AssemblyReference.Name); + }); + } + + [Test] + public void StateMachineKickOff () + { + TestPortablePdbModule (module => { + var state_machine = module.GetType ("PdbTarget.Program/d__7"); + var main = state_machine.GetMethod ("MoveNext"); + var symbol = main.DebugInformation; + + Assert.IsNotNull (symbol); + Assert.IsNotNull (symbol.StateMachineKickOffMethod); + Assert.AreEqual ("System.Threading.Tasks.Task PdbTarget.Program::Baz(System.IO.StreamReader)", symbol.StateMachineKickOffMethod.FullName); + }); + } + + [Test] + public void StateMachineCustomDebugInformation () + { + TestPortablePdbModule (module => { + var state_machine = module.GetType ("PdbTarget.Program/d__7"); + var move_next = state_machine.GetMethod ("MoveNext"); + + Assert.IsTrue (move_next.HasCustomDebugInformations); + + var state_machine_scope = move_next.CustomDebugInformations.OfType ().FirstOrDefault (); + Assert.IsNotNull (state_machine_scope); + Assert.AreEqual (3, state_machine_scope.Scopes.Count); + Assert.AreEqual (0, state_machine_scope.Scopes [0].Start.Offset); + Assert.IsTrue (state_machine_scope.Scopes [0].End.IsEndOfMethod); + + Assert.AreEqual (0, state_machine_scope.Scopes [1].Start.Offset); + Assert.AreEqual (0, state_machine_scope.Scopes [1].End.Offset); + + Assert.AreEqual (184, state_machine_scope.Scopes [2].Start.Offset); + Assert.AreEqual (343, state_machine_scope.Scopes [2].End.Offset); + + var async_body = move_next.CustomDebugInformations.OfType ().FirstOrDefault (); + Assert.IsNotNull (async_body); + Assert.AreEqual (-1, async_body.CatchHandler.Offset); + + Assert.AreEqual (2, async_body.Yields.Count); + Assert.AreEqual (61, async_body.Yields [0].Offset); + Assert.AreEqual (221, async_body.Yields [1].Offset); + + Assert.AreEqual (2, async_body.Resumes.Count); + Assert.AreEqual (91, async_body.Resumes [0].Offset); + Assert.AreEqual (252, async_body.Resumes [1].Offset); + + Assert.AreEqual (move_next, async_body.ResumeMethods [0]); + Assert.AreEqual (move_next, async_body.ResumeMethods [1]); + }); + } + + [Test] + public void EmbeddedCompressedPortablePdb () + { + TestModule("EmbeddedCompressedPdbTarget.exe", module => { + Assert.IsTrue (module.HasDebugHeader); + + var header = module.GetDebugHeader (); + + Assert.IsNotNull (header); + Assert.IsTrue (header.Entries.Length >= 2); + + int i = 0; + var cv = header.Entries [i++]; + Assert.AreEqual (ImageDebugType.CodeView, cv.Directory.Type); + + if (header.Entries.Length > 2) { + Assert.AreEqual (3, header.Entries.Length); + var pdbChecksum = header.Entries [i++]; + Assert.AreEqual (ImageDebugType.PdbChecksum, pdbChecksum.Directory.Type); + } + + var eppdb = header.Entries [i++]; + Assert.AreEqual (ImageDebugType.EmbeddedPortablePdb, eppdb.Directory.Type); + Assert.AreEqual (0x0100, eppdb.Directory.MajorVersion); + Assert.AreEqual (0x0100, eppdb.Directory.MinorVersion); + + }, symbolReaderProvider: typeof (EmbeddedPortablePdbReaderProvider), symbolWriterProvider: typeof (EmbeddedPortablePdbWriterProvider)); + } + + [Test] + public void EmbeddedCompressedPortablePdbFromStream () + { + var bytes = File.ReadAllBytes (GetAssemblyResourcePath ("EmbeddedCompressedPdbTarget.exe")); + var parameters = new ReaderParameters { + ReadSymbols = true, + SymbolReaderProvider = new PdbReaderProvider () + }; + + var module = ModuleDefinition.ReadModule (new MemoryStream(bytes), parameters); + Assert.IsTrue (module.HasDebugHeader); + + var header = module.GetDebugHeader (); + + Assert.IsNotNull (header); + Assert.AreEqual (2, header.Entries.Length); + + var cv = header.Entries [0]; + Assert.AreEqual (ImageDebugType.CodeView, cv.Directory.Type); + + var eppdb = header.Entries [1]; + Assert.AreEqual (ImageDebugType.EmbeddedPortablePdb, eppdb.Directory.Type); + Assert.AreEqual (0x0100, eppdb.Directory.MajorVersion); + Assert.AreEqual (0x0100, eppdb.Directory.MinorVersion); + } + + + void TestPortablePdbModule (Action test) + { + TestModule ("PdbTarget.exe", test, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + TestModule ("EmbeddedPdbTarget.exe", test, verify: !Platform.OnMono); + TestModule ("EmbeddedCompressedPdbTarget.exe", test, symbolReaderProvider: typeof(EmbeddedPortablePdbReaderProvider), symbolWriterProvider: typeof (EmbeddedPortablePdbWriterProvider)); + } + + [Test] + public void RoundTripCecilPortablePdb () + { + TestModule ("cecil.dll", module => { + Assert.IsTrue (module.HasSymbols); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void RoundTripLargePortablePdb () + { + TestModule ("Mono.Android.dll", module => { + Assert.IsTrue (module.HasSymbols); + }, verify: false, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void EmptyPortablePdb () + { + TestModule ("EmptyPdb.dll", module => { + Assert.IsTrue (module.HasSymbols); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void NullClassConstant () + { + TestModule ("xattr.dll", module => { + var type = module.GetType ("Library"); + var method = type.GetMethod ("NullXAttributeConstant"); + var symbol = method.DebugInformation; + + Assert.IsNotNull (symbol); + Assert.AreEqual (1, symbol.Scope.Constants.Count); + + var a = symbol.Scope.Constants [0]; + Assert.AreEqual ("a", a.Name); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void NullGenericInstConstant () + { + TestModule ("NullConst.dll", module => { + var type = module.GetType ("NullConst.Program"); + var method = type.GetMethod ("MakeConst"); + var symbol = method.DebugInformation; + + Assert.IsNotNull (symbol); + Assert.AreEqual (1, symbol.Scope.Constants.Count); + + var a = symbol.Scope.Constants [0]; + Assert.AreEqual ("thing", a.Name); + Assert.AreEqual (null, a.Value); + }, verify: false, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void InvalidConstantRecord () + { + using (var module = GetResourceModule ("mylib.dll", new ReaderParameters { SymbolReaderProvider = new PortablePdbReaderProvider () })) { + var type = module.GetType ("mylib.Say"); + var method = type.GetMethod ("hello"); + var symbol = method.DebugInformation; + + Assert.IsNotNull (symbol); + Assert.AreEqual (0, symbol.Scope.Constants.Count); + } + } + + [Test] + public void GenericInstConstantRecord () + { + using (var module = GetResourceModule ("ReproConstGenericInst.dll", new ReaderParameters { SymbolReaderProvider = new PortablePdbReaderProvider () })) { + var type = module.GetType ("ReproConstGenericInst.Program"); + var method = type.GetMethod ("Main"); + var symbol = method.DebugInformation; + + Assert.IsNotNull (symbol); + Assert.AreEqual (1, symbol.Scope.Constants.Count); + + var list = symbol.Scope.Constants [0]; + Assert.AreEqual ("list", list.Name); + + Assert.AreEqual ("System.Collections.Generic.List`1", list.ConstantType.FullName); + } + } + + [Test] + public void EmptyStringLocalConstant () + { + TestModule ("empty-str-const.exe", module => { + var type = module.GetType ("$"); + var method = type.GetMethod ("
$"); + var symbol = method.DebugInformation; + + Assert.IsNotNull (symbol); + Assert.AreEqual (1, symbol.Scope.Constants.Count); + + var a = symbol.Scope.Constants [0]; + Assert.AreEqual ("value", a.Name); + Assert.AreEqual ("", a.Value); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void SourceLink () + { + TestModule ("TargetLib.dll", module => { + Assert.IsTrue (module.HasCustomDebugInformations); + Assert.AreEqual (1, module.CustomDebugInformations.Count); + + var source_link = module.CustomDebugInformations [0] as SourceLinkDebugInformation; + Assert.IsNotNull (source_link); + Assert.AreEqual ("{\"documents\":{\"C:\\\\tmp\\\\SourceLinkProblem\\\\*\":\"https://raw.githubusercontent.com/bording/SourceLinkProblem/197d965ee7f1e7f8bd3cea55b5f904aeeb8cd51e/*\"}}", source_link.Content); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + [Test] + public void EmbeddedSource () + { + TestModule ("embedcs.exe", module => { + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + + TestModule ("embedcs.exe", module => { + var program = GetDocument (module.GetType ("Program")); + var program_src = GetSourceDebugInfo (program); + Assert.IsTrue (program_src.Compress); + var program_src_content = Encoding.UTF8.GetString (program_src.Content); + Assert.AreEqual (Normalize (@"using System; + +class Program +{ + static void Main() + { + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + // Hello hello hello hello hello hello + Console.WriteLine(B.Do()); + Console.WriteLine(A.Do()); + } +} +"), Normalize (program_src_content)); + + var a = GetDocument (module.GetType ("A")); + var a_src = GetSourceDebugInfo (a); + Assert.IsFalse (a_src.Compress); + var a_src_content = Encoding.UTF8.GetString (a_src.Content); + Assert.AreEqual (Normalize (@"class A +{ + public static string Do() + { + return ""A::Do""; + } +}"), Normalize (a_src_content)); + + var b = GetDocument(module.GetType ("B")); + var b_src = GetSourceDebugInfo (b); + Assert.IsFalse (b_src.compress); + var b_src_content = Encoding.UTF8.GetString (b_src.Content); + Assert.AreEqual (Normalize (@"class B +{ + public static string Do() + { + return ""B::Do""; + } +}"), Normalize (b_src_content)); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + static Document GetDocument (TypeDefinition type) + { + foreach (var method in type.Methods) { + if (!method.HasBody) + continue; + + foreach (var instruction in method.Body.Instructions) { + var sp = method.DebugInformation.GetSequencePoint (instruction); + if (sp != null && sp.Document != null) + return sp.Document; + } + } + + return null; + } + + static EmbeddedSourceDebugInformation GetSourceDebugInfo (Document document) + { + Assert.IsTrue (document.HasCustomDebugInformations); + Assert.AreEqual (1, document.CustomDebugInformations.Count); + + var source = document.CustomDebugInformations [0] as EmbeddedSourceDebugInformation; + Assert.IsNotNull (source); + return source; + } + + [Test] + public void PortablePdbLineInfo() + { + TestModule ("line.exe", module => { + var type = module.GetType ("Tests"); + var main = type.GetMethod ("Main"); + + AssertCode (@" + .locals () + .line 4,4:42,43 '/foo/bar.cs' + IL_0000: nop + .line 5,5:2,3 '/foo/bar.cs' + IL_0001: ret", main); + }, symbolReaderProvider: typeof (PortablePdbReaderProvider), symbolWriterProvider: typeof (PortablePdbWriterProvider)); + } + + public sealed class SymbolWriterProvider : ISymbolWriterProvider { + + readonly DefaultSymbolWriterProvider writer_provider = new DefaultSymbolWriterProvider (); + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, string fileName) + { + return new SymbolWriter (writer_provider.GetSymbolWriter (module, fileName)); + } + + public ISymbolWriter GetSymbolWriter (ModuleDefinition module, Stream symbolStream) + { + return new SymbolWriter (writer_provider.GetSymbolWriter (module, symbolStream)); + } + } + + public sealed class SymbolWriter : ISymbolWriter { + + readonly ISymbolWriter symbol_writer; + + public SymbolWriter (ISymbolWriter symbolWriter) + { + this.symbol_writer = symbolWriter; + } + + public ImageDebugHeader GetDebugHeader () + { + var header = symbol_writer.GetDebugHeader (); + if (!header.HasEntries) + return header; + + for (int i = 0; i < header.Entries.Length; i++) { + header.Entries [i] = ProcessEntry (header.Entries [i]); + } + + return header; + } + + private static ImageDebugHeaderEntry ProcessEntry (ImageDebugHeaderEntry entry) + { + if (entry.Directory.Type != ImageDebugType.CodeView) + return entry; + + var reader = new ByteBuffer (entry.Data); + var writer = new ByteBuffer (); + + var sig = reader.ReadUInt32 (); + if (sig != 0x53445352) + return entry; + + writer.WriteUInt32 (sig); // RSDS + writer.WriteBytes (reader.ReadBytes (16)); // MVID + writer.WriteUInt32 (reader.ReadUInt32 ()); // Age + + var length = Array.IndexOf (entry.Data, (byte) 0, reader.position) - reader.position; + + var fullPath = Encoding.UTF8.GetString (reader.ReadBytes (length)); + + writer.WriteBytes (Encoding.UTF8.GetBytes (Path.GetFileName (fullPath))); + writer.WriteByte (0); + + var newData = new byte [writer.length]; + Buffer.BlockCopy (writer.buffer, 0, newData, 0, writer.length); + + var directory = entry.Directory; + directory.SizeOfData = newData.Length; + + return new ImageDebugHeaderEntry (directory, newData); + } + + public ISymbolReaderProvider GetReaderProvider () + { + return symbol_writer.GetReaderProvider (); + } + + public void Write (MethodDebugInformation info) + { + symbol_writer.Write (info); + } + + public void Write () + { + symbol_writer.Write (); + } + + public void Dispose () + { + symbol_writer.Dispose (); + } + } + + static string GetDebugHeaderPdbPath (ModuleDefinition module) + { + var header = module.GetDebugHeader (); + var cv = Mixin.GetCodeViewEntry (header); + Assert.IsNotNull (cv); + var length = Array.IndexOf (cv.Data, (byte)0, 24) - 24; + var bytes = new byte [length]; + Buffer.BlockCopy (cv.Data, 24, bytes, 0, length); + return Encoding.UTF8.GetString (bytes); + } + + [Test] + public void UseCustomSymbolWriterToChangeDebugHeaderPdbPath () + { + const string resource = "mylib.dll"; + + string debug_header_pdb_path; + string dest = Path.Combine (Path.GetTempPath (), resource); + + using (var module = GetResourceModule (resource, new ReaderParameters { SymbolReaderProvider = new PortablePdbReaderProvider () })) { + debug_header_pdb_path = GetDebugHeaderPdbPath (module); + Assert.IsTrue (Path.IsPathRooted (debug_header_pdb_path)); + module.Write (dest, new WriterParameters { SymbolWriterProvider = new SymbolWriterProvider () }); + } + + using (var module = ModuleDefinition.ReadModule (dest, new ReaderParameters { SymbolReaderProvider = new PortablePdbReaderProvider () })) { + var pdb_path = GetDebugHeaderPdbPath (module); + Assert.IsFalse (Path.IsPathRooted (pdb_path)); + Assert.AreEqual (Path.GetFileName (debug_header_pdb_path), pdb_path); + } + } + + [Test] + public void WriteAndReadAgainModuleWithDeterministicMvid () + { + const string resource = "mylib.dll"; + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { SymbolReaderProvider = new PortablePdbReaderProvider () })) { + module.Write (destination, new WriterParameters { DeterministicMvid = true, SymbolWriterProvider = new SymbolWriterProvider () }); + } + + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { SymbolReaderProvider = new PortablePdbReaderProvider () })) { + } + } + + [Test] + public void DoubleWriteAndReadAgainModuleWithDeterministicMvid () + { + Guid mvid1_in, mvid1_out, mvid2_in, mvid2_out; + + { + const string resource = "foo.dll"; + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { })) { + mvid1_in = module.Mvid; + module.Write (destination, new WriterParameters { DeterministicMvid = true }); + } + + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { })) { + mvid1_out = module.Mvid; + } + } + + { + const string resource = "hello2.exe"; + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { })) { + mvid2_in = module.Mvid; + module.Write (destination, new WriterParameters { DeterministicMvid = true }); + } + + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { })) { + mvid2_out = module.Mvid; + } + } + + Assert.AreNotEqual (mvid1_in, mvid2_in); + Assert.AreNotEqual (mvid1_out, mvid2_out); + } + + [Test] + public void ClearSequencePoints () + { + TestPortablePdbModule (module => { + var type = module.GetType ("PdbTarget.Program"); + var main = type.GetMethod ("Main"); + + main.DebugInformation.SequencePoints.Clear (); + + var destination = Path.Combine (Path.GetTempPath (), "mylib.dll"); + module.Write(destination, new WriterParameters { WriteSymbols = true }); + + Assert.Zero (main.DebugInformation.SequencePoints.Count); + + using (var resultModule = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + type = resultModule.GetType ("PdbTarget.Program"); + main = type.GetMethod ("Main"); + + Assert.Zero (main.DebugInformation.SequencePoints.Count); + } + }); + } + + [Test] + public void DoubleWriteAndReadWithDeterministicMvidAndVariousChanges () + { + Guid mvidIn, mvidARM64Out, mvidX64Out; + + const string resource = "mylib.dll"; + { + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + mvidIn = module.Mvid; + module.Architecture = TargetArchitecture.ARM64; // Can't use I386 as it writes different import table size -> differnt MVID + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + mvidARM64Out = module.Mvid; + } + + Assert.AreNotEqual (mvidIn, mvidARM64Out); + } + + { + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + Assert.AreEqual (mvidIn, module.Mvid); + module.Architecture = TargetArchitecture.AMD64; + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + mvidX64Out = module.Mvid; + } + + Assert.AreNotEqual (mvidARM64Out, mvidX64Out); + } + + { + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + Assert.AreEqual (mvidIn, module.Mvid); + module.Architecture = TargetArchitecture.AMD64; + module.timestamp = 42; + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + Guid mvidDifferentTimeStamp; + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + mvidDifferentTimeStamp = module.Mvid; + } + + Assert.AreNotEqual (mvidX64Out, mvidDifferentTimeStamp); + } + } + + [Test] + public void ReadPortablePdbChecksum () + { + const string resource = "PdbChecksumLib.dll"; + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + GetPdbChecksumData (module.GetDebugHeader (), out string algorithmName, out byte [] checksum); + Assert.AreEqual ("SHA256", algorithmName); + GetCodeViewPdbId (module, out byte[] pdbId); + + string pdbPath = Mixin.GetPdbFileName (module.FileName); + CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out byte [] expectedPdbId); + + CollectionAssert.AreEqual (expectedChecksum, checksum); + CollectionAssert.AreEqual (expectedPdbId, pdbId); + } + } + + [Test] + public void ReadEmbeddedPortablePdbChecksum () + { + const string resource = "EmbeddedPdbChecksumLib.dll"; + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + var debugHeader = module.GetDebugHeader (); + GetPdbChecksumData (debugHeader, out string algorithmName, out byte [] checksum); + Assert.AreEqual ("SHA256", algorithmName); + GetCodeViewPdbId (module, out byte [] pdbId); + + GetEmbeddedPdb (module.Image, debugHeader, out byte [] embeddedPdb); + CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out byte [] expectedPdbId); + + CollectionAssert.AreEqual (expectedChecksum, checksum); + CollectionAssert.AreEqual (expectedPdbId, pdbId); + } + } + + [Test] + public void WritePortablePdbChecksum () + { + const string resource = "PdbChecksumLib.dll"; + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + GetPdbChecksumData (module.GetDebugHeader (), out string algorithmName, out byte [] checksum); + Assert.AreEqual ("SHA256", algorithmName); + GetCodeViewPdbId (module, out byte [] pdbId); + + string pdbPath = Mixin.GetPdbFileName (module.FileName); + CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out byte [] expectedPdbId); + + CollectionAssert.AreEqual (expectedChecksum, checksum); + CollectionAssert.AreEqual (expectedPdbId, pdbId); + } + } + + [Test] + public void WritePortablePdbToWriteOnlyStream () + { + const string resource = "PdbChecksumLib.dll"; + string destination = Path.GetTempFileName (); + + // Note that the module stream already requires read access even on writing to be able to compute strong name + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) + using (var pdbStream = new FileStream (destination + ".pdb", FileMode.Create, FileAccess.Write)) { + module.Write (destination, new WriterParameters { + DeterministicMvid = true, + WriteSymbols = true, + SymbolWriterProvider = new PortablePdbWriterProvider (), + SymbolStream = pdbStream + }); + } + } + + [Test] + public void DoubleWritePortablePdbDeterministicPdbId () + { + const string resource = "PdbChecksumLib.dll"; + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + byte [] pdbIdOne; + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + string pdbPath = Mixin.GetPdbFileName (module.FileName); + CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out pdbIdOne); + } + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + byte [] pdbIdTwo; + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + string pdbPath = Mixin.GetPdbFileName (module.FileName); + CalculatePdbChecksumAndId (pdbPath, out byte [] expectedChecksum, out pdbIdTwo); + } + + CollectionAssert.AreEqual (pdbIdOne, pdbIdTwo); + } + + [Test] + public void WriteEmbeddedPortablePdbChecksum () + { + const string resource = "EmbeddedPdbChecksumLib.dll"; + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + var debugHeader = module.GetDebugHeader (); + GetPdbChecksumData (debugHeader, out string algorithmName, out byte [] checksum); + Assert.AreEqual ("SHA256", algorithmName); + GetCodeViewPdbId (module, out byte [] pdbId); + + GetEmbeddedPdb (module.Image, debugHeader, out byte [] embeddedPdb); + CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out byte [] expectedPdbId); + + CollectionAssert.AreEqual (expectedChecksum, checksum); + CollectionAssert.AreEqual (expectedPdbId, pdbId); + } + } + + [Test] + public void DoubleWriteEmbeddedPortablePdbChecksum () + { + const string resource = "EmbeddedPdbChecksumLib.dll"; + string destination = Path.GetTempFileName (); + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + byte [] pdbIdOne; + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + var debugHeader = module.GetDebugHeader (); + GetEmbeddedPdb (module.Image, debugHeader, out byte [] embeddedPdb); + CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out pdbIdOne); + } + + using (var module = GetResourceModule (resource, new ReaderParameters { ReadSymbols = true })) { + module.Write (destination, new WriterParameters { DeterministicMvid = true, WriteSymbols = true }); + } + + byte [] pdbIdTwo; + using (var module = ModuleDefinition.ReadModule (destination, new ReaderParameters { ReadSymbols = true })) { + var debugHeader = module.GetDebugHeader (); + GetEmbeddedPdb (module.Image, debugHeader, out byte [] embeddedPdb); + CalculatePdbChecksumAndId (embeddedPdb, out byte [] expectedChecksum, out pdbIdTwo); + } + + CollectionAssert.AreEqual (pdbIdOne, pdbIdTwo); + } + + private void GetEmbeddedPdb (Image image, ImageDebugHeader debugHeader, out byte [] embeddedPdb) + { + var entry = Mixin.GetEmbeddedPortablePdbEntry (debugHeader); + Assert.IsNotNull (entry); + + Assert.AreEqual (entry.Directory.PointerToRawData, image.ResolveVirtualAddress ((uint)entry.Directory.AddressOfRawData)); + + var compressed_stream = new MemoryStream (entry.Data); + var reader = new BinaryStreamReader (compressed_stream); + Assert.AreEqual (0x4244504D, reader.ReadInt32 ()); + var length = reader.ReadInt32 (); + var decompressed_stream = new MemoryStream (length); + + using (var deflate = new DeflateStream (compressed_stream, CompressionMode.Decompress, leaveOpen: true)) + deflate.CopyTo (decompressed_stream); + + embeddedPdb = decompressed_stream.ToArray (); + } + + private void GetPdbChecksumData (ImageDebugHeader debugHeader, out string algorithmName, out byte [] checksum) + { + var entry = Mixin.GetPdbChecksumEntry (debugHeader); + Assert.IsNotNull (entry); + + var length = Array.IndexOf (entry.Data, (byte)0, 0); + var bytes = new byte [length]; + Buffer.BlockCopy (entry.Data, 0, bytes, 0, length); + algorithmName = Encoding.UTF8.GetString (bytes); + int checksumSize = 0; + switch (algorithmName) { + case "SHA256": checksumSize = 32; break; + case "SHA384": checksumSize = 48; break; + case "SHA512": checksumSize = 64; break; + } + checksum = new byte [checksumSize]; + Buffer.BlockCopy (entry.Data, length + 1, checksum, 0, checksumSize); + } + + private void CalculatePdbChecksumAndId (string filePath, out byte [] pdbChecksum, out byte [] pdbId) + { + using (var fs = File.OpenRead (filePath)) + CalculatePdbChecksumAndId (fs, out pdbChecksum, out pdbId); + } + + private void CalculatePdbChecksumAndId (byte [] data, out byte [] pdbChecksum, out byte [] pdbId) + { + using (var pdb = new MemoryStream (data)) + CalculatePdbChecksumAndId (pdb, out pdbChecksum, out pdbId); + } + + private void CalculatePdbChecksumAndId (Stream pdbStream, out byte [] pdbChecksum, out byte [] pdbId) + { + // Get the offset of the PDB heap (this requires parsing several headers + // so it's easier to use the ImageReader directly for this) + Image image = ImageReader.ReadPortablePdb (new Disposable (pdbStream, false), "test.pdb", out uint pdbHeapOffset); + pdbId = new byte [20]; + Array.Copy (image.PdbHeap.data, 0, pdbId, 0, 20); + + pdbStream.Seek (0, SeekOrigin.Begin); + byte [] rawBytes = pdbStream.ReadAll (); + + var bytes = new byte [rawBytes.Length]; + + Array.Copy (rawBytes, 0, bytes, 0, pdbHeapOffset); + + // Zero out the PDB ID (20 bytes) + for (int i = 0; i < 20; bytes [i + pdbHeapOffset] = 0, i++) ; + + Array.Copy (rawBytes, pdbHeapOffset + 20, bytes, pdbHeapOffset + 20, rawBytes.Length - pdbHeapOffset - 20); + + var sha256 = SHA256.Create (); + pdbChecksum = sha256.ComputeHash (bytes); + } + + static void GetCodeViewPdbId (ModuleDefinition module, out byte[] pdbId) + { + var header = module.GetDebugHeader (); + var cv = Mixin.GetCodeViewEntry (header); + Assert.IsNotNull (cv); + + CollectionAssert.AreEqual (new byte [] { 0x52, 0x53, 0x44, 0x53 }, cv.Data.Take (4)); + + ByteBuffer buffer = new ByteBuffer (20); + buffer.WriteBytes (cv.Data.Skip (4).Take (16).ToArray ()); + buffer.WriteInt32 (cv.Directory.TimeDateStamp); + pdbId = buffer.buffer; + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/PropertyTests.cs b/cecil-master/Test/Mono.Cecil.Tests/PropertyTests.cs new file mode 100644 index 000000000..587868ff7 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/PropertyTests.cs @@ -0,0 +1,128 @@ +using System.Linq; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class PropertyTests : BaseTestFixture { + + [Test] + public void AbstractMethod () + { + TestCSharp ("Properties.cs", module => { + var type = module.GetType ("Foo"); + + Assert.IsTrue (type.HasProperties); + + var properties = type.Properties; + + Assert.AreEqual (3, properties.Count); + + var property = properties [0]; + + Assert.IsNotNull (property); + Assert.AreEqual ("Bar", property.Name); + Assert.IsNotNull (property.PropertyType); + Assert.AreEqual ("System.Int32", property.PropertyType.FullName); + + Assert.IsNotNull (property.GetMethod); + Assert.AreEqual (MethodSemanticsAttributes.Getter, property.GetMethod.SemanticsAttributes); + Assert.IsNull (property.SetMethod); + + property = properties [1]; + + Assert.IsNotNull (property); + Assert.AreEqual ("Baz", property.Name); + Assert.IsNotNull (property.PropertyType); + Assert.AreEqual ("System.String", property.PropertyType.FullName); + + Assert.IsNotNull (property.GetMethod); + Assert.AreEqual (MethodSemanticsAttributes.Getter, property.GetMethod.SemanticsAttributes); + Assert.IsNotNull (property.SetMethod); + Assert.AreEqual (MethodSemanticsAttributes.Setter, property.SetMethod.SemanticsAttributes); + + property = properties [2]; + + Assert.IsNotNull (property); + Assert.AreEqual ("Gazonk", property.Name); + Assert.IsNotNull (property.PropertyType); + Assert.AreEqual ("System.String", property.PropertyType.FullName); + + Assert.IsNull (property.GetMethod); + Assert.IsNotNull (property.SetMethod); + Assert.AreEqual (MethodSemanticsAttributes.Setter, property.SetMethod.SemanticsAttributes); + }); + } + + [Test] + public void OtherMethod () + { + TestIL ("others.il", module => { + var type = module.GetType ("Others"); + + Assert.IsTrue (type.HasProperties); + + var properties = type.Properties; + + Assert.AreEqual (1, properties.Count); + + var property = properties [0]; + + Assert.IsNotNull (property); + Assert.AreEqual ("Context", property.Name); + Assert.IsNotNull (property.PropertyType); + Assert.AreEqual ("System.String", property.PropertyType.FullName); + + Assert.IsTrue (property.HasOtherMethods); + + Assert.AreEqual (2, property.OtherMethods.Count); + + var other = property.OtherMethods [0]; + Assert.AreEqual ("let_Context", other.Name); + + other = property.OtherMethods [1]; + Assert.AreEqual ("bet_Context", other.Name); + }); + } + + [Test] + public void SetOnlyIndexer () + { + TestCSharp ("Properties.cs", module => { + var type = module.GetType ("Bar"); + var indexer = type.Properties.Where (property => property.Name == "Item").First (); + + var parameters = indexer.Parameters; + + Assert.AreEqual (2, parameters.Count); + Assert.AreEqual ("System.Int32", parameters [0].ParameterType.FullName); + Assert.AreEqual ("System.String", parameters [1].ParameterType.FullName); + }); + } + + [Test] + public void ReadSemanticsFirst () + { + TestCSharp ("Properties.cs", module => { + var type = module.GetType ("Baz"); + var setter = type.GetMethod ("set_Bingo"); + + Assert.AreEqual (MethodSemanticsAttributes.Setter, setter.SemanticsAttributes); + + var property = type.Properties.Where (p => p.Name == "Bingo").First (); + + Assert.AreEqual (setter, property.SetMethod); + Assert.AreEqual (type.GetMethod ("get_Bingo"), property.GetMethod); + }); + } + + [Test] + public void UnattachedProperty () + { + var property = new PropertyDefinition ("Property", PropertyAttributes.None, typeof (int).ToDefinition ()); + + Assert.IsNull (property.GetMethod); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/ResolveTests.cs b/cecil-master/Test/Mono.Cecil.Tests/ResolveTests.cs new file mode 100644 index 000000000..bce000327 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/ResolveTests.cs @@ -0,0 +1,333 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class ResolveTests : BaseTestFixture { + + [Test] + public void StringEmpty () + { + var string_empty = GetReference, FieldReference> ( + () => string.Empty); + + Assert.AreEqual ("System.String System.String::Empty", string_empty.FullName); + + var definition = string_empty.Resolve (); + + Assert.IsNotNull (definition); + + Assert.AreEqual ("System.String System.String::Empty", definition.FullName); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); + } + + delegate string GetSubstring (string str, int start, int length); + + [Test] + public void StringSubstring () + { + var string_substring = GetReference ( + (s, start, length) => s.Substring (start, length)); + + var definition = string_substring.Resolve (); + + Assert.IsNotNull (definition); + + Assert.AreEqual ("System.String System.String::Substring(System.Int32,System.Int32)", definition.FullName); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); + } + + [Test] + public void StringLength () + { + var string_length = GetReference, MethodReference> (s => s.Length); + + var definition = string_length.Resolve (); + + Assert.IsNotNull (definition); + + Assert.AreEqual ("get_Length", definition.Name); + Assert.AreEqual ("System.String", definition.DeclaringType.FullName); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); + } + + [Test] + public void ListOfStringAdd () + { + var list_add = GetReference>, MethodReference> ( + list => list.Add ("coucou")); + + Assert.AreEqual ("System.Void System.Collections.Generic.List`1::Add(!0)", list_add.FullName); + + var definition = list_add.Resolve (); + + Assert.IsNotNull (definition); + + Assert.AreEqual ("System.Void System.Collections.Generic.List`1::Add(T)", definition.FullName); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); + } + + [Test] + public void DictionaryOfStringTypeDefinitionTryGetValue () + { + var try_get_value = GetReference, string, bool>, MethodReference> ( + (d, s) => { + TypeDefinition type; + return d.TryGetValue (s, out type); + }); + + Assert.AreEqual ("System.Boolean System.Collections.Generic.Dictionary`2::TryGetValue(!0,!1&)", + try_get_value.FullName); + + var definition = try_get_value.Resolve (); + + Assert.IsNotNull (definition); + + Assert.AreEqual ("System.Boolean System.Collections.Generic.Dictionary`2::TryGetValue(TKey,TValue&)", definition.FullName); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", + definition.Module.Assembly.Name.Name); + } + + class CustomResolver : DefaultAssemblyResolver { + + public void Register (AssemblyDefinition assembly) + { + this.RegisterAssembly (assembly); + this.AddSearchDirectory (Path.GetDirectoryName (assembly.MainModule.FileName)); + } + } + + [Test] + public void ExportedTypeFromModule () + { + var resolver = new CustomResolver (); + var parameters = new ReaderParameters { AssemblyResolver = resolver }; + var mma = GetResourceModule ("mma.exe", parameters); + + resolver.Register (mma.Assembly); + + using (var current_module = GetCurrentModule (parameters)) { + var reference = new TypeReference ("Module.A", "Foo", current_module, AssemblyNameReference.Parse (mma.Assembly.FullName), false); + + var definition = reference.Resolve (); + Assert.IsNotNull (definition); + Assert.AreEqual ("Module.A.Foo", definition.FullName); + } + } + + [Test] + public void TypeForwarder () + { + var resolver = new CustomResolver (); + var parameters = new ReaderParameters { AssemblyResolver = resolver }; + + var types = ModuleDefinition.ReadModule ( + CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs")), + parameters); + + resolver.Register (types.Assembly); + + var current_module = GetCurrentModule (parameters); + var reference = new TypeReference ("System.Diagnostics", "DebuggableAttribute", current_module, AssemblyNameReference.Parse (types.Assembly.FullName), false); + + var definition = reference.Resolve (); + Assert.IsNotNull (definition); + Assert.AreEqual ("System.Diagnostics.DebuggableAttribute", definition.FullName); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", definition.Module.Assembly.Name.Name); + } + + [Test] + public void NestedTypeForwarder () + { + var resolver = new CustomResolver (); + var parameters = new ReaderParameters { AssemblyResolver = resolver }; + + var types = ModuleDefinition.ReadModule ( + CompilationService.CompileResource (GetCSharpResourcePath ("CustomAttributes.cs")), + parameters); + + resolver.Register (types.Assembly); + + var current_module = GetCurrentModule (parameters); + var reference = new TypeReference ("", "DebuggingModes", current_module, null, true); + reference.DeclaringType = new TypeReference ("System.Diagnostics", "DebuggableAttribute", current_module, AssemblyNameReference.Parse (types.Assembly.FullName), false); + + var definition = reference.Resolve (); + Assert.IsNotNull (definition); + Assert.AreEqual ("System.Diagnostics.DebuggableAttribute/DebuggingModes", definition.FullName); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", definition.Module.Assembly.Name.Name); + } + + [Test] + public void RectangularArrayResolveGetMethod () + { + var get_a_b = GetReference, MethodReference> (matrix => matrix [2, 2]); + + Assert.AreEqual ("Get", get_a_b.Name); + Assert.IsNotNull (get_a_b.Module); + Assert.IsNull (get_a_b.Resolve ()); + } + + [Test] + public void GenericRectangularArrayGetMethodInMemberReferences () + { + using (var module = GetResourceModule ("FSharp.Core.dll")) { + foreach (var member in module.GetMemberReferences ()) { + if (!member.DeclaringType.IsArray) + continue; + + Assert.IsNull (member.Resolve ()); + } + } + } + + [Test] + public void ResolveFunctionPointer () + { + var module = GetResourceModule ("cppcli.dll"); + var global = module.GetType (""); + var field = global.GetField ("__onexitbegin_app_domain"); + + var type = field.FieldType as PointerType; + Assert.IsNotNull(type); + + var fnptr = type.ElementType as FunctionPointerType; + Assert.IsNotNull (fnptr); + + Assert.IsNull (fnptr.Resolve ()); + } + + [Test] + public void ResolveGenericParameter () + { + var collection = typeof (Mono.Collections.Generic.Collection<>).ToDefinition (); + var parameter = collection.GenericParameters [0]; + + Assert.IsNotNull (parameter); + + Assert.IsNull (parameter.Resolve ()); + } + + [Test] + public void ResolveNullVersionAssembly () + { + var reference = AssemblyNameReference.Parse ("System.Core"); + reference.Version = null; + + var resolver = new DefaultAssemblyResolver (); + Assert.IsNotNull (resolver.Resolve (reference)); + } + + [Test] + public void ResolvePortableClassLibraryReference () + { + var resolver = new DefaultAssemblyResolver (); + var parameters = new ReaderParameters { AssemblyResolver = resolver }; + var pcl = GetResourceModule ("PortableClassLibrary.dll", parameters); + + foreach (var reference in pcl.AssemblyReferences) { + Assert.IsTrue (reference.IsRetargetable); + var assembly = resolver.Resolve (reference); + Assert.IsNotNull (assembly); + + if (!Platform.OnCoreClr) + Assert.AreEqual (typeof (object).Assembly.GetName ().Version, assembly.Name.Version); + } + } + + [Test] + public void ResolveModuleReferenceFromMemberReferenceTest () + { + using (var mma = AssemblyDefinition.ReadAssembly (GetAssemblyResourcePath ("mma.exe"))) { + var modB = mma.Modules [2]; + var bazType = modB.GetType ("Module.B.Baz"); + var gazonkMethod = bazType.Methods.First (m => m.Name.Equals ("Gazonk")); + var callInstr = gazonkMethod.Body.Instructions [1]; + + var methodRef = callInstr.Operand as MethodReference; + var methodTypeRef = methodRef.DeclaringType; + + Assert.AreEqual (mma, methodTypeRef.Module.Assembly); + + var def = methodTypeRef.Resolve (); + Assert.IsNotNull (def); + Assert.AreEqual ("Module.A.Foo", def.FullName); + } + } + + [Test] + public void ResolveModuleReferenceFromMemberReferenceOfSingleNetModuleTest () + { + using (var modb = ModuleDefinition.ReadModule (GetAssemblyResourcePath ("modb.netmodule"))) { + var bazType = modb.GetType ("Module.B.Baz"); + var gazonkMethod = bazType.Methods.First (m => m.Name.Equals ("Gazonk")); + var callInstr = gazonkMethod.Body.Instructions [1]; + + var methodRef = callInstr.Operand as MethodReference; + var methodTypeRef = methodRef.DeclaringType; + + Assert.IsNull (methodTypeRef.Module.Assembly); + Assert.IsNull (methodTypeRef.Resolve ()); + } + } + TRet GetReference (TDel code) + { + var @delegate = code as Delegate; + if (@delegate == null) + throw new InvalidOperationException (); + + var reference = (TRet) GetReturnee (GetMethodFromDelegate (@delegate)); + + Assert.IsNotNull (reference); + + return reference; + } + + static object GetReturnee (MethodDefinition method) + { + Assert.IsTrue (method.HasBody); + + var instruction = method.Body.Instructions [method.Body.Instructions.Count - 1]; + + Assert.IsNotNull (instruction); + + while (instruction != null) { + var opcode = instruction.OpCode; + switch (opcode.OperandType) { + case OperandType.InlineField: + case OperandType.InlineTok: + case OperandType.InlineType: + case OperandType.InlineMethod: + return instruction.Operand; + default: + instruction = instruction.Previous; + break; + } + } + + throw new InvalidOperationException (); + } + + MethodDefinition GetMethodFromDelegate (Delegate @delegate) + { + var method = @delegate.Method; + var type = (TypeDefinition) TypeParser.ParseType (GetCurrentModule (), method.DeclaringType.FullName); + + Assert.IsNotNull (type); + + return type.Methods.Where (m => m.Name == method.Name).First (); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs b/cecil-master/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs new file mode 100644 index 000000000..ceaf240cb --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/SecurityDeclarationTests.cs @@ -0,0 +1,298 @@ +using System; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; + +using Mono.Cecil; +using Mono.Cecil.Metadata; +using Mono.Cecil.PE; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class SecurityDeclarationTests : BaseTestFixture { + + [Test] + public void XmlSecurityDeclaration () + { + TestModule ("decsec-xml.dll", module => { + var type = module.GetType ("SubLibrary"); + + Assert.IsTrue (type.HasSecurityDeclarations); + + Assert.AreEqual (1, type.SecurityDeclarations.Count); + + var declaration = type.SecurityDeclarations [0]; + Assert.AreEqual (SecurityAction.Deny, declaration.Action); + + Assert.AreEqual (1, declaration.SecurityAttributes.Count); + + var attribute = declaration.SecurityAttributes [0]; + + Assert.AreEqual ("System.Security.Permissions.PermissionSetAttribute", attribute.AttributeType.FullName); + + Assert.AreEqual (1, attribute.Properties.Count); + + var named_argument = attribute.Properties [0]; + + Assert.AreEqual ("XML", named_argument.Name); + + var argument = named_argument.Argument; + + Assert.AreEqual ("System.String", argument.Type.FullName); + + const string permission_set = "\r\n\r\n\r\n"; + + Assert.AreEqual (permission_set, argument.Value); + }); + } + + [Test] + public void XmlNet_1_1SecurityDeclaration () + { + TestModule ("decsec1-xml.dll", module => { + var type = module.GetType ("SubLibrary"); + + Assert.IsTrue (type.HasSecurityDeclarations); + + Assert.AreEqual (1, type.SecurityDeclarations.Count); + + var declaration = type.SecurityDeclarations [0]; + Assert.AreEqual (SecurityAction.Deny, declaration.Action); + + Assert.AreEqual (1, declaration.SecurityAttributes.Count); + + var attribute = declaration.SecurityAttributes [0]; + + Assert.AreEqual ("System.Security.Permissions.PermissionSetAttribute", attribute.AttributeType.FullName); + + Assert.AreEqual (1, attribute.Properties.Count); + + var named_argument = attribute.Properties [0]; + + Assert.AreEqual ("XML", named_argument.Name); + + var argument = named_argument.Argument; + + Assert.AreEqual ("System.String", argument.Type.FullName); + + const string permission_set = "\r\n\r\n\r\n"; + + Assert.AreEqual (permission_set, argument.Value); + }); + } + + [Test] + public void DefineSecurityDeclarationByBlob () + { + var file = Path.Combine(Path.GetTempPath(), "SecDecBlob.dll"); + var module = ModuleDefinition.CreateModule ("SecDecBlob.dll", new ModuleParameters { Kind = ModuleKind.Dll, Runtime = TargetRuntime.Net_2_0 }); + + const string permission_set = "\r\n\r\n\r\n"; + + var declaration = new SecurityDeclaration (SecurityAction.Deny, Encoding.Unicode.GetBytes (permission_set)); + module.Assembly.SecurityDeclarations.Add (declaration); + + module.Write (file); + module = ModuleDefinition.ReadModule (file); + + declaration = module.Assembly.SecurityDeclarations [0]; + Assert.AreEqual (SecurityAction.Deny, declaration.Action); + Assert.AreEqual (1, declaration.SecurityAttributes.Count); + + var attribute = declaration.SecurityAttributes [0]; + Assert.AreEqual ("System.Security.Permissions.PermissionSetAttribute", attribute.AttributeType.FullName); + Assert.AreEqual (1, attribute.Properties.Count); + + var named_argument = attribute.Properties [0]; + Assert.AreEqual ("XML", named_argument.Name); + var argument = named_argument.Argument; + Assert.AreEqual ("System.String", argument.Type.FullName); + Assert.AreEqual (permission_set, argument.Value); + } + + [Test] + public void SecurityDeclarationWithoutAttributes () + { + TestModule ("empty-decsec-att.dll", module => { + var type = module.GetType ("TestSecurityAction.ModalUITypeEditor"); + var method = type.GetMethod ("GetEditStyle"); + + Assert.IsNotNull (method); + + Assert.AreEqual (1, method.SecurityDeclarations.Count); + + var declaration = method.SecurityDeclarations [0]; + Assert.AreEqual (SecurityAction.LinkDemand, declaration.Action); + Assert.AreEqual (1, declaration.SecurityAttributes.Count); + + var attribute = declaration.SecurityAttributes [0]; + Assert.AreEqual ("System.Security.Permissions.SecurityPermissionAttribute", attribute.AttributeType.FullName); + Assert.AreEqual (0, attribute.Fields.Count); + Assert.AreEqual (0, attribute.Properties.Count); + }); + } + + [Test] + public void AttributeSecurityDeclaration () + { + TestModule ("decsec-att.dll", module => { + var type = module.GetType ("SubLibrary"); + + Assert.IsTrue (type.HasSecurityDeclarations); + + Assert.AreEqual (1, type.SecurityDeclarations.Count); + + var declaration = type.SecurityDeclarations [0]; + Assert.AreEqual (SecurityAction.Deny, declaration.Action); + + Assert.AreEqual (1, declaration.SecurityAttributes.Count); + + var attribute = declaration.SecurityAttributes [0]; + + Assert.AreEqual ("System.Security.Permissions.SecurityPermissionAttribute", attribute.AttributeType.FullName); + + Assert.AreEqual (1, attribute.Properties.Count); + + var named_argument = attribute.Properties [0]; + + Assert.AreEqual ("UnmanagedCode", named_argument.Name); + + var argument = named_argument.Argument; + + Assert.AreEqual ("System.Boolean", argument.Type.FullName); + + Assert.AreEqual (true, argument.Value); + }); + } + + static void AssertCustomAttributeArgument (string expected, CustomAttributeNamedArgument named_argument) + { + AssertCustomAttributeArgument (expected, named_argument.Argument); + } + + static void AssertCustomAttributeArgument (string expected, CustomAttributeArgument argument) + { + var result = new StringBuilder (); + PrettyPrint (argument, result); + + Assert.AreEqual (expected, result.ToString ()); + } + + static string PrettyPrint (CustomAttribute attribute) + { + var signature = new StringBuilder (); + signature.Append (".ctor ("); + + for (int i = 0; i < attribute.ConstructorArguments.Count; i++) { + if (i > 0) + signature.Append (", "); + + PrettyPrint (attribute.ConstructorArguments [i], signature); + } + + signature.Append (")"); + return signature.ToString (); + } + + static void PrettyPrint (CustomAttributeArgument argument, StringBuilder signature) + { + var value = argument.Value; + + signature.Append ("("); + + PrettyPrint (argument.Type, signature); + + signature.Append (":"); + + PrettyPrintValue (argument.Value, signature); + + signature.Append (")"); + } + + static void PrettyPrintValue (object value, StringBuilder signature) + { + if (value == null) { + signature.Append ("null"); + return; + } + + var arguments = value as CustomAttributeArgument []; + if (arguments != null) { + signature.Append ("{"); + for (int i = 0; i < arguments.Length; i++) { + if (i > 0) + signature.Append (", "); + + PrettyPrint (arguments [i], signature); + } + signature.Append ("}"); + + return; + } + + switch (Type.GetTypeCode (value.GetType ())) { + case System.TypeCode.String: + signature.AppendFormat ("\"{0}\"", value); + break; + case System.TypeCode.Char: + signature.AppendFormat ("'{0}'", (char) value); + break; + default: + var formattable = value as IFormattable; + if (formattable != null) { + signature.Append (formattable.ToString (null, CultureInfo.InvariantCulture)); + return; + } + + if (value is CustomAttributeArgument) { + PrettyPrint ((CustomAttributeArgument) value, signature); + return; + } + break; + } + } + + static void PrettyPrint (TypeReference type, StringBuilder signature) + { + if (type.IsArray) { + ArrayType array = (ArrayType) type; + signature.AppendFormat ("{0}[]", array.ElementType.etype.ToString ()); + } else if (type.etype == ElementType.None) { + signature.Append (type.FullName); + } else + signature.Append (type.etype.ToString ()); + } + + static void AssertArgument (T value, CustomAttributeNamedArgument named_argument) + { + AssertArgument (value, named_argument.Argument); + } + + static void AssertArgument (T value, CustomAttributeArgument argument) + { + AssertArgument (typeof (T).FullName, (object) value, argument); + } + + static void AssertArgument (string type, object value, CustomAttributeArgument argument) + { + Assert.AreEqual (type, argument.Type.FullName); + Assert.AreEqual (value, argument.Value); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/SymbolTests.cs b/cecil-master/Test/Mono.Cecil.Tests/SymbolTests.cs new file mode 100644 index 000000000..691581e82 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/SymbolTests.cs @@ -0,0 +1,141 @@ +using System; +using System.IO; + +using NUnit.Framework; + +using Mono.Cecil.Cil; +using Mono.Cecil.Mdb; +using Mono.Cecil.Pdb; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class SymbolTests : BaseTestFixture { + + [Test] + public void DefaultPdb () + { + TestModule ("libpdb.dll", module => { + Assert.IsTrue (module.HasSymbols); + Assert.AreEqual (typeof (NativePdbReader), module.SymbolReader.GetType ()); + }, readOnly: !Platform.HasNativePdbSupport, symbolReaderProvider: typeof (DefaultSymbolReaderProvider), symbolWriterProvider: typeof (DefaultSymbolWriterProvider)); + } + + [Test] + public void DefaultMdb () + { + TestModule ("libmdb.dll", module => { + Assert.IsTrue (module.HasSymbols); + Assert.AreEqual (typeof (MdbReader), module.SymbolReader.GetType ()); + }, symbolReaderProvider: typeof (DefaultSymbolReaderProvider), symbolWriterProvider: typeof (DefaultSymbolWriterProvider)); + } + + [Test] + public void DefaultPortablePdb () + { + TestModule ("PdbTarget.exe", module => { + Assert.IsTrue (module.HasSymbols); + Assert.AreEqual (typeof (PortablePdbReader), module.SymbolReader.GetType ()); + }, symbolReaderProvider: typeof (DefaultSymbolReaderProvider), symbolWriterProvider: typeof (DefaultSymbolWriterProvider)); + } + + [Test] + public void DefaultEmbeddedPortablePdb () + { + TestModule ("EmbeddedPdbTarget.exe", module => { + Assert.IsTrue (module.HasSymbols); + Assert.AreEqual (typeof (PortablePdbReader), module.SymbolReader.GetType ()); + }, symbolReaderProvider: typeof (DefaultSymbolReaderProvider), symbolWriterProvider: typeof (DefaultSymbolWriterProvider), verify: !Platform.OnMono); + } + + [Test] + public void MdbMismatch () + { + Assert.Throws (() => GetResourceModule ("mdb-mismatch.dll", new ReaderParameters { SymbolReaderProvider = new MdbReaderProvider () })); + } + + [Test] + public void MdbIgnoreMismatch() + { + using (var module = GetResourceModule ("mdb-mismatch.dll", new ReaderParameters { SymbolReaderProvider = new MdbReaderProvider (), ThrowIfSymbolsAreNotMatching = false })) { + Assert.IsNull (module.SymbolReader); + Assert.IsFalse (module.HasSymbols); + } + } + + [Test] + public void PortablePdbMismatch () + { + Assert.Throws (() => GetResourceModule ("pdb-mismatch.dll", new ReaderParameters { SymbolReaderProvider = new PortablePdbReaderProvider () })); + } + + [Test] + public void PortablePdbIgnoreMismatch() + { + using (var module = GetResourceModule ("pdb-mismatch.dll", new ReaderParameters { SymbolReaderProvider = new PortablePdbReaderProvider (), ThrowIfSymbolsAreNotMatching = false })) { + Assert.IsNull (module.SymbolReader); + Assert.IsFalse (module.HasSymbols); + } + } + + [Test] + public void DefaultPortablePdbStream () + { + using (var symbolStream = GetResourceStream ("PdbTarget.pdb")) { + var parameters = new ReaderParameters { + SymbolReaderProvider = new PortablePdbReaderProvider (), + SymbolStream = symbolStream, + }; + + using (var module = GetResourceModule ("PdbTarget.exe", parameters)) { + Assert.IsNotNull (module.SymbolReader); + Assert.IsTrue (module.HasSymbols); + Assert.AreEqual (typeof (PortablePdbReader), module.SymbolReader.GetType ()); + } + } + } + + [Test] + public void DefaultPdbStream () + { + using (var symbolStream = GetResourceStream ("libpdb.pdb")) { + var parameters = new ReaderParameters { + SymbolReaderProvider = new NativePdbReaderProvider (), + SymbolStream = symbolStream, + }; + + using (var module = GetResourceModule ("libpdb.dll", parameters)) { + Assert.IsNotNull (module.SymbolReader); + Assert.IsTrue (module.HasSymbols); + Assert.AreEqual (typeof (NativePdbReader), module.SymbolReader.GetType ()); + } + } + } + + [Test] + public void DefaultMdbStream () + { + using (var symbolStream = GetResourceStream ("libmdb.dll.mdb")) { + var parameters = new ReaderParameters { + SymbolReaderProvider = new MdbReaderProvider (), + SymbolStream = symbolStream, + }; + + using (var module = GetResourceModule ("libmdb.dll", parameters)) { + Assert.IsNotNull (module.SymbolReader); + Assert.IsTrue (module.HasSymbols); + Assert.AreEqual (typeof (MdbReader), module.SymbolReader.GetType ()); + } + } + } + + [Test] + public void MultipleCodeViewEntries () + { + using (var module = GetResourceModule ("System.Private.Xml.dll", new ReaderParameters { ReadSymbols = true })) { + Assert.IsTrue (module.HasSymbols); + Assert.IsNotNull (module.SymbolReader); + } + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/TypeDefinitionUtils.cs b/cecil-master/Test/Mono.Cecil.Tests/TypeDefinitionUtils.cs new file mode 100644 index 000000000..73245840b --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/TypeDefinitionUtils.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Mono.Cecil { + + public static class TypeDefinitionUtils { + + public static TypeReference TypeDefinitionForGeneric ( + Type genericType, AssemblyDefinition genericAssemblyDefinition, + Type paramterType, AssemblyDefinition parameterAssemblyDefinition) + { + var paramDefinition = TypeDefinitionUtils.TypeDefinitionFor (paramterType, parameterAssemblyDefinition); + var genericDefinition = TypeDefinitionUtils.TypeDefinitionFor (genericType, genericAssemblyDefinition); + var genericInstance = new GenericInstanceType (genericDefinition); + genericInstance.GenericArguments.Add (paramDefinition); + return genericInstance; + } + + public static TypeDefinition TypeDefinitionFor (Type type, AssemblyDefinition assemblyDefinition) + { + var stack = new Stack (); + var currentType = type; + while (currentType != null) { + stack.Push ( (currentType.DeclaringType == null ? currentType.Namespace + "." : "") + currentType.Name); + currentType = currentType.DeclaringType; + } + + var typeDefinition = assemblyDefinition.MainModule.GetType (stack.Pop ()); + if (typeDefinition == null) + return null; + + while (stack.Count > 0) { + var name = stack.Pop (); + typeDefinition = typeDefinition.NestedTypes.Single (t => t.Name == name); + } + + return typeDefinition; + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/TypeParserTests.cs b/cecil-master/Test/Mono.Cecil.Tests/TypeParserTests.cs new file mode 100644 index 000000000..4845771be --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/TypeParserTests.cs @@ -0,0 +1,397 @@ +using System; +using System.Linq; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class TypeParserTests : BaseTestFixture { + + [Test] + public void SimpleStringReference () + { + var module = GetCurrentModule (); + var corlib = module.TypeSystem.CoreLibrary; + + const string fullname = "System.String"; + + var type = TypeParser.ParseType (module, fullname); + Assert.IsNotNull (type); + Assert.AreEqual (corlib, type.Scope); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("System", type.Namespace); + Assert.AreEqual ("String", type.Name); + Assert.AreEqual (MetadataType.String, type.MetadataType); + Assert.IsFalse (type.IsValueType); + Assert.IsInstanceOf (typeof (TypeReference), type); + } + + [Test] + public void SimpleInt32Reference () + { + var module = GetCurrentModule (); + var corlib = module.TypeSystem.CoreLibrary; + + const string fullname = "System.Int32"; + + var type = TypeParser.ParseType (module, fullname); + Assert.IsNotNull (type); + Assert.AreEqual (corlib, type.Scope); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("System", type.Namespace); + Assert.AreEqual ("Int32", type.Name); + Assert.AreEqual (MetadataType.Int32, type.MetadataType); + Assert.IsTrue (type.IsValueType); + Assert.IsInstanceOf (typeof (TypeReference), type); + } + + [Test] + public void SimpleTypeDefinition () + { + var module = GetCurrentModule (); + + const string fullname = "Mono.Cecil.Tests.TypeParserTests"; + + var type = TypeParser.ParseType (module, fullname); + Assert.IsNotNull (type); + Assert.AreEqual (module, type.Scope); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("Mono.Cecil.Tests", type.Namespace); + Assert.AreEqual ("TypeParserTests", type.Name); + Assert.IsInstanceOf (typeof (TypeDefinition), type); + } + + [Test] + public void ByRefTypeReference () + { + var module = GetCurrentModule (); + var corlib = module.TypeSystem.CoreLibrary; + + const string fullname = "System.String&"; + + var type = TypeParser.ParseType (module, fullname); + + Assert.IsInstanceOf (typeof (ByReferenceType), type); + + type = ((ByReferenceType) type).ElementType; + + Assert.IsNotNull (type); + Assert.AreEqual (corlib, type.Scope); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("System", type.Namespace); + Assert.AreEqual ("String", type.Name); + Assert.IsInstanceOf (typeof (TypeReference), type); + } + + [Test] + public void FullyQualifiedTypeReference () + { + var module = GetCurrentModule (); + var cecil = module.AssemblyReferences.Where (reference => reference.Name != typeof (TypeDefinition).Assembly.GetName ().Name).First (); + + var fullname = "Mono.Cecil.TypeDefinition, " + cecil.FullName; + + var type = TypeParser.ParseType (module, fullname); + Assert.IsNotNull (type); + Assert.AreEqual (cecil, type.Scope); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("Mono.Cecil", type.Namespace); + Assert.AreEqual ("TypeDefinition", type.Name); + Assert.IsInstanceOf (typeof (TypeReference), type); + } + + [Test] + public void OpenGenericType () + { + var module = GetCurrentModule (); + var corlib = module.TypeSystem.CoreLibrary; + + const string fullname = "System.Collections.Generic.Dictionary`2"; + + var type = TypeParser.ParseType (module, fullname); + Assert.IsNotNull (type); + Assert.AreEqual (corlib, type.Scope); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("System.Collections.Generic", type.Namespace); + Assert.AreEqual ("Dictionary`2", type.Name); + Assert.IsInstanceOf (typeof (TypeReference), type); + Assert.AreEqual (2, type.GenericParameters.Count); + } + + public class ID {} + + [Test] + public void SimpleNestedType () + { + var module = GetCurrentModule (); + + const string fullname = "Mono.Cecil.Tests.TypeParserTests+ID"; + + var type = TypeParser.ParseType (module, fullname); + + Assert.IsNotNull (type); + Assert.AreEqual (module, type.Module); + Assert.AreEqual (module, type.Scope); + Assert.AreEqual ("", type.Namespace); + Assert.AreEqual ("ID", type.Name); + + Assert.AreEqual ("Mono.Cecil.Tests.TypeParserTests/ID", type.FullName); + Assert.AreEqual (fullname, TypeParser.ToParseable (type)); + } + + [Test] + public void TripleNestedTypeWithScope () + { + var module = GetCurrentModule (); + + const string fullname = "Bingo.Foo`1+Bar`1+Baz`1, Bingo"; + + var type = TypeParser.ParseType (module, fullname); + + Assert.AreEqual ("Bingo.Foo`1+Bar`1+Baz`1, Bingo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", TypeParser.ToParseable (type)); + + Assert.IsNotNull (type); + Assert.AreEqual ("Bingo", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("", type.Namespace); + Assert.AreEqual ("Baz`1", type.Name); + Assert.IsInstanceOf (typeof (TypeReference), type); + Assert.AreEqual (1, type.GenericParameters.Count); + + type = type.DeclaringType; + + Assert.IsNotNull (type); + Assert.AreEqual ("Bingo", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("", type.Namespace); + Assert.AreEqual ("Bar`1", type.Name); + Assert.IsInstanceOf (typeof (TypeReference), type); + Assert.AreEqual (1, type.GenericParameters.Count); + + type = type.DeclaringType; + + Assert.IsNotNull (type); + Assert.AreEqual ("Bingo", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("Bingo", type.Namespace); + Assert.AreEqual ("Foo`1", type.Name); + Assert.IsInstanceOf (typeof (TypeReference), type); + Assert.AreEqual (1, type.GenericParameters.Count); + } + + [Test] + public void Vector () + { + var module = GetCurrentModule (); + + const string fullname = "Bingo.Gazonk[], Bingo"; + + var type = TypeParser.ParseType (module, fullname); + + Assert.AreEqual ("Bingo.Gazonk[], Bingo, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null", TypeParser.ToParseable (type)); + + var array = type as ArrayType; + Assert.IsNotNull (array); + Assert.AreEqual (1, array.Rank); + Assert.IsTrue (array.IsVector); + + type = array.ElementType; + + Assert.IsNotNull (type); + Assert.AreEqual ("Bingo", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("Bingo", type.Namespace); + Assert.AreEqual ("Gazonk", type.Name); + Assert.IsInstanceOf (typeof (TypeReference), type); + } + + [Test] + public void ThreeDimensionalArray () + { + var module = GetCurrentModule (); + + const string fullname = "Bingo.Gazonk[,,], Bingo"; + + var type = TypeParser.ParseType (module, fullname); + + var array = type as ArrayType; + Assert.IsNotNull (array); + Assert.AreEqual (3, array.Rank); + Assert.IsFalse (array.IsVector); + + type = array.ElementType; + + Assert.IsNotNull (type); + Assert.AreEqual ("Bingo", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("Bingo", type.Namespace); + Assert.AreEqual ("Gazonk", type.Name); + Assert.IsInstanceOf (typeof (TypeReference), type); + } + + [Test] + public void GenericInstanceExternArguments () + { + if (Platform.OnCoreClr) + return; + + var module = GetCurrentModule (); + + var fullname = string.Format ("System.Collections.Generic.Dictionary`2[[System.Int32, {0}],[System.String, {0}]]", + typeof (object).Assembly.FullName); + + var type = TypeParser.ParseType (module, fullname); + + Assert.AreEqual (fullname, TypeParser.ToParseable (type)); + + var instance = type as GenericInstanceType; + Assert.IsNotNull (instance); + Assert.AreEqual (2, instance.GenericArguments.Count); + Assert.AreEqual ("mscorlib", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("System.Collections.Generic", type.Namespace); + Assert.AreEqual ("Dictionary`2", type.Name); + + type = instance.ElementType; + + Assert.AreEqual (2, type.GenericParameters.Count); + + var argument = instance.GenericArguments [0]; + Assert.AreEqual ("mscorlib", argument.Scope.Name); + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("System", argument.Namespace); + Assert.AreEqual ("Int32", argument.Name); + + argument = instance.GenericArguments [1]; + Assert.AreEqual ("mscorlib", argument.Scope.Name); + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("System", argument.Namespace); + Assert.AreEqual ("String", argument.Name); + } + + [Test] + public void GenericInstanceMixedArguments () + { + var module = GetCurrentModule (); + + var fullname = string.Format ("System.Collections.Generic.Dictionary`2[Mono.Cecil.Tests.TypeParserTests,[System.String, {0}]]", + typeof (object).Assembly.FullName); + + var type = TypeParser.ParseType (module, fullname); + + var instance = type as GenericInstanceType; + Assert.IsNotNull (instance); + Assert.AreEqual (2, instance.GenericArguments.Count); + Assert.AreEqual (Platform.OnCoreClr ? "System.Runtime" : "mscorlib", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("System.Collections.Generic", type.Namespace); + Assert.AreEqual ("Dictionary`2", type.Name); + + type = instance.ElementType; + + Assert.AreEqual (2, type.GenericParameters.Count); + + var argument = instance.GenericArguments [0]; + Assert.IsInstanceOf (typeof (TypeDefinition), argument); + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("Mono.Cecil.Tests", argument.Namespace); + Assert.AreEqual ("TypeParserTests", argument.Name); + + argument = instance.GenericArguments [1]; + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name); + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("System", argument.Namespace); + Assert.AreEqual ("String", argument.Name); + } + + public class Foo { + } + + public class Bar {} + + [Test] + public void GenericInstanceTwoNonFqArguments () + { + var module = GetCurrentModule (); + + var fullname = string.Format ("System.Collections.Generic.Dictionary`2[Mono.Cecil.Tests.TypeParserTests+Bar,Mono.Cecil.Tests.TypeParserTests+Bar], {0}", typeof (object).Assembly.FullName); + + var type = TypeParser.ParseType (module, fullname); + + var instance = type as GenericInstanceType; + Assert.IsNotNull (instance); + Assert.AreEqual (2, instance.GenericArguments.Count); + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("System.Collections.Generic", type.Namespace); + Assert.AreEqual ("Dictionary`2", type.Name); + + type = instance.ElementType; + + Assert.AreEqual (2, type.GenericParameters.Count); + + var argument = instance.GenericArguments [0]; + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("", argument.Namespace); + Assert.AreEqual ("Bar", argument.Name); + Assert.IsInstanceOf (typeof (TypeDefinition), argument); + + argument = instance.GenericArguments [1]; + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("", argument.Namespace); + Assert.AreEqual ("Bar", argument.Name); + Assert.IsInstanceOf (typeof (TypeDefinition), argument); + } + + [Test] + public void ComplexGenericInstanceMixedArguments () + { + var module = GetCurrentModule (); + + var fullname = string.Format ("System.Collections.Generic.Dictionary`2[[System.String, {0}],Mono.Cecil.Tests.TypeParserTests+Foo`2[Mono.Cecil.Tests.TypeParserTests,[System.Int32, {0}]]]", + typeof (object).Assembly.FullName); + + var type = TypeParser.ParseType (module, fullname); + + var instance = type as GenericInstanceType; + Assert.IsNotNull (instance); + Assert.AreEqual (2, instance.GenericArguments.Count); + Assert.AreEqual (Platform.OnCoreClr ? "System.Runtime" : "mscorlib", type.Scope.Name); + Assert.AreEqual (module, type.Module); + Assert.AreEqual ("System.Collections.Generic", type.Namespace); + Assert.AreEqual ("Dictionary`2", type.Name); + + type = instance.ElementType; + + Assert.AreEqual (2, type.GenericParameters.Count); + + var argument = instance.GenericArguments [0]; + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name); + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("System", argument.Namespace); + Assert.AreEqual ("String", argument.Name); + + argument = instance.GenericArguments [1]; + + instance = argument as GenericInstanceType; + Assert.IsNotNull (instance); + Assert.AreEqual (2, instance.GenericArguments.Count); + Assert.AreEqual (module, instance.Module); + Assert.AreEqual ("Mono.Cecil.Tests.TypeParserTests/Foo`2", instance.ElementType.FullName); + Assert.IsInstanceOf (typeof (TypeDefinition), instance.ElementType); + + argument = instance.GenericArguments [0]; + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("Mono.Cecil.Tests", argument.Namespace); + Assert.AreEqual ("TypeParserTests", argument.Name); + Assert.IsInstanceOf (typeof (TypeDefinition), argument); + + argument = instance.GenericArguments [1]; + Assert.AreEqual (Platform.OnCoreClr ? "System.Private.CoreLib" : "mscorlib", argument.Scope.Name); + Assert.AreEqual (module, argument.Module); + Assert.AreEqual ("System", argument.Namespace); + Assert.AreEqual ("Int32", argument.Name); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/TypeReferenceComparisonTests.cs b/cecil-master/Test/Mono.Cecil.Tests/TypeReferenceComparisonTests.cs new file mode 100644 index 000000000..d8332eba0 --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/TypeReferenceComparisonTests.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using Mono.Cecil; +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class TypeReferenceComparisonTests : LoadAssemblyDefinitionForTestsBaseSimple { + + [SetUp] + public void SetUp () + { + SetupAssemblyDefinitions (typeof (TypeReferenceComparisonTests).Assembly); + } + + [Test] + public void TypeReferenceEqualsTypeDefinition () + { + var typeDefinition = TypeDefinitionUtils.TypeDefinitionFor (typeof (Int32), _mscorlib); + var typeReference = new TypeReference (typeDefinition.Namespace, typeDefinition.Name, typeDefinition.Module, typeDefinition.Scope); + + Assert.That (TypeReferenceEqualityComparer.AreEqual (typeDefinition, typeReference), Is.True); + } + + [Test] + public void GenericParametersFromTwoTypesAreNotEqual () + { + var listDefinition = TypeDefinitionUtils.TypeDefinitionFor (typeof (List<>), _mscorlib); + var stackDefinition = TypeDefinitionUtils.TypeDefinitionFor (typeof (Comparer<>), _mscorlib); + + Assert.That (TypeReferenceEqualityComparer.AreEqual (listDefinition.GenericParameters[0], stackDefinition.GenericParameters[0]), Is.False); + } + + [Test] + public void ArrayTypesDoNotMatchIfRankIsDifferent () + { + var elementType = TypeDefinitionUtils.TypeDefinitionFor (typeof (Int32), _mscorlib); + + Assert.That (TypeReferenceEqualityComparer.AreEqual (new ArrayType (elementType, 1), new ArrayType (elementType, 2)), Is.False, "Two array types with different ranks match, which is not expected."); + } + + [Test] + public void ArrayTypesDoNotMatchIfElementTypeIsDifferent () + { + Assert.That (TypeReferenceEqualityComparer.AreEqual (new ArrayType (TypeDefinitionUtils.TypeDefinitionFor (typeof (Int32), _mscorlib), 1), new ArrayType (TypeDefinitionUtils.TypeDefinitionFor (typeof (Int64), _mscorlib), 1)), Is.False, "Two array types with different element types match, which is not expected."); + } + + [Test] + public void ArrayTypesWithDifferentRanksToNotMatch () + { + var elementType = TypeDefinitionUtils.TypeDefinitionFor (typeof (Int32), _mscorlib); + + Assert.That (TypeReferenceEqualityComparer.AreEqual ( (TypeSpecification) new ArrayType (elementType, 1), (TypeSpecification) new ArrayType (elementType, 2)), Is.False, "Two type specifications that are array types with different ranks match, which is not expected."); + } + + [Test] + public void GenericInstanceTypeFromTwoTypesAreNotEqual () + { + var int32Definition = TypeDefinitionUtils.TypeDefinitionFor (typeof (Int32), _mscorlib); + var listDefinition = TypeDefinitionUtils.TypeDefinitionFor (typeof (List<>), _mscorlib); + var listGenericInstance = new GenericInstanceType (listDefinition); + listGenericInstance.GenericArguments.Add (int32Definition); + var stackDefinition = TypeDefinitionUtils.TypeDefinitionFor (typeof (Comparer<>), _mscorlib); + var stackGenericInstance = new GenericInstanceType (stackDefinition); + stackGenericInstance.GenericArguments.Add (int32Definition); + + Assert.That (TypeReferenceEqualityComparer.AreEqual (listGenericInstance, stackGenericInstance), Is.False); + } + + [Test] + public void GenericInstanceTypeForSameTypeIsEqual () + { + var int32Definition = TypeDefinitionUtils.TypeDefinitionFor (typeof (Int32), _mscorlib); + var listDefinition = TypeDefinitionUtils.TypeDefinitionFor (typeof (List<>), _mscorlib); + var listGenericInstance = new GenericInstanceType (listDefinition); + listGenericInstance.GenericArguments.Add (int32Definition); + var listGenericInstance2 = new GenericInstanceType (listDefinition); + listGenericInstance2.GenericArguments.Add (int32Definition); + + Assert.That (TypeReferenceEqualityComparer.AreEqual (listGenericInstance, listGenericInstance2), Is.True); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/TypeTests.cs b/cecil-master/Test/Mono.Cecil.Tests/TypeTests.cs new file mode 100644 index 000000000..fddc8e68e --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/TypeTests.cs @@ -0,0 +1,285 @@ +using System; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Cecil.Metadata; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class TypeTests : BaseTestFixture { + + [Test] + public void TypeLayout () + { + TestCSharp ("Layouts.cs", module => { + var foo = module.GetType ("Foo"); + Assert.IsNotNull (foo); + Assert.IsTrue (foo.IsValueType); + + Assert.IsTrue (foo.HasLayoutInfo); + Assert.AreEqual (16, foo.ClassSize); + + var babar = module.GetType ("Babar"); + Assert.IsNotNull (babar); + Assert.IsFalse (babar.IsValueType); + Assert.IsFalse (babar.HasLayoutInfo); + }); + } + + [Test] + public void SimpleInterfaces () + { + TestIL ("types.il", module => { + var ibaz = module.GetType ("IBaz"); + Assert.IsNotNull (ibaz); + + Assert.IsTrue (ibaz.HasInterfaces); + + var interfaces = ibaz.Interfaces; + + Assert.AreEqual (2, interfaces.Count); + + // Mono's ilasm and .NET's are ordering interfaces differently + Assert.IsNotNull (interfaces.Single (i => i.InterfaceType.FullName == "IBar")); + Assert.IsNotNull (interfaces.Single (i => i.InterfaceType.FullName == "IFoo")); + }); + } + + [Test] + public void GenericTypeDefinition () + { + TestCSharp ("Generics.cs", module => { + var foo = module.GetType ("Foo`2"); + Assert.IsNotNull (foo); + + Assert.IsTrue (foo.HasGenericParameters); + Assert.AreEqual (2, foo.GenericParameters.Count); + + var tbar = foo.GenericParameters [0]; + + Assert.AreEqual ("TBar", tbar.Name); + Assert.AreEqual (foo, tbar.Owner); + + var tbaz = foo.GenericParameters [1]; + + Assert.AreEqual ("TBaz", tbaz.Name); + Assert.AreEqual (foo, tbaz.Owner); + }); + } + + [Test] + public void ConstrainedGenericType () + { + TestCSharp ("Generics.cs", module => { + var bongo_t = module.GetType ("Bongo`1"); + Assert.IsNotNull (bongo_t); + + var t = bongo_t.GenericParameters [0]; + Assert.IsNotNull (t); + Assert.AreEqual ("T", t.Name); + + Assert.IsTrue (t.HasConstraints); + Assert.AreEqual (2, t.Constraints.Count); + + Assert.AreEqual ("Zap", t.Constraints [0].ConstraintType.FullName); + Assert.AreEqual ("IZoom", t.Constraints [1].ConstraintType.FullName); + }); + } + + [Test] + public void GenericBaseType () + { + TestCSharp ("Generics.cs", module => { + var child = module.GetType ("Child`1"); + + var child_t = child.GenericParameters [0]; + Assert.IsNotNull (child_t); + + var instance = child.BaseType as GenericInstanceType; + Assert.IsNotNull (instance); + Assert.AreNotEqual (0, instance.MetadataToken.RID); + + Assert.AreEqual (child_t, instance.GenericArguments [0]); + }); + } + + [Test] + public void GenericConstraintOnGenericParameter () + { + TestCSharp ("Generics.cs", module => { + var duel = module.GetType ("Duel`3"); + + Assert.AreEqual (3, duel.GenericParameters.Count); + + var t1 = duel.GenericParameters [0]; + var t2 = duel.GenericParameters [1]; + var t3 = duel.GenericParameters [2]; + + Assert.AreEqual (t1, t2.Constraints [0].ConstraintType); + Assert.AreEqual (t2, t3.Constraints [0].ConstraintType); + }); + } + + [Test] + public void GenericForwardBaseType () + { + TestCSharp ("Generics.cs", module => { + var tamchild = module.GetType ("TamChild"); + + Assert.IsNotNull (tamchild); + Assert.IsNotNull (tamchild.BaseType); + + var generic_instance = tamchild.BaseType as GenericInstanceType; + + Assert.IsNotNull (generic_instance); + + Assert.AreEqual (1, generic_instance.GenericArguments.Count); + Assert.AreEqual (module.GetType ("Tamtam"), generic_instance.GenericArguments [0]); + }); + } + + [Test] + public void TypeExtentingGenericOfSelf () + { + TestCSharp ("Generics.cs", module => { + var rec_child = module.GetType ("RecChild"); + + Assert.IsNotNull (rec_child); + Assert.IsNotNull (rec_child.BaseType); + + var generic_instance = rec_child.BaseType as GenericInstanceType; + + Assert.IsNotNull (generic_instance); + + Assert.AreEqual (1, generic_instance.GenericArguments.Count); + Assert.AreEqual (rec_child, generic_instance.GenericArguments [0]); + }); + } + + [Test] + public void TypeReferenceValueType () + { + TestCSharp ("Methods.cs", module => { + var baz = module.GetType ("Baz"); + var method = baz.GetMethod ("PrintAnswer"); + + var box = method.Body.Instructions.Where (i => i.OpCode == OpCodes.Box).First (); + var int32 = (TypeReference) box.Operand; + + Assert.IsTrue (int32.IsValueType); + }); + } + + [Test] + public void GenericInterfaceReference () + { + TestModule ("gifaceref.exe", module => { + var type = module.GetType ("Program"); + var iface = type.Interfaces [0]; + + var instance = (GenericInstanceType) iface.InterfaceType; + var owner = instance.ElementType; + + Assert.AreEqual (1, instance.GenericArguments.Count); + Assert.AreEqual (1, owner.GenericParameters.Count); + }); + } + + [Test] + public void UnboundGenericParameter () + { + TestModule ("cscgpbug.dll", module => { + var type = module.GetType ("ListViewModel"); + var method = type.GetMethod ("<>n__FabricatedMethod1"); + + var parameter = method.ReturnType as GenericParameter; + + Assert.IsNotNull (parameter); + Assert.AreEqual (0, parameter.Position); + Assert.IsNull (parameter.Owner); + }, verify: false); + } + + [Test] + public void GenericMultidimensionalArray () + { + TestCSharp ("Generics.cs", module => { + var type = module.GetType ("LaMatrix"); + var method = type.GetMethod ("At"); + + var call = method.Body.Instructions.Where (i => i.Operand is MethodReference).First (); + var get = (MethodReference) call.Operand; + + Assert.IsNotNull (get); + Assert.AreEqual (0, get.GenericParameters.Count); + Assert.AreEqual (MethodCallingConvention.Default, get.CallingConvention); + Assert.AreEqual (method.GenericParameters [0], get.ReturnType); + }); + } + + [Test] + public void CorlibPrimitive () + { + var module = typeof (TypeTests).ToDefinition ().Module; + + var int32 = module.TypeSystem.Int32; + Assert.IsTrue (int32.IsPrimitive); + Assert.AreEqual (MetadataType.Int32, int32.MetadataType); + + var int32_def = int32.Resolve (); + Assert.IsTrue (int32_def.IsPrimitive); + Assert.AreEqual (MetadataType.Int32, int32_def.MetadataType); + } + + [Test] + public void ExplicitThis () + { + TestIL ("explicitthis.il", module => { + var type = module.GetType ("MakeDecision"); + var method = type.GetMethod ("Decide"); + var fptr = method.ReturnType as FunctionPointerType; + + Assert.IsNotNull (fptr); + Assert.IsTrue (fptr.HasThis); + Assert.IsTrue (fptr.ExplicitThis); + + Assert.AreEqual (0, fptr.Parameters [0].Sequence); + Assert.AreEqual (1, fptr.Parameters [1].Sequence); + }, verify: false); + } + + [Test] + public void DeferredCorlibTypeDef () + { + using (var module = ModuleDefinition.ReadModule (typeof (object).Assembly.Location, new ReaderParameters (ReadingMode.Deferred))) { + var object_type = module.TypeSystem.Object; + Assert.IsInstanceOf (object_type); + } + } + + [Test] + public void CorlibTypesMetadataType () + { + using (var module = ModuleDefinition.ReadModule (typeof (object).Assembly.Location)) { + var type = module.GetType ("System.String"); + Assert.IsNotNull (type); + Assert.IsNotNull (type.BaseType); + Assert.AreEqual ("System.Object", type.BaseType.FullName); + Assert.IsInstanceOf (type.BaseType); + Assert.AreEqual (MetadataType.String, type.MetadataType); + Assert.AreEqual (MetadataType.Object, type.BaseType.MetadataType); + } + } + + [Test] + public void SelfReferencingTypeRef () + { + TestModule ("self-ref-typeref.dll", module => { + }, verify: false); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/VariableTests.cs b/cecil-master/Test/Mono.Cecil.Tests/VariableTests.cs new file mode 100644 index 000000000..5454b937f --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/VariableTests.cs @@ -0,0 +1,185 @@ +using System; +using System.Linq; + +using Mono.Cecil; +using Mono.Cecil.Cil; + +using NUnit.Framework; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public class VariableTests : BaseTestFixture { + + [Test] + public void AddVariableIndex () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + + body.Variables.Add (x); + body.Variables.Add (y); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (1, y.Index); + } + + [Test] + public void RemoveAtVariableIndex () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); + + body.Variables.Add (x); + body.Variables.Add (y); + body.Variables.Add (z); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (1, y.Index); + Assert.AreEqual (2, z.Index); + + body.Variables.RemoveAt (1); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (-1, y.Index); + Assert.AreEqual (1, z.Index); + } + + [Test] + public void RemoveVariableIndex () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); + + body.Variables.Add (x); + body.Variables.Add (y); + body.Variables.Add (z); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (1, y.Index); + Assert.AreEqual (2, z.Index); + + body.Variables.Remove (y); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (-1, y.Index); + Assert.AreEqual (1, z.Index); + } + + [Test] + public void RemoveVariableWithDebugInfo () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ret); + + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); + var z2 = new VariableDefinition (object_ref); + + body.Variables.Add (x); + body.Variables.Add (y); + body.Variables.Add (z); + body.Variables.Add (z2); + + var scope = new ScopeDebugInformation (body.Instructions [0], body.Instructions [0]); + method.DebugInformation = new MethodDebugInformation (method) { + Scope = scope + }; + scope.Variables.Add (new VariableDebugInformation (x.index, nameof (x))); + scope.Variables.Add (new VariableDebugInformation (y.index, nameof (y))); + scope.Variables.Add (new VariableDebugInformation (z.index, nameof (z))); + scope.Variables.Add (new VariableDebugInformation (z2, nameof (z2))); + + body.Variables.Remove (y); + + Assert.AreEqual (3, scope.Variables.Count); + Assert.AreEqual (x.Index, scope.Variables [0].Index); + Assert.AreEqual (nameof (x), scope.Variables [0].Name); + Assert.AreEqual (z.Index, scope.Variables [1].Index); + Assert.AreEqual (nameof (z), scope.Variables [1].Name); + Assert.AreEqual (z2.Index, scope.Variables [2].Index); + Assert.AreEqual (nameof (z2), scope.Variables [2].Name); + } + + [Test] + public void InsertVariableIndex () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); + + body.Variables.Add (x); + body.Variables.Add (z); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (-1, y.Index); + Assert.AreEqual (1, z.Index); + + body.Variables.Insert (1, y); + + Assert.AreEqual (0, x.Index); + Assert.AreEqual (1, y.Index); + Assert.AreEqual (2, z.Index); + } + + [Test] + public void InsertVariableWithDebugInfo () + { + var object_ref = new TypeReference ("System", "Object", null, null, false); + var method = new MethodDefinition ("foo", MethodAttributes.Static, object_ref); + var body = new MethodBody (method); + var il = body.GetILProcessor (); + il.Emit (OpCodes.Ret); + + var x = new VariableDefinition (object_ref); + var y = new VariableDefinition (object_ref); + var z = new VariableDefinition (object_ref); + var z2 = new VariableDefinition (object_ref); + + body.Variables.Add (x); + body.Variables.Add (z); + body.Variables.Add (z2); + + var scope = new ScopeDebugInformation (body.Instructions [0], body.Instructions [0]); + method.DebugInformation = new MethodDebugInformation (method) { + Scope = scope + }; + scope.Variables.Add (new VariableDebugInformation (x.index, nameof (x))); + scope.Variables.Add (new VariableDebugInformation (z.index, nameof (z))); + scope.Variables.Add (new VariableDebugInformation (z2, nameof (z2))); + + body.Variables.Insert (1, y); + + // Adding local variable doesn't add debug info for it (since there's no way to deduce the name of the variable) + Assert.AreEqual (3, scope.Variables.Count); + Assert.AreEqual (x.Index, scope.Variables [0].Index); + Assert.AreEqual (nameof (x), scope.Variables [0].Name); + Assert.AreEqual (z.Index, scope.Variables [1].Index); + Assert.AreEqual (nameof (z), scope.Variables [1].Name); + Assert.AreEqual (z2.Index, scope.Variables [2].Index); + Assert.AreEqual (nameof (z2), scope.Variables [2].Name); + } + } +} diff --git a/cecil-master/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs b/cecil-master/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs new file mode 100644 index 000000000..4f6aaf6ec --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/WindowsRuntimeAssemblyResolver.cs @@ -0,0 +1,97 @@ +#if !NET_CORE + +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using Microsoft.Win32; + +namespace Mono.Cecil.Tests { + public class WindowsRuntimeAssemblyResolver : DefaultAssemblyResolver { + + readonly Dictionary assemblies = new Dictionary (); + + public static WindowsRuntimeAssemblyResolver CreateInstance (bool applyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return null; + try { + return new WindowsRuntimeAssemblyResolver (applyWindowsRuntimeProjections); + } catch { + return null; + } + } + + public override AssemblyDefinition Resolve (AssemblyNameReference name) + { + AssemblyDefinition assembly; + if (assemblies.TryGetValue(name.Name, out assembly)) + return assembly; + + return base.Resolve (name); + } + + private WindowsRuntimeAssemblyResolver (bool applyWindowsRuntimeProjections) + { + var readerParameters = new ReaderParameters { + ApplyWindowsRuntimeProjections = applyWindowsRuntimeProjections + }; + + LoadWindowsSdk ("v10.0", "10", (installationFolder) => { + var referencesFolder = Path.Combine (installationFolder, "References"); + var assemblies = Directory.GetFiles (referencesFolder, "*.winmd", SearchOption.AllDirectories); + + var latestVersionDir = Directory.GetDirectories (Path.Combine (installationFolder, "UnionMetadata")) + .Where (d => Path.GetFileName (d) != "Facade") + .OrderBy (d => Path.GetFileName (d)) + .Last (); + + var windowsWinMdPath = Path.Combine (latestVersionDir, "Windows.winmd"); + if (!File.Exists (windowsWinMdPath)) + throw new FileNotFoundException (windowsWinMdPath); + + var windowsWinmdAssembly = AssemblyDefinition.ReadAssembly (windowsWinMdPath, readerParameters); + Register (windowsWinmdAssembly); + + foreach (var assemblyPath in assemblies) { + var assembly = AssemblyDefinition.ReadAssembly (assemblyPath, readerParameters); + Register (assembly); + } + }); + } + + void Register (AssemblyDefinition assembly) + { + assemblies [assembly.Name.Name] = assembly; + RegisterAssembly (assembly); + } + + protected override void Dispose (bool disposing) + { + if (!disposing) + return; + + foreach (var assembly in assemblies.Values) + assembly.Dispose (); + + base.Dispose (true); + } + + void LoadWindowsSdk (string registryVersion, string windowsKitsVersion, Action registerAssembliesCallback) + { + using (var localMachine32Key = RegistryKey.OpenBaseKey (RegistryHive.LocalMachine, RegistryView.Registry32)) { + using (var sdkKey = localMachine32Key.OpenSubKey (@"SOFTWARE\Microsoft\Microsoft SDKs\Windows\v" + registryVersion)) { + string installationFolder = null; + if (sdkKey != null) + installationFolder = (string)sdkKey.GetValue ("InstallationFolder"); + if (string.IsNullOrEmpty (installationFolder)) { + var programFilesX86 = Environment.GetFolderPath (Environment.SpecialFolder.ProgramFilesX86); + installationFolder = Path.Combine (programFilesX86, @"Windows Kits\" + windowsKitsVersion); + } + registerAssembliesCallback (installationFolder); + } + } + } + } +} +#endif \ No newline at end of file diff --git a/cecil-master/Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs b/cecil-master/Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs new file mode 100644 index 000000000..ae443930b --- /dev/null +++ b/cecil-master/Test/Mono.Cecil.Tests/WindowsRuntimeProjectionsTests.cs @@ -0,0 +1,339 @@ +#if !NET_CORE + +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; + +namespace Mono.Cecil.Tests { + + [TestFixture] + public abstract class BaseWindowsRuntimeProjectionsTests : BaseTestFixture { + + protected abstract string ModuleName { get; } + protected abstract MetadataKind ExpectedMetadataKind { get; } + protected abstract string [] ManagedClassTypeNames { get; } + protected abstract string [] CustomListTypeNames { get; } + + [TestCase (true)] + [TestCase (false)] + public void CanReadMetadataType (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule (ModuleName, (module) => { + Assert.AreEqual (ExpectedMetadataKind, module.MetadataKind); + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + + [TestCase (true)] + [TestCase (false)] + public void CanProjectParametersAndReturnTypes (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule (ModuleName, (module) => { + var types = ManagedClassTypeNames.Select (typeName => module.Types.Single (t => t.Name == typeName)); + + foreach (var type in types) { + var listGetter = type.Properties.Single (p => p.Name == "List").GetMethod; + var listSetter = type.Properties.Single (p => p.Name == "List").SetMethod; + + Assert.IsNotNull (listGetter); + Assert.IsNotNull (listSetter); + + Assert.AreEqual (listGetter.ReturnType.FullName, "System.Collections.Generic.IList`1"); + Assert.AreEqual (listSetter.Parameters.Count, 1); + Assert.AreEqual (listSetter.Parameters [0].ParameterType.FullName, "System.Collections.Generic.IList`1"); + } + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + + [TestCase (true)] + [TestCase (false)] + public void CanProjectInterfaces (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule (ModuleName, (module) => { + var types = CustomListTypeNames.Select (typeName => module.Types.Single (t => t.Name == typeName)); + + foreach (var type in types) { + Assert.IsNotNull (type.Interfaces.SingleOrDefault (i => i.InterfaceType.FullName == "System.Collections.Generic.IList`1")); + Assert.IsNotNull (type.Interfaces.SingleOrDefault (i => i.InterfaceType.FullName == "System.Collections.Generic.IEnumerable`1")); + } + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + + /// + /// This test exists to verify a StackOverflowException that started happening with https://github.com/jbevain/cecil/pull/843 + /// and was fixed by https://github.com/jbevain/cecil/pull/879 + /// + /// The windows runtime sdk assemblies must be read with ApplyWindowsRuntimeProjections in order for the StackOverflowException to happen + /// + [TestCase (true)] + [TestCase (false)] + public void CanAvoidCircleAttributeReading (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule (ModuleName, (module) => { + + var windowsWinMd = module.AssemblyResolver.Resolve (new AssemblyNameReference ("Windows", null)); + + var problematicType = windowsWinMd.MainModule.GetType ("Windows.Foundation.Metadata.ActivatableAttribute"); + + Assert.Greater (problematicType.CustomAttributes.Count, 0, "Expected one or more attributes"); + + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + + [TestCase (true)] + [TestCase (false)] + public void CanStripType (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + var assemblyResolver = WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections); + + TestModule (ModuleName, (originalModule) => { + var types = CustomListTypeNames.Select (typeName => originalModule.Types.Single (t => t.Name == typeName)).ToArray (); + + foreach (var type in types) + originalModule.Types.Remove (type); + + var tmpPath = Path.GetTempFileName (); + originalModule.Write (tmpPath); + + try { + TestModule (tmpPath, (modifiedModule) => { + foreach (var type in types) + Assert.IsTrue (!modifiedModule.Types.Any (t => t.FullName == type.FullName)); + }, verify: false, assemblyResolver: assemblyResolver, applyWindowsRuntimeProjections: true); + } finally { + File.Delete (tmpPath); + } + }, readOnly: true, verify: false, assemblyResolver: assemblyResolver, applyWindowsRuntimeProjections: true); + } + } + + [TestFixture] + public class ManagedWindowsRuntimeProjectionsTests : BaseWindowsRuntimeProjectionsTests { + + protected override string ModuleName { get { return "ManagedWinmd.winmd"; } } + + protected override MetadataKind ExpectedMetadataKind { get { return MetadataKind.ManagedWindowsMetadata; } } + + protected override string [] ManagedClassTypeNames { get { return new [] { "ManagedClass", "ManagedClass" }; } } + + protected override string [] CustomListTypeNames { get { return new [] { "CustomList", "CustomList" }; } } + + [TestCase (true)] + [TestCase (false)] + public void CanProjectClasses (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule (ModuleName, (module) => { + var managedClassType = module.Types.Single (t => t.Name == "ManagedClass"); + Assert.AreEqual ("ManagedClass", managedClassType.WindowsRuntimeProjection.Name); + Assert.AreEqual (TypeDefinitionTreatment.UnmangleWindowsRuntimeName, managedClassType.WindowsRuntimeProjection.Treatment); + + var someOtherClassType = module.Types.Single (t => t.Name == "SomeOtherClass"); + Assert.AreEqual ("SomeOtherClass", someOtherClassType.WindowsRuntimeProjection.Name); + Assert.AreEqual (TypeDefinitionTreatment.UnmangleWindowsRuntimeName, someOtherClassType.WindowsRuntimeProjection.Treatment); + + var winrtManagedClassType = module.Types.Single (t => t.Name == "ManagedClass"); + Assert.AreEqual ("ManagedClass", winrtManagedClassType.WindowsRuntimeProjection.Name); + Assert.AreEqual (TypeDefinitionTreatment.PrefixWindowsRuntimeName, winrtManagedClassType.WindowsRuntimeProjection.Treatment); + + var winrtSomeOtherClassType = module.Types.Single (t => t.Name == "SomeOtherClass"); + Assert.AreEqual ("SomeOtherClass", winrtSomeOtherClassType.WindowsRuntimeProjection.Name); + Assert.AreEqual (TypeDefinitionTreatment.PrefixWindowsRuntimeName, winrtSomeOtherClassType.WindowsRuntimeProjection.Treatment); + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + + [TestCase (true)] + [TestCase (false)] + public void VerifyTypeReferenceToProjectedTypeInAttributeArgumentReferencesUnmangledTypeName(bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule(ModuleName, (module) => + { + var type = module.Types.Single(t => t.Name == "ClassWithAsyncMethod"); + var method = type.Methods.Single(m => m.Name == "DoStuffAsync"); + + var attribute = method.CustomAttributes.Single(a => a.AttributeType.Name == "AsyncStateMachineAttribute"); + var attributeArgument = (TypeReference)attribute.ConstructorArguments[0].Value; + + Assert.AreEqual("ManagedWinmd.ClassWithAsyncMethod/d__0", attributeArgument.FullName); + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance(readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + } + + [TestFixture] + public class NativeWindowsRuntimeProjectionsTests : BaseWindowsRuntimeProjectionsTests { + + protected override string ModuleName { get { return "NativeWinmd.winmd"; } } + + protected override MetadataKind ExpectedMetadataKind { get { return MetadataKind.WindowsMetadata; } } + + protected override string [] ManagedClassTypeNames { get { return new [] { "ManagedClass" }; } } + + protected override string [] CustomListTypeNames { get { return new [] { "CustomList" }; } } + + [TestCase (true)] + [TestCase (false)] + public void CanProjectAndRedirectInterfaces (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule (ModuleName, (module) => { + var customListClass = module.Types.Single (t => t.Name == "CustomList"); + Assert.AreEqual (5, customListClass.Interfaces.Count); + + Assert.AreEqual (1, customListClass.Interfaces[0].CustomAttributes.Count); + Assert.AreEqual ("Windows.Foundation.Metadata.DefaultAttribute", customListClass.Interfaces[0].CustomAttributes[0].AttributeType.FullName); + Assert.AreEqual ("NativeWinmd.__ICustomListPublicNonVirtuals", customListClass.Interfaces[0].InterfaceType.FullName); + + Assert.AreEqual (0, customListClass.Interfaces[1].CustomAttributes.Count); + Assert.AreEqual ("System.Collections.Generic.IList`1", customListClass.Interfaces[1].InterfaceType.FullName); + + Assert.AreEqual (0, customListClass.Interfaces[2].CustomAttributes.Count); + Assert.AreEqual ("System.Collections.Generic.IEnumerable`1", customListClass.Interfaces[2].InterfaceType.FullName); + + Assert.AreEqual (0, customListClass.Interfaces[3].CustomAttributes.Count); + Assert.AreEqual ("Windows.Foundation.Collections.IVector`1", customListClass.Interfaces[3].InterfaceType.FullName); + + Assert.AreEqual (0, customListClass.Interfaces[4].CustomAttributes.Count); + Assert.AreEqual ("Windows.Foundation.Collections.IIterable`1", customListClass.Interfaces[4].InterfaceType.FullName); + + var customPropertySetClass = module.Types.Single (t => t.Name == "CustomPropertySet"); + Assert.AreEqual (7, customPropertySetClass.Interfaces.Count); + + Assert.AreEqual (0, customPropertySetClass.Interfaces[0].CustomAttributes.Count); + Assert.AreEqual ("Windows.Foundation.Collections.IPropertySet", customPropertySetClass.Interfaces[0].InterfaceType.FullName); + + Assert.AreEqual (1, customPropertySetClass.Interfaces[1].CustomAttributes.Count); + Assert.AreEqual ("Windows.Foundation.Metadata.DefaultAttribute", customPropertySetClass.Interfaces[1].CustomAttributes[0].AttributeType.FullName); + Assert.AreEqual ("NativeWinmd.__ICustomPropertySetPublicNonVirtuals", customPropertySetClass.Interfaces[1].InterfaceType.FullName); + + Assert.AreEqual (0, customPropertySetClass.Interfaces[2].CustomAttributes.Count); + Assert.AreEqual ("Windows.Foundation.Collections.IObservableMap`2", customPropertySetClass.Interfaces[2].InterfaceType.FullName); + + Assert.AreEqual (0, customPropertySetClass.Interfaces[3].CustomAttributes.Count); + Assert.AreEqual ("System.Collections.Generic.IDictionary`2", customPropertySetClass.Interfaces[3].InterfaceType.FullName); + + Assert.AreEqual (0, customPropertySetClass.Interfaces[4].CustomAttributes.Count); + Assert.AreEqual ("System.Collections.Generic.IEnumerable`1>", customPropertySetClass.Interfaces[4].InterfaceType.FullName); + + Assert.AreEqual (0, customPropertySetClass.Interfaces[5].CustomAttributes.Count); + Assert.AreEqual ("Windows.Foundation.Collections.IMap`2", customPropertySetClass.Interfaces[5].InterfaceType.FullName); + + Assert.AreEqual (0, customPropertySetClass.Interfaces[6].CustomAttributes.Count); + Assert.AreEqual ("Windows.Foundation.Collections.IIterable`1>", customPropertySetClass.Interfaces[6].InterfaceType.FullName); + + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + + [TestCase (true)] + [TestCase (false)] + public void CanProjectInterfaceMethods (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule (ModuleName, (module) => { + var customListClass = module.Types.Single (t => t.Name == "CustomList"); + Assert.AreEqual (28, customListClass.Methods.Count); + Assert.AreEqual (TypeDefinitionTreatment.RedirectImplementedMethods, customListClass.WindowsRuntimeProjection.Treatment); + + // Verify that projections add implementations for all projected interfaces methods + Assert.AreEqual (customListClass.Methods[0].FullName, "System.Void NativeWinmd.CustomList::.ctor()"); + Assert.AreEqual (customListClass.Methods[1].FullName, "Windows.Foundation.Collections.IIterator`1 NativeWinmd.CustomList::First()"); + Assert.AreEqual (customListClass.Methods[2].FullName, "System.UInt32 NativeWinmd.CustomList::get_Size()"); + Assert.AreEqual (customListClass.Methods[3].FullName, "System.Int32 NativeWinmd.CustomList::GetAt(System.UInt32)"); + Assert.AreEqual (customListClass.Methods[4].FullName, "System.Collections.Generic.IReadOnlyList`1 NativeWinmd.CustomList::GetView()"); + Assert.AreEqual (customListClass.Methods[5].FullName, "System.Boolean NativeWinmd.CustomList::IndexOf(System.Int32,System.UInt32&)"); + Assert.AreEqual (customListClass.Methods[6].FullName, "System.Void NativeWinmd.CustomList::SetAt(System.UInt32,System.Int32)"); + Assert.AreEqual (customListClass.Methods[7].FullName, "System.Void NativeWinmd.CustomList::InsertAt(System.UInt32,System.Int32)"); + Assert.AreEqual (customListClass.Methods[8].FullName, "System.Void NativeWinmd.CustomList::RemoveAt(System.UInt32)"); + Assert.AreEqual (customListClass.Methods[9].FullName, "System.Void NativeWinmd.CustomList::Append(System.Int32)"); + Assert.AreEqual (customListClass.Methods[10].FullName, "System.Void NativeWinmd.CustomList::RemoveAtEnd()"); + Assert.AreEqual (customListClass.Methods[11].FullName, "System.Void NativeWinmd.CustomList::Clear()"); + Assert.AreEqual (customListClass.Methods[12].FullName, "System.UInt32 NativeWinmd.CustomList::GetMany(System.UInt32,System.Int32[])"); + Assert.AreEqual (customListClass.Methods[13].FullName, "System.Void NativeWinmd.CustomList::ReplaceAll(System.Int32[])"); + Assert.AreEqual (customListClass.Methods[14].FullName, "System.Int32 NativeWinmd.CustomList::get_Item(System.Int32)"); + Assert.AreEqual (customListClass.Methods[15].FullName, "System.Void NativeWinmd.CustomList::set_Item(System.Int32,System.Int32)"); + Assert.AreEqual (customListClass.Methods[16].FullName, "System.Int32 NativeWinmd.CustomList::IndexOf(System.Int32)"); + Assert.AreEqual (customListClass.Methods[17].FullName, "System.Void NativeWinmd.CustomList::Insert(System.Int32,System.Int32)"); + Assert.AreEqual (customListClass.Methods[18].FullName, "System.Void NativeWinmd.CustomList::RemoveAt(System.Int32)"); + Assert.AreEqual (customListClass.Methods[19].FullName, "System.Int32 NativeWinmd.CustomList::get_Count()"); + Assert.AreEqual (customListClass.Methods[20].FullName, "System.Boolean NativeWinmd.CustomList::get_IsReadOnly()"); + Assert.AreEqual (customListClass.Methods[21].FullName, "System.Void NativeWinmd.CustomList::Add(System.Int32)"); + Assert.AreEqual (customListClass.Methods[22].FullName, "System.Void NativeWinmd.CustomList::Clear()"); + Assert.AreEqual (customListClass.Methods[23].FullName, "System.Boolean NativeWinmd.CustomList::Contains(System.Int32)"); + Assert.AreEqual (customListClass.Methods[24].FullName, "System.Void NativeWinmd.CustomList::CopyTo(System.Int32[],System.Int32)"); + Assert.AreEqual (customListClass.Methods[25].FullName, "System.Boolean NativeWinmd.CustomList::Remove(System.Int32)"); + Assert.AreEqual (customListClass.Methods[26].FullName, "System.Collections.Generic.IEnumerator`1 NativeWinmd.CustomList::GetEnumerator()"); + Assert.AreEqual (customListClass.Methods[27].FullName, "System.Collections.IEnumerator NativeWinmd.CustomList::GetEnumerator()"); + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + + [TestCase (true)] + [TestCase (false)] + public void CanProjectMethodOverrides (bool readSdkAssembliesWithApplyWindowsRuntimeProjections) + { + if (Platform.OnMono) + return; + + TestModule (ModuleName, (module) => { + var customListClass = module.Types.Single (t => t.Name == "CustomList"); + + for (int i = 1; i < customListClass.Methods.Count; i++) + Assert.AreEqual (1, customListClass.Methods[i].Overrides.Count); + + Assert.AreEqual (customListClass.Methods[1].Overrides[0].FullName, "Windows.Foundation.Collections.IIterator`1 Windows.Foundation.Collections.IIterable`1::First()"); + Assert.AreEqual (customListClass.Methods[2].Overrides[0].FullName, "System.UInt32 Windows.Foundation.Collections.IVector`1::get_Size()"); + Assert.AreEqual (customListClass.Methods[3].Overrides[0].FullName, "!0 Windows.Foundation.Collections.IVector`1::GetAt(System.UInt32)"); + Assert.AreEqual (customListClass.Methods[4].Overrides[0].FullName, "System.Collections.Generic.IReadOnlyList`1 Windows.Foundation.Collections.IVector`1::GetView()"); + Assert.AreEqual (customListClass.Methods[5].Overrides[0].FullName, "System.Boolean Windows.Foundation.Collections.IVector`1::IndexOf(!0,System.UInt32&)"); + Assert.AreEqual (customListClass.Methods[6].Overrides[0].FullName, "System.Void Windows.Foundation.Collections.IVector`1::SetAt(System.UInt32,!0)"); + Assert.AreEqual (customListClass.Methods[7].Overrides[0].FullName, "System.Void Windows.Foundation.Collections.IVector`1::InsertAt(System.UInt32,!0)"); + Assert.AreEqual (customListClass.Methods[8].Overrides[0].FullName, "System.Void Windows.Foundation.Collections.IVector`1::RemoveAt(System.UInt32)"); + Assert.AreEqual (customListClass.Methods[9].Overrides[0].FullName, "System.Void Windows.Foundation.Collections.IVector`1::Append(!0)"); + Assert.AreEqual (customListClass.Methods[10].Overrides[0].FullName, "System.Void Windows.Foundation.Collections.IVector`1::RemoveAtEnd()"); + Assert.AreEqual (customListClass.Methods[11].Overrides[0].FullName, "System.Void Windows.Foundation.Collections.IVector`1::Clear()"); + Assert.AreEqual (customListClass.Methods[12].Overrides[0].FullName, "System.UInt32 Windows.Foundation.Collections.IVector`1::GetMany(System.UInt32,!0[])"); + Assert.AreEqual (customListClass.Methods[13].Overrides[0].FullName, "System.Void Windows.Foundation.Collections.IVector`1::ReplaceAll(!0[])"); + Assert.AreEqual (customListClass.Methods[14].Overrides[0].FullName, "T System.Collections.Generic.IList`1::get_Item(System.Int32)"); + Assert.AreEqual (customListClass.Methods[15].Overrides[0].FullName, "System.Void System.Collections.Generic.IList`1::set_Item(System.Int32,T)"); + Assert.AreEqual (customListClass.Methods[16].Overrides[0].FullName, "System.Int32 System.Collections.Generic.IList`1::IndexOf(T)"); + Assert.AreEqual (customListClass.Methods[17].Overrides[0].FullName, "System.Void System.Collections.Generic.IList`1::Insert(System.Int32,T)"); + Assert.AreEqual (customListClass.Methods[18].Overrides[0].FullName, "System.Void System.Collections.Generic.IList`1::RemoveAt(System.Int32)"); + Assert.AreEqual (customListClass.Methods[19].Overrides[0].FullName, "System.Int32 System.Collections.Generic.ICollection`1::get_Count()"); + Assert.AreEqual (customListClass.Methods[20].Overrides[0].FullName, "System.Boolean System.Collections.Generic.ICollection`1::get_IsReadOnly()"); + Assert.AreEqual (customListClass.Methods[21].Overrides[0].FullName, "System.Void System.Collections.Generic.ICollection`1::Add(T)"); + Assert.AreEqual (customListClass.Methods[22].Overrides[0].FullName, "System.Void System.Collections.Generic.ICollection`1::Clear()"); + Assert.AreEqual (customListClass.Methods[23].Overrides[0].FullName, "System.Boolean System.Collections.Generic.ICollection`1::Contains(T)"); + Assert.AreEqual (customListClass.Methods[24].Overrides[0].FullName, "System.Void System.Collections.Generic.ICollection`1::CopyTo(T[],System.Int32)"); + Assert.AreEqual (customListClass.Methods[25].Overrides[0].FullName, "System.Boolean System.Collections.Generic.ICollection`1::Remove(T)"); + Assert.AreEqual (customListClass.Methods[26].Overrides[0].FullName, "System.Collections.Generic.IEnumerator`1 System.Collections.Generic.IEnumerable`1::GetEnumerator()"); + Assert.AreEqual (customListClass.Methods[27].Overrides[0].FullName, "System.Collections.IEnumerator System.Collections.IEnumerable::GetEnumerator()"); + + }, verify: false, assemblyResolver: WindowsRuntimeAssemblyResolver.CreateInstance (readSdkAssembliesWithApplyWindowsRuntimeProjections), applyWindowsRuntimeProjections: true); + } + } +} +#endif diff --git a/cecil-master/Test/Resources/assemblies/Deterministic.dll b/cecil-master/Test/Resources/assemblies/Deterministic.dll new file mode 100644 index 0000000000000000000000000000000000000000..44b05a3a1e44c6ba2fca0e37d64da20a3df2698d GIT binary patch literal 3072 zcmeHJ-)kII6#iy6Nw*tY8&hkGS|{BIvDINE5vqu8lZ|a;(}ZjiMFP$2>~%9bJG0Ep z*2D)1LKQ`*h=%?NeJm)nioW|&`sjloee}(jK8YB=b7!`jO^a5j4?<6J&pkiBbM86! z&b{pHTc0BfppRpF8@R?yt*hg4BC{!YW$h#qsA~l;!&2k>BDde85&1|EtK=ICT9+L=k6LpPYALsfr3^Io`tQ zrI|A473zzkPkKR(vk*4O>U73Fth9EXzr`V*htD#@4SkiI(uh|($t@B%Kgk0s4V z@D+Rfk;no31b$*^j6_Q80sKP#sMh99irB(uc#`_NTKnkmMMfH|=OXzK`2dcP=kbh| zEev7=7KU-0{Bg`MW8Wrr(J*zXx_-k$tc-Sbf0 zh+@@5Ie_KFL73`R*|i&fAXP*iQ<~XIDo|lnh38#IMQNElb+$uwuJ(>{VpQB(XonkV z+ZS$Z9NqeMu>A4YKX2W*Y(0lQ(=c*b6GlIUp`q*^Ba^%O{>t)^iJPDBfQ_7y-piwM zSc{oMZ-jR1Y~W9?JE|q!FRq2bdy(Mw$YJgx{gmvmt)=%zOdpDDigYJ+?pfkFHx-0s z&zrSfKRF|%^rne-`)TIbz092n{}YR$7d{MZ_NGt1>*8JPf|Ix7%~EprL>F4gOpq_5 zigV=CSfDh+m-a068S>YXR~J9@{q|>a<8;_<_G&807tZ_JLuG0Pv)Txm$K`vWnA6AG z2sCa~--|_hZCWGxZN$U{)DpVV_dU)-p(;yUxmnqj-F!YEo|rt8(1SA`ZKNQwdPX0?1HS-*-_E%ea#8o=R9)-tfS3( zVxCZMx7|LaXW*ocImHelBAeV@k5!ug7{|~Dbia1MOnx(bIexzqKFITb+JV0Si^3ow literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/EmbeddedCompressedPdbTarget.exe b/cecil-master/Test/Resources/assemblies/EmbeddedCompressedPdbTarget.exe new file mode 100644 index 0000000000000000000000000000000000000000..a324605a110b286cc3bed3d4b207b4ef045cdcdf GIT binary patch literal 11264 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 literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/EmbeddedPdbChecksumLib.dll b/cecil-master/Test/Resources/assemblies/EmbeddedPdbChecksumLib.dll new file mode 100644 index 0000000000000000000000000000000000000000..2de939b9b18609590abed1bde5bdfb272b91ed96 GIT binary patch literal 9728 zcmeHtcUV(f*XIen2#6Gw8mb5wDFRZY_uhL85Fi)`B%v2kK&pTgDN+Ox6j7=asnQV; zMa4ps-lZ1-Wlm7v>wE9a`^_`|&CIvLUVE={*8Z)v&pA9#R&*>A0YU%(h`@1l1OT<* zj3@bH{-0SWXr^X=P7PF%_jA-jwEH=XU6EL*CkE|;fxAN;;T|4n9Mk~;#dv!_kseTG zJtL?)+6e)pqN3pb6BI>sgsF7Sy$ z!SM&lgXm!x1PTp0;;{nu;K0ZFU1V^HCwTx+JYM|4R>A!7gvUkz5Chgw0Pq9%fZ&z? z2gFIhM+pEF06%!GqLHQ|rGoT7`F7SSa0Rlh-$VGt+ zkV^vvAXfs)L9TVIHv&0P=+7#EfPN7zI1~RCz?lJn{v|1);8?6MAftnJ@G8sz?;V6oJ7a(H{RaYIr!KG4602XoREwmtIO}4`-x{ zH|E&yuOLcjcTXhhSZRnr!TpX`*uU(*5$j{Xq#bepG~ffkJ^cSN{L24Wk3%{jQApe$ z)_*S&>=#_{cK=&7VNNL2uZsSwun1=q!V#Y)0CU8lF~9Z7NVtm!8jC|ZVt=cCVSxS2 z4uLU3V0@5{2<)#z0k;Fs5ES(s+`x#xPB_yEcse+wq!@$V#3k{MZ39G52!xCf3P6a# z1uZRJq$Vqqv%5z7o+o(&Gn0 z3<8{i>8cnjp)m*rPfx*LsbBFCg9(8FsOkT8{>n(KCkpPb3*HU@9R#5M+kFO5Kmg+7 zy9<2RfzgG*R|@z6A8Js4Ec{H!c8qQifavJspL+ptDD!}W^jEUrghxdOj&tBZgEsUZ zHc<8RUj}~hcLEc}KPNokyX6je-5u~cLnCFQ5$#sOjYWUGo8d`unP0mu;^Y52beN|T z_?W0Gh=_>;zq~L0_Qs=C#wca#Z5~?4P;n6G=qoF_g3%)~$YqS(Pq$pmYaecENX-xS z=jyzpDI6=@_c5(nVpY&Lz0diMGINsCIf_(9jq_SgdT%&aVof#PG#MHW?u@$3jtOTx z8d#MOO$Zz~l9~H7AW1X!mb?^#l>ef~{;igFUG;IFwl;zW%IbPy!#y&Hx4!($mmaU_ zN|wWBwi`cGg)Zptq(of~x+d(04!yFu6CRgX!OWN3cwTwhEb4Il%Gq!10}KG7|DDly z*#-))TQSvkdY0lgox?iz4WGnZR2dzof*d7vAhn{md2TPdKx4t zE?hiVWf6vN{fZ%0iQ{P^Pd1ttqTb2hT8J8T+^2=Q&vQ9&?MUo>?wgOvYg@nT7)I*; zImF3WqAl1U_^2~aBS-(q)#_Q>6$v@b(hhgr=b`DAs1lzh=}>K}fe$vi7hIoTE^vD= zT{?9t`AOv0Qr=GK6P+`rsh1QpsW(aV9~x83on%DD+UKbYku6v%0(~dwwfv2#mC{-s z#CACIYL~ylP(5kBsVA~O=&2yWhjHmH<5oSF>L&czJ%5&>h<7x~F+Y_H!`8>OMJHtH zMhCz7&MuNhOHfB!N84K6mgqWJ^=S&1gBDIg*U=Ib! zM?wqFFBcdDFFss#Nmz7aysVskTIXt(hKyhQ>ZtA8H_0{MDN+jM1Sd;PFuhQgcKWq& z7MP$&Cz}PdI+MvN<4d2Q*OvqKLb2W$_qIaOSxfVZPlC*p*sKhOSPwV?8PjHAW!^F* zh}9COCiPkfx^{k){U%v5N4Y$|Lu)5W`I)d0bVe%?2~E@tH;ndzMh@JF;s}yTXe+?h zaa2Iy96G1osBk38^G&Q>&cl(HMGyxJnRlngaB!r-;FQWT-8t-vCp9@}^OM`c7@Vzo z`WQ9*MB2P~oePi5`#L70T zb6ANYW8dr=yt}t8M?O=Bd!n(Y@^&6EyOx~Mnv&->^izFZp5CGLmBa3C!i!0fgIbm2 z%|b>;1iR7%yMY8nKO(-Z8fP5kQ+&oIbi!kZ93WN>ifbqC#fI|=!cJSXM<3+OKx3IW z6YgTUHdd)p=3Uy0o{15E59kQK>~KCiwkTFon@(uSAd&v8AH}l5_4jXAG;12Vik?Le zRjoEWGq}R%@^Bq3s(@Ij%x&88qq8>?bK584Y%;1(Tc26$_u}>7bP7?w{5Wx&i?p$D z-V6}phWo6|oOj=I!ysfupWkhz6D8(^RTxe?Hu<~)zW|J5ZRTjMN&)fZymu&Bp-!r0A z_PS{e4xxMHd0#Kjp;&qHf)ifJW!vc(_&22VtIjg;TbD{NbDd;6crcL_(RnWI=x%A{%mv9)36Q>u zNwA4zQ+Qo;LB?Q(RmUNI++nzpQKj-dK+mSfpC?-T@np5IV~&Cklm5o^k6fmhNQ0PM zWDJEa%R_^(=VW_M=`^wQO5f&V7gX%$mh$T+&_Sw`SZNn(kxKgk!?pklIB(>unebNg z)y+kMRYKN{^z7u8 zSlPy0HsXUdC6!sDm8{%mMnH~w+G`W<6gf9NNErAZ^nEpQTch9|mEC5zttIWEcXvkc zQIj7*`dlWVqV2F9Z<;P8clL5twfq$&%Lw}03pAC>9UMU=Q@YfHtALd3-d;n9qc#`o zhdTFMG0pp`jnt{Bo~Yrs+ONHd;e{8(O0||BXFcX3i)FlEln@v}26u|#2+Sd3%wxLr zl_>Y-j;lOJ2-fP9+A4Gw(iVHzcVE8z z$kI0gvYglR?V*>(1?q*{o5R%|7e@-IjZ&^4x-J$^gtS)bwajirKXd$QGDA0Y*39LT z3HrU!{TC3)QiD>JS+j12vMdTV0=oE+=_=+F%156r=3b~*+3DB6-=f29-|A4(V@Zjl zY_V)dZjAdi)oYYguw)?5>U)|{&7aQ`C2UOm(OM#_AH2d_w!a^wh=1 zq|CT2fFrQHG%8HnF@u1g^tSvCm+_nYdpB_Q-)}tK+Ip?yxV`}UN+&fhMYTvzPGsG; z^WNrNAW&)ZVT%L0b@QsT-%J$g^cQpQGY_}ZV7}zCETnP1fmS=kArH^o!tklqxabCUeXd!@g3a0Vp~1iCWU@>dx$j2XU%nOE&8#4V~KVAd@UD6H|;l% zsrEMO>{b`sgpnTGz~^SV9fHm^n^>Xgv!hdzf$k;b$T39C!GMSDQ$~)MM9D{0r@w#n zFd|>vv_bESKfPKv>KwbYT4esw?Qw(&ulLwgS&)1h6*T>0wv^s2CWmY8TMdqGc0ashx1_5l}WH6=G#hZmrHm z-h0}NW~$zwCaPP`*vgMAHM^Bfs~*P~t|_~o9YDNHIXSbNJ5GPZU4YxEVtSTwM?fpd z)UlGH(qrpc$8M-}U3Q_xwUTGU9_TlpddkP{c)v_xwh3T!*po~ws=W1~J=X5|yp&2_PH$bCzu1K(Z!o+`4DAH`q6Xl4ib|rbW zo*(P3bgIbpvrChuZ#$hE?Y#<^(5#P|_k~-K;7X}@uum*p42B?F@z~ZtURX# zT`S!DZK)^YzI-sry>)1p_;xHs%Rg4Od0AkE+f;D#TS$+z6O6vOJ@O!1sW($9bHO=) zr<7)J&e}?3(8foedR%#Rw^I0nM{KRX*whbJLY^4aIs3-C>7XvF*LN4%Dg#e#j7vZ0 z%(`?aLlSS8Cq1SPnHuYiFrF6#22k?? z`@mI%ukMp2h<7~BBTAx}dA4D|JWW#qCt~O@8bDK=vbw}}JySLylA?jR_LT{V!T8OJ zJE!@zc5MdIFd4b>RJOH4&ujvpW%a(T-_XYZ*Q@)OVPr3O5XDy1DtVdnQ)Oz1< z5dYSt-`k8J2u^anci|SP7^cRKSTwX^{ZVzf4tJf*n$bq)x-dgCXS`50acn>sjJ`8h zOq+;=ZPE8|VSdZhkaZgUwh=)&MUuVOkD2X=~~|@Hj~_Wp@-@) zwZ(Ef_CeFOdoIAF+w0@wT{n*@d3U(a75JHHn{QDmRW2A}Y4)V?9^Y8Hg20E%kGy*t zHw8P@{h`zC1?%wzC-jy0KZr(%+1Dry?Y7o#XIsfX4IN!`m^XMo6HUIYBDs5o;jO)eCg)fPYxVLq)2Nt6GEriaFjoQ;u z5nljU+MpRnD!Zm8u$C_IyuEK8MRlaH= zvdQztXDdC@^HLA4HNTOc*&|iI0bjetU#mfmCZJF}w<@+Cyd8B${BSKg5BY%Djecvp zOm;!T2;$~fs!$cQV&>N0fMkw;^(k1B;lYbjQjaA>+7f!mBjYaRk$&)rFV(i5N%z?v zNqM10ENG&SIDLDuv71!1-mOIe-Y!jlon0pM^q#W9ijQx0%~#^VI7EJ$DzIxHCH9x>u;RW@$qx? z+wuOeS|Qq26gbeg8j_+j?Y`jdb&zH3>2Duycr`hV2jcdAL3-SdTwKzfDR_S4BW)#C zn8JIO+|}^R=!f>GC1_z~xsuOA@vma~Ne#-AXnQSObitX0OGz|Oj;?7=OUe-xBP`FF ziT6CsjkVo^g;d(4+`jukVs1ZN*7EhM!P;vi#qY24- zXkMQRF7=o1?e5sIdP)4^z^=LF$e`DO&8G~NJFrMV+RJgbpLux1u5S4#;HA&X=mHPl z(>0Am0e)(l$D2XBNu~hR?W~}B2ZX@+Ay+HK+E^QMkq2YTQs?$bs4gBH`J!%rwIoL^RVvVDvjgvC{0+2e@g+ zlM=Z}Zds$2#qIAS>=#oO&g{5#>vK-Yh*k7Ynww7S-jQ3>KYQcMU=>=vH~hzEUp;X% zX|;&>g!gvCAxjCCj8>VSPbRYPMc%Sj)1ZHTXQ8j3Fgr>5g-=w^bH1P;(K&8!+tJph z=hK5bQ;X=(7wpe<`=sn1%%r?y(i_tgZ2n}%B%CoYO}6myVVCP@R4NY}shs7tx{{t} zEu*jF8gahrcDkmaGii=seR~UE}a3$n(nX;M46jijNk| zm=P%qJji6DR!K`$Y-0buDM>YlL;UhZi-xZ2-w{h~^YbTGTaAj4x0%4+$Ym@7{MH_SbIBQ`*3ZAVTwF?SK3UADYNYs`%E@b$foikPYXs+D z+eI9bPugUBA-`fq&1Qdt?X?OCmH6PDVV`rlU5G%`^v#F&J2bBty;biaPA)PJ3(WF# ziR=Ap_2~-XjvkrWY>GHl<1p#nmcikj+%cQLiexR5ABkdpC=ol05yG7`%mU|o*ILZf zcn^^C#^{-t$BVOb1<9fzm!F?K(e(x37D?N62C@et86JM{BLw|))zAm z6Ktu)d+JY2PnsP3xI$Gd$xL&rfB561=b+4s-m1lyNCq#n=~JNsy>j+1qMEkyQJB=_ z%dKbb&Sgr!^L5rkr-M^t?fNzS z5Z{=YM&-27!NewC<<8Z5T?-U@P&oEDa37nt)O_8zbJSgR()QDLEkV5?Y*d8fkI#<+ z_umgluQNC4Rpf21+kE1g3|~MW?HfCMF@DWd&$Tpx5UVN)H>@r?`b;$&m+?0Hf*e~M zZ^y|xgJ|Kinaz14iCZF?Zk-oW9?UYyP$ClyZ+>+5PiN{{@e|fdRi>s|4yrz+^gSv6 zoR%=(i|0NcysIx~ei7H)1*K*6dK*#)9D0=-F;=|Cd4GL6Z>&Lt2=>o*fgLxw(knUEAJ9TU`LG#w+Z|?ELlxtdWz@~HJUtfxV~O0wlRc& z@AazItgDr;=A~=XD>tM1&6UGOC@YCxm?vL}ucC)cWQC?X#%FM?w2h0sYaANyQi%xE z8~H5kO{2hEuiQ7{pm4*{yEjIrNR;L)A36Vn#+_m2mm68h0x#3;m}`bpTbQG6hp?X( z(C8gKusd8?4&x4g6V8jia@l`y-^zza^0t}iT~RrHgT+J6-Rq~XDj>9zr_Y5~uxXBk z76fS;yb0hz2^+L19}202H^NG#*h=b#qKnS1*aff{cH!bEG{t!NxMV!oU6uB57AMPn z7Kn#w{0nt&6N(2f>Tx-q7pHF(G_K;`+a6$tavA0Xah_;4N=U&-2|X3uC`=HURZSzh zH#sJHn0Qx`tfC=_wp_V3%-BCln4zY)M_Z)HNhU|xJyvNJVFQlU7PV9j7)`=D?r-cYcH*HHZGpY*%M z_tRnreg&_LLg~Pf9)LU65&S+Laolb=wjS|-L5{nn{|xirn*aAJfbUiUz!?At{r6n) zT^;}cyDb0E@`IK($we$gSpC2(a57y))5R{;#cl?K?E)CFY?kgNXex&w_w zt3Uqi#{TX}%KeIi@BjW0_E?MW|3bj1Z~z0wL4ti`1Q^o;a0bxFcJAY@u`y_cgIX+T zhXXj!4-HB`sf@@P3L7O(XkHfKD_4xYV$dy4aEa->F;rVYk|EoAc zU=t4VFWjbJ91IxguRMjpey`BK1^{}}f&TbP;f{ShK+LE=kpHLsU|>!t@Pj8l@I)YB zJ_xXC_z3t)c!D*+XW#;6jqfQ!!J&J+pWZJ$zRGy--+AMupB4Mx-S=nR^}%>(5RErj zGu$8O!G7C+QFkG*mk$BG{=EM0Rr{-E0C4%Zz6xMXv0$$5;OU{jETQ0?_wSYd>l%E$ X|1TpDF#h)uC-J|p`EUCFt^)r9McxBc literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/EmbeddedPdbDeterministic.dll b/cecil-master/Test/Resources/assemblies/EmbeddedPdbDeterministic.dll new file mode 100644 index 0000000000000000000000000000000000000000..74a8e4449a3002f21d977fb86a937d46c64f9a7e GIT binary patch literal 3584 zcmeHJZ%|ZK6hChl76c^_RGdm5t{{rDEH0W&jx4Ys=pqaY*f^x@pXd5=ci;Bj!=Pyj zGaD^SA~kI$3$w{4Kj>7Zj*foN6bH*1Dr?M$X&S#&HkoKz_PcN2vWsKoG=8WV58QLl zIrp4%f9Kry?%SHhon$1U1dQv~iS}V;WY_rLvkok$O+1iB?~OQ>vyXG0%4t|GDtuU$ z{IWa9d)=Xsr1Bntms>-;7~&nZEatdr4(G8WXK2j6q;7%nqS80J1~eVi!D}*&1x&UpKX{(0q~0$<|j}J;?FbLrOIN+ zuRx?K;A3qtH@e6PnH{frUSqWbb2D^yPUf~kA+Dz-|Ug#?{ z?V0Qih~$8019%3wiN=Gc&{R#fP%7n+g)(Ux_}x^Ej0qid17$*IsH2pHc%A0dNWRv9 zFqeXgSCRvwhkSx6$U!kADyrxuhu~@T``w;^P^zM>o>o<$aw!-V18!B6LiIwx-KI%O zY`wlUq>4d-xnap821K6sl@am2wdRx6#MRWX=Vcm3n;C;WKyjp9GjaNmh@CQ^EI_{Ph}(|1dY8jBxZ};9w`5~! z_u{N3<(KnU*>=Ml8TNUorp{4z6iZ6VCE4R^@ewzHPYXX%pKt54QL1%!Q6E*0dD>(g{Gc@BS*_tk8kJ*be5j{v3nbDE9t#X72#=fq;?Pq%r_6~IQ`narZOXe4?7q&U(){Jo$EW@8%bZq7Hc`iLtdV=odJ{YI zW8aPk?UB2e>5Q5U#o$fkqNU&!R1c{dU)qJxtHCQHUtKzs@Y5fW8&?Y(VkNr7ZaDVN z#ghXHhpcXrkw?V$LO{+CEh9;Do2=c74On%20*+STQE@`UtBuvkY9^Yk#gw7~1)f24Hvp9UKgJ>S X4&AN}@R6U1j+wVB;hjAHrw;rHKUTz@ literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/EmbeddedPdbTarget.exe b/cecil-master/Test/Resources/assemblies/EmbeddedPdbTarget.exe new file mode 100644 index 0000000000000000000000000000000000000000..8769bc89e17014bc87b1048e4a00f957800342f3 GIT binary patch literal 11264 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 Y4DoxEo$lX#+~4+lwEh1k|LZ;Q-;t39+yDRo literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/EmptyPdb.dll b/cecil-master/Test/Resources/assemblies/EmptyPdb.dll new file mode 100644 index 0000000000000000000000000000000000000000..53603580d8a2149f4351dfb3971368e27f5211f5 GIT binary patch literal 3584 zcmeHJ%}*R<82=5s(51Dtq=vK+bqW}bF_TsHpq1zXOA)ga!UAm!NtxLlmuY5a)|q!J za4=kqG3lW4=+Ss6{+@ScS+MmZ9z0kcc%S$A{&;8R zd3WZ`>&O7ea_#N{x3~)wHU4X~N%e`RzBz%d-tDuujPmx`g;g&$n^9Pg?1ovjgCJC< z*||N1`OQtp}}KOluur~CXveu`JDD2}RB>)MJW#D0HZvJ@As$n`@SO08Jol31GI zo&$Ej2o%9q`z9Q^43UxUxqi1ZDJ?wUYPlTvGkBkPO5;;dcobh~i+1bAFiMM^4Y!%6z3Fgg>~TE6=#8gVs@e9uA2bz1eh?fCAP;z2kq$YNRj=yCX-#}6td^_y725GliWGaz^@^J}Jkz(A9r2vYQveU~;YMHl?qH)hK)?HfVPwc`!PGo&(0r9G@!& zD8D(##iN|Blqxr`U-|g6CpOBTKDV)T{_`uJh}*=uWz}dd>yDc>Cn@qF!*|keSlaFx zCNhP(AKKq~qPaW~MkU{$vArO97hPAsGosynnlbd$yg$mJmr%iF;z`Vtn&wS=f&4V_`Q+Bc?d;F@+VfUBrs%bFmnkZ< zU_X?|7>sHoVjPcmip!V*-a@F&hV|@Spw^}|rrzds_oxlhFkfb6co?in(aNK|{(wkp z+9r?oUjYtj;CWVL?Ae!?Jw{c>X&%U9(l*a2*s)!rZA9x%EqUG{odvwe8^_SyC~X_C zcAw{Eqd^{wFWD5mYLv@u3OuXpDN|F|))VZsiFI939jmm49tr1k?AcT48pH?7IpySo3|lcFYt|CkDxdjURa@Ma vX3eoKybu8tW?&a#VBiGOAXkCZgJ@js literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/ExternalPdbDeterministic.dll b/cecil-master/Test/Resources/assemblies/ExternalPdbDeterministic.dll new file mode 100644 index 0000000000000000000000000000000000000000..ed05cdf743ef11af1376f3176c72de78e149f7a4 GIT binary patch literal 3072 zcmeHJPiP!v6#va`l5V%AHYU~q$ief`ak)zM0K#V$lk{2z|--=KcSE z?|t7)GIQotqycnrZEpjY_!P=3{?BZK?t}Myau6TwzubRGo4(w?uxf{TJ@9LR>FO2J z^ZZCJTYAv&blcMlvqjzYtCrE-ogGX{&rJZ+S{h5I-}j6O_<@IIyG}UdTU-M#vK8iE6}cD%wpR-&;w16Oc@HcWF-=*H zcVKdHs=#N7`hw_Vj$h_eh$d~aFNOW0{H_h-aNJ*K>{FwXdTB1{ySaccLD_`|@gDnF zRJ~)9W0z62A}erh&kiHI zf`V0U)M{qgu|^|~wcLm-jQeigcFf53y?M(q*OU~t{PPVjvRzBU=qlTe9j&*#yXqTN z$3byDj4T%gA4VnegG4t9wpsIhK@m1hNo6BOU5*vuNePhUibu4$RH4y}_yPfvQEmdbqmLTTyf$d#9Qz*p9;+SDc_q|t5|jEeqlB6pARK&pB!dF-RHkK2W@7KcL|SkmH6J2SB-{efvz`QuyoDKcwXNBc;f#mv+r;w`SCYEV377TSZMdj{qBOMvC#h&RxSUaq{grosZu= z(S=H>5%MJzu}nUJc}i3K(w?F|MgBzm)x~EWKm957_ma$5NN%{yyqyYEG*&ecu#U~| zg~gg4o`J8z236Jqy(X<8{U##D`P5?C?D&*hYQz*V%BH<`jY@B*m>ilvBPde_?k6H` zC%(YlLsV3q`mTL+#^!k2TCq!v4H(_RlH(iRT0jA}F98rDF zv6fF94dRJ-Lc62kUbQR@Gi$JCp2qb8uo|1 zVh5KLW#*+91DOm8FtN~J1{EM1WRS9Zs3*vb5Foz*#COWc2O0K#$vZv?UA52T^atB>u;(67X&Rp6{95Y?AOJDbW5H z`(?oi!3+od7c(tf5foo~bmBhOEjtvZ7CsHy%fJ>~SzMBu%f!gY#KZ=49{{LLPssoP literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/FSharp.Core.dll b/cecil-master/Test/Resources/assemblies/FSharp.Core.dll new file mode 100644 index 0000000000000000000000000000000000000000..02d078679f783c7644e28444436f9733b1f2f627 GIT binary patch literal 1636016 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 T$UDeg^o=17ddlCmA{essktJlMS5#8E%sK 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

LqnFeP`YTH&$F=79Kt%$H?D@T!_*jA3l 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⩔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 z%0A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 literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/LocallyScopedConstantArray.pdb b/cecil-master/Test/Resources/assemblies/LocallyScopedConstantArray.pdb new file mode 100644 index 0000000000000000000000000000000000000000..eea50b9653d9f88fb2bb4b7bce760a5ad2b54e8c GIT binary patch literal 700 zcmZv33y4ADFbrgZbxBPsO=rtXEio}S(!y<C7;`RlEEsoMEf(>{Ob%$?|1tKec&*Ax?WHlW8~ zHEU>bYEdz3ab|9Q9=l^fflFdZA}iP?mXOrk0wX;?*ATa&#N5>K{Gx1~FreDZ{5;z- z6FqZ1Be=DWCBT%ER9cc+478jthOyyn!{vsX4G$ZhH@s0u5}X-YH{rKf;uFR*v!)v+ Xp9t8p{aN&$UIG5}Z<+Jn7cc+-xJR^~ literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/ManagedWinmd.winmd b/cecil-master/Test/Resources/assemblies/ManagedWinmd.winmd new file mode 100644 index 0000000000000000000000000000000000000000..f6e1d4fbb5561fbee0cf62efba1702a77d579161 GIT binary patch literal 10240 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 hvW(A1k)d9~!>&hCuy~0F( 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

buy`x$W#8(KE8x>Wfo%jA5!;%)R# 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빴e5hI}TU2K$W0?T*iA z0tJ1>!>!k6)+Bk^XWo`R1E50V`^?tXXG*cp)SQ2LXA$`fiyz<5mNReayDs_61nD!N z;rq;5^jlG%0dB}=@@cToXx#4jj3!XfXFS|`eP%q#%Rck5^cesZ8sBHOu|Ct9<};rx zBA;RLi}}n<_{`eUXF$XEnF;h;QJ(>B$Y=6tu+M1R?)Z!*P|#;Q+-)GjL--`MSa6>+mPlJ6% z<95eqG=YLXo!9JsL6Q5bNxusM-9IsxQad$bbi}rEWgbm2-yqE>_cr&zlY`x!5 z&=1zWmir9_4>kB6`RK@gL!q;}GjzSK)HP`Mx}H>ru7MlUbv_N&wZ=_!-N2f=CQxvE zdbstD&-F-N9-kvHKBp&Vv;b6S-0_KbtG2V_vm+j#_8j0yBH*0^g#5+t_GEGHAnVrL z%hHS1YwNm~Wql#v(vWX_!()Yx@EE@>fmxb)S zp8}vlUC06&hcT9ep|Mm@Eh7$hnV&<*4sI zmP5&QU6W)?1}#4(Z%n@x&40iR#pHY%9FsL}cVe<8P%tKYxb?>5O-Npj$!oy=mn1O@ zK!wJ&|FY!A-?R4bC1Y}HWlf^M@46x$Pb2&R*dLA$TDzA=iF>k=du5!@C9-r6nSuIU zVvgv0AFQ@xb*mjhcPDKsWE>9}FHK|wP@(Z<+$mMY2|*dRZmCPgGl+xZm!zvO6w5e# zeI1NWX+Xx!gpBJz#>)~J0aR#w8Fx;Vabi$L`bK9xc07QxyD#IRM#k+Lka2S%<0Qy< zc_Jf#3XL!0E~zrE7nE_k`s{c%ap24NYa`=n4am5KkZ}XZSV?Lm02LZn#!(sLv9ckH zh_N`?AB#9-11F5%B&V@jBTU~7v{MELo*j4N*AI=mErl!_OIZL^XbQ`+N%v)$+ORBJ z30XFSEc++E2cSaZ%CaKqde>Cn+ngxK;uZFx0Tby!q+eJ) zdR|&BSJ{;a#E+8C*}x&^_AQMoe9J%k zYJ4@g&Pi9ZDNUf@oX^9}pYy?%n75h#oM#Q)o4%7v{r4kHMUlQT66c7GFUW7fVXSP5 z+Sui_8{cA!@3LfB8XR||y!f20Q_QBliNOUfKX<^UG$`7H3atG0Uc36nHhM-n?xXY~Z?-?c#!KlPbjQ1|2Kj&;OO;D+L7J`Ika z8dt>6hlyWzpC~ncF3fMJX|{A!{u30Rbu+Pt>g_05Thx9-EslfSedgx$B#Oz%kNgdz z-1@_*WtdijF}3&}3O{Pm#5#W7w;3ati^gL_XZ3M1bk~M*EP^t|VoS6#`M>rJ^*xNm zt*K_Kj@p7;qp}VC={W{IN=Eo2R&R~Q)4xMZ+`%Ooy(7PW+t4}N5{1flsG*!6`fl8^ zE8Fz|_Z?i#N5Ps3xS^PkPlIEE#uYK)axW%iyiZi`-m!j|9_bIhPBl^1NcT{^k#1tH zyLUX7tk$)Wv@>X!In2qyIm}K%f2Rxd8LtLud?{du#wyXxw@4VDi_gcHY|? zdnNSl=Y=r1xs!P!!B4|jjb!cWeB+lH?!w>?-??tTb13=URq%VUrAUIl(g9K;;P+a|FMtY7F2C0`$nVec`R%MePe@&xB=J|*(-7H@ zztiZqqVX5Fq4=9mgX6Epb>eSJv>nBoNqYV+Vome7e$BNPa`HS`6WX6j(dyb;;ajU$ zk!Aa|^Jm4AwE~_i_rSAmTZGSAZ1SR$>*V^L75WZtVSBx+pEZ+ASIA!7de)S!Grz;@ z`o>;K&cn?T@#bUiwj4jS??tybsgYgtS^fAs$u)Tq%dX+vH|DVs*KPT321ZC+UUj^53FP;InuDDl~4LFoI&xG+USVk!P4H4{*J( zCE<~Nct74ro#O10V*Z~e%cp(h&929Vzm2w+kmL7K4geLJ!g4&=JvqwTH7dv6LXL+a z2iKVZDm1Pfm?!Na>_PLSN0|TAc@hT)Ho$x^Ue7#fy5RQ@QttpNG%mlH{__~~-H8AE zykWiXBjos_lmkG8#+PGHp?BJs{RwtD=|0IPSdOidob3z%?6J^yqTFu~Orv7Ml>Kau z&uh(*)Qp>MW^!|9^?Tb>yxdI2OVIG+ zIrWRugmfMKQxdhUav)?K3p|CCJXi(@bryOTU<}B%9l2x+pPPHmY z;^cv|I1XSQ-@sgrpY&h-q}+L7XLY}wDJE|&V=~C#i&P7c9Q3!TUNwK|GdO&9Von`# z8n_&%`;vTm|Dt)`;T9n8>(sQ9n2a^ge$;0#lgIR@GYvJ|Au8_ce4kiNyRY+J61IF0 z1>=lwQ-L4xiW+^J3crc_I`KoseVrc>4_WthqI=4HoktLe>)g+XkaK1YK!wK5?>Muz zx6SW;_4;$=H7Ef)Lop)m=))O`YY=Oj=gkEj$~C>qxaU8tza$M+_odAdbN3|> z?R|;(yL>Ux9A>^;itQ-57JVdPFz;W2cYea5(Yw8TN3QJi2#;lN zUW#Pr_Ywe9XnfiCO_lxipzL%-0PKDY=mllJ1G0A|vIDWO>^0Yaqj!7xhFsZ?B|MhB z6|(dD3IHlJzU=#@%Kk=B_Wh0B73c+J{~EH7+SU3z5DUw`o^N;bZZF@QEBkST$Fg@o z_UQ;J6Nun^02LZncAR~knIe1TUnIIbE>E#td`E9SXa?o~<%QxqdO(cj$7Ck{)K&1# zYM|P0KA1NWGryyEJfXA9eIPTRzXedCab+GwGN;A3%A0I%$VywgHopA;w1Tp3PiC&R ztYc#|5DUr*)NnAP=gN3?0->^;{iU1$Dl~=V{CBFHCxTW`&e>8|%pdPl_jr1^^8lwjw7S=;eu14>A^zcK%XFUvu9{3#? z02P|zdUz*K4`+a8P!F#`56x4o9)MU_4>frkz3b7#nS{@JSPFXJ_hJB4Xo~CM-8?;< z1)4!U98M~zUXS1*n>jwsNx%RkHCoZI_5b@0#a^`q&S)mix5p4Y$Ob9hd5C^qV8CPiZaj#D3+u^J+cbJ0|Q`((nXIAVMQ%S&%$`0mu1idO?W-;yNpXep4 z*8$O%yU;V~KPm5pLf*Bd9{{M(xbnge4)Nu^J@$ij*blJo)GgcH1kviT-9WpPfubPfC`PvKh_9lr`cj-2qM1=30ZcgK8K-CJeJ&}wsH@jZE`+DZP$^A z-^+ymdN0u1{rrt5+w<~n{Jd1ix2cp5K!v8Te4ANA@wzAEqt`^DYMt`+*`rpzkR?5F zV|#W)JM0#c_c9^x7E)dS6`I2GZrOA8JT@S2xo&%2F65gG`FOkmsL;6bg~r>~R;(Bi zHe8KtIL9Av{{z$hcq`w7k(!nd<@oxM;CEYT4*(S!m*33s^&QK&^goQR!|U|F-S({Y zKP{Q(aM|PQ3L)S2kdNyV02LZnzRbL|0}+VplWymwS0P|MdFe_a%Z^eO02LZvmLs6| z=9ZylUC;6UNacGh%a&vxs(0&(e{1fg?GslF?oPGcGw+DPXPAC00g^qqG!S+wuUq7vy{Bu9_g+x1cTChX&& z9hbQg6}UEzkk5{!M|t(_HA3z^Avec$02LZn?oeFci~8|gsZbscypxQ+l^mV?(3@@cTl8dt0%{F3xUYRg$ip!cC$C!R~F>9ePPy`0%o zufXg{KU=GGiwSlKqF05^!t@?oY93UIk8RDogV<3XZm-JTghmI^Lo+QKKPN=h8&F^S zzIZ+9jpy|TOJ4*~q49n3C_4rRn0fsn@I^gkRIpEhhLt)2bd_M*|guNd_@{7I1 z)bS{5xElq(M@W7FRA}<}oeO?%!&BKGFvt78i66}GF(LhSJtyaQ!!zf2oz=e)kuJL6 z&y9R|gdb0CqTh=c_TW36hFVfmkbTrvE`@4&DFs60l z(}XJHWNVp@(TwdIEy=Iv3@!~UIRSHEsWxH`EG_Yj`E}})4rdvPg;{PN8oTVYK_ zNn4u-wTejUAroF4O2?7^u1D(&QM_o?N_E8Gwt;PQ@kK{#c`=H5QAfO-#p_w?M`t}A zjU)NIe19|f635v2a!diJ(D-9&o{g~sO^iJrV=6tyvMAk-v9}0*PXNEOlXVgR6&jb{ z#YyI4Jbq84eijElvOM%+@&WUD7i>iJ1Fq-n-BuH$mRdTrj`LH&-^o&+04g;0*>)}3 z*XJok_1WzlaI4_=G|4Z33QZorr-R@09Kbs5b`H2r@OuXMI^K@)K_<6eN&PI2%~k7~T*ZHT~;4N6`{t?LyZ{4j(USJ`MnR;isdFGN|>DTPg<Vm$3Lh3<%YUI`P zbEoTP0eSW0+)U&A`<_sZ3VC(^y5x25d(wI@xZVTYP|VM#!7*RsikSZ->E>kef$VvV zUhlb{P+RmqX79jmdG30Tezr~l6K2{Jkhb3A;U@F5(fT&N!L0*Z&3$~2)6k@`t>-Ov z;^K}4y#|C5$D5!0f^^9-^ye6-976$AXspk}cMwBQvEy{GiJ^B>Ka1nVP!^zI43#nd z9>L!|;BPuPw~6rpDm3=l;BROxf2GR3%pmx~T5{mMCilVz=KFjYiSA#f$GVqW*l{&} zf*n`xe(b%1@B6^_-U;6TDl|Udr%Jt+D!;1bJ8-W`nD2WG-z6_Y z_d^F?MdYaTh<+s!?l(S9;UL5=MV0s4f`ZcQFc`cZ;?i2j}4*YV?0#KoG z`9;q9p~vsx3Hbk5?pLKja%7ds}p08pV} zU9?1-kX&bZx(Kf7(mq`m(d&zSI$9pYKHX4KUDPqSG&UMYUT*g5$mY@6px2^Tl{5D1 zSl*Kl)bb+q(S&^gtt4R$j}{h9vK)rT*kl>K)GOJuqi>5WO^@?(k zFp6lLn_fl>#rerwhkX2ZLZ-h+ znE+I1e3{PmWx~1zHe8?UVVMq{)qqUD7cxCBWdcy4ab<$9p6AIFT-6{EUx0{?uP%}8 zt5{VjMo1nM=ol_F59xi|AFqJIJCmqNPj**Lw)LE0BE z>t?+ok3g@Klad%#O4sXA^Nn8N7Z(xl7wWYP$06#t|7=%My}o0mjWbMfC)xPm+DkFu zB(-a}=bRggQ4a}UcvboWfC`Q43u{8&6kpKsH#Yv?6XW+vk_}?0=+zF<@eYRP^==rxR##`7X>|4N+js3lyJz2rg?;}i?F*nnD;(ET^=jj~TpxK<==Ck=_3k8J0;tfiUd{T*r9!WC z|JmErF-FQv8AdD1~?)ei`(s9;4sPJp9+x!<&aMNp+kSN6y1_pMvvn;D+Ym`80SQu5r6F z57z{=-Sg++9&Ww!@W)ABo`-)1AK5qYZ2%P-_K}jlbMw>zDt58vE)-8ud2OS?eukuHs^Dm)ue*YFg zg@$$B60J^pxFS>Mq}$3@R<+6dx6t8{)c49-9oF^k8LMge!%0mYT21{1wZwaDs0s#` z0_P*K!eDeUAli9f)O@gO3*HfneyruuCvJMX%!G4p&P-i1sAo;j6NBEYDKtaz4gwHA zhR=@Zh+{)*G*1YdQT6ZI3_yj(x7k&`&Fp#=ZR4Bop*ImFJ?9ZNJDK>o8hu^G6swUt zN+~xuvJLM(LMIbZ2#0i3TNlqip6lYHiN|Xejt%daTVq2#v#2qewb{%=LpFO-*sLUN z2B1Pyzs*`b3d{537km3AuZhxZRik@==Zm9Opr@^(q#!YH}{ZZR8shD03LM`UM z?_xmyHYeg4eDgQVWZwBR`9048M8 z;WFr}=A44=op!bke%#fvUGlsND6`-7o)njzPsh^H)2emwPXvxP4bPs6e|6i=DA+<5At z))h~mBVXrux(dcL$5Q|m8arNbo(}Q!r*=#)W#XxP|JbaDA=bt32s4BB9bwGp`Akyg zJHj$H|5fn2y5tu?g(i>RHK?B(|KZ2r_f`{|ncwH)I3)Rf7?C|KHg{IX&!?C~t7L9W z0!cq6Jx{+CjY+@_#iV>19FsJzh)GYA%zd3&DD1y|+UZ@r8wj;Eo|!wlPJKJlcSh{Z zP$hn)r-PR^-RYC&Oh>G{-?wi(cj)4wUvsi@XI^;rP&@2VE^$$W8LO*C7d>RwT3}!Q z9geW94UJXi>7Dm1`zf`Lhnh21!S{bi@$R>%Q~7S4NHqif=U6AVY_sP-a`vm8S#L%u z%d(wJBOvot77x`^L!4*I(fx0P&H=nYV}WDV`Z5LpsL=Q^;5Hkx=$a_hfE#%+K*pKB ziDztxXYlA<=w!0gJAev}tCNu4bMiDZ*zG*MK=8Y* zg0j(mh4E(+lB!i>9(@)dIm;iY zn2Vg{cPeJ5^a@wZo1KvFm-Z}wXSIv4>02aXZh|4pXIJiptm<|8&756X;l!G=E6Y#? zrBx))uIN4m&#nMBG@r?*!Sfl7E9NtYk$=_k4v8k9rycocS3KN$&#t^d@^a03ApDNc zQ2?mWu-}*!W`icV*uGm(ayQ&;{Sq2cSaZ>S6`5>wRguxZUdFU_Am6XXx`$aeS;> z{_GR)tc1%?(n@fnD#xB#ouSzCrjYwkDK~%$jW74F(&WY}g!X~TqLh2Xlk1lI-$L%g zq}%{1G``%wPLmrImzKM_DCPdBe!2f6|OUTAE+C3Jlhbj|SSOMaY^!-`w(4jOZ$H}i74mlX*i6r!mTjiQhmM%be9ceet6y`*`$hFL_p8&hnX@_z z`_S9MhmMs#1fW9W`_OOGd?<;}>f7?6^M2TX4=pNNoqa}kZ1s+?)$!6+04g-TtsY3T zRgzPF@NL;@#+h~6O4d~G3VoaieN0dG#Q{`kTz!nDG5NcoK4`9dl2t>Ta0nN56&3e! z+>`VF^ffQeIn&O{5s+xx@wvlyP3-8bE_OD}SLn4fcP|ArdA{;{$e`Y%-^_evCiU>n z+AquV6?4~#-j_0cwx-!%^>OOs-|eE)ZuqVfoE)ILPV_Umf5Ug3XgUSwO~4J!oAPP! zyh-DBXWpa<6r4ACxcT!Y_}N9|3+|pr#y4_k%IElE*5umQOS3)d9J05*4l-q%hPl?L z;r)rx(IMxBYLWNJMm*O$4`cC|WQ_qpg~lC=BT3!|?O0q+?@yFkE9cums8OMp-3iZp zmt53h&V3&?XF4kgj@+G)+n>4Vxujmf?BKI~{9SSxXFd?JT?pCu+$Vqv4a-)F)+e4H z60*h1Cdpk0SVsX9=Ah?AR%*PTAHR4D*?&ZI9tNHC6IprRrEzv2Gq$nV_OC%*{tE<1 z>uE0#nD{jy`u?fJC;caN_g|sAOQ5@(6TbjZp>cJG_g5eBb*BT9Tzk6I>MS`KY2x)6 z)c;ZRUuf%4tgJtsOUm*Oz9O%Br>u>RI-;ZIht9$OPw41!=xBDLBLEc|)=>-H+z>^7 z@O5PC_~hM%9}y*14*cmL>h}wLySE45TVQQmcAg$--b-*czwJMhYvZGd5B-gpo;vrg znb1?Jea^2r-y8b!h|Rkl(ahkx2_FiZ{1`Twp41iqDm1Q5P+L3}v;5C5 z`)i?lp4S4X(73wCy!MHp?&+PkWISAFjgSlqj0wCK63Q>B^<9!~($@`nOk8wfz)B+f z*zsZ44XuryTsStm`l4DJA-sDLD{p*!ENpaxv=M*`P5m~yG1W#->2V@!fS$3@?27|7 zf=*J`cCC$cp6U4*cF-lYHVR~wJR5x?Y;=pX5r7I!{Wkh(s*RprXf|5=(twTh4Aw?F ze;mm=J^!3B=Jn(h`(LB)WU)Ma) zz2lSV6u9HlL$2qJPwv{-9iLwR9+3BNt@q43P5Gf3IZs~qZadwz;QSi6q4{+_4W3_X zTrt1)-=zu9XPtLxv}ZMPm#BXB9#oxG&wx(#95?NC5)U`~_;WnI`0TfgDW8+xc+UF( zVhX<-0H8u+$C14^^iMXXEU)LhmETc6i-UT^c{hNWZRp<6F9d%NfKHJ_K z>hV{qJj4uwzeyD5%pAg5gP@w#Ijz8aH*|04mxAv{z&GC;3ZO#c^ZjS3*HY!tTE0Vj zM?tu^>fdX!G5a|UVLvT^V{uv zL%$aMJ_&yL-cSG)8kb+(8~Uur?^Dz-aBnE{S@_=2=P43&O_6yJWc>5!-_UPG&!Yo3 z6esg(aGcb*-HVg@*6Bv#q<*%Jllku)dbr(+lhFV-PX1N;GJpz=>l^UpzgXW`!Nkeu z;mdq9Pp{3xm;34SsEQfx_V-_!1iyci`~s-Z302P`%eiwjW z=lwt%E8=_nS-%Z@U!}7;@kcZs=~iC1E(J+{Jhl+0MaLs>L*p@@29HOLE5@V$u53o# z@(Xgm^p)A3c~@35s0VHSyIme`_MkQMC4N^{);1;5E!Q^xl0F5XLgV|?b9T&*He>e9 z>@mRno<;6a`#z{X#hP}`Sn}H{`2COM7eIw3kKeaa#z6c|7xUZgv*K-n-*+Ux04g+j z{JvXMzfW{mzwLtG_a(moDl~cgevqQyIL5Gk8;UWdD=5ZHl`#e+{TS0hzZH!!zzxNi zd>R~MG_Hs-PgCG<-$4taBH@S9$@Fu%K!`*te^_7VI>%TNtIJDD>8 zsL;6lE>3>SuB6e3Z`S(;kIlUayLI#c8^Xch#l+`wISAz#q?P090t~v+aAg zzWqzoFQZOj9vg}w49`0^`w<; z-RscVwVQnC{tfUk2ma&maZ!MeduTD;+SU7JP<*b0^{M;U$p?Qki0S-C^O3o}<{{U! zzNWhtTweojD2L?J;2ffHMGm2Nd5WGFnJe}eb6=1(#?)yc_xo&`FGlqajhGrU?Ou}s zq!-Qyiz6QJ`Wb)_P-^&NLrOcI@T8mnGh1cHVzU-dpAsE9XU-R{qtoU-OSC zIQa(@5S?na`{K3Ej%e0lp)(2tg)T-w7rZ71phCmCFn8>}D0D&ZbB$zU*|o%+H959n z!8JLVa|Q{%mzI13sLZE};)3s$z&GC^4WL5f^X9?Y53BV22 zf%!DJ4%E1!4!nr?@A-4X`Z>C;`w;5SIyda0dL>}2+q84TBSAQi9(t zB)|K_AD;j%&8;ZU8G&uHZToHQ@ zBOTQ7?!6|UgKGY}_a1KkJ0#NX%aObsSEs=4d`}F33XN;`5hTm2b{wsYxJq+ZoF~S8 zp1Tu)_@0;s?{;B%ZkkFyQqSEk%L`eiK^8t+0H8wS%7U{6e;2Z}RrW9<=zU|SHekMn z?oAgIk)Bh|*xA}Z>Ujmh+g{*}Yasv?8kaZJLa%we?M?kM;sNv6?RYR+@VgKAtt4y2 z04g*tzoUrXe+YhgO`|e{2smpQlL>c#yO!Y`5t4Vzut*=l9oqG$g^7|pDQ@brj)=ZV zN#&aVZpn&5mi?se0aR#QSwgzsKSlSmAakUc(UI2#Vq3W%jg%yq**bFNF`;*)RucRk zAo&GQp~>U-K=AvA+E`ri`Q2z*fZwiXqj(SATsBV^!;MJTuZhLd*UN(cPVhfH@f`pa z8kc{(6YVK!v8Te1}0kIHI)QzGS~DY+i@``s`6FU&vEEbH@JK z5$&*B$ev?`ymO?y04g+v8+h&bEj1Vzu%Yk08pWE`OS-HUZ?+Ue{HS*l_8nu zaM|`)RmgV?L4XCFA?SoSMh%t?d_AZX@-lu8A~#AfcuF zIB4@1N0RSc)4g>g=~3SMs;djRe<0-sP@!?<&a~kPJ!r$n;iTC%?5vKwj^<9Zi{_rQ zgP#1k(;DPUcCdA^K6DH;iwT$6#tf7QuVh zm>-X)e}`&%<by2wExa-PQr(XPE7SX{z2_WE&C$);1fV^E z`VV7%6umFryF8T|qR`jySYDSXM9ms>ESPR?DerfOIcltVSdC~vCi?v>;-OS_59E|D zpx(Wk+sYH^U)??SCg`*|T7~+yC<-xo#zg zrT4@`v*!5wo+m+1SU$-5Zu4N8qd!Qzy{YNX8;|E}-Oxp0z3E%?BbtqJs`ry-t1m&l z7ePQE#-Dk{PUQ6i{vUVW0cKZiw0*sMx443BFc?!zzu2ZX8`C=py<>V0OJL14-K^*> zKnNvtLhse|9!Ll+l%@BU4uOQ;1ONLH0RZ5G@3Kg(W$h& z`u$9iLk3pHr+khi84HvAvvvCvxx_QCd2!O#ZBv%BjOO6~7LBE&b`I_~n?Bub5Y(3S zS?5ms9co|K%X+&0wXbUu6$@9_e6Rey3|+h5MLsT7u6!4ny2OW~D(@RzE=T#PF5zfW zUEY5Mboo~lMweuClo)xlH`N&4D%DDipGqxkxr*ie+8xCX>=-<@g0C0(x?3JxVyEZ$ zx+77s2zB?*EZylZXqgX+A78Ay@suCc-NRQxcORfIx+CL%Q+K>yvF;{-OLTX>uR9VI z3s-lW!EQdt&|UPaN=B6@q^ivMhHo&&SK$3q-MVA^k5@srAEGe2C1X{8R%(Ew;u$)| zd5fGeJ~NzMIxE{T-c^74YD`~vNhz7WkY5{c1g8^B7XG=L6LGQZ{6*gA{I#Mb`16;R z-7tTBX!@`=E_?pElzo;lf7Pym@(boK;xYXv^B1pq^A|7V%wJalL*D$w>KXIbN+5}C zUq{=P_wGqlEX20Wd7b~Vw!Nr7f606IzoA-~Jx<@dr`=wKaq(|mck0TNo!V{UPYJYs z7_?SDhpN+a6B+q-Ej=YBrE>l>_~K^jO6_b!p~=9H&AD+Ox(X_Zu5R>oMWSNSysj>y zuJqJyXCLb79O&vJqpMXZJF2ULu7$2HL}7GA#u=_F3bjsh8sii*!T9sbYG4xGO!IX^ zqGHj!ZZ6K$&BsPJt5bGVH-}ya-CT^q=!T3lTsIVIb;CI^s+%>yB)YlH*A0n^Mf1A3 zgu1ycHpV_Nx>=L5qq^z2o_2%6=!T3lTsIVI$Jl@T3?z={7?r51tA5xG@c+B`{-5r+ z!T+y?i)H;kd87V+ZAs(CuI2lUbL*p{}YetBk}*d=J|hK z$npOV0z;nvXY~yKzYa)Zn-BZ8NupvA+U93QFC%J;2mW85a>DbP@1$CyJ}rr-*QM;x zHVL#o=Z&zxM+dBGk?2S-N3vTA$~8S5!9_ z%Cp8#C_Ac~MQ(y_)<9u&L&m0c6FZr;VS=ROh=PF8_xnEupXlfbUq>V=7NL&5$kLHM zfra*Scae_Pr|hVXhTRMuEr-JBh>Smujwrc|jy3?F=;$e5MA)zM7Tpra*G7#)%E$I%fbM|9Lx@4N+GA4|G!)K4co#*g_o!lkl4pS)3@zp*9w zK3~gj@cCaEz1NW5%F0>2NX2LP{LRs>BA-t@reDP8^P1=Lc_GK=zXl9>KA+VyeEudN zi9NnWdz_r^aVJr+aP4s{#{JjU9+wP!etOncFC?YmKKw+rayshaJq_j!H>KRr774O` z9yC^ekZRNMJ{g;~#iDqhLfdQSBl~1S`@oNF1_sf|yVS`}Oe*T{t&*r%xH{oF#Wzu% zAldya1nB8c)+wkDyp&P-R@a%jIb}xmvGc9a#~~<;KFG)=^(%^>f9%r@tJp!uStp~- zTYyd4{1>)ap8ZHvEZjCP0sP-Z+w7jX_MB~eY7F*y=0B$GTT*tk?ccHO3*BbhPR1E- z3lwU#!+0ecvu_0^(aqm|-H@nQG_RZIGj;R5(aqMB9o0?8?a<94D2!c@afa)LLalB% z7e{ro4VXkX@B6wTQL$)VH!o!B<_DvjNm@3CCG*)y&OrN+mOG%E`A`_$ka33VhC;1w zI0q-X>8gK?`}X23A$Ka{+!C(8Y>R7U=Q8rjTm~P?%_UfGD3&2>GMYD?-?+wm9^{nV zH++D1UMSLp@~%$48=KVef6+Ta zjS*D+(_3I;%inEnjEuqaOzhK14H+rcYp>l3gRH;~4}rX1cwRT=V*iFQ*Iu|*)}F{4 zwWlsi@a;*?CJMZRDsVTp3t6n&9f(7$g!t|3has1Gwf+^ki?$G z(4MYJ=Rgt_3)h|)gAKIyG{N|+c~DPy%r{rhXw|ubpHoI^ONqZCp!)E85a(a=ZYA+o zWVHT@ziZd<3Ev#T;pZv$0aY+BO3d;;0f~x*;AyS!eS)MfN7NF`qfw80)@b`{fS&9@ z+L!gCc<28UY@aWF82?H}ij_RX2*rSH{J;ha4P`kS&w;#V(E9O{~M zsCQEND?qCnKHE({Jed4zCHz+yKYV3UZSBTtIv+9t^@gzCI!V2&Ouei5r`mH3|Frd7 zn@CwVBE{r~iFYQ-Suc@uT~g&Itb*5k2GmB{ImP0gnfyOZ_^;=kT6=Cts;wWnlRs~C zLs@0VIeDYwe6l6@<6O&b80SNQ7ta*6iP__PMVL$0ym1nGyl9*gPdLtb%^T;ukTcF# z1BSeLgVi&}`F*f@AjvR6n8S;Y21t73momUa zIsjB@%TL)BdFCZiv2fc$e>+pV1LXxOhxR_T1o)I4A>WJPa@t$^V7aH9zxYPbPK6w=P5-$yT zgSeL%`<=L#co8VH(mA|3wlb71Q@8I}{GH9%*ulJC+P-9ul(cUfG}71@8Cz?kAZ>ut zWqbprAsiuVN9`)08r16SWNfX?M=Z&R0;V=#YBQMJeWQngTR>4kb~s5dBmu zYnIm!kDXa2Pert4Y|gRzIh6Oy*3a&#e#n^U$J;~Z=*Mmht%{ZF6Kk$WHikCXK4mte zNPlchMQzdJ=G3G3C=wM5(PL{R=A)KHJ@;G!>W9xyBhC0YjB--_xZ~phj*pc(?D!y~ z9UuIi_^9+~FduslI0XAv#4clmM8(3zJ{p*255|c3Rx$>~a_sR=z4?>)8JmwZ_OB=_ z#h>I&wf$@S$EW>EM#u2;_FCCyvP!!i2WdX^b;#?j`@sz7PFgBW#ayCii+-Bt5 zp48klQq#sLbFtoLNxeHvy*rb7o9EPfL4P-JR6iGFs0)*Z*+nu54^W-e_!d zgeCZ~jh5XI+sp&JjBQrRj&1hfkjZ!^UiiM^*oJtFO-kN{*Sy$<7jj~oy@4Swwqf;* z*yc!(WbAcw?1|qXQL%8x9{t8>qn8o2l}&6jiAuk7a+uczniIAA-r!Fi`h#{rmZ>HiLcoWcC=Sy|VRjWU3D`&gl7`G7A+4tiJ9}L@m+XRO(Lh?j$M}qPx}#^X`Go zSG#whhD`1XYXCNP^$XTd^^wH#VjmOVvGY3_{rOR%96J`sWAjvg8%_d6+Mw7584DyT z7H%7uhnp`L3pE{0V7}i`+R_ES2TZJTGUcRgac%uHbZh;z7TXpwCa>!{O^U|4WKFs( zb*Dl9oB|eU+mU|TNK`Dsw#^^5?FMEA(6*hVZODb$e)=Wlq-}HiNwFTZ=$pak4AAL7bGQ~3mv_LGfi1)OB^|j3-%vE2 zCA`g^1M@4`q>RPWI2I+gAyKgqU72U11?*T{#l$veqMjeyxO3TQ-aXFn$2*CNg?kVB zvIV_+IA_iL+KhMm9(wYv8qwKhG&bmAXQ#6hv(I`DowE207h78$7h7@I7P5~ViG+ir z{~vhY_)LVZ>g9A#FK7F@CsDC*^}@I^)ctw6xNqGI9dWmf2ZA)H&wx-TBI?Ka$8L{n^#-=1H7A`i% zR{^$a_vHp0^)?>#*w~x0CFF+VY&~L*_qE;E;Kx#Ddw8!TUWuhhR4iP)90N5^m(H0+ zR|#(BMb9^Lr#ZKsfdt)xek0mBo7r&_dl7zzJw<8&9Opz#yEy+6@q#@+0%s3kt`Fnd zbG&w3yyv(u-!~-G9QwtSh(0?K6x7I)n=8CWcv1azITsXc@J3= zB~h_(??K-))@y%z_id;rJZ>8<@Z{e?`QqD1R4k-!YbEB}?#z^bp(p=tUp|S7MUnh_ zto*Ke+k=Rp4@@KIh zP1Lc{Hn<~Wgk8NDVL|p-UW_n5WQ}7#xUw!vWZla!yRrUUbDOz8m>&eo<4OIS`dI&; zOyd2pOW<7gk(G8Uns(gGyT)(75Z#pD5RvoZO_Xs^WNPjY;T z4qaK{&Y(4y8qtZHKN&R<=nC0`?E_tyw4D?_%jj}3l}f_&0+yw z*Pq$3l8iOMYRB4%`D4Y$cd3W(IpPz4NTOm9;#)kx=lVm7FNyU8pB>9h#d?={_+Iq! zk*HV{;Y_XB2lq$@iBf{!qXq(r(nJ&#`6A1RGj#uBw{V{ zM;pO=^&Xu1BR#cHR_Kqg^XhqydO=L-?Y%dosBbzD zE38f8yT_57>nleINU)hAN$s5yku?*3* z=1p}?{ay$Cu7Uky=E$cJNr(~Z7fHjm@kfI-No%``9@ObZ_xcW6sazj037bxxuNmAj ztkuic1gz0AI7Vg8AW^Y!$0+BFCG8kp zt<;<$*r$8WxZ1<}0rAS5L84;e;^myNRDd^U&Je79nlrBP@crBO$s{TkA-<&pd^vN5 z;Oo%RY{$=% zs93mmLc3np+R5sr{Hy?+Za;gIhqsM*#m|zcSh#rUXO|1`=J;8`+9yAIvxl#f_#`$b zQLzZ|Eg#^^@w0-jPkwfqhi{;dk3_|y2w#q$6?}d2v$uHoh7h0lEfN(A7a#rBcu#-R z>$ju{&H1gfF;IJ_`hJVD=(o&z<^uF%E>V1j>Dtx_pq{&JT>TDg?+1kA&)(*$E z=`_cbZP6l~WA8LvIHxncWOT3H>cHPyx0(^zYPiChMz;PVS{lb5abqmUeH-*9{&f!8 zv&69^Di*fCX(#lrD_DD8vy^`oq|@zRZ};%dMZDr)NmMLcy!5XV1H3u@Rj~HSzuw{D z8}0iq5*3RO---dg9RDi#`s82l^zhB^<0DbAD8iTHUj<*E{OesFzJ+{yBvG+&@x|A!I#eZJ8-@`kRcx8SfQL%9Ga(-GR z(C><yt#q!rt4?_hJ99QdXaR*q`F-^S2(})reP~S4dPW zT)fohs)0UNkLYs(_Yow{O^>@i?HhT}!?&i7k3_|y2;W*|@bziFf5^kPj*pK-#i9t` zx@GY7X})A-_7qmY#R`p z%c4@R9ejIL^Hb6SaigJLs)&3cz*m4}PpWg#AK zYQ{Gxc+Gp4g%@((W!V}S^4?`(^>p*K@4p@cN#@(_AZW_jSW7i$*O91LxHdEzdRf!j z&^lBMZ0PA^@Aak-;Jin60C?BZyi*^itZndU>7KtuVD)pMrTX1em41(cjKTiv*pADF zmnvDWy>>13PNgrCeG8$zN2W%mHy^O0gL5LEz@@TwMc$}g{m~M9yV9~7>}u`AuGY=A ztDSP}YKuP<+ZFMIcExL+UGYMWUF}|ASFE04S5JZ@cC{DnN_-QEiiK-e^iAtnyIL=? zE4xO#BLpPxUUY#kd0*iv$_Z_Xpz5dn8Sfjtf4zNQfsCy+y~V{bt?2s-WDVX|z{xdG zc<<4^A+cv0ebm#qTGp1xE4C#2Sc+xHGl1qz?TfzqTIi=_P6%&GVl9(#a*z{pGCnp5 zRGo4v{DRqgsc)+1t&gFY+~v)HH6saR*E09JD3$|y26_@(nnGKW91w|$g=)|_u z_#|c}QL(W1W{gdIKMC;V$bBk*L$q@GOgf1#{!ZSVzLE9=L|8}nnu zGQ^K*UeAwBgU;MsM&{aJ+jwjh$A3;%n_s4h1r6KU)V3T$DLcwF1nt!hf|7DSVIQyt z84kN|yH+{&hS+-^FG649&rYQMh(9Ayv2g8&{%n0~KR+$y&jjLh`?HrkyeAW{_%jj} z3l}f_#RdW19DgQQ`{d7F_VAtR`wJ2kixA(20lpl6Ciwc~&tCEHo$li!QL!k(m*dX_ zU!VNhs~)~z6QB4q5)}&o9S>~pGnphm#x&VVlFM*BlkM`S^V(Dw0rTxBq|oJ-O~?mZ0&yi zQhrzfPq!a_!^3+S@roZNQL%9G(hqME;LY*Fg0)Y6_)QPrmA;=NQLzZ|Z5rUq@xy|z zPk#6<58pLDJ`xp+B78Z1Sn&1955Mia2 z=8eBWXRaTPujy$&jI@aL!)@kBs>&R))g$VMt8z4Ze|{=-B!bsTTRYyl|H$;}kgD_k zr3R{Jp!J|iGXrHg?SMDmX`8ud*~&#P7@y6#hFeZoc2J6p+f zpvZbTk#$r4dnB1yKJGgfybJ5MYs?Fn1ktW5^09Q)$36xdKHj%sHYv2>KQ&>)2=fVcSFD%*#b8@)^YDNtvlJ>7?1 z$bAQJbF^)9`m{*U#th@O_L)=3t#0M5I`rFygVN2Y8z7!2_F6YGn1v zl{q&tKB==}-@|47H&Hi1oo}6+W8a&=qSYhj@3b^bBAf~CzKg&@AALF`px2Ld&yX`y=1lD zk*3BQTJ5iYehPMJ^P6n5JOh%bSh#Iw%)PbO=JxJ>^CeA97=trFKck$qoyl2#x?g|8 zew8yo$!O04?A4{McAvv?(F%pHnWYkt*PHoP89oJ zh`sWpT`wo2#m?UecD&IWJKOqOa0vGIh+WoxNK`Cb?93rd3hccN*oDW;g%iw}{*E%D zxEBKC`ew^mA4W!to4;%4ap^vG{{DYJ70e&_m`PMD1dmy-3Ng25WB#5pqL^3pF_Y0^ z=I?CGKY%Kj|LxldiHe1bIp$Y7^6k4aa~AH?pk~LfkkR7i?|l14B;sKI#K%seVo`*> zGaq{kQ5?PRpL`8)fp_6|@5^S8df zNmMLc%rQG3NPW-E^Ly<0uU7DYQrXV|k_P!_nng&kloW8X3_9w5*OSn0#9r86$7|lR125z}I}8Jc zyk`ei&v*n{|zj21h8=VKoV4#7UBkDWxtq6m9Id^wDAqS%A@ zl8hERf9GQ#4i3RSkB^;1#i9s%L3}w2O=m}7pWAikV~a-z6{_>znkH-G2b_b6}(_OU*85*3Rg>;>`VoRkyA z9>kYqwAlGOANyS35bTTj*hy3@im(^Nmvd826nhX~lF?%4?|kg@fJ3k^N$e6|lBig? z*f}@uiLjg7}h*O~#k362zCA zBMj^Pr5|51-V5W)1#zuxd`aGDe7TS%`0=Hd-4I{yYIIlIEIYnj3EhwtU;e5@d`Ub; z*AidynipU4LQZ_SIxytLm#m%7NLCRrAA0>Nc7@U8#2qRntb> z?_xQh%CdT(#Nc%W;PRhq$AU+6vA(Yh5*3S37kh-dXt0qLQ(c^ndp=}rV;tqBx=6mW zpl#!8sG&aa8LJC2I!c&}B5%|`EoKS6f6}rW z{L`L^f8x@wk;cAj)!$$kq4inY0!q&EPhU})d*iWo%Fj_8+M>IVeZMUFV>Z(t#1r}_ zUi17DFXZ^ANx+cjpIAM^KP?WD*xnAbJ&8F;R4iQEW6be0YkL^8eE!`C^@PXdo0FW@ z5|okJTk`BnK=mNzAfp{M{GAXJBjgbvd0?uV|{6G2=?8GeJ9w4nGZ-*EL`kd!|U>}V?KC* zyB?6k+JuexE&kEChPSt_Gj$otOxuyHS!(_7z;+yp!psF^Y^^;ASp%GqBl->&S?wC$ zL%eyoa_P5uS+Gl+_hg%84kS^raNEo|@aJKh8~od*kd!$GE=Rd(yOS78w>y{v$@t^= zIZDo(1D6L~^wLGWV7^amfkef^)yopl%RZrAw57SR!DciHc4Vp?&W9JG?!Lw*##44w zH+nvNFtrIX{y4g!eHsksH1OO)HukiO2MZ#O}Q2&5gW}GdCUx40&@St7puO zD}f}ocPMRdr_@)Is93nRM_;|4wY_bq82IW(l6S8sQyW}R_I)+?i`C7zT$wUc`%8Ql z0oK2Sw(2uIXMHsp9VcBFo7wq^_3Wr)Oq0HeeJMoup6MGJyB&r`Tab5OSHZ=yc1GT) zovmsKzMW~=4R$squ``DHMp{D*c1(_)eMY4f#9+h|+8M8TcE$@ic6MTcow0g`ovj9v z*x4zxGufw2qGI9N*(lh|{?^VWC3a@_FZDn`WZCjIaqHSB>ZyOm)wvDU>ZCeX0(zY}FwvnhkDJN}PGAHSN+lg&E426l`$Qby9;NZaYdDXfDRDd zlC2Qtg!R)lx&3t;+qC>i_PK$Ket%6_4lC?O zG8bbzh&;A~{BiYDP^1kP`29noV&S$S*Jm6hZE^Z%eacDO;`YyH3i~L;XOOXE|B$ty ze>MP%wCy6cZJ)G%NK`D`wnh8rXlawvKO3@s+9tPu9%KJZOuq+8#-M*1zHd&Rc>in! zinQTU-G(%FAW^Y!+rYf|fu3(DTvy(ha?-XW&(?bU1nbIVv^K@x`RfpyfJ3lf;bSLJ zu_(gcf_gdMUEh>)qS%9VWindq{GE?|GjIs@t9|SwDi%f93)Yo4r<^GEU|pGv7CV3E zW8VTCg8e!lJBf-#5%z+0v*kxUrM8(3z z&OFjVfxYLfD{oC1QQX10G8rvy{?1;b-3C;_Jk7^UqGC~mIcHsYl9s_?&;8==_zc#S z$!Ib2cQ)p2K^4rm`8GnLV&P(r`IUloPjyt{%bm>=}@O`>AqVvgB)!MgHp zloQ1rtSghz;^uFo@3QO4yQ7A*<@aohtSghKSh#H&4gDYD>A%#v@*b3xw#SXvf^}sw z`ms%T$aurE0;_n*OuYYufT{N^KWV^c_;6i$Ph2aTGazp?XYeyi@N))Qc0adKjb%9%Iuw@ck)_@y?EFZ5$pP(S3M^uT~C&oWcBlX3Nxld7rec zi9gV7J&SFh61M-KZkE zc-_|piHe1*i(Ffc=eH(PPPDB-ev6DHZI!GAwz?l!q-}5cZ6i^!DBZSreydJ7(Y6Ko zEi#sD8(9n5HU%uwws-xuk*HXNZR-haINfg_&u{HdIceM6@fhT{$mkennZ5R`Vuxpt z-#P#!Y1?1?wvnh(RpN9MvdE))k z1B$faBi)8HzeS>A;kJSCx$=BNVSY8@>|D(L$H5G?2_LiQL%8b^BMZ^z}|E6 zTgOpG6nBu{BBRC4-`TmM<3Sb7KlqqQR4j@x=j69epo}QyAiqUMiAqVvgB)L4NCW%8B9*@>^uIxcS@Y zJNopgUjX)FwKGsd+A@@Fk^B~kiiO*j(a`^qp8iYax6Y)jv^{RT7UZ|c=*KpN`7Krn z@>{pz`MCESKflF%6VLaV1+9#o?{hBbWpiERm0XwXu_=}@GxXQS{liN0rui?Pdla7K z_3lU_ZK+)_tg1FJ|f|dH&vGc>v zhhD@VE<}GQxmgkw3)dg=+4U&v54TTpv%kZh2kr}6n69Sb{Q2L5nsaWN;NSX1eWn>s zxf+0Tc>Rxins&&!X}({-z-z}MY=`6#NK`D`cJMj%Xs;c}!;TUB<3Yz^@I$?RLng;L zw^D##PvCgBzyNQpRNfe4@b;@Ly^PU&SN$b0^J*7Deu-RqtV(pnc{= zpquXzuJ96W(S0{nnZCb3A37R!%zr9iZtcD&f@jp6)(*^faF3x5oT^*v``|+t0|pGM zB5xN>VO6C2aTGGt6^UT;iKgM4>P zZ-TMRIjLbx&!}$&Xb5_wKTXxwwnxJ=MtZ;+jCAWuv%VE@F>Fc3`UH* z+P03hV`RrKyg%a=mj z0pC9vKb@6jRy1cZ`s4i)uPrP3Z6Q&yDBYHoroSz!&uzKXYs)HrTS!zaO1EXz>2J$p zO|+$}KFcfcYZv)`jh4#!+Vy3Z;aX{57BDyC%cN@Gd|6Px&%R8{De23|8}ntwGQ^i@ zUeA}k9{94Qa1K$1FS`}2mCDE_LX?tc!gk0}&~47#sljR|&;|3!^?Cto;PuQrTdUmk zvYpr5^}NfWSMhlpaBRsp7fDns+_A-PE*@un-cIy+?cE!q9w%q|Ip>>;0<8b5Xak-x z+yDS_47PriIp>ODyTZe^u|MufR4iO zSh#J8>3Q=aJulf8JzwQv+tSBIqGC~mZL1<|+xG?A)gHEOh)w2X5)}&+?-u7!0^YvmP~vz>=1>GdVGbo=jiwunKbCLP zbk+aPKEK58b4m*P{JJLkoV>9qm->B9NhV%h1aoYSdy>@k?DO^TY*N1lHCnp;XJS3=njEPIJzYx=a~Ox0S!vq@W<>7{gm9PKkPKPWmv2CU8jIGY85s%TdZ>It+D6J8=yyt z8xQ7OCTpl9Di-cs#&wz#Y;3l(i5m|=J{DEOlZQ?D*ho|?im)ACgzeXf z-kOTJZ}zYq>0={Nu_(fJR1vmY`+{wnhwT_*lf5=1Di$s_<}iakt#%)4z|r2ulTM%H z=AN0u+%wHHOJ6@r%=tM?KL>M*hxd5moea6=d=L^93l}fP$S(pL{0Oea^4Kwgb^)_- zpn8manCNqZX2!^^9==}?pNtU_6$^XstTA$uQD^wSmzeYXx zj2_zZ;@~@(d=(`C|G>5&uG-m2aL-oT6;c{}{~}`y-mdygZ^Cvi_icwFL)*Cn*UH)s zdBt`xr&o0R(lYfwK8V{bI9wl`FfbM6%J zc*|)xcbV6`_ZN5}=lz9Cfg$hx1y;{^f8j2W#6GU{?Sn+cBD9ZRTKm}D*vHv{eQ^If z7PTv|WN7VqWJhVCDm+!AwSrnZIkd;AjyD^yicN zKoP9h6YIn9_hvpJQL%8b&Iv5P^7M?eh4!Q-+N&Mi=W5i%tibmW=aiPI_ft-a8DZ+E z7Gq5HgNXSO6b3UH{d04sOtkO3mp@yOQtYl&>d(zhJ^-4u_a?UY4{3WzR4k;u)yhI> z$7x=Bk^j?+b3^ch4ab3tZJpicIsJ9DwEee~8EyM}Z2RE1ZQIGnRB+R0EjlV<+L!ew zZQVAmvn~GwM&8eA$=A_?poorcp^oI-DH0V6(NSw<3AFe0P)9$bO~5w#<9r)^Cgu5% zq`kFw?$kM`dxja04^eiit7QL<9*?&`P4$;jU6IkZlg#})<;{jd?cq0A$F_&x_`3NW zm_#?XQ#UfUNmMLc-NeTB1&*yaWBd24pSIuiN1Nc-0cUKJ(T;8YPR4du{f2iiWnGz0 zS^L4qAHgX^`w{n?o`-Rqg*v3kaw^$18}8^5D%$haXhwHD z#$epcpz~ZQ*$y5?CF#jglm7&ZyxO-&8i;-eY(2E$Y_ws@Hh1=GAJE>?bKflx)7o=C z|5SS(;Gedh-}29pYR`lEZ(Gkp_*-fJzI_rZO*x8BKS!ewy|z?VgWPi{ciTkn?^w09 z=lA?m?Rl7g+Is%LKal$f{!-p{8S>n5^BAC)9XI5Sj+@6V!5=qTcEh+i*Vsqx=h@@t ziJWos3iMwT>k&^lZg|ZbH@uKDZk{O^H>{p9Zk_;1#?A8_H}Wh%qGBQaYtHLD&*)`D z4bSUbFZ_cYB?+UA_0HFPQ~yXg=@?0TD?!zl`7`F0Em4>;LPqOb`8$dA_N7rb#(GbJ zL$JR@?C7W@ej-t^5bW*xyOS4q*fHj{bc}gEkqly7@f4iE;32qjEq)BI4rw=jVR#!3 zckVy5I<&3(5!}nhhcop{W38un&$OLMtfkv|58L@l+DPx(ldA4(Vned~X-y=3L z%8=@~Aw#PBFV7RiiFAib#41f9@NMh%Ir=3fTN}^&Rc5d?2 ziC#w3x{W`5!?9l{Mtz?3Q~OQ)D8bZM|2yngowv?%Eh|Q)E6l;#h=7V8vl00e=rI&{>bRZO3s6p z8I~o^xu+Bx7wLyabB=9SebhfNKyL5{2n`l-ksEKkgiB?|2YI98<7G?m$A^~PFg`9x z#>eFB@$oMzIU`O#0PQLoAH)-m4_@=e2QTD|k57RiZ+x(N#`t&zB(b?KX>*UJHb3-X-A6WSuLdA7(4IkwnufqYwJ^$c5l10=D(lX-=V7At?JxsSR4xsP{nv8)}FH)_Z4T7qxKT6TjS zU!K_U{@Hds1nSK4sZXM1MRrU)p&j#@XUDvdW5>e_?3mRv?D$V0iEYeA+mJnVBq|oJ zZH$H;UtxXf0f|qw`zi-QK(eQf^EdKX_8aSermWOXlJ6A|Sbg??!lsu%Vdif#CL1A~ zSN)=A){wR2H`f0GR%z!PemhB2EK0X?P-Z*-N?Fl%?&7zTj3wJi){^b~8(5{CbNTHg zQL!l9&cT`O{5xeu+j*$pPBNBkCt2g|?5dv$slB)QUV?*G=c6XT&aQ+_PT4-m8$HSt zQESg*{8R0DoPXMSo=EaVJCw*5{R5)Q`Wo^^ea(B8;QJaayTR97mG~M)n?_ngo^>(w zMwYL6hXbf!&Lp1D*YKL>Yj`2Y*DMVTdGQ;oXZV`;K@!_sp0+9bgh*5@T-)Rxh^wuy zInd0Rqft+Iyl<7UTH3WZ+=@W1W_BDL$Bq|m~*cWKP?yiG=>fK{4-b3C&B~h_(@4E&p=$;<9lffLV#XdHtXv@Z_(?%pHWU!KXZHt{d_sAU8^Re)enCs`q9!&-&QN| zNj8V}xhFTtaq96oj&jex&B`UCGx?V}6O2`C8Y{>jegTs7%X-wAd~1e8#lqDYzcq71 zs53q<^0|@OLjByhkX9bY1;5dk!LLpPQ#!L~DyS@9Y!#59LI4RsA<~CHq9k=-Yf>a&weoTN~~Z`5rWB?-p$DV`+Oy zR4k;uW}nE-UVC94dWV^{6AX6j6B*;!iL+1S2g;1LeF3(8MHI$P$k?o%$jN%m+XU}t zwdC6be7vKht*N8OQyr10Scr~{O-%E2l=wltcW7*C6Ijo+ey|_qMD_9z_40bE7cvGm zk$x|u^HMX>JdV(Ba8tUW7wdw|GjvGR8u>i|#$>z>4l z_iK}Rk3_}7#frT+;j>b;`vrhanCP>21P}Hob8p{3%1H6L^V{KX0`E=ZZ7fDcKNg$P zaGoT2%ppsI##TDRy^4cCm9})TEfTYms93mdVa$4q=WlG@9x>~SrUTd>Y@xUQW-#SM z+jAA$^E?XUhso%-CqGYb`-=6fbMgJ@5KyFj`>=iTyhWm7;kGaKy!8^A6?@(~!F;!L zCdx_M=lYo0-a`AF0@; zqkS`!a#HNBtsP73*QD6V*q6Rxy?EaY14Y_5#cv;pibdGI+rswUpS16lX#0j!PPBdf z-$wfuMPd4ejD2Yz>&4qQ3nwsgS5xxb2JOR0hwMx(OZ6uZ=#QVEn|al##a0 zwYzS%O>!z^w06he+4+ePpbF+ge9R;&7DbqcWMiIe@0`qvK?e5&**b`GF^W(lKXWhrr!!9qd#67=RWep$L8Fi zh~AH-UL@uuQL%9K5{o&98MTDZ+4Hb|R4;4!dydIy^}^rrcw;mug7pL+D~XCl5!T^x ztn;#d6l<_Qnv51Jf5)-T2Z~@lN!wd$&m<}qF4ovsd=gk=V{w`pi}O=X6!SXo!$$T* zVSG9nEoS~s#v(TYY6yO;umCs&`!9)I#v+M|g^N8l7M}uk;qku9z93~pai2@vGG54N zar3u7Ufl7$5U7IrG+*B&Di(sr?DGus$xr9&dtu6n;=a|_HyJH%{?6BT4IF~~Okdw5 zDi$vGn7*IM*7qWm5ykzYuWvG1-25&2?y9ec$Hd+{{KYM<5@87(3ExTb|>JBpx=&i09>rxj&ty$|*m!WAz>r%vHbT|p)7%>L+|MQx+F2xHu z>r$5jL*BX+t7oiB;Y%luja*3^kr;|Z#UiwkJMH{ZDi*zYmem!zC1_KAR9-zvpUMvI-l6YM$z*!aA( z6gUL?O~fv_GZGaG7d!K*_j-DFb7$v4g85#(lRI0Qa#HL`e4_2;G-8+B85w6#?u?>r z7!%~qmH|oHd<)ww>n9{C7H*rlesZ7JW<0-ZYe3ueUU{V6yU$PCeu~6q%Tivn?KiOP z_ow|vM!)Sd;9W8bO|=l_mX`xj^l&@%@I)HtlBigS9@;8=Pw4(!J@8clyB0B|+Q0jP zR431fPL`+as7^+G0-Y>^!o(tE4ECNEuSMXM@-1<0r#-(|Rx6y>0-Qv26Yl}oVMSP} zR{eNrJV>I`yQou%kx5i6M5kuYb22B5s3pEPBPTb3^;5ki&#rnL1vxn~TCn^bk2_ZY zMX=sWtdf%>QL%8bGA9?z6L~qgiIkDzb;o^>lOto%a|wB}b8;(!Ds6dyZIPTDiHe2W z7Uq2(2yIzsl`?a3D^X6gJwZ;6jDCB{<>Xk;8kTQYD}y5Kdx-6m`H@7$!fhX)5yJVg zASbs9<)rO%?JLO1k0eeRbwC_>BeIzOtVf!8o+n1k{TZ3|rh4% zbC8oGqs7eM*_hV_RWSDwvy5>P6$=-0Y>XG=>V&`L znU}GZmy_GTlj-`SASXvgf4ny4-Rx-)We8?k;= zFF{U@j8-rF9gjCQ21T&G;bSFHu_(ftk(1km^`lsWoE#Y~R{oA--4qnT`nI;WG$%)* zV&P(qjm3hT+-8&$#T?}1$Y?S1cQO{Ais$4u2Zvz)6S2!!BvG+&vB$<@PEKwM%823) za&ly}xcS>3FK$k5OHc*#UwwU(s93m|WBM-0$!$eBQQSdJj*J#Jf9LCaYj6nmfB5<) zQL%8b$Ml_(liP+eqPT;c92qTc{uX_A)qC+&)q9tplVgUgF()?(SIg$)$SXOyx!_w` zxz47FWy}m-^KBr_o95|8;k-ibdHWsbhD6Zr7<%<_pZ1%KqqBa-lv?_AibI)_vBxH+ zXKvRPF=uD-9Ih`Q>-UsZt*wK%%?4EFl+!5rDVE@Ya$AVkUtzIllsR87@QyQ2kJ0Pk z6XZx7DmiIuyh+}Fi2wL0^7s;Y!qz5-@O6xm%k6l#yuI<=@>GP;Di(eQ)bEBeS~|LS z#qUAGT9P9$nUM&-q+rjw?5zCheRI~OJ)7)dN55L+J)fDg$tY74tg{?e!Tr!_EtP&1 zdo~$mtq1)g)r-F3EXD@nn9s-#*H|mQ<1O2}Z^TSKuw#(E3wB#r%>62BtZC0c8~-`1 z_wLks^>=}2H{rX1+csgl0}ZIY-9Wo1+%K^&@)Fb+u`qht_p; z@4?OtKZTLlw0!%9&iEPE>7Vu?<5KR`i+i=} z8E2qXY40?+Cv8l%T`-;O{}H|nk$NucAGhDZ&Ofb{>AC-AUrq1*tCc6v{zusUEC?|x(r|T zS`|w)6M=v+Q|s{R&?*+AI;yqxd8xxtDs3dS4Q&Idv(1n?6B53zW#@+xl_@7yRz>sl z`K*WwD(BOdl6JaZy7T<5o!G140VRP2=)rZs*Lt2!u)AL+Gkx7z*a5+ReZa+c_Tt@|6L?sWN+x*mhUJ^5f`Zk8jHA!_QxC51%P9@{k4bOd{_+kf>Nl zjBNbjqqN(W))BR-T$99_%i7v>M??o9wztQwo3|on!W}D}*5W#0Rol_v`ddTmkGRcT z8q-yO4vp-+*Pk?K&SUiV7g{NbYh3R4$aVl(<^=Kcyx#5k`CDNlIpfj!3Qyn0qtdt3 z#=FqBdf@GbIbp^OJY(}CD%;h~xJy)ZU#cp+AU)s+0tn~V9jS*cKrQiYH}Z-u<(Z;b zhUi`MdU^-6$}#W{_Ir({8_m;_+6KsKlTaY}Xy#Wfpyd1-@Rpfh&H2EC>8~nE>fgW~ zLwy{`;>6(E>hogoAKj(|VPaD=&Y3sb)O%1u@BOJw>6ncGLYvyD37aBs%%+NEh)rqU z>9Hv-prlO&yiMDb)c^n0rUc=C!KOC&4mS0GZ&L&i+SJZX*c5rirkpdhcd-P2Ka!T6 z+7IVPjQ`4GW{#^J#wl)Wr5)i7a>=dwn<7|m#r#(rhZ!epKhnKuSgqhadE)V09QGse znztW`7jpI^EeQ;H`;k~ZV?WZaAj#anECe}oKZ%M(IQKtp=l-7Qo%?H?u*=Q;TKCn; ztN8nbzW>zSh)+)s`(k>~@hVS^W^?QR8i(Bqv;D{JRv>FM$aY?nHVn|dhq>oxF z+!OQ1j6SL<^qGFAcoFIzu~M~iGWfB0#CLV}puAM4$=PS3(Nj~6k}=V!vo*#$I|b3a z)?q_5pQ_X|9F76q;j;!=BpL3A*YI>6y$$-Z(DHHWK%v8elGmJaw``i;Sgp5qqj=PzWW)k0=(_0h+nhGCyRJ3HA5 zH;3V7E3%XI{oQ0e*!(l>@3m@l^!FLM&t&ZS>xA9#YRj;ym$3_Y`*-6_M?S+1 zwSM1bO5PZ=+MLYES1QZm|DjOe+V~$275YEw|1A6(Sg3#f+ye`Da%6dnBgW=+VL)PH)EJ=QQ!OA|T+niaoayKv|o+_{zEULGSKMkyQWyi_34C>5Y+38GD zTTZsi0l8n=o{Ue7N#AJJj8BXu?OLpI#Ep`Zd8>T8?r_@W!x#D@#c7HzUhM$r7WJAs;`@p=-w?0TzEZq5oYrW6d`Q!+ARGhQD z3F`TKz1?_bvUiV-c@NnSNTOol-eVN*(d*p<`6lhXu^(_#Jyq#EGvxkg&X9Z3oFVrV|KQsLPwT&JJ+(w)pqefd3`h+s=u-y+l)L?Rk!Wsy)y1 zPg~Cm`~!P?5r1i4yOgl6{k^`}nSFtUmSnylQL&J|XswI}mY1V_0bjlg1UTQxZhrrQ zC@k5(urVy7VE@9AZ7q{~A4;DkbWW3U#?0N)P0J7SPzQikHeXI&Yr}5rUo1o7cFpU> z?Fa^&$(L&ZC3BkrZ_~L=ssI0LZc`Bc7jl~~(zbr*+ZF+YHg#YVHbq{sDJQpikR|xJ zO)WdMANt$Du%B1V7_1%5kS(6u?4~o!IKzF}_LjojCh?ejL9%><+$OJixlLZk$!+cr z40*XtR?o<79t@JivIj%Zl$}!FM51Eh`lbb;mshQCI);j|>zeRQ`%)YH#8Tp*z{}j( zLHPTct~2!z%1rYkNxp~x>!(6n^^2%7{f#9uCixKtm&xZlyxf`1evq}Jb`EYkn-0DP zC5`PIUPXvi#fs?X5Zn83YGUvW1CC&qBaz6yrtg0p_@?Zd`2Lsa=39GS;h$>HtNhc} z^BVua_rH$6^!>YK_vY?jqCZ1yma#Ac79%}Q)TqGBO7Yhs%>t<4^n*sK?~+t_BRHQ+S1 zq5a~Gz{*?3etRfCv|oa)PlM*_f28`f{gN?xuy7g6{PP@X5Y!P3yF$_^qqNjdB^L!_UIcZ-c z?>C9f%X{Z!v`yjfWZ$_SX^ro09|aD3;bI>ROz(Qw?R(6ad(MP_WZEJA z$>2o}nCmr1Q&x&U$;oT{`hEYE`&(Ngqchn=b^$l^7^|4qI@9lf{0#DX@gUH!Mc=TG>{xo3|O zbI&ojXW6-jywSPmSWEEd9xc0J?)kIno7(Z&bI(~cwTyV_33f!mS}^gLzLa>0*Sxuh z7jovF^MN5RUSjo(x#u{L#AYv|&5ExiQLzx4HNNsM)@DzL%{|lYE05=WQ~OS0DmJ1X z_)0SVpYfG!OjEw{1XPf|yOez=zLG@6Li*15%D;MjSLiEGq@1)b5?`tNLdOTjr_mldTe>sE`rL7cS^(49_D^1(2UZI zCEtKGy6S1yJkNhz)_dniBk&$N$Et`}eGu-3!FoNi#sk{Z0cz?a_c6B}>(vVDPYCP( zEUC{|0SfAKtrB@S|Ni&4;C&(7zsWtul=Tneccd-HBv^b|3||}CHGS_4$}PY67Vt~F zGf4lo0x++@^AFv94R|VvT0zTT^h>+$7B`u1`(>GBrC*|Y?L#iQtG)nk+KZJackHsQ z;n@9U6JwXWv9Vh$L&mP=^~Uag(51V7zF_{=0!q%`0dKkan|*M(v2Cf}#XfAX?fbYs zV;8k;f4cU#Ib^*@+qNFZS&sMK+fj0>8+oe^J&I&?_7|}H;0;`Jzs}04>xy6K%l&FY z`hGub0IR&O$F9?`$kTc1GM#qb#QV1EcBU`E)!5GTtvCBVR=>(d8_O7(o_nr6Q{V2n zHrk1}j{W#Fy`wwqv-8c+*GyDUx zv#x)j4Tk>V)F%7`d1L;eScdoq%{x8*K?^A99|GQD|KRUW_!ZhK&welS*>6)=huLpL zqGI7b`*C0IKRI6b?%7GOb*|Bz%vlZFQ}|c!>wN{1(loc;8*~8bnfb=qidMLv2VVsl z30uQgoO8n%C2DvYR)I0O0sUI+z4`9RW*qu@IL*_;Yt+LgsUApFEL=T|MteSp>H+z} z*CD`JN8d1Qd*Ea8pOvIhrwolY%KGbd*Ne63bgxZs`h82HV&S%_T;IO+KkM7C<7!Cv zV#WLR3{Ma5_Qd zi)Dz9)V!XLJPTu_WX=KMmNSkb%U&{9>-%U|dj0eED1eM~L%;jSaK6%4=A&1{$tZ?4EtTL&7!N)$o6-HYRhH0baeTtbylN z`>t~QSxfJKUmUD$wNn_QxLPl>PdwWaos5Z_ZgJn85Yy`{r{+%YU5PSkUT1_gAZ676lZUqU-rHPfd~RCs`d)j!Xf8UO{3$NzIX`gig+a*tbP102Mj z&E;*ReiL~cC+{QmUw+iQ8(t#s6RrPTg1x{|<3YiOTv_8GWs;b5@S-Pk6!P z>~@8{%KHWVi}cm}-c~WUX7X%&?*2%(--%iLJevsqj(Q0b3RJNq6l~1D>S{6vMaSe< z-x7?ZTaBo``J`joTVbPmLu&-n2sMUGjhrS=`-WgHHIdvU#A*3K?yBK9P&#GcOH z%L^^R-%Frnr*Wp;d-*Z@1B>{lL9<30F?sKm{{XOAdkHQ^BWruZ+@|~-#i1?w(Sfr0 zo*DMib6*JYn6*yXOTcU1UIJdo*-KDeD1R>jt7q&b_zg(%T;B;n&T~D9ibeR$^NG>R zh}!8?OzgS-d+(Wtdtoj>n@8$;Q!k?2aDA5`>)%6T^_fT6y)a~SURut|0;C&an*25> z#kbe4!k*1^-^|^(cklD5UE&F1z!9{K@HyyWTr2w=MBb<^USbKpEo#{fw)kmci)Uop z;vjTimMzXUXR$33PiTw0=Gh`ISAQi-|!90UtcpEn6w(0lkABCLHjcs1W z`-HYh(Dfg+#vULDtW>-!*`UFPf}^2&G-|6eRa z@&=kW9YgxeDeR}_w8FC=H$(fs(EXj9XX;G3evVtq(c1(5hPHO--2t*xK?Ma%70L5( zXJwUj>{>-@WhLD2OWvJmvOtSm(vuI&MGf`;_cw^2YkPScdeo=1u$A z_U%`t`c~J~U9ri$jeSd{ly^N^+nsZTm_c+uO z9`Boc*HA_}&m?>F2&g`Ke#|rSO+GT(J$n2t=TTGV?)#S4f-0C-CuaG^1c{1;;4zrL z3otJl!92mls@G9Q6!UmumhZlj(PHNB?C&*P52|2Z%g0QjVo`*7v24sYP(~DU@SQa> zTFm^Njrm4U1@pQ-W)c;PBFu|tW4?(pqL|nB^-M;KnZL6!-wdi?{wXobzEctv3m5Yo zu;>2-wy^~2`R4_gJ^J5kzNynFCyIMF;#Me3>_kS3o4=ENr(V3VDDH306uJc*f_+0D zJBf-#5%wiBuqWU4yp?jI*w^vDHAzN`oxk(XwZ9DiHb!L_NDW&-$^-9?7=tr$Y`}Yl;DDxY%KGdH$N>z39r4>q%#@+x@eg8{SMy z*Jz5@6qTSou6)BZYtS&ePIl^@(Hy1Rr*G>9QvYAXiGaLB-rmXkOZ~pBJ4pS$tvg8l zzO6e*{pnwK5Lwf|?jW+Jf89Z3P5-)s$eR9j2a(msbqAz_lXH!NeNb5+TS>P-$+Ds| zQim+0R}7LfhgDQL0^cSb76hy=IM0;%CBbwH>%!;x>w`K?ShS`$*z5@wS$$aJ;k-J7 zZFu&De+(Pmw^3?n!(H{$!PNU&8p`OiXQ-Yq7ju6Tu?%@*u}rZHiDfje7t5RvTX5ro zexMve@Rp< z-1ryohg4d0T#LP?XX)HawfiVk#3~}~Fmuf9iIB|fh!VhmGxo3%Zi&sz+EX^#!{{39 z;dS30C?d3n-{M-?*p|F8dnlG6_MmzHTlS!DR?Z#*)~4*?LFh&7;UwC_hN(S}s93o6 zz~`Y>YY%7B9$MC-VcvW=YzI$dT@3nH{yKCj|wa{4JtGCR( z>bRHjC0@K?G@g`|K-v##hXy2aof5pWJ)raa2eA-rG!? zarYK?AoqT|#J#)fYb^?Y@TTt%C?oU-k2K*A$Q$zq#WKVnXx{1Z2UjlM=D=}F6VR3 z6&Ml)@AC3FG~#=*lVQ$n{=nO`>$^n#j{VMN$#_%nPh3n3PF|ji#+%dmEG1E{+;zXk zyNVxi^8wtKh-V7E5BMxK?03Dhwb{|tdlcT$UFvgsUv&13t~Xi zSRGT}iN=O8wO&xuc?j>j&TdT2SiXPrvAk}8zVFscHQtw6E{NrM-vQHe-{DI)-j}vq zaNm7!-|309vr_0zPh78&`Jrz5JoB@?Y)sNx`7dDEXqm>a`+tRH(6S}4bk(l{Tkku* zZ=ktxfB%zoQWgGs+WdmQaK~{k{YA-fOkNqs&VIIMEy3T7_AH=g?XCU+jja{zXCodj{faY|dCl9;#tS+7*5ybO9-`y#K{m+UtvmLc zV8cku*zU+tFM~SWM*=}`8c$5pTOb-;`&+<@D^MfbJ9SX>cFEsCiZ;+om?5YnO58L>sZyOX7+Q#d+ zRyMXEuh@nYyS`xwe(b7cr*>dt*C9#ldLf$~|31hMP(@bkx;q+HD~Mf*#|uReyYiYB zyYfO#>{>;{lNY&!$LM#AJ^hLINp+Q+k*@9OKI-Zv6vm#&*s4u)fb)u}_uU!$p^o^0XX&Gp z`|*x(gWDQcc2iFKki~o3Bh4?u&$7~}JQIt3A@PL1kk>q4$O}2Xa1LO|^M$OQ;S2u? zlGyRwv|}Wo5<4bQu@E~p=f}@#?f4QZroDS8mGB@v3A3p5Bj!Dx5ynpcMmedSChw*Z zRDE}7s6Lfy(teMO)^7Mad9UFCE7>1|e+P$PpO@HW?SVwa!o|+DhuJ*r*vGR8+Q3}* zFbKf@E@DS`PE8v<+RsDxS~ps?Q6dz5n)o6MaSKn?A&~vc8GDQQ!10OYnV@mfhf+ zMjGAKF3t8$i$aT8zG+W1tSC++9;54IiznhVUh{ktFXZ^9rGO#NH?ew#Z~8Y#VpGe} zro{e9R4iPZqWvd&8Bx2;_@*(a$HQMZt{waTi1kxDO6;Ft>Vf@}(b_+M$L;@PPz37) zV%;gVe-af77wdw+I)}A?jTOG=^2GkfLO|r3bJ$>88Kvt?{e&`8{K+`b`0wX9c%9v= zeJUB790#mo<3sF%7@H9vehM~e^NMUU4oOSq4iXg$x6KOx|D4e_BL?D~^ck+>bdRyW zP6vPDhd-mdw7rQR*6rP6CA9Y#6sEmo4C2D9ao^VIeI|Hst-KB+%Bt3KN?AM5Xz)c?WMuiUEj(2sxG zdRp*@-;SzNOsEcxV>QT`pK_)oa#~rlwWn(2v>7?={DW^(b>J`M?Vl-+xE7$i0}^?i ztlHYspMR=71Nf({XJ8`dK*|Z#16=O<)aS68vU3M{qjSd>mf+7FT6V+Su^{mC9IC5e zIz}38);ou46MCSGZ(8jM(=VDkh$oyoc+HzTcp+!**b*4><_=cRm^;1%Nqo~J`X-5M zNmMLc-!upMbs?jd5w)wSnD*{fs02QPC5$$%U0Cx?{fct7p_|_qMKXsFRQ)<=sQx0= zqm_*Kj4yf@5**dPKiXt z!fiKmN{d9>&72b2ujj(mtpd`73ER({(imfd-&1yW`~Q))pNzr0nA`p)Cr666YU)qh zi071k0GsG(59&$sCL}5rq9>C#8Jnvo|4gnmtj2;fxtvzlN}^&RIx^#Qv0NSLaSElGv-8%r z+6u<$qcTq0d7o^39kYhj7a4p~xkm(wdhy2;gu;Z>eaIJDZmPO9U!p>4z4aXw+YKA-SY(Qzm5nXTh}*0ee%qw~?{ z|LXaK?L6f=`Rs6Y+>jyF5_xChE$)y0;FA70z_)V}6$|MPW9Lg0_XoPc*!j9?A2gm3 znfL{q9-P+)m#$^|fQxR6 z!|EB&JA*+IJ3fkbjN>|!Tnvedg=@#050|objI)~cJFR%Pf9yaTPhs+J>+C)lveJnk zbr^r%fWJvTb_ivM{)0g4tF43hds`GH{w8Ci?Ox#Qh)VOZY3L~@12ylDdA}f;`#Qk% ze&Jgv4JJ50XeL}LYoFwe+ULxc;M=E`-C&IHKyyn>_ zFXY(g$p!Yw>KXPq6eO|FU(r70`G`ctLhRGTrps9SyeY9y?QoJ=PRFLlQZ0N!PfgT5 zA1$lvP8~+sp?wl){dj1teg##hpV7$}#9TA-`H14J+q{{hEdG2n9BiVeGpHw7b0<-; zaP`DI<8p<1Iu4Rj73nd2fsElRr{*dJu3fEs| z#kI0ymb}q1JHitDF{@=ajM?RrF^etzS!4EW8fV6w@(3DMG^Y?xIA(dx8?(HSGiEOU zhP*k2)icKIY#@m(UQAn*X8;lv3$aBL8;!TNh@*k@oZ>wv*}28UMrTn$kv$H421sI~ z*?FJPHVL|}^E(n7k+E@p+45%Daoae*L_h8(Y_q3PXIr_w4#Z#wxfdJF@)MZxH@+Fu ztQumYk+@jaj>#Lf<2fwBw_`24!Hy>+cFdHMk=Bq4zC6c{cR|aF?3j2$JLWadj(H)+ zj;|@OV^+_w<53`q9p6AZ-YLyVlBigS9k*7PlU%{t@vVs+>kdUu@-l0*jXB9ACpRZ$ zhBixp^_!us`qNaIo^#09mz*T)Sv%{GCyit>>8daDQ`p&ezMZk#8|-W@Tr6v6vPXA=`UyDi(!rsde#QD|9_oe@uHXT0Xw88776*&PLT#_Ab%HV;T*XZQGa zMxtU7+S!WM&Tdcaj8E{)ecxPYXQL@Iv@-&%KL>5qKcLFAosqFGcE);9JKJS_*xC2K zow3^+>}+0KENf@v6+6T81z(CozOGot%;0Sk-qiMD?-RT`GWUG~eY2A969l|{d!HbV zr{wztf}rqyf`B!;lRA8#psRihJNk#TqxE|uloZBa^EJ`WF%{x8)tOb

YN(yy}NM&>=^uKHutOFv&Plo#q{fhP1q-k4sBWr$uhucw!Gdf9kO-wkbJkUtWpGimFpytOj4 zO}?wx>2k|=75lrFRwewb!;nx6M{#B4BvOTb$_i zhY&l=pHB0qzxgw?YW`N<7|Ol1rY{$+-2O&oVVFG5BW$f4fWIqKN0GM?2X?fK%Q7K* zHnXE72Xos-jbAY#;_xdb7E@&rzed#rGGK7y65Zn(!CojrogW8R9QAuj4No-+#_IcWQl{`=kXF#sPaE zjnKebCJr#;;9R}uy7m$>@&gk8<&KKz3&W0+G9a}dS#6V+$(`Db3?9~+c#*aB2gvYJ zkMBj`FVH=SznH1A*)AN5#$RlJzjyTGzxh<)*j)ZueOgx<#{GcN-n|C~X7ubT_sl%{ zrd4N z?i#ylOxjOfhe$td1DvaAAKJ%$>bF_rK&P6-O(ys4SFz{6bk+AprQTM5tW)#hSYNn_ zu}OfRP8VjE(*siB(Q0yf43Fxa#UX3bKAL73iq?}Xl4 z=q(|k1W4dgLa3&Ngc2YSS|GqbuXJ=qqtza1_g+K3-_H|qvzjyKozaXml14gl9_;Iy zR`~h_q@VuOj`nVW0$-=D-_apHfE`-h=b=WwO!o`d52Q1lMIT%6NWFu>rZ25^H*qKF zh1U%JjWq*4!-7hM!d)|%mt~36q#witFQVU( z;=3b0<9~!&p6*%OjOghyNcW}$+mCdVmR%)u#&!uI#}`r#R4Np{9Bcb>+(q(0jxSk` z^+=B6AcreJAp0QHbc45w-#aDqGe!tG{v+i;r9$D$v5qgt-I*L;_l_Lr)-A_KA;*8E z9H>+%d^y(j<-ox=w8ytB2MwCx_DJ=oMaES%ij6nyxFOqQl#u0nDGMqU3SXA7zAQK> z16fL)xsUW%meb<0bX67_PyK0&>`&oyxKpMHU~oKz_T=0gi500nb=?fKp}sZFgZoxZ zEBe;G3Dc2jeJkQ9%^)$3@@V66l(dI2Bro@w{Yit)xf4_>6s|qs+{t>@9_}GK!2R9G z+Y{%v2WZ2bV!>458q~1q2E$%2DBlYiSuBa(X>6W8ON$(TAQIbK0G#!_}^`^I)6Nv^}vI%^=ZcJlc9~W(|^;ZDv_%GpJN3e4E+G+ROu)&FK6DH#cs%AIN4{ z{LSV}iDx#QKsM7~+6;L3HnR@>mTEJg4cSbb2iuIM&26TuazAhmkT^l(<6O56oS+Ti zjPqcenl{IYc$Mb)VjZLxztN;$ru`uLjV6z@u62;Hq!;#qwc!K1(<+3ylL?gyh3f-! z_f~0R>jQK{2%Xn#DX*hVzW5tWydchi2W?YxPHMk9C+8sR3A|&0m)C7jsZh9h=Ow(G z2)r~0=_1^ildi|O8=RA}EF0IBB|N`gU&yk7lm(Rvg)hsdzARXVhAbPhEY2F#dQ@Am z2F38d1pJ29pf(V4Y%JwKr9zP`$0j|KW9r04<=9Zjv6++ul?sI~$7X(e(1&vMn&9R^ zIq2JSMQeiG9``gX$3{YqUr0GnsZjWGZ0^gU^GC_9wq!Z#UlU|`25(#C>iHV@TEXvZ zZ7k#%2RXQJLZw3C$`S0F#xwpg`TByhCM~~-$$w0`CNg7nKS{6z?_- z;=Qt7yqgNV+XC;@yzfV)LJ`IL%LKf;=3B|E-@nw0cQb)^d#PVkDil$?J0#!@jaA>* zi+6K@cSqpmu?m$6g^L$sRZTzKiE;PD4_EtT+z-1d=MYu*KpBIf>HHXMJpGm$D}pu@ zgT;Ap45n%G7_6)EZ{Qpxae~Ijxpf^lK^wvu=fOBNZH^PUBG^+rt9m~r_Du=RNbmh_ zuwC_@BF6rLJw?2?!98bw@5}nVNqf#ce%FTEC+~0f^t)*6;wN7xAQ~EKMbLB2W+rs5Zs+WgQKIg&5oSwGb?m(9|35y04Ndo)jXG>Ps!?_ ztFpu-^1Ioj-$4lMt?ZAEDzLXQr4AniZO8}XJlF>{ZSI5mzU5a9v`~JssWLaND00?* zo%#25vCpEJC9X?&wDENb;PLP4593M9Pi6!Kd8;P5#v=`;cpBT2_w}DmKH%m6gz?hl zJWV5MOUsG3kONRN(~Qv^Ll#!J{qK=_)7~t$BV}JK`JO19d;|*v!cn(gF?H!H)EfenU!50#W~3 z-|+6LTn`@`B7F=(`(xWK^jqo}4BC)i#d)w_Y1-Vc8t^5}AkmjR+PE*tcHWib<#s+n zwlgXf3csCyVcVJRR>gf(C!?LkeN^rpoV$s4oP>99oQFzDrl*^+*`mMx);8eHGt_x=;_m7At^Yz(h&>@M_j8uYS#KEFVv zLgDHK_rGr?^wL&7ou0EakYf>|S;_bpV_V};qm#`syKbxUsreVMd%EAlr-n+O0-F(f zcsLfSC*30_fciGNl8$t*x~QIghW!A)mxUiVzOO5_ja%QJT#xT-oU`XRsR!*h11x>t z-xCzHv8GM|_QB*1vY>(z1>v7h{A4(cW8KL#1y2jDzJCe`O zk^7Q9O9hs`FO})HR9^yZ$d}?g*q1bIPkc!;Nc1I-_DAp~MiBKSkMu|OB}NnVC6BZ| zUz$cX#lCct^d(d(6uvKwx4!iIBwu2L4f)dJ@TFnWm%!5Zr3(F)>Pw&v`BIz*`;w;Z zi7#meiN55~{s_Lr2%^5^k^acO#Au?vEch3`vSTVMJ^k}omB z27F1*Q}z{j9{}D-6wsOZC@K{S7w=*epH2{Xaer$zhj@?}biP8tFyEDc*oam%O55NW zcRpV0cFk?+{pR==%Q^Q>dhr;;Z~q~EvT5wAcu)ReTRSJ%YMhO^FQ$jO=ahX0So(d& z{`6aFp8?uXpAqN5eTJqj>@&=Kpyry8W{}utc(jf68DTt$YeI}5+GlvA4fh#gy!EaL zF`8(f;gQzYXB-_4(34WK--*f04d~ zN`=DrrERS*J(A>0jIbeJT4yr((%jOQz|!}n>GWHwFM&4XOK~3TOPaROmzJ0x>r^$z zCCwnwmpt0IFUh#&V3L>H`E|52ukoQ$p>W$7Yka@7?fj@|=Qrp%OXIEaF}~BOxv+*F zS>u!V4iWg?l6Htng~GlY-(odumg6jTw5tdg1|Q z{g?Id><*#z-^UR7)ms0Rcn=kL-<5b#sZhl5zDLi6@ZRX-eIZ+$m1{PSq~o0-@O~ii zqEexV;r+QiyD^YC|qnIzy6$_3)%2m z`aT#3F_`ET03zA{RMO*FW# z!-laa^e+v=&f&uQI!6gvzLv6}Qlao=*~yoslF9N-FUs*9n2TWcd?}(E5_>e|6@2t?{y}av}VDzTB7ez7JUX zzH~hOmg-BOWnUUVGR=-X;-={**a~?kr{uo3z2oRzPuvKR5|ULf~vJx;>ceBVBueoOUj&<1_` z3|k?6Tl22+?Oik9zP7e+|CBUX%eP;Eq9VQxJic$^H{sj(p}@CC5r!h)#^W`7`%J20 zdm0UU;yFJm6$;m$Fz4UR+S3!pw-=%3n5LyPmS}WdPt)|Xz$3S%?E8KIR9R*>vZXDT zv){-Ap|yYf-FZIFLfLO&yE$5CQ!Qg&7MOXyfJ%je@tAdh-95~U(sORUAAB6~_uR(E z&jFtx?oYp@erdIKiyMR%H~!AP?We~xpqKu8E>SS{6(n|4Diks7ivhdHVKdmfw2afw z1D_!FRW~B+V@dI*e*&S!j=wYPdhS|{{d}Te>?;8~j{~SwC|v9q2QnWT)|uJL;`Cf# z9Jm0_2Qho&00=E+{2d+#E~Fa9x~kMODisPBD`FboM%J4vtmjM3cM~rHpCIN>{ziJ9 zE&u)_2rXv(o#|Pxn^f!hVxnN|KbP21sZhkQe?6y<-SweM#5>l+J9wN#r9$Dp1LNc# z!iQ*_d^Fpm{DxkpbM1^BX5YuW6nujE@xG4IuKruqHb!rk8@sw3e1du#{CARXMJkMZ zAhdeJ-VO|&YwN~HrG8Hosrk)Rq$=YZ*}9N|2%={ zZ#MnsmEf1lFtG2ad7GN1>oz(RGOWA2l>vm=m8;nmg3i}baD!kT9d(#MYC=2zWQ7Nl zj?UlEh(Sj0UIU95!nOOWh>&%#k+geMDip2`VE0pf9gvWE?dChSdnZ1;8hmouUHjCs zpOLp82ph3aJQudlYp90h+Z6JZXro_HAC#wl4^?_H{(<-|jT5ZAFl_cV2*VP+2Q>3~iwg?olL&d4t=I z*AXepxrOvYR4Np%oFP9fp@07)+7jMk<|fxPAj_n@%}}XOxUwK$q+F}b`q)8>^F`2h z2hcOu8o6!+&s;9I?N%d^D%<9AfiSV{K-%7UF3CA(C%mJo1*Ob45jo4ewUil^3PrNa zO|~JW%tw>V*BO~_2G5|(cR=PRbD2SyC^JYinL}+|r2@}}Z=uIo2NR_ZP^nNP>!3N> z?ze(xPzOJKSF}3_6LkR6I@yyq_I9FR?2}}Bp;Do6u^0Mjs}(}pEd2BaBgY-!nakn& zsg~pFTn-Q>wiifkdqK`BBb74WN#rc^WXQ~MA}SRMSLVX;vW;ZU;zVb>ybFACIoTt11Y<#vX7=4o0LY-|!tdtJCx9Re z4of4tD!b8IM)yK;?GS5u{@UU1=(p6hL(uZtA@8xpdHjTQ(h8qfnl@ig)CbZo98StC zjR@^;nJUv;8AVQ{0FVr+X=J(CT(9o#8i{+=&8zfo+?mT#Hi^DvyQ56U$@>j#%I~)~ z=YusWCQaVox`*TaZQqhHNL!gKbCC=C;#S8L>OzTv*}+jgRxuI&gwEgfq^AacbHeC+r&Y!y_F# zd9(OCVVXg7ANjId$@Y{-+t@yG7?1U{s_V6+pD}`hePkc3CaufQXdg27vzmCVpBc!G zg9*sAU@|uu{)CoM9W7<|E79z4EY#w$??-v0L7}MqO}@!eCH{WY_ORbYr2T@KZ@-V# zVZWda*>9W&+pnfAwBLenA<$NV(hQ>ZYdR~BHqCy2M*6%0IuNTzX zKZkElCtekd`&sbiemn&uaBdU!PLtRb+$_=E)WCGz8~_a%(vkbK_qg}{Yk3m$s6ZR) zKjJ*N|IoCe|G181cKh#e|3TwT>zKodG~kKh{+mClW*R{EIisGVJjSAEPvc|K8XdOn zulK%${orW==f-A1A&56pZ(rZ^ZTGFUPr2AS0ic3t1})^k@sCKqKq& zrDGp3F(CZ$8xnw`#(c~T%S!W))-lgj$(nsSZ$N1t{>H)3mccDfw>7xMj>6oEgIj`f z4{iy5G0$o9?a3KTn-6X=QE_Y2kX8{DvpzI2(Pd#V&E>?_NcM$1Tnc6MvRdiNw`fJ2 z{y{JPoj_r|)O-Gm(LJAw(yk>L(3B4yX2kSJ>&t0-g8ZB3#g}7V%sB$6R4CkeG1eLP zwe#X9Ol# z`n)bxpYu&MF-{#hf)eka1>PGZUQ{X+F}ydX;+@b_yiWzJJWuFCsF z*}a&IJHW?}^Pi^QQrBWY8yctMJb0Yev|^n0=cxsK8{&M;ATiGOXyb9dwA*fym;0@I zq}`%Yp>XX0{ni224*q2Nt@~lOB0tDo7k);(<37BD*Yr`TP`K}ym)>!pcn8@U0(>kI zK0pj;QPB2{zXF}Bv(CLjzO0|F)i;6{DZY_!WU>BF#Cz*G3-PSb%WtLbQK?Y4dI{a z!MmZK7dm-F>K&B|g{za0-v3yr_rHjDJSO#yN`=CG2lPJO*ZY;3%|9;nez0%zw?he4 z@qm81Nbfzi`T3?*Dc{6)eM;f;KQ9QqJPEyU{wFFG3Rf?PI}Q*h)RXRz8i4|at@V;?`hLq{<$^Ac5#L+a&C>jXF-JB zi_0+%Z2U3qMfxpuj00_GjEnQ&F;3HpG0s0j6CUFd*FH6SJpvZ2eVVY{BMr_vjZMls zNS(NvSv){nqp%sd)>Rl+cU8Vd8~s$a5m@?d^imyd1X^w*n&aEEA}`wtnNO~H=k0+p zp5_dtLycYPq0?|f&QWt|IjS25e`)G`gG{wnKKX`w$Mea7hqsVudPZkO@SDgd#}5Vh zz_^h@)AAAG$Nn; zRq)978nfIE0ID2M+Hvy9L1_2?@ptWf^4F-AG5=FyMx{c*c$!Ng%rDo*JQF;Em@k!> zL1;1K@7kDOr&`ARF);J|7L^Kxiy33)VV<5}q37KBt<9sMT?6dvz5zZ#+z$gc=fH!| z;>O=u9*wh3=f4_4F0=G$~)tK&3+A>Iu10NBDZu7DRK5nYOX3bEWPyw)%JQ%=MGy zpJ@Hua~924M=US6p%!6rT#(WEb}*zndeogR481T5n~?d%X~B01m;z* z6NBnpsdvFAmy?EXrvDQ>bKA=L7yzt%`Ai?mozf4 ze<%Svni-)NOZ*Fba@)${Hh`*}N*Z!v2@u-82!9uk$Da@dW1m}MN2Nj$!#)7m#d?`p ze>&dy#i!sC#C{F1KY=FJegQ&@9e-!opCJut2wjz?{m9Ull!gww^ZV0(({HJE4qCQz z&R2``;Q6Db&23-js~w5)$K!qfusS`OR!f=~LV!c!|i>{ZNR2h#pzFvy;1%GZE z#*;X=WdsFtTOVxC@_K6G?X|of7HaWWUXMo_oUoI>n>o9i*Ru|6d8yo%b^aWf`L_I7 z9kvYGkS)h~uq|ua+?HW4zWs*ts;E;k_Ny5r+OJ33nEi(FB-$?{h}y458f@y&+RQ!F z{t;7LDh!rrGKAN=>!@(oAlr?tTT)ki4v4m@g_BnJP=?KNd{!e6$3?bMeE>J zH@Tvw@UANHqEexV;ax2i@3B3_`yYY# z=Mpa}6^a<%HGtQNYpp$;1iL9YrvF3`uZ~-5?N>>A_*&pyOX5YPLJ`BecB+0CJ)my; z?W*ia4|UT@yg8G*kB(R15`KUG4gHoHdxJLA-^Y1yf3Impe~<#AM zxtVtQ-Fh&<2`!UaRx8uaqb zGT$G+r{7Zj5wszHjPqcB)U?7Mdo}*j?9<{ek2E>{`r-NyMi}ouJlY=hAC%VU^dH+v z`$nZg;oJ8qw*PqE^dH+7+cyL5as1Io;GHD#qEexV;oUJ6Z;#`TCV_Xd#EVLWB8GPg z@Yaq$SicR#A9VNYfz*F2Bl{1q^!txyLYmrtfHu^B#CdT4p=m|`aRCj|{hj&q(eq(= zH!FqS`q};>M-$&y9oSsGEw?T0M;tac4YEqVO!p?Z_Q(w2H4>^lQZJ#}%;Od-Rn7_B z(cD6M;qiJZ?1A^TP^nP3_JF;uQ?0-K1^z~R5q3XsFJh4842~r_(hr|Y!o~tbqYD$| zc^JljDYZPExyiD1`q{ac^L^uvl09?NRrvyTvaGZd@bc}Xm3~XL6VQh2B+i5FMAJHU z((rf1HKU!$Bq|&Js-f?S@9DRJbE2?+d*rj`_Pm%gEmw@_9YU1!4eYMU;RjJWEhpOv zjPM=m17R>^F_<^I`$6q>v>9kaZ5HRjZKi3RHmhD+46k+MYm1tJ_E%hOYW$TJ4RKt% ze^dS$CX-6#(Z<&nWsKcH^0Ln!2A}0z98@Y4uFoQ`%RQW)vox4L;!MFx z@Yj-JeBIP^b?5f=75I(>KHhgir9xrfZO;^(?%_L%o(qjJXMoPd_-=+##?*90N9w)r z{RG})fR}R-QK?Y4c#(^Erib@fdJcvx+p53deZ15KDisQsH}>FsU7S!u7iamp_{H?l z{Q0lc;)!?Q4-j}yl6X<6P{i<_Tm$dfKHd+4cwbD%J5b;~RpLdZLJ`AzS`EDC_;?RK zIH=!rTN@CiHSP^fEcm zze1%#!Fp*atxB?;@9SliOfP?hUIt}J5(6m_t8e)nt062;4{fFE=UVlh9oG||3$%{r z<^ZL)bkxR6)~%xkwiX3^-02Qc0c|elYSYAYeM(ne71HHTgf7p6F1bHLr9#2FG`ZD& ze|A1ShyDz9G@Nu~{yB|4^-$vrk=$z89}X7SE|l0%sZhkQT@=H1R3q4i2yB-C+l1T( zQK?WcwwBUTq?8M5*&uw>v%yOp+!xWa$LaC*f5q<3gVN-|8p3F8?cDQ1wl-Ag>@w(V zQm!*pDio}Tru}Dk#a(XZ$g1xOwG-2iYv{<(3cO zo?YO+61aKZgGzy%|KAryQ}aF)l?sK+pU!^!^N*JDgY+P- zPCJ3xy?aGD-A3;+LT7&|P?>p3AFN%KS}+Ew`H6t%&^#~3@A5lJPAs4+^_=%(*c#1a zv)fXdOM1yBA3N;#!O%ZC^Gtqz;1TBen@R41v+MTx?Cd)~zex5xC3D7}A5)`$cE%Rw zy9xNV39)Q{u zkEfzvb|nnkm1_^6WqaVYbpy1-Y-jCpi-f5c_ZHOb@56KU1V!2 ztcxD6sVpM!z9#XaQlW_9omm5Kwx+^(d%UKysKEP%#EVLWB8KS|w?RqIp#up0aU*QZ!3T}K79QrG&_PlaCI zgI>5lL#0CD>Lt{ly-&}fKl5S+2HMb?N~gf~Pl*kc3PlXthcRpot*I;_uzd_{yrzOm zg@Un}HI-|8d$PV6SX23zgZqDFO@$k@ku{YOLT8^sXS_CnN`-=T)?C8;_*!3Qc7FVC zqafH^gKHBk&LKx@M@nCt7%61=9I|lSf=Y$Ll_fM*e?iZM;+E?mvpbe_97Fgh_LF0Y zo?WMnC8Gr1ucYo#sZh9hq5JE7-P?7c|Ma5nE0C?8wTUH#EZ<03P^nNP%ktk|l;zcW zWm!td@*QO1{uh-Bg)2*_|NY*G;H^#kOz`eQXHFg7s8lFoyqoB`>R5HO;7uRBapx7N zR482DSex+Y6|`HC&nx75`qF}bJNWb31S%B@pZ^WQUfar;=`oGF_OXoM-xvIOZ32}F z1wY$N=~-2Ad`p=K^xDMOV`*(-rF^QYQ+3h1n6-(g&^$(m?p$6{c98aY-4K^{Cx7-gl_Pa^9J7=YZGAOuT3n6woF``04>`C zuT8{xu`u<^I$*Gw7H+?734EW zoi)x6o2p>`BZZzyGfVUtkG5W)8AGzO&y0jE@i%f%sZhAKv?$rcE!LJ^$$aKl^k0!@ zF$%)#yaD>Gb+*sv*-%HbxM^iua#fwunVMF?l219lD&k`w+P%x#&P*cfURBx-nE1A{ z68)BHJD?5OPMinZj;76R2Yn26|Kd9mk(@fsAkkht+IsC}Ws;ZeWqH^OuX~_Up>XYG zG|6(SwU<{jd(nBY?l&}7AWpio%{w6I0p9|<4bRH+k?skf;DzDt2_F`CjT6XBI&{Z7 zF#j+N<~&1N0^dx*R~OA5#%!gnCS(5O=d7(FbTJ0Hn3RtrY8;7i5okj`8|T43t7&`UvzkGo&w8|RpM~#SKss`B?hE>m zdUNg>&)Acw(e)ktHFEAf(zM?TpvVg9& zqr8C?Iqy}?n(FEF{Oq__t>ooYMaN{`{jDQqk9GC4lLNX!AX?oQop@3x_Wilg)ke@2 zk3XnXC|Fl!-TfY4S1-UO+}L;HDow$M4$JlA#V&Z4beeKdIb@yr_ZTWUN5+ECvZ=fQoWrp^0C9Sc83>a7tAo2r_zux6InPkOZRep343 znj|~-H{)Pi91EjTp>S;rvGBdtwr19fg~vnqSsM$po3XU!nd#yr}3ZES6l zmu+kkZ0yv$uScaq;o8{ZWMlVR8+!vbM*S9sm;P-n?d2VbgT8ev4;mr=ZuHDqI%ih) zTTbtt=dRPI(cB9!^J$oAdaac;PYZNU`a;NT#lq(L>@?ZVwXUQ`y4R5Q1=aa|(>nB9 zYTpFfkgdddu&roXVJj4Vr^QLFV=f}nk~{f`9#6Dq!@`$~vaU5Ot?Sm)N!LXYl}GAD zRCeCmSvv2b(D=D7>5%QO3-)()Zhxp$C|vuSgG7G7+TWY7zqaxo^qi%Ey&+d^R4d{M z#qe%}B;+5*5&wc*HQ5J`75Jt~e5h0??7I>3h4Af_g75E*;9F1Nnv3M!qq}<~jx9P=`ur_#=LOsh{;e;%DcfYpieQq3%A=hC;qyK|bDpL#0CD z%7^{8-wOHK$_LSNf&2#s`)H?JE<~k5;bKEv_&d?2)@Et!hE3`9_9HY} zJ6_X#JzwXNV~lgKn8%Zv!!{eq=rgrNXR?OYQpRm(Y`Cj(Cee1UDaUJY^2h5<>9^GJ z8nmJDI?jW~YfUT0>%B?0N0P3J?^est8*2uMv7JX-Z)~?2$;)HwiLevimqDdM;o1rI zWgfD2@>Vu~z;sy5O-~|DJb{P3>_^Ydx_uc|L;AkVr?8*3r2T-8Z$F#UZ>jbJ+K~Ok zd9eLx+Cuv=iT*X`pPE6U{dlzX+RqjwFWb-AupiE?Mx{dG+7Du%-&^~6+r(z>`3xJI zWx3Ui&+gS@$1OQF`-Q-F9`JFF5-Jr67awwz{@~#|pPmclD1Bt&N5*)-TqgdJIZA(q zcckSgZ7J|x2)xtsSOb*`g^L&ZeAvT#5j|&VtUj}I6^wQBvkX>zB`#T?TM2xZNPVJG zp|J0^x$3??FHO~FCBxXTKF0~Xmq~r1QlW71hV*%PiasB0M4#gYzAL3ZQK?Y4_(Jx1 zRSkVU?Az!2L4E3-&@}tpTHw7#>Jya;g^M?&&)VmuCJ6r5X?^5#Jya?bE`Q`CJtFPj zo|n@30GQ`h*}l!&iP%1TXAC`moL-lZxf8rDq1dOgyd5`Gv+=DxQzYZtZG^lxL0*o% zQK?Y4@*?*374b?RH?}_!gB4g^LaG?W4j@D88-A0k}hJ5?E(h4gj}G(z>U#mtP9G?~-kT zN`=CeJ7h2R9B0iou{mUQwaIn@+r7ZXdqSvGC>WdB6M8JzCiZ>@nsm^f(0#;9?zHos z&>!*q53?u4Ew>^3$=^RiB75qd(Dp)C4@h01QlV%>R}U8G>hT{#SF4;8(3MX1ugV<@ z@1N};boD#viu*`ZDio|MbLWNMN80nnHErJJJw|N4t1|jrnm4R1=M69of8H>OeoLJ< zfHpL5i1XligQhKcn)3$DAaUN{(bhX}*pcMrdBYQEQ=T`VQlW6$6mi58wy*e` znK!t((`Z-c{4wKeXx^}s!1rh1<9P!r6$%$0;<6__d{0?l%m{%IcY9~^2FBRqdBbFZ zw;OnQ-hfJl!o>@H{>j7p3_WLQtUj~YiLo{`ZGQ8C`fO<4u#3R=lGG$@hV96VpH|#0o{y??~DisP>?vTCMGgdX*q@j7k zRDtayVB>iMDisRGX66k~2iru>8$Kpp{{!;|Zn;w_bnMZ*VK1SpPo%C;sZcbct4|Ab z^#jfuSXYOf7tmEb^MhVzp(pK-MMoN%WMXhZXtI1iq`Xj(CU z`I!3Nql5mUjD}RY9cH5_J+nq_m%4AYqTbVN3_`;6v=W&VrPLO{mI!>_f0)0yJ=8Hyl zJ@$?}ZBE+e7g3+FuIw|w-yEv_7JUe3zj`?4zNA_o7#UObp`Wh{ zhnp*_o<6}2n)0CrMjPRmsV|G7rys& ze<90!QWjJy6v?v8uVv|~{GM=hua|c{`Y0|?n(lNMs1WPP{`3GMU>jz;#P6~{ZBS2| zk+zQoey#O1g}OvKO4f|47JWTsLad()q5Ds;@YkOY1inN+1ue_Sej4Y&`p~q(PYGH* zc~6>w)(9R;dD&M+!oGO@8I=l!YhPH8ddd3AKTHfYik`DH@DpeKneiQr zHYI#@<*ghf@GS*=9OI!r*6$%$G^!ciXcbR}bv-M}jI^;5=&&b}r+&4W~;9Cy(uFcm6QK?Wc zzLpZsFuW%4QQx@OCiJazxyG?h|Vp`1t#Fzc9Sur5YJ7vYcU zn0}+9H0{7p&hH^YA1liCLZw2%`Y<``etV5cX|E4o>7(txuJ%#_-^#$ZMc!VhR4810 zYm)9~dhONyC(3bfg6%~p*v7HSRfyk!_SwH{9@uwOM|(@>5@e;Nj-hmg4^B{hYiax!y)QZv0ne=>J)sjazlVZ6qk4lcdgH$NY| z+^VGo=ym!W(~|VxcI2C=Lxm1jgAVS_b%07u!8&LutwYZy>Y#N{OL_GoHK0E`iuef~ zi1~H8J+qZNea@40DvPjKo8E5ckiKRJeXRj~ai57wg@X0fT*97+-)F8#&*{@i86ouG ze2z<8w>WL5;^*U(Hj)5afef7D$ z4TyH-X7uyk+^*JnS*K}+U#`Ot*s*)7POt{ubggRXF;(-06$%$G_E+BY z@NNT(rU3|j&Ty(X{}khF=$_7F1h#D@HdHDUF>Jq#VVm;`6PLM@JQBeAM>xmuSb=SO zVB@$9l?nx8GjZ8lLT?n8?M@@B7nkke;C14%ZS+{);5Zif%n!HIiqJ(PaoKS~A3H)H zJcmc6Lc#iI*56Zk+tWv_xMwHm1aZ%R4vu>=d!vq_^ocpo6Nz_N%m;;-^XYJhScih0 zJl3IaJkAHZmht)VLhdP$yDN`%P^nO`+%2Wmh)1H_h;??ZA-eXp!+hBrv=1lFVI{p# zhmr_~jd6ZCC8Vblgr0VVo~Gt{LZw2%dNO$qUO&@P-VNF?Ydd4;oss-zmgQ5(627N2 zoZoz+z}p49Y|p4vC|tZ)llq%y&-vNOJs9^`qRZx5k@J!azvIf9Zkg-deuGrn=Sf12 zsZtJ9DippP@Az`qSZyzsW4#*sA5}9>V|mtxJhD0R{&uak?H)Dr%6T^<9rNxV~HKd%mZVUN|P24jbf{2$c$jYlDc1 z{%&pXJrffhOwV=xkvC5eYphOmWqr4fVt{)=7JuI_w0)H?5#_cwW~I>l;530>0spjo zjR=(rg^M3+ME~&c|BKqq(f~Ww+_E(y#-6z5&{esggzVlVw_oiWVB_2G>GWHw{em`R zzi}RHznV6;Uwt1<$3xmtA+vAGrm9zLS-)7@@{p?|w(OBcY#F$3rM7bS^K0U69YaGB z{d2AYN#Dowi6{bR4NoPY$wIAz1#@4vjnzNfQ{omR4NpV&BT50 z3B9!ps}b)a?mHE*10nCMiu<^&zJfmTIY4o6Otw%Q_nj^DbUO6JaUUub3f7Z}`#k$< zDbIsGBsuP5S?Z4a&JlRe0$%n9R4NoM-jF|>jmE2<4>PW1u1WHTuFCdA*uAOj=fTGB z=g+0zQu}$(hWhz95ANqRZQjp^`pBAbO3(VpQ)t$pudY=Zg6{F}gf@$!7mu{gKJq-$ z7x$5uz$SS7N2NmH+62b`_pPsgVEV{{@t@%(kN<wO!QP zw=v{|zOAeB1ngvUX(wRe+sTFWTdJLaHe@Gp9&9I?R@lkBePoPfa>N3$Ve6QGlNw7U zCtWT*#u_!SrQn0t>3f;&oK`oeWz?WSMO>8@R$Js!*F`MSBlRrOjJ2JmkLT>u3>C<^ z{zcR-Y>&TzJxm;yRLs@x3w z`-QYWu<-5gQu-~`{y-bDzc>%JKTRv_@Bia|R12$ZwfTlfKkAXzu+?xs`fF+zw$;aE zKZ;6)!nIZOqaRsY{dku4qbyiM{pd0`k{xd;?HDY5JHCv5OSNOrhU_@bgY8(;3OoKk z){kld()v-4w1#bl`_aou*KC{5$bJ-+3WaN%=tn=cw)wAK??+jfq<-{R*xy#t{=mYw zzbojsRQm&M$o}Fy*#0!Fus_-os3!+hGtliH&jIyl>&-E^lH_F@cm+1V_sXJDp>S;g z^U;4<8~6k^&{m#F&oPaACiyDC|26P`Iv=Z1sZj8rzd&%=9tR||RHl=7ldp@_=+7Ry@~ z-ZkpQdyT;RH{j(pDpV>IE?%rrdF@kv$H4V-Hdv2|_jh(x6baBhPWm+1_&$9t{g&#} zpbhzSoCo`~rWHQz??2RBqiPyi?_QdInfCwaUYbW5?Eh=+rCmpQVc-7zC>FkM2Ktq;<9b4Wt)t|F6*gyq=Cqg~DxrtU3MLw*S9%``5eX#DJ65oW|Tt_OP|I z2e9z%;YRu`)gC|_vWGYiwg*is?14T_BKGx6W@d1%eiM;aoztzA>X2U@%v*ZtOG`@Q z)TVSgX|iwu(73aY=rD+Ro%H*m1 z*fyncrrDH78ndac$^^8{HnMHN#BZBh>S!C#hT101gWE>ainj5`|6cq~mwuU6@J*zS zLZ|geJp~)vuQmSPN_t_R9SWc2Z!)1$p>Tb6H2Li3)@MJ5&)PL!x*uIHyW)GKvlAzI z;|StzgkFY8y`WN| zs9!I0*3`?FKY(673F+kvYC}GzUZt0=%0F)-f1D`&5xVyM@i+8aYF`Q3kUz$Gus>?r zAIcx~%hLSOBdyCHZzsL5KQ1Kg4wVXpZ+Bl=fBZ7@M|}w1^~d3`JLG)lm(g2){Ld`2 zJJ!R7zX|vwa@7m$PWs~=LNALzFB9@L1XL;%te2M3Qq_#g|F7R9;O*+|BJ7Od9?MehuuZ;vJWl^TRSJWHB>4TY-`P>g{UpQ zv9|VA=7V-`X(?jhoJZS~Xjc!NM=Sg;p<o-UivN77C;-ag*Xqk1x?!%ThI&=ZNa0h*B0(0dD#}$ge`F1 zIVu$j*A|d>{;jozuVD*q<+bR!&KKdl=F%RF!#G!ag}z%~F~&2g$*S_sJMYJnY3FM1 z7kJkJ-bwk|9x4?I7cb6|d?)ZyPHEtxCY&8#7jisHXxszjkJE7K93Y2m_@3eS;MuIR z?F-J2v*>R?bpLx^&(XW8&yqiZH-^rV(>J~XXUQKBI#~}onM{1m{S2s7C|D;grBw+( z9Yi;G!{|1oumM=`ou6wlr$8KWT^>iQ553?E**Nb$w3Uw1x9W4qR}!0w(F3%Wa3?}< zQCW-c5;9{>rY(4tG;`xxMTzVV>rw(CS1S zxF6?tM8N$a_i^~0&kEVNyBU~f$vjxUPj`vWkr-9ilEHQh;%?yEk90QczEQ>aF1$zM zyBXfp9>7$dW@8!MAUos@LcwFd8Q|lOUk^do_u13&ud-3_II1g@HO)JK)M@V<> z*^ZiPLbLLlq#BksfgSH96&K|)d!*iM)%FAYO;S5vwP^cQ{P=+T=uI@H-iY39NU3vc zYK1vF@1oA7=6D5O^`HCWS00X6%B|UaPPA5b?$6?F_3?fk#7n(NFgoIp!t)kc@edkNIjmTZQ?XBFr*I{XNAMJWs6X7&V`Fp;Do6V^ri+%my5| zfAYWdCYmSiL(f?n^gYh`UiRZNW^3S1u|EiW`$>GLR4DAbaYi$QZ~qj0&!pkAed|yB zwix|zs4dPYY76k{v7g?7_crLKt3DFKJnQ}RHM}T#1&g@?}2glR*FF4D@3GeqGQYBsAd zg~F8&Z8g+ytCzC2I;t1j>f35z{MbRt@|ck27}-{+R480o&{nl%X)PZ+OWW$`q4l=a zABB9!Lq5&{MWsUF%7+}#*+pBml}|8DX1uDgj}^Wf>v4hYB#8}`3PlXt z$uVpPG=l93f$daa<27MaDikg@tO?KI>FqRn&b^;a+TN4m9cRdQpi-fTz2nTncl=4b z<81j3R4Np)cbrrBjz5ccoG0IbN`)f!j`IuO@sxPSh4LM!R48KaxTx?QPm6b4BHw{Z zg(CKjOAFu8E#7gNd@*SvDC}Qupukal&iFZ68-+@Yn zBKD343*Ygwc*pPLJ5Z@m#NP2x;X7Ut@Aw1WF)5#qqEex7-+}Xo!^9XxG4lgi9QLq% znfu)tbB=pXJmcT9Tb$RxvB42$E+CWkuq4A912#sp-%vrUI}ve+Uf=QV_f388h(GE% z2$q8Q{J7rO)61`{s)BSpfiOHJ}qq!l?sJ#gY)<{NOr4z6MdlB@24M3 z-e7kP8@#HP4faqsb)*ln7Vr8~%>459z4X^1J-#mV_$>6ePrg=xN`->;*jiejl#0pPTT6ar-k)@%b%0= z|EE8*|HFoi|9kz|4<@fOAbkE*#1na(4BOBf!iHXe4Q-j*5GoZ4wjuLfCU36XQvRzo z4nv84Xe{YzU?2tvE@WLchh7|!T`?8}tK*C{)(rW=n?jD4q#USJD57$_9F}8HsvJKZ z7LWsrWvOz!CFFP&a`0LzDisP}j`@6_rkjKGTIy@WAX`iA$^P-b=B&MTwN|#LFXOMb zg&eO-IZ&xkB+Kze@5nK6u6pJ8n~>uzDF-SQ3SW--{r1oq479fWHp|iDwe6;E?fdSs zogH`W{~MG9+=k$L0*rh@XGQ>nAbKhgmBf9Kf=7;3i68P zk3e79elhbp>aQVO(fwlZ%JMCk*IX}#ct!Vd!7IyyU|tUdc}4Rez$?p7U|wsy6v9=Q zpMV%CDC5&XUP&@$d&rDy|Cd9!3ipt+es;&apVfJtVCm;|{sVnzVqPa`xgX}d&NvV5 zvo)>A>m+FP+~1=a=zcwZUdf}SF@QF3``Hg)(tFKVyI5)csiAoEU6PmcO~*v6^Yw>l&ZXVok;o*f-d`o-wBM=u9xdoDyUOqKv3O@dyc$<= zmzu;uipY0rJ`i#bgxtJej7o*Vl^grTiwL>f%7aYP`TNBTc-Rgl9TT~MC-JedXL!H( zp90%YfUQinYR-6|QlW6MEkryQ71+qWHqY#9Ffnk>?`=S|p>L(tT!V02=M!UI#5tVr zZoenjRay2`ia&SC`$ZjpLM?v3_#yq4+Ao4O)Gx+)aKET&d(tmz28sQmM_X^d_z}s= z{o*{*Mp3CyxOM;=UCi1+A94ul7v~MzC}V5LMn4wV<_ES(xs9Syp>VNbPiAp}jcoLa z%tjX=20DR2?#a-AS^6oSaXW{i^)kg`okSK$U7=hixsu+;%L}<5Znk-7T>6)gaUsaK zb-vz%N`=CeaZ$qC8I+M$2=%+MFEU)W2x6MOh(4I-)Wh{LM-3~yRy87U|Fe6Sk-Mw% zCXsbdmi`J|`u_R}{g&#lpbhzJoCo`>rtOKpY6gk^>e1Hgub+~nl3!iLT! zS==*DOU;M%kieZpO(Q96cJz#k)ob~t((loxw#@6K;-W)K9;tt5$;Qi5PdEOFzGAID ziI`i*%tNFUWWDj-d~=hpzx3T~MX>X`xr%pI)9>r5=PLO2d7d*MCr%jDO4r7>7FgWvx#Cqh(G>DwywA@w%xOdCl{7@8LSWeqM4O_8IkaJa(*tv4iKp zs8lH2u>*79k#_88HnHC3)Q`D&m^IsE{2H{lPi?ZJm;)ECrAfS>3%sk#u@03Ag^L$s z-6(;V#yb6#Z5r#gw7}(9w-r5ej`@~pIT-eqXRA}L+1J!^VeUnoX7;0&UWEqjlK1`j zfGl4MS=NCpoZo{=g~F9(G~rt+C=120(524r*~T`S$nT+xVoO_N9k^KsFa6vj;$mLU z15Zawc|64tBU{xrWRLr7ONIHQ5x43jBR%YOz>ucwY%c88(}ay}J4!osnRe}}d_~UL zy|WBVz}b&&zoOq#;}Xz@;*vNIj!QJHh)e2Rqtgr$V_T25-q`j(Bro?*o5F@3%jZI< zR47~k5F5>adu5S zv+^zhMjpLOz$5h{9^1Fby96#sm9hRilo`$+-l28Gq6vjZ>LIuDiOM;lb&hYy7TLEa z!nZm0K&3+A`Zi*Z(bl(HP3&S{}7H_uS&3Ns8x5PUQD{X1}8{Y}M zlO+C6oNw{TBg>i2trcNd8ll?p`+uYYF7>NmTSg7MmYdx^Jj z-(KP^&F=c!?h-F56^a;M|NM=`o8<;DUYi>r@fPL=NW6Un-aRE=R4NoPy#84pi#N+Z zV7xZ}K;kXTKahBv1m3d5i%NwehSxtAWbtM>4vg34I7qzLQEZy%Z_NU4MdC%JLJ`C3 zpE0s{vpF>5wRsd0Zyj^L7J+v^i5Ha$MGUWhUdiIkay1yQ&DD^2-%rz~Q8c(c3~#%uFhB;LZD4~e%!;5|&@MWsR!!|R{#vUs!H8OCdKXC&Uj z+!=|tufThx#EVLWB8JyLD`xR#`8kZ&=I2Pfh50!WZ$E+e7>O5^3PlXBf9}lUt+EH3 z10?a*VGsQU-s2@+R4NoPy#5(Bi#N+NV*T1YBZ)VXXLJ(gpu5UBC|LS)&;f)rbq)&J z&>S?*gXf@{wr~zw^ZvM|k(h&O28nY}k2Y-%dcHS5E5Jib56(Ft+BD((`+Tu#pYgQp zVOFOY&U@54h0`;S)SI5=`B8hH9h#pFq;}%@*;%m9?en!4R4Np%ea=BLFKy>%ZDxLU zHa%x)V4Jv)XC-rIE2H}yf{0KUKE`a`8c!T4HAOOkGu75Hean)WY7_P6KvXz{AG zqkJLp;?*mY*K{;JYw~NV&%9iCYhaZ#KU2omR>v7B*3CHRrcF1UyP##}{(VX_4l}mZ zRrwbYcJC(p60q_6lAq9TseK7(Lw!k{2lpkKwy-ZT7njyt&(aJM`x1{f-j_(5A58MH zPhJU|;x%DE*e|SD+2~Rh$R=m8LE9tAa5RW3*vF*;-nTo}1n5!Q!^_ekK3;wqg5h zL>$T+Q$e}x&W3BATReOTyLW7GjDfx#K5M*RjpHLMTqNSq&o_WWuL(OiZVKR_ZaEo; ze!c-5N483ROn8Czu)TJnP&OHde!c-5dJW9c$3p8?Xb8rm*XSF``!dW5?{d@yB^qz!+TJnQ$s~bC~m9{ds(9Mg`4GnhL90ZjL1?#4n4i1${Vcod4@{-UD z=4I39x!@e6_v~c5j{_R8@^|eKS}&SM$o~rD=X;A#sZg-|=H8-JeA}qLGY08a`df3a z5>FjXd-oPyMf&Kg{ib^Dqu5T0{icrf5VoCB{|a~*Isl%`T0MsE`l;Nq`sEkwViu5E!f6f?$o zaLlM_^OzC(@^fe-YsQ*E;@Xx+TkqP|aFUl}*w0`qyk?9_g~GKJ#IS2xTN#kWu;_wB z4EtlO8M7*SzGl3z(94(53&(4yR481%AYNN5s+S*n&6stPzGi$I{Ay3>SK#CO)gts; zs$YRN{pt$(61tE#+pH*UwO3k`qiQ&FZ)%WpOO7c%J&~psZhA~gR>}WTl*Q9 z`IXMtqO&MX#6SnP@+=C@U7CAKo%4XvwPMAxjs83^4)zVk6ZYI?SLGpksC%lk53uy@ zV=?+I)jmKQvX3|qwhv94+s9H(%`Kgsq&GSuiayxSi8fWieLFfX;^-3x6^rk^)i2g| zb?wYZPP9krZMvHnc(GDACwg(x5!+OM*c9hPqf()8Z3;Qj>sXr_1e>D!A*?B7gfh(EU1#oMVkMlfOnifYmY2o# z)3x$~(UuL~y~gkTC*E7nog|$?FN2{M&UZkiLgDHK`3_@+UfRk-=s8ORIh=e4#j)e%{`nBX(kQg{;12-UAv!+zPERP#mV9mk3YI{G6 z?1x4Pd4@}QP^nNP%d>Fr$@6`pJYAKgza;-GOaDY0`~JBk{g&#VpbhzFoCo`-rWO9_ zkBv*rk72V{#zy@z?aNEP9vK@w(z?dRrAROA$0K1c)AD!=l?sJxFX*2)u=f8GGd7N* z=PZrwpR;@~26qxQE9T^N<$L{1;9Cm#c>F-6LSf%+^U*f+@ck@+FUyx>e5X$~_#)$n z^taIh-_jBvDiw+tzGYJIJ^s6-@lE1eTHsp__&D}Kr9$E2L+rDWr@s~HIeh{+Bb4u0 zM!aJMyn|yOR4NqiJ1`b(EZ*UqA0I;uoY-fe$s6Q$I{Cs-?4wVg7sWnf>7C@Se3sei zlEqnO#jm;zcVskV zgzzmL59)P!2k6I{Z^?KNTTqGTR+bZZSCe>AsZhl5ZcqJR2=4(Ver3fzyF;iAA4|u( zyuiDL#EVLWB8GR(8v4D_$NNGSTT1=Xk=RuIt|0KPE%BmKp@`uf>*1AtxT1K+x_Afs zAu1IL_Z{%VO?*GJG1+>=!12Q!e4D!|>o28F^wULtSbu!SW-}A7l+%w$d^bkuWCQ4g z*PBtPP`En5dh@12CvD{ojVknfY&g}Me~$nCWQrL(>RNAJNnqPpVnd}u5yQ4g4BL8N zHGpkpfo(I14V4N-4BO^0Z2P5Q>#CeXgx%9*ObEO1W5QMFx73&rw4s!JYcU)`n>Z%+>4|VS??E>(8 zyI8djy8vy-F5*1cE;OyMiw8;O0ghcPHq6)s&Jk!+>7-Rjn(B>e9fK>)0ynM<=xF2n zR65LETN7G}ciWW)qHW?S=vUiBM|pdC)xf49&DrHEml1}NPugK`{td-FOO=lLO(^bJ zjdaKJiJj1IaJ-31g~IJO5ch0u``f{0J~5e|3&jx^8=GO7R`|x)j2wgXu1am2Ih7vj zu1K2!OW$Tzr{7Zh63~WhCeDLxM$-zL@%O)K_9f>0m1dB*{^QZsyZ-ZYl9$_gPqZ`7 z%TTFMxb2L2;}*7^hnRMrO3zsuJ8#V9WsL8Otc~lMm#rc2m4UA--)BapLSf%Ml;Y|I z2;VORKAaOW>#?naTFTRi2lkw0%(bR?PX+JcmGz&_#o5 zwXC;6|0Um$!II4t34bSJEg{Q(kcIa&QK?Y4vWzC3ZRN{?yHT;HsT1I^|GhtP(%zgW zr%N5KE#7+|-a9E@gFvN1;l3ApKI8oN+WW_Th1bcuHs$-)5$~Ih_p$AwQlW6)7qZ=h z={crx=YH!7{z~#kr9#2ans3_szHw+x{$mCI!@!^WSX3$$E`Ri~#5=kwyOBwD?<0F&7_9k{$?imrFPWG-Mk$6WwdlF@`b5EfEBBZ9 zU4F}C8a-pyj_b{p3FkKQuS&m6_pSFDznVfOYOlq&eznJ*94|S06#VSyZ_RjhbMYR9 z*BA2ho2EaH7%N*l;pgX@YTiGY!1KOQbnPU_Ypv(aedu-aI*f2Vq3735;2Yh0&67|g z;SP&>5LDHszhJ}X-_Xx;s!~38wC8l7cidCh7j|bOu$t>c{H_hYqj$CIckzvO(5iQ% zov{cxWuEaH!j(bWaqf#JoH=Kx1&;_aQiLv?OWTvaj1z)+`irOMaE}+ zxvscmBZ2Qii4TVE}cs6+#7v}^--t0@88}uYG6~r-NW|yzcZO~E<|o|E(OpycP6K++)57K zUfzxVWdBBAQp3LwJ~A{n+C=E~a_E-hD^w~Ju5L$@oZAT9QcRikL;YTy2lsoLHt+XBeO+V@rWqvmbslZK zecfgxFZXpf!k#8kE10_)P^nP3_Jp{3qP3^l(bthZJ(|ruZXyOcOs~$B+7{2axjoVG zTCr?*Q&ZDGEDhw6VD3KWO6^c;p4Pp;v=6ZK?PGKLE!93i8?ui$54I0YTWBAVu~0Ke zv=5KAUi;XB7{?gjV9MQ3m@ijCS{zBlpSK>pZLJ`APFcvbt zhQ`7z1-=J>kHjE%=9>Z4|OZ#Mi|IzOn>q@LFW=?E+=(7PU!ey=$Ow4pi-f5 zb&N9tJNP=*5e}`9;J^Cragb^ z22&5OFB)&R_l=LpTAg_iEb0 zzBe*9YX*sZuSZ*N-@7%*%YE-tu#-vo*o;br!nG5O&6BL14D-h3r-?!Djm<1uLu2y; zu#W?!eSoEJ9~0=eRQmue+XwBFl=OWLP1Cor75MH9+k)nu+X8%)e7&@z(O>7BP~XT> zn^{Y0F5!NNVeqM@&gY=Xv&ij+eb=X7+o*Xf)7y|a2AJPES0WB2v*~vTKsPmaPQlin#en$_WTM|+Bn&NLW3cl~ zdb(dzTjv=1uYNppROr-QTbxLo*{)uNU2z|eN`=C;EA;U@S-YAmv#YB9=NYI4i>A&R zZAwnXmh!QlVh|wCVMp$%XpCnQAC(;GnF>9@;Xf&HOa96=!G%w+wDAKWjBO zv~6(P&~`%CJ_7p+v-c^LrfB}tx5N8chwX#gS%*hKhgZV@wGKflb=Ydwvqsfv`scshZ$%3n*R)L$^P3mw1f21F`}z-bTjoO2jzWOERgZmdvoA)oFdEk*tU^%R*Q|{kVhhX;NG=u0^V>Vtr+W1%lJZF+`Qa_pJ8HDlB zesa^uvRx)|mNG>Qp%}qwO*Y%K#xAi(8r&r|>zpG?+aG7vL4fz3RJ^TYP9sta*;ynO zka_=`(jkI(@i{^*{%o>PnlvaBfiiL}Rhn^=k&8Z*2K$|!+pk{7fQEeg-JuTq1#QTF z<2=}YHLb8;%6$}hDQ34NxMo}LIUfBoZR?|2DBLW{JMl<^c_+2b@k}DUaNqtZ`gWer zqEeyYzTNDr?QHw@xuf%02G`Jhc1MBlbBPa?3PlWG!F-nSH8h{yN#Oem_;@~xN`=D3 zhxzO-p8ouOL-@9{w#yjpUK196YD~6_KlLdsF(NeAnk?{sBk`hAp@`v)%)c3LkLTZ0 z1m5p}mt!+jDikhW#Adq+{r<1azgaDf%)ez!wzJSnAKFIRXA%O*> zSU!_$vb!(ejbWH~R=5vF zr9#2B(p*9x++}TL9y5l`M$dK5#K|yod6?~k_W+%X@d=E_gi-dvuj9#D`Ee5O?gH;% zi5Ha$MGS9b%wYZZc+BV$cxMORNqJv`N`=D3i@s)0q2Fw}hjWQN?rT`I-sx-h5c16l z`M9q^r9#2-nZ9PKFW(Q}*RUdz`kH>N)Ylv$`x>w?eGTUZ?Mc6J|G|9%ewVpHPCkyV z)c$Vcy!!HS_<0+LB|PuMNc_BwIsT_|Xc%52IW%1r-F7N(J3XfdPk)@4iZ)8jX#p*_ zGtcScJlG~QZQ(d^*DZx}dd(m@PMA5pM;jj}(1-hT`Y@ivIXxqY&gnhU;Pf|TPG1vm zug&QhX>?BSkp_jLzQ1}-KM{S;p}GC)IX#$-7*T3!F0V>`Zpr+)F8{d^|2dKWoWy_b zqW`4#$?vD{Rfi9NHsk|w9_#~}R`>wcWoRKQUq=e>p$zDta|zD6Okh`PU|%Prrf+sU z!QGY8@7C_K?(%j$rmsGVFtnvK+i>|(5XHq zG1L%F%!NvYg2zk~bM0lv%y~`BwF*6Fw&G08CEqbkyklj&gY&>qsZhA@z}dU9c!v{r z7$eK?{}_lh_>y9!yg(*e9oOj@QmwcS{mWQ-C#?f<-juT-D9^z1tA@4Fs~S23ySLEE z>Qe8hR481XAlCKu{&P?7HrB1u$piqciggQhBHOSc@UAKGqEexV;a$hWE8nq?c*oj! z2iplM6$X?+ad+uUmt7WZiNE{zAb@|=klmjC|rCYyWNVObH|mM{o4cBndwRY z_A7yRyu^!2g(8M`8xODavxCGtCg2_1zoAm0aNkkbznNGn_p_=#|C6lUet`b%Xqa$A zfHpcwe`Nnq|p5hvt(TPeZzV` zMCfEE=ww>H7KBQL!qo}-w|%_+ZD)FpY1~{4CHPMP|EYPd0V)*=ezv(pcjA=xmHb=E z+04N9o!PxP+;^5bOy3!~HwVv;A^v8q*a_??SJyem#C#V3UpZiyxlo_dvde|`V-6Ma z?xy9<^@&P_!j(5<$Gg*W?l^7xyS19VG4$B%e3A5RTH;T=b7O|Uy9e-=bG)cjC|tY? zk^c4*?c>DcdlCcZZm;!;cD6cW>D8g~c0CFbr|=%ba;t{U4jd+A*$c8v%4I>NLgC7S zb2$x=om$TN~?hx9!ZHlve`OlYMZ?4cYkh*zHx-Wzc28!t)Wt( zaPcohxDNE&$HtfY5d+88HXz#i?vdm68PZp~IU=t*?vXoE$a4VX;XGGVDip3f$aDRb zFOMD(+&tF9^E%RnUgkl;S*iO-a*=HKo1D7To=} z@S0MdE2SAk*Hz8JkVhL|SC#F249UxDK}VvUr{(R8N`=C0=aD4KLDsJ4%kn3;$j-Qr z!!Z_|aX*SU<*Adp{VCK4e@~?FPFz0cTJx3{*1$6T0vm?@wV!(! zAbQPm;Jl;Kuh1U%E&->IWD1RX-iPt%oyL|rN)vao`EFXy!*e;w(fiE+Grtcy0Wu`+ z?SPi`z+mk*>Gf3=%JlcBupc6@6?t{*QEpn`bN`=C;MZ`LXSX-RmtVf?u z&vm|mQC;Q$DA1J@W1KR8TDWT6;7vSPYb{FlnI{Rn7Xt4j1W7u72bBtiix;uyp#rZH zM_&ZsSg4cd3=w(5>Mr<9<-#J;xcZrk_l?p|& ze3$l~e7g?p4f#$H@?8e`xX(wWLgC7XKL4;_`%x?h{p!B&a^hrSxx9a}ZRcd|ingvkMr?;5<1V+&L&6z=;FTO8rPuPU~2A>Vnrc<1$aC+8fZQlW6)Ihx*ir2o#F zF{`Gw&EuIHAnfl**!;!vy=RE`-h}tEO`%euaNi4?I?8`@trxKl;aMxMR6z{qf z@0ynPKd4kF+;?Fe=VF5QK?Yyvu1zL?~m`G=XhPCtMWJ* zZub%SNU3*`Vb&%hIGdaokN71135MR(xaHJ9Vf zJ*WKqPiHe@h0I6M)=_J$uap83l+jrxA)cmt1 zwq|%)Y>mVoo;LfjHLx5^SdNA4Zcr9IAD|%oC2xJweBeVB*J&=fK7jV@A-jpK#0==fOUuY4ey--*L0N zaZBjW&xMB0Sn268&)_)QuP%_y zh4mT_jgOB*cjlWV>3Ie$&&fZjJsd!XU*LU8>K&B|g^PD(!h3?i+cGS;T1n0DG{k71{kvu|&5rh#&QY`+ zibJTdX)^ZGCuYqWtE2_}G>i9zXqWj)&4x84;xuPV>>L=q&l{gJ~2z zD))Uo3WB%q`xnq}slE@|knhKNuXyWsm6@~q{+_Q{X$IP9*Xp#%Of<>D z#j5?AhV&81Odf5$^Ti8EUiQ-$VJ{qOp;Do6?FF&ciPl~g%>1;*+683K~s#iOm)UM?ni*e)!ADzWi1G z@^|9o&3AjtUs&F{{6)@_E){aWE9FL|LgCAOiZ6H7ob0_^?pYR7viwPFyIqxM(N7#B z`w1}d`-xxEZ>jwRXhZ!(oCo(4npX4^*OP6nO?%t+KKSssqVN4af=HV?r_$1x7@5Vn zXQkhuJCe~uDDVhh=xz2&JkmS^dI3F%>pL9uFupOp(H+LK7=EeJ_9yCVk-a+>E+aj0 z|MID{GgK-RzMY+F?QHmuFdnfc>hiCy%J!t=?qj8$fthb-m(y>lb_UvzoyB>uooQNO zXLZIennB`tah>+^AnfHhX)j>r+sl>o zTdKW)He@ex9&9g~w$NT8@r!1VXfGaZz4mey$;X9#{Bnjbe^va_k2uYu_=V-I%U@*ta*dFCfRr1R z3WYECnZDdr@yozm?pYSUu>6Vf%X~wrpEzFj6JX-^6W7vjsr>|KL;XaY2lo@2wy>WF z$1nN3STjiMCp_AE`-$sFUhXG`Nqa%1LgCxXS=L?_{Sn3$mbflI>8k7xdpSYc3z+%# zay|W)YA>J-*-M-U+l!_xw3o=Zq8TLGi$@!`7p!eO=*8b*JkED_O#JQaV2b!Vzjw&F zCz^3RPt8;ql6$1-A$cB??|n%qCclB&l6_$~d|_I?M}|s;!u190k)3UQVKMkZTX|u6 z&eA}4&K?s3w|h*Hd}P_T-ze}c3VgiBhDwFPz8hybkn?bkhi@@@j`!I3Uh!-ni!s`L zERo;YS-6iS@!llx{uFp8<@!XWLgC`Y-toBtFXcSgz2i;*mwU(1FLEBz_RUzdY~M`g z+a~OrN%?LT@{NFeyhemdg~F8&G1hs$d{txZNaFMZ#aOJ824bvRg#1fFe%?1nr9$D# zKbqt}-e0r>QfV*0A$fVcSsC^+DeoUqsZhA~g8uPBYcGpuvDc&7-Sex!ZK`v^Cekw( z;TbofAiB4%Shfk&)U-Dzy@CcV=OZw7znbr!Z=Qqf<0NSxUX3E3k*AZl~YM zyOY$Fo#~14HpsacQp$FICL(bFnR)WOzkVihj~lchn~L*bo6@woP3b-ENpMNylm42K zsj9i>rI{t#mq#17FZ7fCT4@+h`dTT2h_01-r0Ic~v7cINrFT#pvY(8FpG?dB1eFSf z>nDiIF1CL1QxliDxl3ML#<&}b%kC8THUK`3%TTFMxcCs4UE<-pgVyv4;xfkAQd`8X~?r9$D#H=5-8wJ%>) zTvDCSH%sFZR!iM+Nmu1s^uH&|{ud1W@%bM5Ep>bbZKyAe^WeTz)8>6C^yl}V;kjkL zHli6M_MaYYy#JKr^SvZ5_dDB2KS8BJ;o1@WuvhW89cwx$6$0~Xh)X&)2FoQX6AfkPv6%zXMOLJ z_J2RMC)@wduz#N4qEex7?H}{o%dPz{k=cLMd`9MCqYs!y&)wMvI(3$eqA_Yh{wKF^ z1M}Mlg#5e7aRikLg)9FS|Bt%w4z#K`{y)4<7f`UEVnMHfT@u#%R8_*n+*+sIkNnOEgB!Z$7(c&+P2o)9!mCCDt`_qphd(Dyg9u}|kp773^u4B3j(6s0& zl)Uts4uXEac|Yp1;20IS><_#TJD&#oj>gUGHxHPJA#3Ve3z|S~ziIAe^l*#xoAviH zhUF=EFC$BkdoQDhnhZ+aV^C)N$!{%m)^0*uJ~OFjz2_E`P|s%mVji6PP!FP>_58)M z3-$2lFFwZ1O#S?Y{-&UB05{|t`83!!G_KP+db90?{CiFLZ)r#_iJ@Oqc8CgyT!zL zJBQOY}Kfe(Q{9e(1ZebNHD}YQ5czC%8!F-u}q7u=#?`lRI=K*>_-bJY5D! z2DQ8~+;-5|Wsc`;Mh%GCn=5*Qntih@dTju?a%`9W(KdTT7`jl7(HzmRHz=p`JZzqv z9e5vS0U|$f$Cgp42?#6mOm`?_Y~DXQ@|Q-J&e{wqY>!WA#I5!v)(Ta6|1e zp9Z%_jhnPbJ)ig{P5z|JCmK-dct;bxY92OFL(Z3r?P2d{@utA}Aj z9S4^lS~rh7f<^*?IH5Y%_HNn*Npf~>OvG6^m*e8G1$N&L9)OII~+mZUKx5%zN0xjrY$h^ zVgp=D9#OY|a4Sh>kKV;`s7G{2&5V0HYZos}es_-aJ5co7?qBG)qHPzrAs@=8!9JvM zGkqvL-=550X#xd($ivO|A=G7e&;PR!x%2-XYLaUCqsWqbr5~euh&5WNp^Z%Ma!T9On=EqOj z2mh7y<+yW~Y$pIJ6s{kkoy@d;v~1i5+x7Xoi9q+w|Fdol&HwKO|2R+j2T1zL0)j`A0qt_79EQ75~r#3i^kKTh>3GCVkmI9)N%F{5XILh3g-fAHT)=$8xcM)Xi=F znJ6Xc*_=Hi$QEc|e*77s|AWw<=XL>9C|vz9w|lFvf88GYhltV~+GEf9mfAZk7tfPJoCXC!V9Kx}d#0bKy5t!64BEovB$otG zp>W#*a`RcXEi9j#o3r2z<>oI4`JRV-oSOrvP`L6TH^1GJFDEx=8M~aDzbNE=3G%)} zD{?iS*4WdJWr|)x&yg{&>G{ z%c0A4L@7(%Z9MVU>fD#j_E}+3Jr&^II%($ZdPK)g58Vm;lCa0Cu*amtzW`Jy*dEP# z^6yUH9(E6Tm-i~MD%~?yd0FW92K4(|Qr`e76s%usv;x)LUA}&{zV&8;d3iiz&Zhqe^{pdB)m;0}eWqbipp>X{O zW4zy6Kccn3k-aG1+A-cgh(Py^@mRNp#(3YsKQ5I10g}FdyiUIr^$*~N{3D+R`-jHO z^pBkLk(xk3|L}0j`o|ljFZ;*W@DCp20H{#7{(&*hAFO|@82d-v7{}asjF?R6NcY}L z%o>*(<8;<`T#WqXBIz$6=KIT=^jlGX0dB}&@@cTYXxvPH$%!YLKtX@;aLfA3Tcj`h z%YWf7JSPC4LgD%g<^=As{<2cqoIteFT$>YM3p6k%@V3yuiKKSg3xEoRt3TSyy}tf+ z?WLJ0&7nB~*0)r9k^RU!Lhn|oH-HL-ulFB)z3b)#+7i9z*qi|CUvN&~Uc`xuWt;#J zKTiCOek&R$fE$Vv`7}6AXxy&E2~D72obYhV#))@HUyc*~;V&E~08}Vke?gqM&-%;C zX>np6qBNK04%q??#EJKW{sU!u0Z^fE^+%leldpeWoEVg}mu~M@S>G z`?}Y)l_lzQpG>;nIVa8^ut6G#ksk^DheLlJdjP0VxcVbT{-3XZU5s3cD9xc)pN3&%(R6$;m15F;P5{xUi(ms*)9$rw4u;sjfu zfjIH0(0{aSF90eOuKtJ<5BvJp#fepu_R{US6zkiCIPsa#dyLc@K!w8B`w?I7x;U|V zqW2t&6Rdy1IB_cC#APy0fQTO_KBwP`#tGnt;zT|TjuRR;i4%G+^HVhGk+PTBfKvA| zYhndshKHLUGeT>!VR^c=Cd+c=uE~0+U09RttbGUnxLo=N===Wh&l3It+>n3d(_sJ5 zxQTzD4(P~~xFbGi?oJaZ=o21pzE8+GoG(aU?ngF3JeicNH3FzmxbXyQ0gu{vvTEFq z*tLL7i9q+Q1+Z=ntp#kdB>BhhqdCU<)*mXM8R6-vRpbcmzO&!qp#n z#$&$zb$P~)L}?CFf&LEX3|7~BZ5&=NKGH+KCwVi?kMwG*dqZ+zIx#_? z>Aj!J)4vb4Vt&N={-bl6^!GFHeR5ycQMB8qj@B|GB&}cjv=&|Lg#~_^J7V!0;o{1&SqcIUo&;?7gus$y&p%2c(HIHbP>jr{!7)SF5Y7X8y<`O~`*Rm9TD>?6d zQZ1H_yaSe|CaE9cXxEQF^=TT|Bp!eAP}{2%7<$oD%M>K>TwdIME71iHgnapXvLVN( zBjL-tCcX@yLczY=9AS^@Z0pObBR;iNkD~7^ju+Qiyyu_^^$VEy&WP(We*Pfjn=0i4 zP@%BAaj$PkzGI5W*Y^Yy>r2V^qmWNY`2bWX^5i?VhED2E#A`$phDrwhdszod;WJ4eW!<$F(P~rxxuHVKW862Vtyl| zJRkTZP6DUBKPvsPhmiM|kauz-FMtY#D=+-<8BgAm1NMyHT4h-$#Cc4q^Oj9QzEh<= z0aPel`9k*mRf;{^phu)w#vkK0E$z8i@%*S+$om^9FMtX~p1i+Jk@u`NPu>q=AC>ab zafG7v-y-BaUCIlfLXju$87cDC`D-oq0V!_@e{B`=o&|Z?UjbAoTzNzOdNzG$acq3A z^Vf$P@z*vX-?`GB04fxgx4pOBZ~y0|*z;N6Uk|UCK1ka0h~oa*F66yH+7m#9!j(5< z&x;*<%J|YD=wGDmk@Uv^Dikh#yfylqj4v(KOX$P+tyGM$>gsBVxUb8JEvV};^t~Bp zIFBx4oUt#(z2mTv-H8XAgKn9(N_z@@FVp%a@f1LX!qqnvuP&$WLh=83zy6;H*8jo9 z>%W(f_X@~M(Jt<<08}Vkc?Z_lPxVSuJ$ekg7{SedjvafxY{tOuVGu&HdG*kRO)iJ} z34XuxGRDtuBiZV5!5)$OJq`4O^*gF>bH-^FN7j?Ti|!C`SXnv8ZxqTodkY(0D{Tm% zLXl^~>+)>aJi^!@$A+@~^%1h&AY}tkp~#c%#yr_hI@aVNrDW?XWSarmCMCWHphDrw zHkj(x%hg+|H`9kP68vW@;oPbBcNA#fr%%`I8!0HiTF!pC%IHvi_Y-p8B5ewwLgC6C zYBRUy*>r(M>bt*?Z5CwXH>v?tC|ud_M)eCK-qQTV^~fOTapc>Lkg#i)+tr_qtz8$% zZddaNUG9V~oJ#|!P`J8;V(DGgQ4`9T&=_wIzz>(gTFNzlXdWO950UTzNx& z@dsn_^jNxLu~;hOz(66}y^xLl0zierl?{IJqVE^?#(wcfBV@Pu#pSSjxQ`9T+d)E? zKS^BxR49C1Uh;MMW30>l-Kfj(<4fu?uh8Ys(B;7-1_G#1xVm6I^<|+8O||Wd9>0y| zQ~ysZgL;`rcqY&B=2K52`Z~|y`P8(DHK$ix1JOv<635BywhzV0`Gjr{K{sv>04fx& zZlU(@u&JK(_Hbn*adNPb?NP|a>stUS6s~NT=Y2)ko#NyT@S%9BQ_u7MMN2E&-Vnj- zaq!wPsbc^Y3g*=kEl0dw^?B`wIwoG=*$3x7F^P`()t=QSVjF=ktv^Js(YI5MxQpJ! zZEKpg^sK0*t$Es#_@`ysaQxFcZ7KREYWuP6NJ5%&JTlZ1s9+hIqGgFrJJvGP{6hY} zLjFe+`2o}z{H-~s{JJl{US+Uyld)Pms7?H0S}Jr z04fwN55)C1g{{bydd9KvH6lRcEUCxBg2x-+!R;78g~H_#YR7LH(jM(a1nsvaZ2%RD zJlgMQ+MTt(P$-yvm7JBwJ5(l1l=eczJF7If@92`CU zj5#9>)HB)xzcYEmp45PPCF^s#wWj3_h|i!kj^4Qzv{oExa(qck*G?9#@kGnSdYSX4 zt|>X<9|V?d)xAjiWMpOYvT^I1xDI)zBs^q)l0B~CJ|=t3j?H;vhCByXS)TI~dFI@` z2BZ46W{nwH=siZ&8PVGCtg~6>6C0MXYXP_9e3XvESu)5de+If z->$)ew=?eNkH2Y(^csusPR={raewgpqvCm?obThvadi?o4x!dC9bzCBHb=`)y}gB) zsfHmYY)rjhZP(?FuQp0X)XsBT6D zwZ8g$sym{^mI27bEWR&X%ds6vS>4_VJC?VMZ@}gFR)z-0Ld{RCE8b5sx$BB1x(4=M zw2nbjZFF5RH8s@|=>Yr`Y9eb%(Lil&`bqO`SD)iwk*wkn#ekP~^#*opUT9c>EVU zIOhORp>TO1=Xgihq(0}cHi`R0wu$W%rA_8QpU5oZKGB`3NMhDFr%!ZZ4uAZc<;fjs zUD%yKB>ioFU}Ki7wEA`ji*AhJlTc|+1eo+ zkCgyaC|uc=B-!2-vZareAnTmXEm-|Hw-DOfda=2Mte2&P?!BNpkKF)NC|Gwhc6-m) zy};NFcK9F2Y1mkCPU9NO+RElM(pF0gTlJMb44^{6wrY+-K5TM%vmY+lzHFcF3YOcx zDnhn-ARCWi0aPehHZz8O->=7vF)ZqDF6Vb#S8;yln#9(X&F^GgEhFqP2=?GHHh>BR z+rx~p|1RuNKgNa)x-W-h_2L}TRWFIBHizu2&7#0N` z0qV$+{pf(Hd!7v;am|wg~GK7a>al6Ho3u{S6@LJXU^w}tb6%fae1NpO3@7#xPq|NXxNJ9lmS#I*j6T2{8ZSgt-7jX z4<}b-xlUfmjKxIekT>30QOGt1vT?2mphCg2nOyNRAse;pK(4sDBkx?!71<`GbH$Z} zJ=TCdI9CKvpZ4>wm_Q(K{Xb46CKSgv>zImYbkl6+3*ilAX~#ibyjUI%g4 z305XJ_s87F;&(S!)U>ZpXzN@NIGii~6Sh&S;5(fwwya#A8|{;uqj}#qoRere1#=SM zvJE&V$)~~g(zqfgIhXnXcP=qCCutf<)^yf5a6lpL9%Ex)ooO5c`(|YtS|mo5nTCxQ z!=r=F49yXaCYx}su_@XI=NbSi6mI*#TH+VBeXMPAjm_vgH`hS>Kpqh9`C|!RgEBO~ zB$*>3JsJmp z(0dPR>DOkKs0X!Tje0=KfY$1kXje4&fo>lYO|xdT5Z_3Qb3mE<^msifZDQCx3^b~v zHRVmK5@&FWZjRLEmL_U5fmFv@u7wBfU3iccQ8LHN18{sC8sC zpmhY||20IXr`}8Plda#g#=4vEe-6Z1C3 zH@2Ou8@H1+kkr$@>XuP)qv+GocVyI)QX-ubVbA9Cx=lDaZf;KG*x;s10)G4y8l_GR zJBX3(SGV2H`tkelyP}mhCC%Ktm+RpYTJYTQ@MxohLb==8q%Zr&q41A~k~j*WLc#uF<_x~I{;^){ zAAh2%>Wy3)8+y$i$-{`2&6!i@42tC*Q%)n1%+_DGF{UNSifyvt>Z!RycztOdVUHtV z51!uvP@!OZnE9Q53wyLxk92f*=66`G7a zmg-a^9Qv{`1P|@MV}m=k>_0ZumMgCk@~!oRywf0WHHkd{Dip4~!$_X*ge}RXv~N-D zQA8jPJCJ<~!VR65$sUI}`mAsCNjpQc(Z(U2#tEIKLnrnR02K;XC#)5Fbx=LdRDq72 zLI1b_vgP|nXYCF`oIOLvK)9J71J|eDipD_ThGJko4UT~tSH!^k$qt3)O6JhMD=m=@ zs`ITu#?9(*JyhA@+Wt1Y?`i|G9mmsC;U7Gw0-!?S`UmDz{$qW9oS9Sk6@3?)Q+d_w z;br-*`kmRsiv*Cj^Nm4oU2IO}XF}fJKwdt}2B1RW%8RpX-%EL0s=uWVVE-X4p#}DW!q55eLCcxoWvFY6$)4G`ADW8q}};afr+wZZoBQ@0)zRKkS!PRGweA?yLW2})`6eeLSC3A^d+E)Ug$UeBPCq)& zV>zncaRpUHdli~eqJz)c9$kw~vu|d0e3T#K`Auu=Z5BlxnC5=V0 zSbP0^?~uJV7WTRT_Ttz9phCg+GJ7`t*l{6!R~b)L6eGe8n2+u2`}KQ}pZXXXJM=B= z#bU=MLf(rZFZ(!v3WY20Fp}fHo{yV%0LiH@L2a601!UfsaL4L%2Huz=b>5tt>|!RQ zz>nSIvB?->{SE9G;wI_~X5TFPPtfuE&rRvKqWvduL;Yty4emcR?*CN(sU_0==e%p? z^q(GTnf`M#vK{xI*T^;iphDsL6#CDogW_CM^We(*rvJPaZD51?HW2rpEMJ%V&&`Fr z*F#>;2LV(lTzQcX_VDDrfxfe2B_|(bIU72szJ-wOCdkJ7JOETET-nfXHwoF&`=A++ z8GTTn4(@}f^FiAs$Bq7J&JX1DJ*?t=SLwbd9uWg7t2R)+(+y`kh-+RM)y6=j-0}K8KC;LJ1?09JasNWv`H(CI~y- z20I;;*a<*|g6-6d+{pLcmg+26V}#Z{bv(&;l&~&eKo_~tWaRA;g~yXy33=~;yzI{a zDip4~*tgW|`Ey10aMa)2$#P?z@FL@{=s7cTB^JNqYS&-g6EJLd^3PsG+Vjt?g&ucH zJpfcFd_7uxJ!W9eh4lD6>rwtZ9qY3Z^pVw(^q1q}vjcR0AjSUKGi84X8t5<0K2Ebo zU>o|aE9)%Y_YJSJXgUSwuz?%uxASRmzpZgazkLtYf5CC@S@4y}Ii{GkO(02GN2RSO zD=m!fvWKjd(`9?8vdfPBpc0*SS7=UTTe2JX*$={>Id26}p>X{feRiw$=M7As{Rn;M z_StegwVmMcuxv8`DikgcwEZ^0gXWTcM!e8w9_2QJ+_)Whkz=pxV6VE|Sbv?C8>8PV z-~QO{(b~i^r~OHrY%gr`7;G{niQfP!6l{~$Xd}|K!?(%1$dcXt5LgUz_Cv&L$&cIm z8PqzUbx<1(HQV%h7!6UQo}k%Wd5xnACz)&bP8*rBj&@iKA9?K&O4YB~*tJLLzdH&$&X#rrP@(9G9iPsy z<4?SX%TC$A8m_eCPQs4Q!j6-YxiA0~3bvzJJ_n;A4U%ho)QLvt=sAR< z<8fB;7wZOGMZW`|Ebk?`#+DQ8*!)}iYW6KM*8okEYb;Fi=sU~R&h(qfH72b`e5$`k z7_!qJIxihYxaL0}xw-lW!nPL(*!*)L8h!vDISu%XLYs3wJzn#9zZf5l++6*84xeR+ zk2wRw`ZRV1#{0fh?qu}!?Rr}oyK3ad?D|9*yK3ZOcI^XSck1tR%}1Vr-w5uXd8UW$ zs=qI3SJZD`PmWW@!C$2u8<&tne_u)tcYlZ0r(kXj+)!?uPlIz~jVp5F`^hE+bK~;~ zwJtZ#Ts|(4AZv+qg1prFR1;ZiLLRD2kWJi3JBz;y*^cw$j}f0aKL${tu)b%{^z^gw zc@uI7y4(97wl9kj?YyoYZ^h27Re2Js)a9;vTXt6N>dZT_t`jyev`U=`|GCijGw926 zVgM=>uD+NP>+k9NIeizH6JyyLT0`Ge$o2(fdyoRN*$)GtLgC6blw_Mn$VNF^a&Os} zT1wQ#M8Y#`>CONS_p|cm1-rE+ zZ=vJ1N&Nw+P`Em-KspZcb+l)ddSZ(a4REUew#p`t9HCB+pl|2Zy2?6D-MgQ^&D*iY z^FPy7EUiJe{~v!fTStTESRI`)UJEgUe2fP<`xmdHJwzS-7j?w35I}{3>&WaU z@?#-g$dlAZFi!t^BN8)zzldy0dkWc_h=(H^fC@#PY|VMH6}c}vsC!$q9T-IS^{Gu;C$xG~jfR!ZWb%9JFI zqr;=xd7;>`H`#@Al0K+=es2Uog~F}-`AFv>Hg;@ka+1FEoy9?0#Qq6Ac8DB3_JAJb zo7mt{_`Q*Rgna!WAJ6pzs8Cqm$eFNqHNTKAeeG%<_-vQguGs!ZL&bKxo3ATtSNjUR z2SRUNy8=+5V7<-SRYAS6b~PwP^*Ob6#YQ@_gpsH&O|0*T!fRLi2|LXPJMr2TfC>fM z$*f&1ApE1Pr8*eaD7<#Xy4(z1WOiozrtsR;{zBgQAuszgfC_~xFXpco6!KDTHhgp1 z*Fm}20xY+)b~PVCGuEzH{0BuH(la;p$N)zAOs0x-q_t6?%3hz8om@UJQD3d;w6QV7*Jnm&H?5pY!o$ z+Y&~~jV}iYJ1q%2aeM(#p<~D{Pi}Ozam!g+W1h!K{c6v zGxOEs=nH@TZ?oL_Kkxfe^MCIAF4HM6zw06A&+lTsb74>4M*{kOg)S{T@A|dw&m4Q{ z?;Frp@9A~u^xh11r%9ajbpqB`BR5xR${=%{0QxTC>AS4vBjC5A=b!EH*P@%Bx1LGXT?O~{2?04J}<1oq#55^o0<%R2Uyle2?6V~Th zI8C?@3cqhr6S}MqU3jhoK!w891@pd(30>N%8yFRIzTnJtuv`tz`%V$EZ3x+T-WNcH z!j%p4zKaXl+t6RwKo5XgPb3}&;+M7w*04fxD zv^S4w!(PEUowzyqTG{!l!-Z^HLbeYmNSnEQ02KCH1kb3jK3`)vdJan1;!Lc#Vkv1hn%KRuUDv1eOT$%{rJhnm|5sw`V57bNfy;j`F?%1L(v?c2ft~UUvXc zp>XxUy2H}G9(C&u6N!>uWJ%T?B;TV2-(A3$V=90Oh08b8wtsHSmL5|J&(ZeZl5*Tx zGRK8o&HYnrfe(#$BJ`OYxSGVo$0cUL)Ds2}4O;*>$YWn)ajH6F;H^t=Du=^ym7IfsYi-9f8Y!hJ8D< ziHF8p`83!kHLl1V?;$$w9tCqBZ}7cc{@rD4Y}m_=~>Z2Ri%yqUg7x{sP>PzvR)F6|Q$Z za!IRq>qGiZ=14KE1-1*((!FaQtr0p7IJhp^C z0ypH3`83!cHE!aM`uV8c?$(_$Z0W}`0}A?PcgHd8#DS1J&zYvR*+F^=i(yjD-KF>8MwI2j)@qg+GV49h@gTr-f6A^q!9Q zeW|$>Glys9w3yBxwH%pqS{`z-IW4m%l|TJ3pf9%Y6xCOMUs7MpX}z!ea+YJ~9qa9W zMEYFfk!CK@`@R7={Q5sDAV-<{*WZ_t!<}2x`V`EMfE$W0`7}7bXxt>epzS?Gb>rqo zW(*LFDVGpxqkA|r&o7wfq@&C8sE({mNo&BUUUcF9?1BeOerR|X`(VW8$2oN;op!dFE|JgYmgQc#rhbEG= zG!~S(qi$|#eYLE=6NJ1MN_hcPDDvdJ2=abNd5kCTawfN67n^VAkh~w^%VP4LDCE6F z$_t=Ektgq^MeVz1P~H;uJxR!WIppQ}3IG)fS6<9lEbsY)or{DYIP-;US34(A>i(=> z2-&WLY&_ouphDrwhPn0?glu-ckmjPUA_DQ+Zuv1htMW&fTu!qmiRZmi%xA5$MvrDXdEsRor!Crq^jSHm5A}&Xu_xQseP7(hy(9IO`cC71Ep#7u z^%mlwXBwQ7sOH{@SBb9aFTK0DbLan3x8!$eu3lcj-LqfHt=>-h@`b4Z^l#zrIEf9< zzYyw=elB#W(K3{X*+Q zJm>5C9UqN_tsUN?)PZm6xUtRGp+2M$4<(rD57oqf$&+D z(}a%qK}T+@04fx&ju=af@#|`*cr2lv1a0+CR$0+jF_u_8B1flz#ia`zeS7HGMg8KRi9k2xXP51vl`7%8X9ztWl=TXr zLgDIxdR@cUL&qK4AEI9C*9y@t=fv6$dwIOJBV%yR+Rmzb(j3~|at;j?{khRI>9?YD z^}yx1i#}v8{XTWm)UzxAYmW2K@2z^CNYhT{DbO$UCD@wA#uX@FsF^d~c<-9-wWK{Y zmA|0zoI{gzgMaMNt8LUmwW)2mf_Yu~rFJeURylye(3AtIIJ!w!A!v`L?}zB`wLE&o zzA}+;h(aGDV`X)s5H)GgGzi_)T-l4(_sK(z445;APW1azBtuKZeN3iuHl_`m+A3q{ zU;TM}4I^yoo(VgfDD(WpGw?kge*vgaxW0$6L2Q@7m7QUjw(2AF9RwRh{T5D4YrR9EI_soO}nmrtP{77UDDgf%P?|E`&el2{PqEP z{Puz0MEk%G8SUc@k|C>o;PaIBaUp@&=iY(OaUTPqLgD%x`j~aC&;1;Rp*aA%ALS(? zp#8cfqPP$}U}C^Upp*Dn?{@8H5UMtnEL6J)X3~BJL}VW9Xa333I;X-XZIxNNJ$2Te zCsMQTm7avE)os_TSF8uw)y4FqS+5wq5A|o>odc+Et8@5$SMU2$^VLQUvnQ45G`1(z z`@R7=#(DOb8L-E$CG4TUFC~XNf3Ni^IDZdZZsWYaA)f~KiyAj+_sAdaC%<*)@7-=k zG}M%PxzmQ$yi}b%6|E)Gle?dxCbFjPJybb$Z*uLlI~Xn@+i|=90_~prMF15F+XgUi zkA87|+wONmyKk$0X_~t~XU1}!yDzCwb|2%VLbk7^Yyc`0d9wX0PqxB)ysjZ7X8$n> zDtfO4ROB_#4Rjm2jD9mQrDebRm@+B14SC;}YD4ZCDAULC|f12t=Y{Apur ze%|+`^mSu~rc*Fx05=pf@@a6)(6}OI+*CYf;Q9bDHB#tKL+8S6&0WWby->SZ@xen4 z$A{_Hh2~8zCp&R`XdO-QVKNfk(UjCp2T-AK+u(ep*3WEw*xkg3Hu}!uAhzN>v|gu= z6w7uW)Swu#Ipw+;=b=--ertI(KxZrm}zn;*K&wB%?P*~X!|DfN7o_@Uo`o-tH zS-+m%g@P@%|^uWu3g7AYoQs{O~r-{;sL-(yS{?_Fa1G_Ws4*5#GL zRs&$GNr|rls8G1J!ra(+QJ0j%Vs00Ess|DQIc!Si#?0Jq(YY~JaTk~b zn$#753Wcl3Fw$e=G(F}g0^V9r=$#FJ6tOe0G=~RRm+76lj{Ijgl6tXs*|&hb)s6I<$=MI3FZ_9cJ#uq)@B30YteFQe`w5v&V|QG7 z-604fx2+d}@irHv7Ln*4e+eP?mJ{ETJ$Hyk@Zzm|Q+3?biYkdI?7 zfC`1>jr z+gpTg>q56lNj?XlLgDI$+YweKuYdi?v6!Ps_S`n>J7q^YyjFoNZHlgQ+(3AIJ z0jN;8dJZF*xA*n5`>@6n0WUW%_kI=EVPpHSW(j>ZhCX~BB!CJ9>tpVN+`-o;a3AC* zM9apBxqKfa8>PT~kg|Sn7xvf;_Tc>$04fx053?6)N8cWG>+qWsCEaMn{tB$aclSM% ztbBYArF8ZZ_fXy;Y_TP5!Tkk*3WaNnP=7JO@q=K0QFxBItxEaopJcuYZIQ3K`PrTH zTeV<*2Ha47mQRE8GmZN{m7i&ebZ4x{W|{M!9%^=ehW-@uQ#S7qkJMivdufaN7Xl z{mwQX?1dbZ`fi#r(Q`^aCjwr)FE(Uq5NF>n;|)~wC5fsKv|~%DinU5 z{@nW8-ewGUP`FN6wt4oVhsa2_QvPYcF#oo}U0vp>X{h^AnS- zfA4GB-jOhZ^De6FADn-Sg~8gJ@T zpp)#4!VXK?LkPud2U9K7&P7$|y-`54JL&LuSj;BZuXDsW~!{4y-eLa13JOF*^A6qJ2$Z*5N+My@3?L>^+4S`E9km)^AYF{ zJ5{p=Lo`ebAhZI02KgEN|3D!-G%vZZAu^|v`-Qe%IZZ!2k-MlF1x^?p{=#Dtt)(sFFsT+J3uA7$# z!gX^Q>^3QxO9N1$aP5Y&{5qu+b;t%E)0u61PPc9{ zh~HL(t?naR-ED03I{2j9YIGui95EA@^0*@b2o6b1~rHC zDr;abaN=&BJ>MXFw&!)y-vCr7*q&w%?0__T(jf=)Ue0lO{`Mwlr`vFuBdxyyvD^F& z#H@J=`P*Cc0o&(B>2Clk6l@>kZwF@DNBZ0G`Tq7c_@vwF`ova1oV)%8j@F<>{OujW zXM5fZd-6OZfC>fM)9ka2^LM&}lbR{*vps>n!+bN^rE~t|Z}>j3lbbs(@lNEPKLMic z1Mzo!{-m=u=_ne)JeUk&^vMehDKsy4-tk@fvFKO}xWO^Zdln$aFq(GV80H}3Qx$X~ zDPx#B;7TcHFMds$<&9w=kFg&uzQkvf@S7OJ;D?Mc%pXXGtT7BePZ`6!PayV<``{as zlKvh*g~Ig>^!EqbwssHRZe1Y8C-!iU&OprJ9=|{PfY4ay2cR?e_W&vsuFmN1t3jQqzehKw z-z&Qf%3~xa`up?g+YxPA_YXlkUH1i#wz>n+>FBd`FMjk1M6GpneHrV>zWyUZV%t0@ z{Q*FQ!nFTDE zKO7R&+4YCp^Zelx&`#I=KZ))@>~?I|K$at)2*Tv(Sv3cd-^mzO@jGhvYpCZNb;xXhgb;9u&zlnH^A2Q9^>Fnm*cYFJFHTD0F@Oq%>x*cAQ>-sm<9K{CE?uMc_n39T`tetsSN{_<6CaGnUl7p5 z<6g(um;}V;%1m6@<}^c*SKIC#s96b0XKh;|JNr@TVyN=EKK~2)v8ay$H|S$uT7dL1 zO}oy=4vl>b6DNim`j2LM?k_oy{8EOGoeqQL%v(Yp-^cKq@G<<5;bX7o_!vG<@v*N6 z#6I>meC(2BFA#tVh3jKD<9nF(vB|NIq2D7PYpuRm=Va*fPoZxP*WXP28Z;9hi~D>C zSbL4ERr@~iF(8(Wb5q9pXM91$1~x>B-u8^|k<-ZQ9+O@NC-Bbr{)>Jp>T|#i`rJ1b zAbn2LuJgGgVxPl=P>RpJm*H~{l3sZ}2YGy-!*9ap@I!{reU#&K_&mkuz9kU*+^6ul zNl9D-P@!;r4sq>B>vM-lpR2xG=W=>nf;=tLeiJe{b{enL7JYTT@SH0ievj)G3=KlE#Lf3iUBHTtHy6V43{j4C_OFGF-j zsZD|04DTcO-z<4-`ET}V;G3Hp_~xt3Z`|>mwn4#tB*5i%#^-GFY0N|RYsDOrv3b(= zI%{L6Q*Aw&)RsO|33`5>^F8XSpq#)B$(c`s<nV5&!0cN+m;QD4Plx5D$%3YlG~7q)TYxqO(yb2hK}6_P|HuYQGj%mu zjt-wX^aaB&7k9!h{wnt`0UWC(PFHM81-ShZ_TeFiqgQ5u~3zTrgUo+Dy@ z9nm`DZ9Hy{E+T%@9Db&c=FGWXyJuht&B9w>Y7;z$OCA6!6h4pRd>(e~dnwJMvv%w86bfg{P>A|A z&kW52EVDk)1ATwgqI0fxLf}}(@e9ApcZN2iZ~Eh#KmvnV26i(2tqxs#jG_dly*iU> zi6Vk*2*#f}qE*(k?Vu%UgvZCEb{QVnzk57v87UU@XD66_vU`d^fvr(Vps;(;mKkB= zL`y{D7qnfr2?obWs^r)tIaB7`U&-80Tv3}Teyqs}7Z{gVJ8ifH+X;JvX#7q(IJp@{ zMxk9fp^Etx^py`SS^dUu#QJra&%7t*@`)Yy>BMmlp*oljFf5`F>PkYD7}V876~iC;93=W7DGw)6L*d$?uu{NAK5=lL6x`#L!qfC`11 zcOXYQ!R8%@Qg2B63^t+f(sQ&vg2!f(2Y?Di9*@lhkIvdwsQu?;?ZX%*wb_ucb!tO- zmYdu3B@C`#t~2~Da~tFYCz_l<19g3zLQJuzUgiXc<>dsRb&^l(!yv80vuMRyKc8r= z`$dT7`+Ps>Q?OqIF586r#e5oUKaJZJpVtHm`n-o**5~_^zU=e6NPh%Sq453j7uM&G zFh0MV@JD~_Gmqf0D|qmj0YHVq<$*E7F9i=8mkf^A<1oI%Ji2*h&@h`q(f5A0U)7zKCwTD1->vZa}dO(4buRIxnm5`J%*t#2;v4zxcKB3>ivaSGBC|v!9 zk*uk8Rdwsi%(47R+ahm{MeC)fbN2p4{T$1Y)I>eCk};D%$MS23-yEA`VR1hvas4?K zh}+;C%V1F-Q&1l~#{!^2;nqhe1{`YLEJl=dK1A?196Tl^J`JEk;qrh_|Hk*}_2cuN zM_6Xkr>V1wev5DX@oU<}sEU32$zSRrr99Pr6j_z8Fo^3v?Vhyxg^ou_9RXA*d>v2o zbv&AQVh_jB-LKo_f}u(qjoNxVYI{dAzdV_Vd7*Y25O9&n}fyXvUpAVoy;qt(ofXAbyIzuv% zJeCwZW`f70ga?2Mh0B9F$LIp72R(5}9|m<8F6iGT=>w=x37yn{xvnkR}$~l z4H1=T8sasC7@ChVhyE`)xO(m?G`&k@u5zJ+!qX7??~cQ4YkoQVTk zD|D`lXC9+|Lp<8_lqWx>2o^lJvbo5*>+w3_SmF`7$0x|+RKo*{!tTXAmhLK}8>GA4 zWS!6C(T!{G)ui@x?12gV*t0b1rC{sv-Iax zM+hE|Nj(5mC|n*PJ)X?eW2E5mgwz8-g~H_lJudb2(AhN&N}mepF-q{54Ib4b_W)3# zaCrB)WQRw?7^yT;mphDs5i@0%>udkiMdrPaSeZRrE16Ju4(}%}XD$O*gjK`EcBD;SG zx{M@wt|ob={N^q?me$rZZP{6LGNXCgDEcRA`?2k}^z)SC(Y8;Z!e}CGu#&LB-(;Nw zs8F~zK%HL`v;o!m@g$Qz3;eD&26(MR_}4pyj;93Pdho)rOi|Adm4z1Q|NcIAJ5qUn7bd3-wDos?TtlRm;B9} z{z~LIxN7p|*ehR8yi(`4pyB7YtH9q1=C{CQpXK~Ep9cH4#_dXes|gg$Z#~?y`R!=Z zm&exMBJOa03!p;b#vSB^*V(vpg2`|HL*J$6x2p;s-+>3mcK{U%mj~ke^@0cW)$~}F zUWfV~;l|HzR}(yblzITDP`Erodh}Q=OOG*vM?|=e9snv7E)VE&gRh6(|IkDP>hxG$ z@Mr-Kt`7he3YSMnkM>MG#tI&7QV#$X3YQ1;xY5_c=II?FJ=PFBdPzM1R47~?Aw7C$ z>anKa(HA^;EC8TF;qn+pdfepeVaEdfh(JSQ0d9hgj|J8ey37MzCM9D502K;X7mNjF zr0Fui8cwc97vE#SI(5%jU~Qq_An3>WI)Dm=s~__9n^W{_t;>*AQZ<+G#$~$O7sXiSs&+@?ig@AA;(b2!Q)E+6$+Na z+$VLbkb}^Bbbngs^Zn=-8Ya`8Fx<2_prtxGD8nW~hSeYg`viar1C&p-Qowdg?l6@l? zGw6{lBBB||evQ;p=Vb1_hfN92V*<|e@q7I^_GB}T)j*xY--)}|DKEzgHs7tFv)MVY zhk*Iczf9qM5AoQWzn!~dZ{}Nm?9JcK-LW_GEjadGp4!TtXe*K8Z-<-~TI)KIMpc>n zD2^jq|1^7Lhf?3z%RN9V_EGS8ynV_0^x0T_r6|ts(Uqdkx)sZ`=LY0A?bUcXV5r_> zK^?K)VX*{yV%}llp4;1HuLvod|6Ul=Jq2{B9Tb>n_!ZH)(&&dv{Cc(Mt+Tyb&6R$x zwtag#rw@D99~bV)$Avqbqnj+%W_yuTJ*`mlTjk;-!5#Kwuss(%INGHa&2RP8YmSbb z>HArj;fr9Hm{)F0v-<~DUW3m-&e6KQ;AgHd4b?R{R`iWygSf6DXND;6Ot;e@CT&Op zb=c~tKcQ{wp?|dDc4$k+-x{3f|BnR;OwT$Z5ujSC?I-;iP_P2ztN?{ESf*H!Rvy(67cGkT^Vw*Yx(m!_S}DwF0`1X6dkD+J*Za_MNqXM`GKxF9 z@I%I(T|1HtS$7fQ^OQTgwjdDCQSO4AkaKqc6$&>eMDBjK%}aj)!_d&{m*`b#U3r2| z1u6G!iAZnzM#Pq&Lu-G%DhE>$-*pe6Y7@4i`-5MEne=_IK*SD{_(Jdao-X&Mpt}2D z@rk|W-pjcs5Quf#P3i`qLQz<^t%AC31v)|9u8_I`v7~PJBt^Ha3B#p(w1| z)f2Sb+ zzQF%X;NNTTCkFBN2ma?Vep9qK$rHyO$g}LArm5hwZ11M2_@10=Y&=?4g*&cOX@9-!@F95jKi9CT^#A4M``#bJD&5{Gvq5Vz-PM95j208pWD+cW0$?=yB8TsZ}CxUE`) z5s=l#h;p80lHhSHcyO!-P@!;nAlCm$@UZi46ziuD0X?2?i8doV8up-n-5qq2m_hv+ z-Wh`8wXs`MtY530T9J`q)Wp*RLBsb?2vmDu zWs0X;cG!3dMC+gUyK+rh|8fvPS>~&x%m6ABEKhS3lKGr;nGXhypv;G@B4h@ll^K7h z%UmTW%X}?l=6D03LgC7cc=M2F=X2>h8E-_NI2m+;axX6XL?BwZ@ppYJaM$P#AqBNpKfLE ztgUty`T1wk&*68zpC3iP74>uA2L1eK3y^-UY1jGrW3iu8ww#tf{t0GE@$)I9SYG}J zd3-;|Z^F;uP;3+dY@jQ<=1+KK<@bF&!vK-Ai4ZB3JFvtT^!{XmT~vv@+^c@F{e`N=?q z?r7By{SuOq5T9*LXE<;-j6lqao=RiKKe{7&v~rIk|+KzzxZnPlM&uxQU$Dt4mYVW!?(c z1Pbms^>EAXIX#8+W&eK({?GXgfC`1{|Hx;awElk<{J*XGs`d65QO4s_1&>$2gU3$* zDikgcjGvwoJgALfQXO-~uMq(~esXi0UkM&>NId{lC|n*PJ>JgLGAhWJ$@^Ayf5_tP@!;nK#$qJ9_SQMA0LGD zI8E^Q2t0Ui41fxS%L993o)$dXsvjHD-kAS%LHiTXo|KGr08}Vk+Ss4@jG%2}Hp%}f z5ipC{9eqbebX&H+|LhFG?{moyK!u_(zkh-sk|N#@D%;DMg5Q_m$F>7dp>X+yZ1)v? zN6p0F1HkdZo;7d})R6A}SpzBCSwgmdK{nnK1fW9U%7*#uXM?tP`^#^%w364^g4e$# zF8~z^pVxC~yl@wpK8N#NfY&*K*Y}bafC`1r>v^A-KKDd=C1-wqNOE&r0!`pEK*v{J%R0)8HzrR&q(A9o&o!}$y6B>264f7~08BT^cu^NnvwjQag?y62q(`{S7J zKIhaOGO}^Vp6x>(g?(FZ`ZB+OZ|nB->0UNV=J7-;c%OOdeQ+%93g^~|o5am=>+@X# zkoPTL-e2S6I(c<(nk6sROoH-e-+RVFe^D=V$i~i|7yfqQc}C^}`^9jsfkJJ8yCa$W z@gU!>cV+UuLVA04`2K!-cO-nG_&EyZchkB(>iMC6@Gf<KPidsi?wC2|C)5Q&-QNsqX z`rq&p>yHZSo!iEAo2T%AEeQ*dljOaF$5og64uXf8{|>^z7gBEebrM_kJR6AkvGsxy zu@$(X*qTp+W2?qZVrwXVh2Iz~7{4@m9c^>tmxmg32IC9zO+-I_rOMlF@rxzRjb9#W zP$}|d>*HDRD?_jDj9)BqZv664QqzaOZh2zxuWwuQv~_oJ;c_G~Yd%zH`?#5qmJ! zdk^EDNU?;kQ0T;1Z+EQWCU5yJfs>1AV?8PFMMB=yq`Uws6nXNFfxOQCCM$1WU*07z z3dyVY*cFraVj=HXDKCHuMV`ECdG?hyxkT_-6Fhi50YHVq<$?L@cSIf1{4X{GVg7n; zB0%#f)+T>5<8`jX!-F=_U#Hmwv>F_*GvAlMx2@_<&zklq?>kzSbZbXFs!N4k)|Ivg zP-D1u3HkPVuze97_1Gp;k1GX_ zt)(6SDikgc=<&X83I+3MjW!}4fA@LVwF5+3zMlYR zwed@GR(l7l@1WKJt%KTV)xOPpPxNXb&rXnMQnEeX*PBYq#I@%uRuNbY_yZ|r^q+_>HBO{8n@QW&9TL-Sxxw|YJT zx(&(69FhCR?qS6DW6f7bxL)qT$lzJs=25A$!Med~VYa@c{)HIG;!P$JZxg>eqTTm5 z<3ZW3uN8LOUDg|b3WaM&)Z0INJ8D0odfOwf-mVk;_5wf7g#c72Tz;YUx3^^zBTAjF z7d-ZrIsvFqxI8j-+Rrje^TitkzfSPu^+^B~3YQ<&CqMCRsC}PW9_EDgn&AON$$z)^ zM#1YK@Zx)P08}VkUPFo3r$JtH*-G``n1@-P`;73WTo$i4jWz2{HxWHryE+W4;i;w34+eBiBDc>&lqcnoP@+>nMlTRS7Lm zt}j6A>X_DAOv{t&XouD{2`x{qFG1_tnAX}%%ad!WL+iSPmM7O&pmlvrYaOQL$#slF z>xP6@B3Ig4-=Iq=2l__lK!_%Kt1q#k9?9L%@_gV!Oes}UWI_|wEb(Vu#2DVgopg)FG&`k_#ePe#g0^Nt#lUo*O zGhp0b4T;XViO+u*UvFax{@b_l^)}>6{V~3=v-e_3)Ul3Yer4YPpGZ9Zg?e-6TXXNy zbQm6bnI5ab#C(T6c8AyBVQ=4*vg6HfG+&2S@5{}&3dDHMK<^i}$&DQcx^MG9hi|*0 z!y(}7-@^~K**bLRS|r!t^Zm5P6kLm>eY7RtaB|*6XQrjzMDMKWIR0%C$7#UWYdVPe zW7(S#j|;9j0+(YtuQ}$^;P|g`ld-JsK)$(6cOdXNe_U%oscVj!SnjyitT}qP`Quv1 z#U@H!ofa{NTQPS>s%ANw>7Y>GpmFSSO^n@@zy{=9uyW?E-3^Y(FX z;Ep!>bfgPUySTCBv!ff^Sf6=*N6j>AY0g6p&+OWY8qJ$gk!NVr&x~M z^%D;@D6)xpynZ6b88fNf@SMnbNX&RF1E50T=HeL3{2TGIiRN`LpfE@Cy64k(?wp8? z(UjIx-{5G}YiDw*x_RBTvgUO=Yx_{m&Hi^1FZ4PZH234ht@K;bcmdo{yvV1)@j~M! z@gfu>a^}7?f!r8j=Ds}K#$rTcy*zPSJxq4!F6Ip$zzt_aV>c894>$gh06nT zpZ^g&XbyLO(5LyN>xqD~PEs*3kv;PzbWC+IQGcD4x8jWPMJB(mYXo9WPBE(yR}iaq zyENkNRI~kBM`Z79lQy|s*yKiOcK{U%*CyyEe7oNayE|(nlE)o_#|&wA02Ky{di}cq8?OxX~((Hc2w#2F-yWc5na;vmEfC`0claSqShuu@x zEbbCKW=XpPs8F~(VD}$hp_P0g2>|Iu_~LT0|? zp%&`P?HG_IWs|+K;e3fMT(Nt%w8-%RUUw*%clD!U39nt{Y2km!(-2YRSQe8(S;hh;7>9uFq5 zq478iIh~?ZK?l>QK?ft-oAGV-csy0FBI9uuIXA!cP=g|8kH_z!ILrC%Bj|T{JPx2j z;r2V|@9E%(8INCN^4rJgy9(M(j41oIdj*fb$i59gg~H{5{=SFcLHX@)(5L?Xaqio& zmn+V1*%VKpqU-v5{dHD<@8q|2K}+UY%xb}_h*d**)*ppUo|JY6P@!;b60-Yj*gZAB zy-)D?tF$|S3Wdu9c5m|SZu8rxrQPHFmW}ZS-i)uadpG8{%xa&8^V>fOn>;J+4xmEe z+9YK67hw0){Pupq<9TU!02Kb zuL8?b`RxP3CNE371E^5AHVN7NHP}7X-~TLlyejPuphDsD$n^KurQPfNeU6Xk*xrqg z=l)OF{GcI-Cy|r==aD{Y4`1{aCQEDJCH|gU!?n^@te4B z2R~%oxAPInkagb;=dM>VCxxV;C8`}Z{h(O$xXzx{j8 zaQAg5@sIB<{fnR*-`A+=diON~FP7Tl#%3Mbwo@MmouJK*C(o^24ENPH9s$t`kH2G^VL@GsAoIW{2!mz+ z2D0-TN&qSpEW3F_si#-p8E;_qYb6f|zoFC;T}^e@7ky{b)F;6!(a){Bn>VHV1|Out z=m*5+iheEx=h{MbN3VtGtDIV_0yS=x@lZd0D8;E~4EU2aO51#NJv&!+>3330J$Epo zwGTM-6qgXo_fhKW_!;_w?G~*r;vs+v1>4QMW0o2Z2N)xHaqC&oNo?f${;r#mg)rna zz7NELaSNz9aqBrkVcnXc8@GJ`6$;j^blV?Tu}X z^$#G*7SzCPcOcRcY9z?<+%pI-5hB~5r)(PlDip2_kSp}@ZBU8FRP%D%m`r#N7~Nk6 zokVwX zIm@e{lj!HR{g-6h2V%jt57eBt{~DpNZvCMf_gw%g6s~T#C(G}<1{;<9zUy^-pXlWF zUC+Z`x$gp^tq1%a?z`R~2+KMUvhsU=04fwLt9j3_ukU9%C#~zd>fZAk;^_1`=^XcC zZ-P&vlkCU7LQVDC+GN)-$Vz}8|%mPc2(26rM+2H=iiW~T%Y$AeZlsg z5BBER2B1R0_AVOR=GT_>V%yuGm)O;fZL`RrPHY3Bv}yyf4Mf7Rt+VzPrO>l~NQSnw z8K&2C3^jFb=Dx}C4*ghkYzy4r*!FK0Ajh_vcHP*vpYi3&rRihap;S$2W80Ok$sgN7 z9#an!NpWhkG`7WWVr+{aGRC%xkqlX5TYR1}wtbgC>~q86b3C>MP@!;r4r8ePwvAtA z#av$F@MUu@8Ue zjBWoe=*Inort6JufmpDg0BTM@@d2T5y^NIg0-!?S+ALHr3!+{EW83&X=np|BXtR^a zbDjI3foN@pzy155W&iyVVX*AW$@&IRp>SnKeGl;K8}|`njbkCMZzn(b7<3ZZfcXY%)fo_^ghcK-yt5*xU_>5bii z*xmU%XqM04Kc%nOcB{a4oc{o*P_XUH*gcNJgDY{oNg2C;hVK)5xG}&Ry93esGyV?e zKc5qXWnB%j^4J|fg@R=@WA{N`JvT6R|0ifCdL%iI_HJ+N4piAYclX#G9LnV}U(gq9 zx3RDr$9n)33bvaWyQjwc@YwxJ&`E6M`o1@I2V%jv4Ah*s{1u_FZfnW551>N9x|MGG zMaS-6gI7?0Z|n}l?r!^_S-$Q6i@svptqa?6ehZ*N!L~E`?Yx=oDRu1r4d^BIiSt|C zg1oUi5M>K$Aio8XaDMBJ-M=M7w!!+cZ2+iHxHdrFIG=BW?6Ld5K_}7O?Hj$ZI}jV` z8}VJZZ~TrRtlx%GKL8a9U%%A0A0E5^2Xqqs+_vwH-GNxJ?E^KZ?SD@wtlP%Wjr%SD z6$)23jNSddD`o8d1HMmma{DfC><&cRcj51F-}NIwSk}!TE05g)R47B`&rk< z?*9d!L?_vgd1H5=%2xPOj@=1X}7q}dE!>j0{> zNO$K;;84zYTIdV5+jg?80;o{1-Ar2@QoOCA6(@JG9OT&WHHuFQoAshr@L?O$JuQ01 zSNE99z=m5=VMbIy4cah1Gv3#kZ$o7`D@Oxb>X(iNwBU$%-P+NB7CaPge(qVnqy!-b zw1lS1PIN7+g`FB08}Vk-9kCjq2YSykM9$m zT%WmD)&mf2J>c(fJ=hwQ(efhOF40W}zV zyKSu=9Ln`y1L+I4Tc`A202Kk+`^^$5NrA)f}H;nBFs8bt$Vo;87jXLvl^VrO_RqI|-= zCpx_MpBie@$iwUIMaX^=g5|koM|+?oK(=~X8?vrwe!rI7jo`;Fx3TZ}^X~K8Tvw7Wp(7j~H{Z4aPA;o2o+ zdzESX1q6?2()Iu<6fO_genH>%TgJ9OR@#0c;JLQ{E@*rG^&GYRUe}eh{er?S$4T1* zs8G0e3EBQc*gka~a3R6t1ZjH!6$+OJY(Lbuz1`z_lC(YTMV7Xo<9pKC)ywQj@2t(H z%9%~Ur>U|BE%{E-cWQu^zn6Pq`mJdH0^Csll23#C7meGM{zVfg*uQwV#rl^ybIy-N znXp|>*W#giT}yl(Zg_Oinf#v8{p7=i`oz{T=MyS*Ci3}&%x;l(+%7=J!*nSMcTX<4BP7hUTXJU6HI{V&GzqttcANQN5%lHAHLgBV;#E*q-+y0&DH_t-+ z5bM=$zqzR3ai)wP04fwN55$i}1P|&rX``=RS3XbJd+C(qCuA?(%0r znB_BIDZ9*^v+~1)P0p2e2T-AKZ4$Ek1+aT+++IxZIA7WwK!w8P0lN?L?QY}th0^YE z+-4)p@wm;b%EWD%CoV2*a($mY zs&CVw%XLIe)r|0`uRMN~__XQkm-)Iwv}V34FllSsY-?g%XKnWzsju!K`)Y{p_ti_$ zZ$Y(WYuwDf+T6ctWWj0Xxz*^KVyvrZ#-!N1@n9lH$TtEn!`oZ9~GM4D!=B#^2|hEnKgCgp~|VNWM0m$ z`9N;}z1pxH_5E9zc1*bsJ9Bm}bO{#=`f8$6hyTK`xfjht4c=(QcW}AyJw8;lPFlxY zLa2?-IcC0I>v-PCTME~nM)hjX>R5>`c!1|sKOnK`&XSzF>~#IzPpD>_SFcFC$(xfD z+xjd1POp3YIalA*ME~5H)~LanHaX~W(ahIF?=Y=Ev4+RkuVXC5>y`j26z*6GW9$*g zn{k);m1d0nmK{RHh;kgiqTul+cgHed*K=S#ife1NTXkMu{0+mEgkAn7Z4aPA;o2o+`}Z?#zp~)*p0quH3Wduf z)AoPQvHfwd!B1fOd&=5=6=9bTrR@P!C|tXQZ2u3~K6UtBl{E<;U+e>9?Zs8@L?5DId3Y2(D!T@}31vJBih3hh)EK zMPuvA)o4oLI|N%%#plpLhQUAfz)s)V)HdwZSeJgO9ZQN;4!~ZT1F1N=NmnIkk0#pj zy_fU!2v|O9~yth=lLfhGanhXduJxr zB@C8*0A!z>ta|~dP`I+sN3yT%$$s`~k-ZXG-&=z_h8M+}OViZ#KqDyk11r<+=Pf&| z+(5K)lioP`EOOeB@k`S?03h4#=N@PEhW}>DKw$TJ6@>K(un>@A`W(+`Ty)5(dk@pp+dz zg(6S(^Ri_h4?02F$4c3OXl2LWzU-Z~j}Z&olUS(d`w*M_Shx}WRx}m@mt!H%_vO>z zTvp>I@ew%~i58uhJI|r_RAatR6DXL=dbs(ytZZW&lfGQ%OUgP2P@(Yad=(oPt~D`j zIDIE$n(J4a2p&s=$F9jc(H@TqeaAR1{Y?e^5t2TD3I%`L9EIqQOr^h> zpueo751>MkM}IkoK73*c(s6afPPe{SoMp!B6UaWj+UnMb7hWW^Z*OxU-wKeA`y~Js z3RgbF9KQ}%r0?81gp63HJjc90!+y3?EaUFffABk@N0BGg$!pigrO$048~c928e!Yuz233-rdhwFARbMT?+>s|+HWVD zv}>F6NnXo@O}r=V%{aFsT6ZI!M}=M1fL&(9cG=k2Wuw?GH|N@AD`A(lVV7-_I0c|W z;o4;d;<;wfF7~cG+-f3)qM@LzK;^GfvZ+OXlw*oK=K8*YMsTBdCp zoAQ=`DLo(CTG(=&^f3Sx3fGosf9v?RwBxn)tqEoOb9@Xle}#PP`!4#}y0Fi!v3<5M z_Srl(%xwX~$hfqPu*-(hE&wVNzFpSy?SegzxL0d@y*N+#efBS$^C3Q5CZ3wK{5~32_3B8)%MfSpAz}#6rJCd+QY|;PaHwEYOBUikvB)tYa?vC7{3v(p>~7IPM|Tzf6ay{#a{A_#~OTS9NxfmYSmLAe0WFTxIK&uZ5a&Mz+@4UXD{6yAIkU@xLAZcZl;Bln$ZCb~WSy(#G1U z|L*1vRH5veuIa;y{r0>M)~r$J11nYZftedfyY^X73cXXmuVfv~4h13KKf6NNIIwAg zcgK`Zln!C>O37~&`P{jZ&&?A5Gg3ZLI)wFK%4f5N&v`D%YTBIUa~=GaKa)|;=jI9C z@27mCbO?*LjL%&w`P?G$KQrYMr9)W%rF`yI!{;F%5}%h2mCvaO-XErXqI3w0w~Ws{ zD*2q2_}@L{6Qx5~|D}A+s^Rl*9}=G{T{^`4+%mztXUZo^hp>3d_}sga&#e;wd!>A$ zbO`Iel+S%?_zZKXIo;pyV{SH-{=RjBcR%pzz7a}?uz1-w`g%HEG!KyD?7mStkKQIZ z$Nro{=jtdO!k&Y<`Ztnu$Xwm;F3Ec5K;_o#P3agijJ+wwsi8mbsi!=oHI3tZ@Jnl! zja%C$oE!`%IuAhU5SEj&JU&d0QyV)E_+H}wQ2gsW0Hs6du@&=x!_G$E#vd&m3(fW_&+k`6Qx5~|D|=|7d3o#xc58cdDT;`3EF;M zwL^mUXz)&x$$a*V97>0EwGF*(l(oJZ>&N{6uLDXVuU1~|DP&$TWm?fDk%X=L-+ZKe5xV=wF4 zMV1KLn|09q183T8@>nMZmJaK=uEuWSYh91cUjZDQzDvN|oEqL6(6vnEZnLjazA;W3 z)92fw8>_UXu(2xV&T^x_vE>fBx2k(DJ0%>R0*CsJOq32`IsBOT{J+vz$sXw_*3s;d zo+_Srj?dPy8OgbR!@1Uv>lu^|Vb8UQoa@`A=j!e2Y5vxqWBTBlm&+#1=(v{kn=mky zZNhAYm8^f#J(!(EuWMCZfAaTq4~9L-V_Em-FR-$g2GV_Rf2?16{%@Yg(en-Uc^t;t z?_~L{PL38DTlbZIZxcM!nQ$G5+9myg=M9vfVCO zxL)lY)b64DS`Kcpt=~f-XNvEPY11BI)$F&8>GRc*c2Dl{EuSe{clp+XHhbSqWXe(g zXiBlw-n4MrWnMGWcg9>Mc|KP1e560^q=E7_`)3=D6w``lQ>3()Ha=VpGX2GbVeV6< zYkE8_4=WV$c+-koE^}P%zYSlBtCMfTYY5tW8@||NZ(7>qtlms+Y;kbe*tLuF72SWk zjPXRrf0Pbk#}mf?^}={^R<{3kxg2NLJLD(zQHCbQe?>HUQ%Nex@ANwP>h1Qbrw{gB zA!F0nSR?${gv(-$_`dwD(;9(oS&gXop*6zWwyhC6p3}BQcn2NUh=OfrHR7m3e=Bc~ z^tVp(Qd>})mj%;~@^bp%RN_1?jWeE#aUL8(oUtv7bG;9Zv$t&<=kjOl;#lAv)W$h` zIIdt@ALn#_I8*Ryf4+nMtm|l$4q^K<>%Q-X{``lmKi?_Gsg0d~?wa_&EA@}kA@ta6 zzrN`I?n?i=CI0VC{iAe|I{M0R#$#ITwA96{vc`J1GG=;B}#{|?W10lk+TI@}?R_+DFG`1~Ywu%)_NM39 zJvqnYoMW0yTC(*wN{6uLVEw&8!n^F5h4uFn;bc|o?>&<9J;nKSO^4DU?D<&JZCE^? zzgJ4ubZ1My@@u-M#Z$xI>#~E`XV*f_WS_5$R;^rn>)(l|LA^?9X<@@i&KK4m+ia_Q zaNOUrk+gf}MfrUZ>t**ve4Br|_xw(Nd&I@u9oIs0+K* zUzg>4ZJhD7VaC@+IbWC8^R;Kf*DLU)?=nZ}5Xx8fF7wUX@|Avf{O_K*?Eaj?q}^|3 z>vGRs_OSJs^kHkW+z2a>Y6|=LCIlCGH`&PEw5G)NT_wc!2Vy4#V)O5c$NL@TYV5cN zbL;FLHMwWDu?75Ik@LHG#_uK>znk(;&z_s*G+$XpbKzb!m+<`0G%ry)gz}ty_ho7o z&#^E6>qE}V6QOTNc{vT)C|_A#ZrPTv zG%sKO|C^UfUOmjb+zNiL$@$$T<9Ex9->vwkXV0y3ny)RRxsaE8Cp^EE<|RspP@c2A z+`7oKp9k1_`F2@eX7^9dk$QO-^bIL5w}H3oa^AMfc-uDP?Rz<4*Ow8N=H)&KU+<=T zp>&8MU)xsk75njfA2MGnT{Bd^z6W17Ylob#8|(SnH{q+XYBKLb=@3P} zwkz`G??tuwH9|c7FXnxh!drTwP{xL;dEfSMc2myTjEu7#GtPF(IlH-@v;7jzx>L?j zIz*AP9jZ8sIo9((;_Oq`4u!MnaCS@1*)ADpJ7=6VbIxw9=j)d_Y$LY2+JAw z67QIB*4rHA8EUzgSZ5Q%x|ewWq-|r;c%pO&+cwrdJ0)!kYc1&m@p{%+-`eSe*9hPD zj8FG@XmWO~=~gOB%eAHhM6dfex;Mk$(`!v;t?!k7-zD5%GPHYi_4sgIzk}o1_xxG5 z@2SVXNs7r{&epPa3O9hxKd@rEeb2C7&);XPzQX&AQ(vpp`Re={oSy2CWo5gz&$n7H zkrL0sCDN?E=(8uZ-K;xidmPmk-TG0u+ zu+==&YfJS$G-ti-?Cd9c2OaJw7Ho&QpLmeq)&0c9s0F&8h|(c!Enq)!MyLhnWc!Ir z$Z=|8_Y)6J{C^bxdS4DohtOlQ`*L4s(t2d$Ep8cw7x0wZ5Ws2+LzxeO+CStFEs@*kxAoZAK3Y0{q$lu_e9CJAjvaz@+*PWI`=)#CR$jZ+Iyllmi7+qo+#53_3T5u zAIZmHLX3f*Gvcf`XFLjiJDf9Ot1*)MU&6bDjt+|ST|(Y>oFB5EGfs|?&qvbN2exNQ zRsJrabx7NacL}{EQ5dLsmk{kqZe@~p3Guh&T|)e!&AWuYEp2G`E+G!Dc$d&IqSCqM z`r^o3<3s5XwqJ3L?}wpZoewc#-6{9QuMHb4J?u5U>>2Zm=?5cc9g9!Nv(W=Pi^#t> zP6G!w+FRZkv;36s&KL|k{PrfMeFMkIY3KJ>8^`8g`}4=#3;UVJiMe9lD8-D@Av(tV z^;*ow{$8Hx`b z8~piVePM1>yich7ewGgJ6Y}o;@X_Wzq3mXtf@w$h3DMrmq~FV681Ex2Z?Akzw`Zjz z#WW9T$=f8xjWSp7M&%dS?S(mQ;a64+_d|~IueF}oJ#wDzfeoc_%s)^><84PZr;1WO zYEg0#Pa2htc`G&sPiMT$_VAvSf8~f8TvDidR=Pq=Q(W1_$+7n0WcHQ%cy}jXsb5ge zY%e`#U#aJ>n{3o?ZUj}}e55(MadJX;hP-FwJUtc2y|LKk&=-)d=`RfD*Dv#L*vnf_YP)-6Y)IdcwC!#FQJ#(%(^v9df;GP!o-fJn50mv{niFrm zD-LA8><{9h&3mUzy^$%I>F_ zKKPlNWMG*$4lI71fZyUA^%VJAr{fB?W#dY{4;@#$Z8ENWUwHY6sb}T)pT_$ny#qgT zd}$!m90|Y{QWVFGoM%K{a=d=ZF#<^l+z3Gs~IeWi+WqXrx z&feiu`nn{4drIjo^iDy2{Js!^iu>gYrlp`H{#pK}_sbWbT`0%p^FmT6=}c{&UC;*2 znliHevkL{&x@Q-r4}On6H(%Q4a6+FO*%%OC9owju{x4C9z9hjGmN!#L*4w+y`7++N?dVjkSsdQ3~c74h`m(e6AW8oKuJ zeXhg37;MYNxq2Tu&UxE7&P^ZONm_c(q_j3*qqV`$H{HdtHeB3_&CfNncNAM}{+JH2 zVOxf+-iKoIwhjpj@GAFxT*4^CJ&gPqJ3jx* zxbeN&UnX{s@5_JnjPIW`aH&{L?CtID>mN0tdqU5I-sUMG8WZ~_^iAxSw?y{)y%T%g z?Xsk;zoxCzBna7c6O<02ZS88XXSi3=R=u2(c4&}H9xFLzt^~7mL%tMq8VdKQ!f1yS-Z%D&bxV~^>a*mrg$2+km zpmYd5$0)zYQ#glRJB%OIyg4}|dGU<2YkwcJkEHV~T_}WyI&~&*Cj#cLcH}pIwj;gy z^N`jKy^HFSqF=u2H>$Ck#Oi>g=I2Y7F=2Hg5AeptV!y=u&d`Wh{nIwwlC^$H0-lr_zZcDg$Amsw3Lv+T)ga3cIIQagK`(8O0wJ2UDLm z9eu^Dw_-7Gck;xnuiVUeUi{A9t-`iU9eMIczmJpb>@^x+TtwbVCY%a&jU`2VO#bhZ z-~31Jb-sqy^G<$9&RcvAsDm{$=j&j7t0y|06SW5z)_P%m%Q?8G<6u9}GGvW-SbWKz zGHmHJI3_J|avXfw`%dBK5Pa3{F=(?7;Z#L_I8$Nj8|J-XkAb$2koc6%5$oRrqTTp^ zHD#<$(yA$>ax~?UlF+78$XK7>c{fX0_>qerIX~(CNF_fe1wQs@=jROHsmN>E0^)J3hOzWY={s`&)<5OAU_&k}DY=l}r=#tAkswR^zA0mMoBMRq zx%u5m`~ID_52Ztdb5E3eeCCsL7u)w*C++)SIPJS9Y2WK<`%pSWUHjhXqfr9;^Emi5OTIWE{#){DD`6R$rf?dzj`(_%eC=@8-E)C;aN9-i_G$DXUqF%5iFAa1-AU& z29yq=$96S{|4~K0LS8T4%Gc2Dt=9Nol<~z=$U}(#lL?+BQamUfqKN0{BA(EHmQ*}x zo;{VEXQ}i&C>^4Bo=V<6uICB;X1Kgfc-;4!A@cTgf@c6c>%}^N(jhD!#)86F-rZbU z4m5)~SSr`%ao^62@y)F94DnT)51~$nwRswsXA&Hf!7(l7GfIcBIH;e;6yu+5uk|&T z33#f;&}WnLEywwE4usMn?D@*(K+A{Im(2A?!K8bZik*sL`JZC#%Br zd~&`O((|Eoh~oJw=OHV$o{zkcMQwf^f9PYw4fSaf*ZI2U{=X+=A92CB=JwAtP;at* z#8+gV+q#eVg6MTkJ-4*E$L}NZ_jDi8tQ)=3uYnJeQ?hP6P5M%sb>r~((9@j4Y1(gT zweZ0?hdzhWb1wO$KWF}y9NGPg&s&XXggF%FU=Fa#kmdk-j;Yx>V6W{M5coTeobPz9 zq31a-I}f{fT6V6Md97Z0Eak5>=HZ#14q^^BL#y-J=C3~G`R8p>9dVQ0i`Qvi)AO94 zohRjn@xF!|)^NxBcsO_F% zBg|cY8OE(^B*$cbZe2M}ZS36jrNsZY@INEYSx`EJ9-F-n=Y-UMck}<`z?OCE-xA;7 z@xJ3c0;NM(-;C=groNl&$#G^nRJcFn<>Vaer{_TF5OwF+pzS$cNzSoRdJdEhQFo3_ z+n(d^$vHOR9J-Hy(jn|Qm^+@7a3%W|Va~OgIB1E-Kaz87!8tUSP&$M?M_DdyDaWae z&81fp|I_fVxrEXo^w^4A+N!MW|4e*ugKvE=6iSD%zG?ff5`KD{+g7&yUy1+i@UPsU zbcmw=Vn5s7_^0NYu}$kh*E3oD9@0MezmxV&PuqvmA?n&U!?Z7*AHSCP-wFR3JCqJ# z{qr8DmO8Mr9N3a~|4DrBlC~YCLs;Ksc{j7N?XM^P2h+BrbO`IewC%f=wf&96_Ycyx zqjU)CyR7ZISGN7l#Q%@dwxe_i>%X+^dz7{Pt;F|_)3&2@2w(nim_Wvfn_w~Nx*n!d^tnae1V?Q~rdhB>7ImiB-L;E~Rhp^`;hX{lXNZk?oNE4;@cnl0!oLlzDsMx zshRVXo1Vn?Z}2U5*5v!IC>=t5cQ+=r<|(&EArxPae^E=JA7=MJH&6En!S|zx??by! zRAH~x3OnpU&fK*Ob6Wvpo%k{y8c+$2pus>kCSUu;(bN zFXzf})%AFEa*p#k$JVh1pmYd5M|Wd2!SU-Nj+c3Zw%oosg|~U}+^WBUOFqOqs(C>; zKQC08*dtH=^%TC#J0@wvMJY~{4xw%6YLwx;nDg+;I&V0A@H`3WJqyR34!AKD_$($m^^yG)srnhIKP4hkf;l%#a_^t2PrLkN0LuymAvo=v5 z@_U&ypTfONX{~8{FH>cIJMu%qcV=h!W~a{F(0Yo}I`dKCF#FHc>q%3yccFMDcaH_m!^OD(`8F%edKlG{y9a4>H(kCeiSa zNg`giqHWBSnv5;vI}$9Jk`s*wX5oZINlUJASkhxW=huz!$TpB~fK zwamD#U6<=`jI4Mt$Di2GnZE{~{^Rm}{&j_8N6s^Hz`h%{U|M+LTo$*b8iOWo*LK?O zo|TRh(}sQPUv1NqZ+(`(2~b;nQ0L&hX$mgGHqbcg$}A_-J&5rVf4vU*T)J*T=@7+r z(;4)`kzJDpuFbAPKF_+T@ZKi+{+U_dS151fdCyHudX4)!@lrXiOdtIE-((fGXv}-R z3d3bF@8^=gb(;6sYTlc7!p|KP={w=Q@0jCoD1Ex|`;3Qy>!G3io$#+fO~pImod6ry zQK*=?lZZV=dYbXQqWG3i*zt~Z+LLq>c_%!7OWq03AKJVV{$J9DcJGAe@QQcBPY{*n z$Lnc+pmd00ew-EZ_Fb#x;&VCY<#)Uy|e0#$Mx?l=y!S|9agJr9%*KB^PA(-D+V&-B`*-8D z50nmJ+x{tO`$b9HrH}iSpIrOkUwO?-CeL)ddrXD=znp#A)DY5YXKZT=MIj~E8h_+2x9{AA)c zuirk3h4~|fL#%Ne5^7wbeoq#a#$_2e)A=Jxhp?P6f4nr|tlj)^nZ*BcKJKw!pmYf9 zpZfyxS~qDR>(f>9$7MObG!}*VBZeUs{BARUTrTlx<4~ACVwlFEb^eG=AU>TxE-xD8 z{WEEQKiu1=$%ilU37qKlJ z7e5me>A2{9w~ULIWw|(TXZ5%^Md+;>7ta!4b!%_hlkvET%<-kq%i5d2CF3H0XfrOZ zCT(apE^>IqxcFI7X|8-B%@vdmQOuRgLm&N9HZHCR2_@s=72a;v3iv7J3XK}v?8Ong z3_b`=eq6*bikaS<*$92cj^Vam@};innbktiL)^0T<`b9IrQF0RPPp2q{* zntRx~8&b-7KR^3NE8#2hA)n-8f5Nk|rw}oCY-9t&w64{z4>+WE-~`s>ed8uKMiuVK zSXtDHacwY8ix^QlgvH3SdDm27d{8j@M7Gc7bvIRgLr9)U=%KAgieCNyfDdndy-@!2O z!|&Gl&cgqc`OZ@5e24i*alZ2v`CF&+9c)YIJ6{cobiU(#x6F60&vJ2q#aHHy+SAoo zLGnoMdzD&0u%*yjHQ)J)0IQqt(4LG(o$v6sWWK{6+RS&pCv9jq-{J6z`OaFR(p;II z<_b!ODCWuyp^x63&3871gzEXu*YH!!6&h8X?_d~mh2QPxJ8O%DwtWU|*P4vdA#B^J z$u}l#m-!Bxp^WF7iGzHvkFh+z*6?-w#J1;s*0+6@M0fB!LhR>i7^Z!;^h#>WBA?^R z`|&qKqxg17@u75xBEFl7`0mN^ZC;9R9sHEy`v82O{a3(;;c)PATsgjPibnCx1fSj` zkJ2G5KJJmv`{bm7JomQ9U`fC1ZmcQ#{2Jc3I6mUa$5J1+ugGPIL0$%z#SO!dbNn7S zzwFx2x}wpx{veG7N{6s*ZJTRTOJnhW_=#<{xwe;t!Q>i-!-)mQmB-@SqEURir}$7h zL=j(Qu1zb&_Z|F{;=2NTnrj#i2Oq};eA5SC7pM1pA{|$#^TlyxJ^5Rw;|jK=v zH(w)qzgy#%Z)Rro3B!EFY`O$rSZx_fFzw5(UB|E#=HwfTiN@vqG%hF|!g5v?7uPl} zn6PL{rzcwx>rE$Tq!?<8t6PL}! zMB~y8XZlPwN{6tVu~xb*$>rYW-a?hy*lQ+RB>sExze8Lrp>zm6HoLbVuTzr-vi{iJ z+(%=cRFn>3d4c!a3%u`J$@^A`|FQVjdpb}$g!RuFwT1Wn zQr`1>I=1HcQr;)LCLHNK9T*1Q`Q2uXx=rHK^8RUj>OCD87I<&DrvsaE-nSKv@;-OU zJ4%PJyp-|&lSI`?pixF$}!(yAAK#Cq6Cj+oil? zSjRgy<-G488s&YG=OykBqI3w$OIiItKxnBRm!~J^Sb%frxQx;v>^a)j{{uA!+^@4> zR&#d5PiYK(w(CecE@K#C!0(#+zfc3A&0t*QSr#6;t=NZKDzI)vq{ ztUnx7*&lXJ{C_0v4=5eN`Y-Jd2Wu?My=6^~FO9{~X@9^l#Dd>#`ok`XPum|ZO8Wzb zb^QUG^8WCB(J1drz>AK%C>_G`Qa0`$Qpx*Z;{Rj#*Krr6Ls7+{LDx_uWLJybq-Lj?y74FJ<|DSS9a2 zNc?{?&3BXzVf~l#et61zKJNaI<4bw(`j2p=<1U7QcYe3Y_a7xbE$^Sjr;fWA7I<$N zcd;qweRt6)@5^~!V*N+y5SEv+`u|g*WuQx*AqI)pt(+j05G zG%gEfHEA#Wl*Z)(_|x?=h9NHet{Ip2PW;-qT!&vBmoe;cT*kB}F8hdy#$}Z>E+`$s za#j|XpSO+6zR5XOOXGslA?!KY#^o2KaoG<)rE$4CjSGe$F8r>E%TE%&HZCuwalx>| zxL{fnm;J>=IMz)$4N*5nVsw&d%f#$afQ0M8ke zJw?^BVZ(9db^1WjD84npr+ecl9m3*cZ@jQ>Y#yD#D(;OR#PJcA-P4*Xkj&mVh9MXD zUA{MduxPZcUrpPJ(jn^FdQ5p+58?RIwoX|?=J~phk6~ylzsuWtsA#mUYo~dG(jjbH z>1&mFb8Kne9EP9RW}7#A!LQ~GhQrAljw{cb!$qU`)&XBL?(?8@2#aqK!FN~EFXW!s z2YkQi?rR?B0dj3+Ke5ZNiTxBmrTESS-xaZ6U})}pWp5_VRpe1oZin5ddzo?Ftq&Zw zbQN3$$b~)4BSfW`*G(~_bciD6yNj5Y`lj4dBcC{K9v?C9DVX#9+MnSkVzzbec`$dq z5o!U3-2?N9v(W~+Je{b}Dwqju*J18kKt92W?Is)bC^?}IdkYpwm0Qanhgc_G$rBB?K;5B^$+`dozD&js&?DLxVOZ-LLwkCSqGa_yb^IS0SleJQ)iQUCF z2eiP)S)nkbb>RdtP!6_CV~)}xECJ>N{3Jm zIv)>yZF0hl2fxN=H4i!-V3_hS$HoI(SFls;E58v_#k&i5d*fUYr9&v*`r7bYlLw|Y{0?8$m|u@$ z0fw_#8&)k|-^FK{<^oOzVJQqSJbalZqana&VRyDhIp6L0`;&ln$XBbY2fnH~qlW!$07&nuqmb4q%w_ zFx-0B(j9PJ!A`M0oGqrx&yUj_LFo|6Pc~*gkn{^PU!;Hd`QjNdM~>9_;vexBxoN43 zXGLx>%(*eiQ88casGH!iSRsmBoFg{M#a?hR7}ruL9l~-kuV5?expnt6&y3jR@uILs zIG5uic3T@>7ubU@JwGyEBVcGim)C~YTU3d<9JrYY2tVx z$48ttj$_`II4&$ATkBz1AIB-hp^U>S;&_p$6xTuE8WnM&bO?*9eH{M~@tHVYjGu_l z#?j;ZM8t<-$8l_d$qOq{w<~tksee=HGB_R9zdIpx3P~`W29wC0ljquO6UCMb%`BM9_>R&cEI-^I|L24st=(lj z`BMHzcQ!+40}=v|Ho}!#M6i*Kqd7aFUL2u;!mUozUpZ zdCRxVT6nuc4p!cdO!Eq*Ls;JEM-L~w$y`wWD9??^e(^c6ADKO&EAbQguyx|Xv*h`M z(;^=j*4ByIO%c4rvQgL{xJq=2_bBk{{s2mcP`ue1pc1d_4W8=}Gk$hAjuLM2eXy(X zRgL-Xh#5mO+bJL8DlzxA-5kVsU?QChULzXi;n=jlpmYf3A)D(wlEhv6i;utWAm_#S zo4v7X@fW$Ub=1fIoyY}-oz~GxO2R$?&I)BU<={FoP!4_x2f9Ci(jkiz&qhfuurwc$dO z2c|aMjITDBV;*2=5@2>}L(9Sl-+_s=U)&-Z<>5DJ+)+A&@{q;-(WExWnDFPYKX6fu zyV)PO6+hJ++#5N-us-e`EqrhlAQ#4k+eD?9e+OorKcI97i<$j_+FH=OIAS;T@OJz~ z?6w~IoY#7Y;T)@nI4kt{H12nZfpTyr9O(W4N{3JmIaWv!GefTNGat>Io ziE+fRzRpz*_F>Y4mw>jIzxRty@m>VpE#uw?N{3LqS^s{#6ffV$;iKhaWzyf@yu$SF z-)I~kz-Kk~7bA8I=gc^_On*=EvhJ2ErkpAgl;*>OqEdb?P5U=Whfsd9{{2M4kLlm! zh40^2#=J0Nz@PCKxv^t_&x#=vYvjGMuqMnzTFR?Gdq2-mZqX z(Q!Wtr9&uhU5)a6wyR^Vn0>ZKIX-e@>)~rc%V6JoAy+W0tsyg4myL$xJ@_6UQewKH{`-{Gvb{Trc9pus)8f730WZ6>)r0REp~saE*(&P&$Og z)jp2bMSLcXPvIxxvvKtJrbc`ib{xkRm>gXf$EU?c@!k&JJz^b0=@1rgc^t2gI87X% z;rNKt#_@3C*gP=o?_*dW$9NlP7{ocOB970BN^$)OTxUdFC>_G$Y9GfNB0dwx=kOEp z**JQ9%iJIEVc2mTTVQf@T^yem8^wDMc*n=QMd=V0Z+RSVj5tjkU*PzN)5h@x;&@if zR}Aap*s`YJu!=aoC@RHuKe*8N=Fm)^0H3C5E>!A9z`G ziuV!l>Ru8`hfuurdr7x=#LPRAedbs2)dq81Lt{8+=GZe^G63I!iF97{chM*he}MqDA@E5tT`R?Pd`zjcAn(wt~fU`pSryRU02Fk&caG?7tC>=sM z=zL%0Hj@)(U*(_ptmZ-YRWQtXFsU&+`^+t=!6^#t6z9(W5)bbO`0AZlC$~ zm>Z@x{2M=!6I&a`y`R(u3}?SK;3f2kBHq_Tr+A-FYXeG$P`vfE;SQ4rN6Gv0_4KD@TRB~^UGk?dWg~?EauMkng0~An|k;b{vvi;4}H#S zJ;ZR1)kB;WdVCu9x5Yp?_y-(lJw)jc%0cJ#@GjF2Og;QBKC5}qdWhkNTn{-#ft_M~ zct=c>pMRw}g3=+BpKQ#0I_Vc?ABz6r_o42NIb!yi-^E`wH*3fKfnmov(or|TV+$39 z{_>vKC>Q@pYXnM%uw1mxlch%ZH;-|D!ab1#Gf#dWKcyTT&Dd~cT+d;hCz~$M1RE8*!WaROS6K2DiOW#pC|Uiea6HVIKPo{&4P7 z!AW|bO2u zQTw|@rMTV$*Q~g9N9hoXD;xLIy)^bx^JMPnYu@h>W@`d-|9LmQB1T*HJ;sM(K4aLE z<+B<7OP^KjR;cF2f|92;@mb9BwEp*qh4Ro?LwL|V43rL`JY?g3%0r}~uc!GyjI-&} zz4)o-K=&{(?6j^a2Vtv*ql;*Z^}J7P6mJ)J&x~G?WgZc(XcCiC6A7ddTE~ng5T)S2gDMB4!Lt!9)Ys^($Y55gJ%!-e#r?K#3j?}G8k?(wGg zgaX1T13iU2nM+j4&s^}MYXy`Jq5Nd?z~_>F5$a^#Km0uKk;su*E6k0*$dMg0eE(Q| zl`t2;u+w^3+f8s*D4%JLOb`R*U>-Qod-PB`gmRG8&RPzn&pc}Sj9DwpgU@Onrp8>s zFz3N^o!QwtY3VwgqQFkEc1{!%dKv@LFFN2y`qE=DPcD;V^6Rwo z;;SzBQlNC~phEn~pgs9YT4_#+>Jqz9oI?k+Aph zm&ldbdzgfu$dw&)dK%rk3{Di0?LA;vKjw6_sKQl6J(*urih1D_GfIajVt%2B`O$#+ z@iNQ{;HMPx%3%IR#Ejt_!i=j5%nOQ2F@FTiT0>DfgvHEy>cs@Jsi9!^HS~#y-K?b- z!e7L0Yv{^g-z{Rtu;UuqQP}ZVm-7pYjdJl(xR@u_3X~3ExhP*(JsGi^b=4vqAF#cSIfRuSVxMWwht2Cj(_7fOe)xLWrJLX2fv-FzzIGwX?u;3wj< zvGw?#jQB9@G`6iUIl3;6i;0cm{Y2W2Q948s?_ZOgmfH1L=*Le-yry<7j-QCv#&g^V ziRVW}WVH*!+IV*MUL#yp#Q3A4Qp}%B`!Py~u$bw`FC~~mjC1V1A3qbZn|{0m{vvi8 zYmfb#5j%#R#=0{K@K_iBCB;U$ST>D6N{6sqwC1~T5ckBMjU1SK{}_HsIXHp%>z){f z!`~C*=sLVhiH+j@R2qAf4q@?jwkP&n#BKJ(K90YL+pe8GZru~ZFpvH4_r!2gu}V(o z!JiOA<>0ev%uzao<$##~Ey;h0`Cmexe?DS2Yvcj^MC`WDpF_;AiFuDwWV_ulG;WGG(+}L{P^J2=# zFcx6gaXqX{51bWBL(0LjVxSzX1_yetDoTe?4zhby|K65^kSp1}s(&@PV(wL44&T*$ z>=XIGFz3Uh%xtWIYEy6b%mV4aQ15nUSd}%;Qh4d6z`YPT7uFc6mM2bUM3@E zYRPBtS&e;-h#fR`;cLmuF)vIl zSpk2M8(T|!UK}5}!Elb%5}XyfMasd7VxSy+Ev+Re9YQ(CYRSLaau9MQt0k|PTrsue zbNH_2Y+PrXH?> zpHeKlgXKUG85Rs@zaHWxpe@$_RYj+GzYSjf&JRk5uz1V9H?Yw(`+cSEhWQ4@YWRp) z?K_pv2CIG(0K>2m&hPY_0QUV3tBY3K{9T`C@m>8W9m2M`?A_xVOPkYo!gn{;kytL6 zz1Q^f_$h7o9kg5D*N$OmH@{oo3vS!KhFECZH%$3P=@7Qnj1NFDL$|ro5wc2+C{7$*C zeQ0gbYMZ}DoAui_C>^5M=HfT!rk1pM<*c@R9UrA_-iJ2p_h~Q;ZRU6SeHz>5Z-`dg zyhGY%lnznX=4sV!UI!ngZ9YD2Glrqf{H|{EH$|&$-YIP}N{6Ux^On_Z{uVw;+k8>l zW(-4{`CZ-Sbw#UfZl-NU=@4~o-m1FI|A&v#Hs6xA8N<+Kepk2o+oIJr52kHK=@4~o z-nzQY-@!*|n;%NsjA3XqzpLB4o@lkryU}L-PAW==ux&0IJly8&{VcT5B_xCFJ{!hmDM))ah_u903YY`dW7>0K9 zJLmh!a=tef3vIhg`9|pww(VtnZ&%ItCf)~A%$-HpIqdsu%R8%d{KYV|o8Q%ZZz@`C z^FArxC>_GKxs31aEBJmr<9jpwl=6Kfe4iQl#xS&--#On;mGiy1SZLdSLffasIVMVn zux+0t^XkI**xlSg31_W0Rcx-v#>Xx25!-F&CXdkWb5;s#Jq+vSCfM{2oFK2b8#}qt z&o{1ZU!5vi#d086^m{TW9l~NM`<~2nfg;mo@tu5YeHzC{95!!W28Vv51;fBUzstYT zvZZLWt%sy-Md=WAZQZfFty^(?Xe{+oI9tQ949jTbt!=ozC&4ZCyX* z6~oY0ewVj(N6~0okEgBQjx`OXL)f-1F7@h-WZx(3d&;-@c9BMp?H@O}G3t}lgzt-O zPxju-o$wXgZLcZrK)a9ndZ=v}=6igm#3k1Y0xV4X22Q8M z5L3l@A~)$rf9Xz zC)4KjVr)=4gtn)v!MCYyNn+F6-5iugo5>(?*;ee{%*M)H@Dtl@$DBiH_emnMxe10Q zAjv*`z=KWiz;P0g`TZxOvXQ44i|>n-;`%kXrp0|Mln!BWEhX)JE5T)QP7coS<%uV@ zVEm!{`*wzL5T6mF%{`Ctric;44s#FFJ`1&&f$4ZVQ_L0fX=yA`I)ues8p~b5%D1F4 z%Mi=|W;l1nPsC|sIaj~La#;~sEHSK$B{m_J{!>VP7Ez4lZepdl&PZd4(jhFawz1qT z;A@TLI~m3w;4@;hvGf?HMvNGC7)wk;EVHjZWgl0H)g+DO55-(DpOwZEr9)WErLp`$ z$lElQ?`AlEgrA7h#_|GUd3VH#VO=b-39dtLyMSVx_n)PjecjLs(pGb9z?5*P7FL9o`q8 z5u?p%k5TI|h8^ZKrXiRe)ZzWaTrppj#uBANSj?rd{BcO-%rcCr?`M7YC-{jtZ7lmn zODyLXk&USs*2NN=5KI4QjM6&1zgQ`*YtvYwbO?*9Z7lZ;_*!H6L5A@Fd`65mmLB8k z5hI2j#uC#I%j_#4ZR^v4Vy>8P@R(zLLg^3|bLrlS6Rf!raWs1?2jL@Pv~k>@IO^UC zhIMhorh0GXV9_d;o53PCiH{ywQSRs78>K^7EQ?FsY>ejn0$q~^?vvf8(PnR3T~orE3d0WLhG}26ZB(4m7UzD4imBqf4V?4Fd(KfhgvCkB zMkF|8eX@6J%tm^fS%={x;t`wKmO!T*{6Y>_4jxS7 zjM5=22c>cT3E00ZeMaNFt>Esx#+cdk060 zmEw9hjV(%tu(;aBcK?7cjV*fz{Taq%@EI}M*m{iXM~oPD7+Xxk*yy1agPF$iSTR@3 zkEO9h=@1rkX)F&2SkqXJ%5WZspNP}O@??QHcuvHLVO=b-39xnd$ zC>_G$Y8%S~1HRT+j?OUt5}y&HjitxxEdE0r;31Y68pH5?m(jhG7 z(pVl8u%@vbli@rOKM|*m<)ULHmdlFB=Byaj#S)tkOaD6O(pa7(R*LI6aQ!UK-%vV) z#l`w^tZ#3a^T_>!yiVJHL+9WCFb0z`=3qHyT!!&i_>36sJ+vOu$uyi)CRR5nEwXm@5b1pbO?+2Q^MO^N$kViDbE3a@ARPo{J2s1wmvy< zyd0Zj|24j=vA-0tW0+$%sZhShQ2V?-&f2n5%!%K~0m{$c;pc$J4@!ry{4h_RJK;y> z$%hFYxe+|DwwaLSz;E#pd9eL`<8jj8XNbu9JBD@r9h=^Pb1UY_r-@dv{1Yt4L@X#B z!eUum+Br{xCB#~;7acB`@*WN*);3#p`|qs%4qp+I&1;Y8hY=Ho9p*KreHpakh+B-= z>0+ulUjyf)xE?_15Edsfo0#B~nEkXhX7gq-I|CmPpN-jXh}lIEABJ@?!=`uO?24G3 zDO$zy23Y2gSWr5I#X`*HOR$)j9nl)INg1Z!<11paG4q(NiI_0#FlLzcWzgzkc9xhb z&bPriHRdKthp;$_+3kK0B#c24v!Aub?2>G~{RezRd^Tn;6SGs}dK<&Km|@eKUA*)o zYC4XbEn3C$E?D%sEJ}y4ScqBWb=f0ZW0qf+{Ug32CL1%4Nw3Rd*kQ~t?eMznIby0f zKLF=JF=i+o!r~-m^C!6}G5dLI%ofOU@?3mGd^Top6SGm{Lv6&cE@s&D4*b5NpPeUK z#WL~>g5}tV1*Jn+EW~WV1dHiszi5rwwpndFA72rZjhV+ZF=E27!(mqDxRXBUX6 z;_LyZ?jfLb2#d3H4ttc~t6p1Ph@Xhj#%&FOXV#V&*2N8*Fngil;wR#?vD}VW?jG|M!@5{v6JqIK>sh)UxlF7S*Z4G+C>_G$ zY8%UA1HRT+E}UV!9G?-RjitwUYQ%_Phq1&o#4>w>Y1?`D6=JTKC#11N=@1rkX)KQe z>sl>)KIdj*;Fb7^IBhInCYG1P_hn*O7fWnHEd6UbOJjMJSShY~(^#T(2#c$2ERPTP zT4Q-}hVg2AMvOL=9^>+HoX4=kSYjGtnZ1#;Z7i=5bHzM=8cUQ8VKJA+@|R$3-M?ET z%h_x36LH#Dj+jegIiHAZ-GE_TEU^i(996l0cb!-%u7$v*`vfQ*!s23|V9{iZlr>_v z%wPRJ!3hCi3?{XQ>(G~GvAiCi5u=Tz$N0sF5yS3*E^$1Z_u6uF2(L%qGKi-0yBow_ zc~}%4bgV(?5SE9wIelUa4RNf=dAJdu)jW)f_ZDN=VNPS(7IcdFCNWpci-TGB2~awO z#r!FW<42O%hxt*S1Ad?2qyRqIC-|it`&xGI;m!Dt*!@?b7alos)_3JC!h=2w4vkrW zX^uWihT**B7bpGsy*yUrcFP>q%9iI`S?eiYv(h(zu9p*ZwA=f?BVh2xi{SGl#%uA=SMClL~b7?G3 z30Tuuel){*Cw?MM8_T9Z9NZ`3#IP=w*o0X6SG<*u#eWhj#kEWtOOy^_akY)*sR3VW zESJbI-i6PI(ZK-@n;=@1q(Yt$uu`^~<> zuLWyvM4x2;?qeCod+-r4+Bm*O9D62&K8ayn9I@#g_-(}+^__==cp+&reaA|?zwj2otX8MI>WE7sEc#Z+;w z2u`h~C>_G$EbV{46?`T0r%z-UAHYw*kK$o4gJqUEk-k~r4Na@VqP_k zB}#{|m`h{%JFr%+YaYf=#A#!B6S35F4Tg2G#3sbDdR_B~SSha0r?Euo5EfV4Se_p6 zwZ<}E*F1{Ph|$K);o8m*o)&Y({B@^UI6K_A)T6>+{%zZ1=D7D(&;nitRkqg`B z_Y)e-a~2rZ^?7VUwpTxA@prLOT$_PQa~-8aSX^y${k(uLcKMj=`EwTkz-Pp0bKPUq z=PWSnFxN2+(d^(ki&w>5F;7iniP9k~=F(W657yQ>+wxhT{wIDSP8-Y9h~)(_uQ9BP zB{m_JyppbbE%h(4Qe0c5u|(+*7FXL?UJ&rL#`04c#((28VzjaJ7$1rlG3+pwn1)z- zsO{HMuZg*0-WJUI-UpNpVKL7m^NpL+dnB3{3e=MKKKzH{BR=~K^rG`g4E4Pa7=~wt z`Ca~O`sb^_gvy4q@9`_RRK0(pI%ep4ol_AEoX6H0{-AwlNIt<#+Wn+i!|i z+q`4SFG`2d_H;GM_`SHC-?uovw7sjQ{9+i|%kOf2-xiIwb?3CLC>^4%t(TOy^}ifn z+Sbj}wqh9C%J1^Fz9SlK>-TA^<^oEGux%~Ng-fNaYLn!`yZ9(=@89Q>d)YM?FbwVG zcXckjCt7Xuu4$W5I)t{Tt5MeG%c|S_K0Zp@yl0xf7=||UySmLEh*sPDL)xtM0i{FO zHkak^<hp=sBU$*d0hwkPTN^sbh zy&}7II1(R`-(*apz52`;hIL~SHr3CJb%|E7> z<0E3RwfT}XS1=6R^Se4%dPJ*j-aBnGN{6Ux^HtSt?!`xGoBx!y8N<+Kepk1-PqfT!q(XO1|3nQ;iXo zVm=tm`pqJg4q-8WOt5^~&$GfcmvEgT$L_BcUmLL>DfU-q*vH~8Vz=vRkA32#u%^PW z<26-B6yUM${nF#aM!7gFjXz3rtj~WxGr+Ar*beJKcyT@75IZ)Z-n?` z*zMP3!?{m_qwDa_B{qup2=MB+AyGPn;?2GdS&3J^b9cQ*%o?@3@e9Q~H@>PdPl=c@ z%rTo+)t7!F)_e`td?U7}_00wNEHaVyfeB)vJp3FUdgFCRlnyZz9&RY-VIF){^YHqc zA@&%~CJ(C?KWc@~_B>1!3+3Txc+gsa(jk8V@LAK)U>u=uZ*&rtlm7F*y zs|EAoFLGhmXucoJh&h2_UJEixhI6L~PCEMb&3t0092^G+`VB~w4xt=m-*2epK>Ef_ zCMQl+9wyokO5>2<0dH-pRd5AChsDH_iAl z_Fb(0<-{*SpEq!H0j%(!;$2K^6z}Qa)p-L-hfuur^M>0! z;+A>C;`pk@tn&s8XLG!4`5-Pni%g_Ed{iuyhu_14&KpoV#87y+qnw8&@Kw!&&KoeC zO&(f`A3odju%uWh4`;)J)&P_ap*(atZ@AO5QJ6P;41bXeJ8$s)K<5n@rsILBgmvR( zSTN$GqVlJ?u#^}o2j{|p&KpoVgmTdNyx~tKC(OLz}I1*eTYG zPl&1Va{>J5yaA;{42Pe)%J~_i$OyxX%v-!WszC-D?_UK1>!H#d{fewRWO(2*q1JhTLQF zz^px&!B;hAt(_Ro>Dr0UA`@xdSXL~Qhbz;#qjU)6A&dL{$^1#?i@f>E&lm5FaW{KT z%i$+-VCRcI?vvvj8bebhEAD6LXu}0panhJ#US3p+`5G|mc!AO(EN146wQH>AeG$7^ zXMPHQ5xX5PJa!!~Fih)!VWQLV0w)zcKIP!kVyGNk4+mNgQ96Wj(D`_Azh@zvOPTTF zGx)6LLF*xgDG$RPFIws$t}ECn)`!oEsq%AEnj0`M)Wx%6|G+Tk#w16@{aqb(6Fe3xM3IXX#YVZf6)pzjz2qnz!g4XM^q0c5 z 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

me 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

M#y^Aj zFimzA(*iB~GX|PZ5tE_CwSPttp@04<{Z`jMgEr=$(>%mKGp+K^;ob9b-&cPADZXyc z<*>W{{Fd}COVtcfK&m}~Td$Y%Pg-}cCYgvYxJ2tNG7S=6H=w&ebGEj+^#zxf>#m?1 zmM^$Q;k!)hE;0=gA0Kr0`T*bM&|RF$@^lw-ruQHqcz*5z^Hqw620>sH@k~ zZ*_GQv@u;x^AKHSTBWPuewnzg)?D*q_N<~6YhHGRJs>T52)Lz(bH?S z9w5^o3H9Ixrw40TJ-rTkP=05(z#PVVa0AUb(1R&j55O|igP+lFb@c$WF+E805Ita8 zr3YAcs})mr&%T#P-_yA^37`yDgf;F`5_P3h3`hf~=;EWho{z;x*OSae*KUEXNqmG% zgT&W0_{1BXuFbN#b}N17XoC1i!0rC%Fyf;d6u#TEEg;h%ab>&s=;r~x+hGe4pZE*V zWuB~$&N1rv=tES?q64?`9F@5}R@!!NRCw>uc#&z4r11W_1n*5D-Up+2KU^R0&lTRg zG+tyHBq_Xim*CC&9MOT*|7vwW%eQhJVxV~#eKfSB_BCJ$U(=B_NFP})<`?wa;Qkcd zH*cgb20w*3yg0(lGMSO}PS@v+`J3(Oo539@apY28|4wDl#{5&7hxjL^RsQKc+&9Kx z*vG7e^{lGEDpO4|fP5ca>f&~J77U(m+%JIzD%n`!@7 z^qax3em@8qSLt^^+LnIbN^%qZeq8GdG7XYYUv6>wy{6Ugzm@3At=8uYz#Sit>GxXo zef}>M-X}F)WEvzXynipjoBMphdtDT7!sow89}O+7^&2ch{l1NUtE=Cjjp=uqhv+xc z{;%jagJJz%=Whx94oKV5@7qakqTkPGeLgqRWWBQ%uA^Od< zO240=_^Rgk=|&=L*) z=ln6;qz#bv`I;sC_YD(A=-fg;`E{NC6Nsg!=e!pY{Ursd^?wQhl`JU)q{RfrRH~O- zQ<#|bP$l^V#C$)fcQ#~|?B2JssZa$SSN)pwQ~bzV+Afi4kc4)5oAV?$gE0^V?}2;?B56MaV#{{h}$TUboefgF1A0M^;VWN%TsI(Zp%a#^jDD8in<8&6nT&)*GEzUZ9j5q_8RcbLob_SJJHtH6_gv$*&2 zCQTNtJ}*7cWSs9WaMB@}(Z_&gXgl`-L(MrE&`Le%ys5pHu4DdhT?XcRq<+l1uoJXB z?eov>usYJf^+=W*`mRpC=Wa6gs&_P&M3bIQ%PN!K8bu3SQ=0R8u(e=a`lb0CH9+G4 zs?NO6QgTEGs|R?`BHoMg_l!q97d_TuY^+HfGJAmJD1h$hZ0wC^-Ek*0FhKseYma_k zmN0ZR{Dq9hY4r8zj-JMB`jyvJ^&Hsm=*PP925nT{_qz-& zZ|2=1?_cNgMrT|i?-eTK{Vl3lO5VT|${W8adEc%^{Lb zbF02=ZsQCn1qkhlq>lOcyYU11m6_7YGgM>+ts-bKt9zp|IUD-`{aRN?KpWMOKe`O9 zBh0%+NAAjXWbbmDT&+S!rv5XnBft~t2!2yKf*&e$&hFnB5!H4G!OBMOk1=8{C;?bF@8>z*ZOgWkr{B`kiG*qpdH>B#yFmu>$!rU zVm;TMTMbByV5Vw47xH`e@4ywL$vbcZ(rBf~*Vwf#x&Hw53ip7-+o609$T?SJJu|x5 z?7Y*70w{S0Za^9i;4Nm^12WJ&8Ai8aVRU>}98AKv~L zcAYT(%{jyP=9OW5v)#X{u=#y6*QaK@4BD99rg@0oGOg0v1-jRU*|Szx=!xBH6Oh)@ z6FuI0h~y!0+D?emt~KYtC9o#n#4uirmkDSN*9mniOY7~d^F8>#d6NjL1`M%lZT0d389E$@6A z`=G-4`bS7-#5aCc`$l9MB%yD-*ZIcvt#3TA+BXW|VfaSv%O6#E2Q^+~8YC&abL-+g zqkUhl@%~leZEC#8G)Pi-=K*hIZ`&^R4N8&kqfxwkBY3?t>yIhChXC(fOhC+{jq=AJ z(;)HjVoqZy(1%0mJ4XXw>z$<#tXuuZt}V26mf~@R@ADcTG7S<}Hs;o1_ztgwZ(coo z1I@FEaA+m%|4~ix|GW-l{zku9|Nl6B5$s*#H5ET54Zm6R>8fx1K7-4t*=K+@)@P)7 zNT0#9s?T^g&lqv(+_5Cj7zL!dW3l~8Ba5FgdV=I6e)4#&cgQqILcP1s*~JFdPo7Y& zcYWUvZaKq zkI4E;$d)e1{A~@~JZ#{T{_8@cl5GtEX)!>cZ4LeYwub)3M$|^6>wL|XJuCU~CF$l@ zvI(rke3csVM*81W`Wyf0KK&o0bK(n5)wYIAgCw-I-#J_Rg!KhqueLR*%ALL<3*-HlEQm>UA$AD9UkfiW_r!L-M^ljQd zJgxA4Pvb?VL6XAzec(k`k`tmY!k(A=;YTtf{$Zz>e1}$b{j9ySZTXJs^Ql9`WM~!l zjlByEMTC9xf9bcneKTldeRGTH|?Zs|$jcX`k0X^A`F@bl2)3sv7Fy zGi~T0Xk&Vq<{^5>v`P=ZNAZELhw-?O*2ubN&nMC>TUz45|DF52dh5l5z4hY3-g@z1 zZ@qZXu+Z6*#=by$S#`D}Al0Unx!4Zp$PS~%IFJ6)USt|1DZD?gi+9Aa z-3touO&TvU4U!bzo9p5oacuXZ!h5U6i%f$gh4+_r@s2pQdr9HFUE@WjL6XAztGalH z5!($k4|$RLqz~%Y2qql%NiWlHbz>vY#`>f*59yPbR`p5m;W<+V!@fFs&NLtme6^d0 zi=Q)nh2$pwc}VLEG7XYYU;g0y^Cs3m-&d_K0`N9!`qpzlm9drXPhM4cf2Z*x(;!LV zy}vHraWA!vcc8fseKfS1)^CU))bH2mx4QZb+L(T)d5C^9?f;5?Gnjh%9gw!A->;M0 zM8E%{^#z#*NvJOmIQ`z#>i5Id`XT^Ftlw`aypL+U$TUb&c>h`#@38#$<O(y!<@DzoFJ8=Lyz- zIlXrocx3wm4JGM30e(|^m+?cz-sNWrL)Cc#eD3xx2V<`>iL*a5-TYDD6Yg;bsODBrWOJLxK}@{I9fWR=JN|B*NqgKEZEQiM zFoc2TeMCF-p+Z;q>FVwse1*W^fDH5ndk=56XCk`6tI!wPW`;8n0Myqa=}7b z$DiI>Xmn5KytQZ(!?F1PJ@)6Fy5@bT_z63Ekhk+r-QmI8k2)f!f8gEI_z5XsMt9A0 zWGfNAUf?r5lp}KJfgE7!rk+8}77HrVenv<))v78`sxw?T-u#9xo4<|^~o7g5z32hb8+#rZGb32hL+DI3HO z6*f45FjV<#d|qOMqbW;tZxQI8>;XWgLE`Hk_5eKMbZ=`2rf0ApLh$w)Ie$HXy+$4L z$AC|vbJQon{s5}^G)bs=w{ejSF3I5Lgwc6(*b~BbJ1p8tdJ2DND6!y{8*vElS z6#FY0I|v>twDk!g^mu+Il}?=A?) zeHZdq-^5#H9rKq2pD6adfc?PjUH=3^haG=g?9p@iXoi92`EZ*b)ov563vP2wstmbJ z?K79A%(^}kv{9eAjLXnIlXfWx*%ZA%JSG`*-Ct zLFjY{f9LvN663s|CdYydcdfI2gb@8~~k1wawk9B<|XrsPz zhRe{tl6klI%D?5la{F>$xjl)y%vXMqYL<#Gfyc^Kd?kKUz7juF_{yCLLzS<@=Ow;! zCS{54?51@GnFdLyJ5M-Yxr6nU+d&8sU-=}{&0h(8Lfru7Q8K*gCx|Oe>lC_$?DBs z5JE(62JAe-YTy&<4L~)|Aqjco5)eAQ!QZ*wl=QKy6NO-(tFa@~AW30Q==>Vs6UEMb ztmr%l9d`U3>bxG8%pwZGK2Kvura_Xzp6Fvg1U^yhK_3f3haG?C*h|JGA0`UHeyGNd zOoJqaJ<-R`2A?SQppONi!;ZhJv9C!Kg8guf9hnA63VWiDT?>4o*n>V6gbq9Yw%9BB z*dM@cZmiuVTo>HtkyM$Mamhz0v#!qsZPaJ3<1)0*WZo@4^PjoT{8YKmJerV}`ON2P z_)Orj@|C_8zbT)IA1Zw2@r0quXX5h`pZQVB5*<2G>ku*xl2C`9az1ls>oX065b>G+ zV!HVs1D{Zb0IKY5?gCvDL;WO6Kgc_xGq@s$HM zzT6CaLfrwV=J>Z%d)>4fDp>{W^3>X^#-7tcWb=?q0<}u9qNtlr?w#q!G4{_ zj!c6jh5f>6?4JamDE4PGb`U!3_`4eWwnQP=Z_wD0X^^C_UsR2KJMf8OU-)fhuOM{T z@pm=$?TJFL|3YI&ra_Xz{=;hQJAh9V`)rLJgbq9YuExG2Q3&>1G@j!c6jh5eFh>^n0bTuM`H(}!;ZhJvF}0@ zg8dGS9hnA63j3wN?w#Ls>r~IMKbrq(@QKR(cwoPX5*y2d&|$~l7Q390^Uil-8ZFqv zw<~=ib-7E|1(^m(sxITtuk@L_flst9Z|HUap{oo2u5O3ji9)d7qp>5?AW30Q#0hi2 zCyG6Y6F}&&_rrU{eF!d znFdJ;dtzL&H~2)c2jdbDI_&tn8v8y(A=n?#*pX?Fq_8K(CHsO;6nii(0inZ=zb*EP zamo9$(Q}7BsY6YKdk8iEOqFSw%h``I>&BU&jmDY#y9^y?GVhi+^VvMk+`T-`e2kEm z#hG8G8m8h*;IZn-d|nb~4p5fp(7&_}A=4lUb?7-4XU?&4 z=0gxdd7OCw_=GwHP+^=2LZ?IcyV~!3mM8@K(;7Q64U!c0zf@yC5PYK8gE$j}4mQS3pS2||Y*e^+ClOB90r1&tk<21yG0Bh}as0-q@M zAkGA#!;ZhJu{ViAu)nOaBhw&BVSlt5`#kW8Vh`d>5IXGmyBhn!L?PH;)7X(|kfgBx zwHo^&;1k6j#F-#;*ztEY_Ctw6u)nFXBhw&BVNb+nhk;KNdk~v}&|$~l)!08z6oNgY z_|O}RBhw&BVL!84?uUa<6nhYxfzV;c-__WUAPT|Wsj(x|AW30Q#AfrsCyG6Y%|Pg| zX24_RE3p}VQ?VI-sEExLCJa@v89pzG&5oli(V@k(4k6PZ z33ccN7n|*AW3zP9RjFk;4?w!bO?V}`<)YrLaj_#UA)f5IXGm+hVWqna7Yv8QNL< zOt>!i%nwjyT72eLDYLH61Z~u3p5ijJ&t%>$KJ&%gXYN(*Gp7^MGM{-*4W9`-R=(mh z@tg9Q_@TmQu0j~9d?r3G@tI$vEYYFWwGJWEAPIHoCFe8uwmx%32%&sDdn)*ZIs{P7 zAVvnE(;@s_?RUOT6oUOj8apx#k`(rY&-@1XM6m}x6NC;s{;tM;8c_)LH8pl*8YC&~ z37>g7_(ZV>J`;ovJN~ZrJ7*AuVE>55j!c6jg+1Xj&jg<+_P}R?&|$~l)!5G>3c>y{ zjUAZ=NeX+yXMPiWqSynU2||Y*e_QMoK68l<@|nA7p9$C1vNz#d^kZFL30m=$@_tyF zhul}ew1xk~9fAw=O&Dg+msKR+gb7HC%POkg>(cA7XOlccM>f$qf=q)X)RC8+Pu$1) z#7*ft-zU0z702NWSY`y~*58WVtH@)#diV05qwsE_@gmb8N#WfRc-7e{e;?Sns*J65 z8OSt9Qe|v|GQ4+kwA{a~%GefVY+0O-N2WpImobITcD9WpOWqk@|$(d_p8YF&MOHf&% z9_>uu#q?-B`@XU0(Z1vxTJNLk&qx|&dNk0y7!GCk!lCfnXkcmIj@<~gVi}IYeU@1l z-(&C{$`^kjJ^;VBz8$+I&faB)GueXs@;7hyQg>E!tCit|?RalG3orM6uHqH-pN@6@ zrroG)_L}m(JMK=+?NWIE==D)7PsO|Xy&vGj{Us-{jV~&fdeRLO(OVVhaN_7=7pI5z zJoy{}`Sc9#O<7sSu&3L5&qigR*jO-=DrIM*oG!Mg(HSmr04uuC0(XeUE^#P|a~InB zcd1LwZvlc{hroB7RHnt!m+ibK@MT%9LvsopI*5QD17_jfD&K{E)O>paw4!6uC#89a zJ~D05C-L3=^Q=Onod{-jJju^Ky*s&KvpO1hpU`&Rc|hJVgPPPZGuGeq`<4Oi@ZQ>s zZybH8)8+!&;n`dqPfeQ>1WB6#RdHU}o5&3(TOn*(jk=F&XG=9sq9<|_Od zY>pY!w7GzGcs3WuQ`6=ILDJ>|(x`fdHaE~b3+=p@Zf9@`+xdbv+8MO5c24tBIq3i>ai0$8aq;CzG!1%nx7c=uou<$=i`gM zY~78mOfim~LFK(h<;`3FdMd4_pDAwV8 zy-l2Fbw_aCLA-0?d;>T)%yHghasDR9xe;*w8aO}Gg7eKbaW2yn!TDTwZF#;0oS(>X z4q2S{<~TP7&O3o~KZWx!YKONyoOZZ3CK*WgdatXC@?DA=^sz>ao7kCa1Zps;>){DB z(ZG*h_2zG1Jv4#*ob`zdW!vqAalCyKVKw}*2-Rhiye_}9b-54!bRG5Eyh@u!s+2h$ z$z^{C)wq@}@7g;u*^dI=&2qfIw|MW*fo>iF>Tq_@ckS5RqcNQO*SEP&;M^j|`GCdw zhaBgYz&SbNYG1Su`JLuHR9^4k ze)Olfq61pRQp_)W>=VwvcV>rDc|Bfvb}%^%8(<{6_m7_2$4JBkfTYv}3LDsVPiq5^ z!6Bgx)clL*kKJ5L`7?jElVofQkFF;r*AMn(d+hJ#VSZ2F4(+XD6)N8Fh@P=Yr^)MFKyA1o{Rc0dY)i z_st@UOOz}w(`}7RgT$8wbh$s2#i685(B;dW2t>DnwodfrQq#l6E{L|iRMqbaT|ZHJggs$R_)g_ zc&)2ePKY-1#!J#DJ>#fR$X`PLSzGCtG3XXnybxS1tQbL%oFfZJqcbqAb7XIjh75hC zXlGu30H?5>uV|y4K^tr5G!JQKrX5K;GlQD#9MHZ8?JNkA?HrKSYG>%>yT9fqNR#Ui z0co^SWLH*y-;Fgt0hC;S2uRcG4|~3kY;Heob6^tM+?8$E9B5-Um*ych$F$1kx<=LX zW!cb;Zyn|KxJJ8%@68X*jwcmtEgnsi{`mJtE3fh?8O!E-G$+XIEhB07#j;!W7 zDYIukRuLQ63ABK;!jH+`1Z`*6kvznYJ*)KqnFdLy2MakrHrM*G=b#6eQOF5(89!5H zyr9cKra_V_!in!gnpdNp>u@CqLh4(d$ z7nuf03h(Q{Te=VUMped}C}R$d>+Jj}G7S>H49qFLPqi)0k8-VOPU$UIn9M2ZHu$+J zFZ+&~13{)i;+KaxkWiOK(RUSlXr&E?wTJdX_>=+dQ^3;BfjmuBY@Gx71?7v+5I=z5 z^&ALvWy|s0w{Rv~@gr0u`fj~9m1pY8`a-97`8v7qnznF^SLM79czOGAh1UYwk4x3U zW@D_o!E!3r2c_r@2WT68Fz*xF2^=hM73)n~?daA~xIGUj+LPxkP)^uK+=RBOId1`4 zX>XagNb?ZgU|Q8j{EzPWV4$q02ST?RyOM_}+4B*QMtd6>vxR#;#$nDsGs5JqIk9~j zl|B?}c`K8;`Mh{3u8+=TkcnZ%Ql>){t6X%f?aqw=i-O)7RQyPQ5++;Z{vcH297 z*tOzG?Eh1?%tf*2H=NwM3ObKUDzn{it$1Otyy2`B3z8v160Q{kN&9QXN(LiXD;8`= zFIrDZu3h}K;DhjVtNco*27VL_UlvkOS0m7?~y z^{Sq;i`T2&J;MShIcFD;rswRAfz2JLZ4OLAo4chAn*(jk=F&XG=9sq9=Hg?|Vm*Wz zByG+PF9X`N&FS&LtyEtbTh73EU`{dqK&C%8qH2#?B z1_ov0k6)_tR@UPWWEv!Xc^H38R^{~!uHuTx30*9n_w6E+Kaz^H&dF8w?E}qS7bm^? zoYpI_wBwHkmEAi2xQ+5fZ$uaHyB>cGGj3o;tP?*Zcoa8as8Tm>$m=v%)QMwouncYG zcHpfUgM(J;EHQYRhscL%m96}b#^4N; zxJDj>3$J0t;5HUs)Qe5a_i&2{7N61@vIbq$T2z?hCc9DZTLXY#(ZF! zhxkCIRX(uI7@Zj;;{_Y`2DIsT0qq&ioyTLtnlZW{NXF;^Y1EVcZ^Y<=G#R4@q|r)| z{kZ<&n9JP0?XK)a`rY5hQrZsPvwuURZnjS?{dzm8(`SVH7AuxPz9kBIj_;m1etdV8vlIC} zQ(t~env&l?CXeE~24LG~kWlC@isIaUTz>72`viM(+!v6h#(jGHatHZe8NY0!#}mjj zNW$^N5^g+k7{)I>gP$xJPmIMmq09)v|1Lv{Og>YuDPd1>%{B91E4JwZne= zF8ZzRSO&DQemu=X`f;YM?8g)1erAyD$L+X3piTGV+HUTq`ikA`q1zdm21(e?OF2C} z+}h2aCGDJ#!v*6o#^D<8Zxr6WfmhBUAk!f6@vcgGxwOJd^Av2UbPfUY6@1UoKCTAE zIfQ}c^kqrEnp(e56+8aljlO6d|KCITqCcV&_+5|x-?7-3i(>6Lf-2B5Lr@(XbDifE zb>{g2Fbr+#Ueu@N`~YZ0CNe*e<{|Q9T4htCgZ@5lQ+zJ_F;W3{E?dPwDd>3`>m7^H06t~pT?=KCEteFR-B^~?!WA3{Hq$-mCXLo03m!u+!S@94Z z0mUqcIqQiL0|vybt2j6q?nGNmm@`JqIbn{6XS(zBjEgy7&iT~yOn3ULPxtFrT|NE6 z%r1U^{?V*c-Icnkx~gBlel}N}`5Wg&cy6|siMNd8z=0;-%4c1Nr^Q?Ed7j4AO?wH< zR~PmYqUVf^%bxp?GKvR{wl=hD3f55U%MH-_s_S_k)BO&*^`GbA#RXfD+MK?rz|Zpx z-Nm~?_rxUvbn!w#8r_z{;Uw=LbbO4SBRZwJc>kT>w@kePOR;728dSS^Fo|r;f7}?= zIPHbK543jMQn;M>8tCw4-_I5oE4ZE)Z5?FX(B-(T`zALt{W>x2@5X@Xq}>=}Lvt36 zJQX=2xlp88;bwgI5__6z9RnDxi_K_Wad<+3ibMC=TzOkH^Llb?u~d|gDZoX z=l|>Hm&|GA-iX&VC=~gak?Z$(e#s1F*0EmKtU9)%S}K#z9U^@WNPM50S%=S|Z^-Ae zaj?(nzQX6Gk4oc^(@;N*i|cLx6&kmGz;n(e^g2Y(IgdcSL-oUv$du?g=jkXL z(%uVyLC`x>(gRST@#zin>8Xg`S)k{<+e(*2!gvmq#sdYJBIRW2PelsuWT$zH?iqcN zz-${l-}qhDC=KR98j+sM&oGz%Gs@YP3o+eOmJZNO&xImY9u})o*FHe$`{7H_Q_k84 zeOcFB`()$bdC`4^ANp%wiXYaM|M!e9I3e!|N%KO7IPfPapU;{kvQjq9J-=UUSG=TV3UrOK6XONbS9L_UDJ zYbo?|^}pa?vdfx%!f`-gTJ*OnG^N|ifdyYYJ;9n~jcZGV>52IZIq@FwbwT{_$k^)8JV<(?Udxotv4s8fO!re=iTWROLR~wh%QQq2ASZ{rMo>#oP z!U!6;D?8H2;ju>aItG-!|ILD|IoC1tWqt8FmW_jTtNRN7^VhMIXHHnhG=j`^%+zpR z-^SLlFh6!3%ZLZeK}tOEnblo$$AjPh3@QtiS;Ki<4UCy%nfmD*-oTib8yK_tvi0+JQ3GSXYGBOz!_s(bDsZgTwv#hnqi-l) zXXD^_t@}Fh+MKf+tk>hLcTV(J{dnL^lFz@N5Qgq=0-HF{UU1(zS%ds$h{>TDVQIOZ zHSZ5~9${UtygR+vcJMOIg@xjb+Qyis!m7jV8L%A)2@f*QjzPj-Bj19*=F~a*vd-yz zPGKHAi*KIvwgt#(TAO~Uo=t+4_oo0e@c?QLZ`SD)aIZ|`=VN}vrxurOz;w#D(cUH= z(!Py`;R)YHdxt=rZ@y26oSF+jg~rbVm$7-^(NIjO@+y?z)G+<1=AtB_u&nMk>0RI% zgEaO)YM`ZNBV_dh(oprkP}6y&up`mYek%%pN8h>9Pl#WieE>NYD`J3&WlC-}R35m|nO6tRKr`xAmP&p(1^{#F!#3JvqqQdo%iSzho= z`=hoN{EQIj?;I5i6q5>%7`{IRo|tb+r{SBL@183V-~FjEzKM>gx~`eC&`h7-2~=Hc zZqZaa8el6PhLp;8l6;!3E8AxTV%dIyZ2QIY0iZ(T%0_3Y3Xz@mFPr%&Rz7E$s1~s@ zeU9-#nZ`nVfsRt9iL3ZRppO-zqq;94=$tHl7(V6u@E7!3ULQu^pbvj(0n&#x z?iwFnA@X4yqe<}L-$+|YK70!%I%BN@KfVv+H{rwhA;pJ_SEl#3YU@N^zy-BvR;fmR|0)Bj3!EeG=@I#8N z^v$pp3{S9?ZwbV-i5`vZOx{(v7+{9zdJkd`ZBc!EFt zmq2V&E5fG6qj+1HQlrTLDm1Q5VVzyg+SC-|4@*M{$+7c)z!Te3w9bMl-yhJ?`UC#< z{h_1UzB1X$iPBaucfPIsO26f`74!|-%5N4RZAIg*v6YdLt>DN&f~^csv6byeuq;~v zKfbNtH(@LIA;nhK$gmX*Pq3B3+ODmvBW(phg~qp))vc|ZU~FZTbX#cx9^Y2Lly58O zXl(_5`?exuXEXI+J6|8XbL<3Ap>cU1P$(4E5WG|D#J$vb*0w4k2*=JA;EMT=VyEU` z$IhvkX1)J`j&;UP4Dn*;)9{Crr9Z$veSav@(7gVDzCnLzwE*c48h4F9tQq;kiOK%( zN0>rF?CiNpwm*O$-yiUs@CW>m;tyLA4{5Oz!xQ|WL?E`Q(Xc6wod7B{u1z6!u4QfN zB;yYoK?(75RqQ#M{j>$lTHFRau{}kx6HHZi+qO8Nx<;F=Z_&~E1OATuL7%&>-A`+$ z9?bjp;GOqK090sP-myorw#WO%G>-d-J(3>45#)P)nptO$1RX8k_&a%zq$fd{=N-W_ z?~wqg&@ew{k7OOeGklnqHu&%+gdo}@=^)u2H2UrZJTc#q|7v|dFuBKs>Ss4weWPPb zc?==z>9{dY8Q0`I=-OuXMq*Ra&!>3*r#E$B*>-_!Y)b$tG_GtRTiTSy$-54Vg`G&Y z3-SH8=1F~kCzj2%r8zb&OsI}0gEFxR9qpXpZ(~cL+vhY#9n~FaPCHMPVF+PiuzCK^ z&r;@~AM?f`^bN+LIW0iOA&t8x4y_x-p_7y2&^}OGLL8c!BMyNdqt_kHo;U65<2Mn9 z@Iy)*I)Hdci$fS58;@Mu<{}W=&ID;Y04g-T?W|}0;uI5y#z6^z9B%J9we9o;9^ZDr zRJ9ZS{I8yEk?o+PwH^E&#UXwFVr?9nn|d(s6Tv$bB2oScphDyFjySZw$NO$Hj{BH6 zw3zYde!vmr``s1E=C^3K{)~>6Z~R@pHfgVR9)dE@he~||sL(J!<{eF6-@8NKZ{UOq zw8C+J11;O6d4VU$_b1TztkJEJzR}V0jlUy(&$5`Mt@NiJ%=@3gJI8$h6&ja!=zBv? z-+Kh~J;LaFKHv!Q?Ztg`w0z_5E|;GOdubhNzV z?}+y}zv-x6L<2fcmx~bA1V0yElzz**2BB|o4O+|s4sn!E;`1T`hB zK`+DjGWHR`kJ00f@fw8R#2SPjQr4i;iHEc`2*VTBpaBG8TRB_W3V;fYZ!4SHxN@3V zgN}z1l4IiHz~kErn5xb{T-Z4}T3f;2=`ryS)Ps3H7rb*!1W=)Ic}GnAqsRLc8pnM^ zE<6x8f_!fZzWI3}I$FN*cXCWzf}qUv1ybJtDm2WGS%Z9ipOCKaLBJE_`(&wabhLcq z?{s}HNj;eNY2bZayygR_(73!0B7JWr^i6rZ_I%3YPlOP-;M=|Pu2`5tW9X)3PJMX^Gq3? z5G`owr&_>0Z&apV^TsFi<@mG+;cCG;tg>;;MSWYjZyd95-kFXoh&xKd=d-DRXdbc| zoe$N-cBUz;rrl9$j$nIz8#^Bw<|pU*Q05@ze5lWCedj}OB>nX!-8O5h>t9afw{`e2 zn6l_pm-7a&IN~0^6z^Q_!%_@=A>(ZguWQ1APn(T~y_B#0NgxF^R zRA^kEMT{I}efD${->;`}wh!!VAoZbV{e6WE4UXP@sO#R8!GgaV!Qc3pKL8aPOWWR? zvbo3KO$a4UuHv2jXGNArgx)975h>sMBtrzh(jcZ+YVt`iA0FHV%$gx^En>mThh+mJ3(u*9{>5!(>yv9N#k_ zvpShYAWD#0hhIQl#T9vYT{7v4Jo_4c))jf0I~@%F4kOVQRVKVp>2;N-osB=13sWE9 zcNJ)lO2n10Y!nAuho47XTgop|X5Z7j1TY*|GH(52KG$5$ij;8wz1KA()*OFlDAp`P zHo~#yKKKU58UPg<*EbMrwy?f@hKV&ZXdL%(&m%1>@c%{oUVI)2K!t|Kwjf3owv_mb zl?P}b?H_t^j1_P#bVci1MjXTV;e`Jr9S4ziEI01 zTWKn+xRO0*`(NtRdA9UjpzwWn82y&lchNWGyV*F{cXeOsyI(?&1^xZuzD?414Jhcl zpOVVx;wx5HKHp8c#KF1gp>=4Vv}@to>bYq~i>rgd<|D1=Bm@Jms|*Gts*ML9_GzLN z4>_Z2)63D^u+KcEZ8~26090sPo5mi=R@SD^G(PhW8W&nmqI=kw#Rl$S>!_}?I@#no z(k6k@x5?${x4brqz9E~;#=$nJ`^Gj2f2=eA)d+Itzh2+${8!HN3M4Pj^K+PIu2lh4 zXxw>5Y~0$;^I2w|J82yEaqVbDf&Y1FM*u1`Jl52e+j#h2fE|fC-legUpz#uD@N*mh z6&jbuLL|dzLBl!6@-iWa;_yb)FBC@;7j?zcF^#O#3#*aOH5Jxf&%{+Z7b^=nUWFXn z$Lk1y3XLnr62#xOK{@D7v`1;Iz7y>=Es&(OilFrdXpN8k8$gA|r3L@?=Vca+3;B1H zFS0Tk$QLEQs|tSK0>6Cb7eIx^<+mU4yPeQYsaSbitD>X&HA2T!89KnNdD--7^db|` zbu{IE(R~ZUsRPFb_ILa)-!(-YGQ!j$8mN7FjWx{rjkics?r%iA7)IlJ&ZX-Z9zQ7> zzX!qiT{FEepHw3N*S>^n8h9y|{|3r#_LgUjbFOAm%*-=jrmeCk@j^*MPcnm%II3Nk z73B`?g>82+xmapGvK?_`E|+E0qt?`p6QQQH$>MbL5j}zD#uG>Zw&!G^@MHf7%+0n0 zt!(G0jqSvJml%C{etGXB8wcBh?ki&dXQY3(ehAm@wD-|E{88#k7j4&@gQQ-uoj(y# zns;rgyI~5_Dh;ozpIq47;=zwXac(uzGp{-Sf-iII0Z^ggIWlX)_STorHfzo|G%gf- zc0j*^Bg}$p8Nb`jF@X8X`uR$d-^kcAQtZra&LUx`P#~ZzO0hE5cS(ARt8*k7z6mPO|aJJ6T)G2^|fsnOW0jtR(03l z?t+PBeCL{s4QtUHax5#-wvm%R1E|orwmUD$x}%L{Q%x*uqjB8F&285f_)Eagc@KaJ z4UaW@3p+{t#Y#K&vv_YI%1v1O-JvO}9k$HQO@G4DFGvCv-BG)H{F*jjNN8-uprCuO#VxeL-VxsdoSs8kYw2zN@eIS0la8BlSMc z*ZaOu2HCXKyB?iW?~o*y-fwJJ?;8l6^p|=EP@!>k64Ltu(7Us5FMVo5L1TWYcK{U{ zmj?8{o3D3@4f?F|f>Q6%ciq|NzY6MIk51Ej{k1leTw>jtFq2VhZzOcGFm%HE9snvd zu1-R6dodcvecZUcvB1A5@N?V-P@&>v|x~Nlo0|8G_G-xP4x&Lj65qX=9rR zdH(=;Ic@`}(75u3?0683OWx<%RM1!gG&pVpsL;4HV8^@rcC0IAirY)FZk>9Yjq1fn zw=#ZY*4s|p#*S64__64EjmGUi3Z0ap6SiXj6&hD3Av+#I{^g`T0aR#Q{Mg5; z$>&zc(C2%zNuPgMzfOH_A>>_2>JvbP#+5gu&s7ukxuw9riqt273XO|DsL$aU`rH$8 z&j$OPTCYC067sGFc{$DksL;6bhT`lRG|oMjAY=K~g2w8g!EqKqg~p|UIJ<`*XYF~a zHCeZavwh6ID970+BHhY3n|k)a%a3a=a7)UM=h}d#v7!8U8=;f6rQQKlXk49y^u8YS zo|vbN7BtqCdIwOUacMyBd-{5}cN(uR^}ZMSxpm2oP)1FDtVgHiX`2zvQ2jSF{c8d| z-!Fo0I3{njacIAATcMW?rS1V#Xk5L7biWC7kMj#rM``oh2^t$q-2qy?x!k z7S$%3O5N|{>we1(L%P?a({%6T7Um>|vk8)9^HV{pA)DV`=wvgg695$&Unl$eIyo0R zfs}8JVx4p)*MA-INb||a^>+|*Y$4?UP@(bV*w2>(ACG_>TXv5eJ8V?19AktWTSE?x z{QxR7t{fph*oMZrF$l2~aXH#2Wj}3bpY$G*s`GrgPYRUSCpGscc0jLcNBYg&pZGJ4 z@a|7M51O{`_LPY?f6Um8>mPGp17rGcQa_z)17n_VV9el6>*sAs>KOOTu%4f7X}>qe zb2Ib}?PF)-;C*b}cLzM78B!?G*&TC7;r`kOqtmR3u}+WO3wzVwl6?Lhg)pYPcN87~ zdXaHzgdKkj+);ReHE(lA;R;!I6h25uI^#j+jzaM4KReh7K9N)B=o`{`HV)Rg?(68h z_MD1&5FR)$WzK191Up0V+2^#qzLazc8q<@%T^%%G-zM=jVK40KnS8ecf{9< zu`Sla&tw+0`IjD@GY5bqDfZKR6{wySfP`u)H{F*jjI!^IlkTxf!-7I-dzQa zgQea9RA^ip(E9{m@3%$!lZQ&Z?^@D6&B{0v%BabE_2@Lc*PpX6$rnMguAF6@(8-^q z-T_o-T%CmUJ}Fi2y9pYHOT7cA(6}_9_k(=Bt4QxhNWE8mdtY!=Nbh>|?9%($AX%5* zcNaQQQttpNG_FoUdOsR^pOqA6_7F5COT7cA(6}_9_ldsV-;CnSF;edb`+D!ac}VYi zbei6sS_6{giZfe-R6}uQPob0Jq}~BkXk49y^nL>L{#KIS_YyRwNWBB7(6}_9_d|TW zza8oQM5*^feZ5~4)Vm&?Q}2)@m)>7&Snqoaot!N74xmEg>LjH1Q=s>Etlm4Sb8SHx z&xJNkG8qq|p*dc+9~6h8{9eW(ZLG@Pg4cX_@J>*--e-x{cMkll$W;`$!QBICQ* z-vw7``W{HQMwmS*#?{zaJs$u6!C5_KrrXczG3s1r^|Uoy6kEeVG(VGp!q0#A#XRTC zf6@r z$Uo}*j_R6(^HACsl{4PwKcB(&SmVYnE#xzV*bs<_jD(|cYC(18Ft`&O*gES)wi;C zkf{~j)zONc|0sS%^B;;|H@+(4S8ubvv$mfC3$(tAxKKV2dxdH1yAul;*D_m&aAiJo z0NDxTcxN6DS8V zccKEQ(6~AFyd=w?Y~68z*}J-j#&I9_jK%>1|9!yE&jkQfXn3qSPyc5R|NS(s{3@MT zi8@*vz1rl)tb=KhUCHOQ4`5`HAIfKK;|0GnB)_dOmVXnZ1R z0I1Mp(fBl##*u=?=aL413QZP`FF*rVVMQIKu9Tqhm81cnLX$<~>r@&?2^!x>8UQLZ zSv0-{jl}twENJ{&(g0AQ$)fRnsvJiP8b5#rzuOI6?K>2dpvxL7`CA)XCxiR8cLGOQ{$NmeTLgUg4`R}hFlX&02ae_wS zYNEkst^rhNTpEa>M+uoql_na;eOwui7x-I%pJf10q2aONe7;EIScZ=3$nB_-yF^xU zm|C+Ze+Nk%+LNC`J-Akzi{xn4`>gm~?#T}%SU*!MXrQjGjwYh0*{{J#_)<-Mun6sL z(y(~XlCEv+OS8}8w_4h~3%iHd)1Qeaj!CtKT|1-qQW)12L0p;drJ&}o!S#0IxUTBq z$++0ykc{`Hz3*#f?BnbEpdhYX`x-U4?rj`b%{=}R#FaUZL7OVHx8${{#bI3fKgXs< z4Ke!OlWeNy{7F+`;YHXcH=?m7raFg@0$;D&iBOqq4A|Tb0-2J%A%V<1-mB;PKQNEj zyP1sG;M)D|k>3cr@BD&x5X-wGeCm&*Uftw=9M!&`o_R8^yCYon-A}^f|JN8Vr1An?u!8qoGtTidsWCgybhYUxy}jpdHjg7hmXLJr zZ;S2uZW8D<+S6qM_6`PN59Q1~UHEd%{M%<`0#}IJcu9+MD%Y36XHATr{tG=;ta;|0 z8SghET*0`Onkzan^l&`?lfli#AA5!$zD8+_y?e&Yt&^JKx`9-3_JTzBfdtRcqu?NT z0S(bKytEf~+}+G`l>J;9XFms#FHHtAe;@k<W%Ckgz^ z=)5=HI{;9jaq&~WSvW@GFII-pKjo(X^ojY|W2CdUaH zv}a<^_^r&kMLde0U$G9}gbv8Ab|X3X3{K|rtNQaSCb`L&8nwsqbKT%QYo`jGtSa>m zphDy7B&7G%QuThCpfN(~9YBS~r2)Mk@9W*}RgIK-kLnRt!o5&JjoveBo37}+b;o-3 ze!9@f8dC27Dm1Q6LV8~tdQYs)&k!`$l6nVFp>b(I?^Are+jqp*k$R8vFV_3EP(qE~ zGxM(viRLuaZY^38ae_#`$HkYK<_8`de={&=pCz#q~4?FSFDV$gL+SWeuaFbEA~ESr+V%EY@w4)q}~BkXk49y z^u8(d?mYK_9EiPrOzqD)c?=BJ*kWofDA%KN1izbsU*6XOP@!@8#rl4tm_u6sXdL%( z_qC=9{F?(m-z5N`Lc?RtT>>@h`<67&S>K~NhV{^IXQKy-ep!1?iR(MxWyE;50^WMo z_j853TSMOQ@%j#+LgUICn*VKSocp{?&e?f_#%R#s^&LQk#-#zjJ4wtLt?&A&8u{IJ ztXtSv^emlqa8{&SxxS}9lY_lF@eWV^a>cuML8_s6cfQcc4pQ#`Dm1Q6LVDi`dQV(u zE)Xb)Xt}{DJz1OTWEAA5V?b))<><>~6>HR{Xld)3o04g-DPC|O$4SG*p zXD$*n#!0;csL;4Hp!dYQYImvkn!M_opx$R|UiA$~$}p3W&rTCM*;DErK!wKDNl5Se zr0V@*L1S;JcK{U{mj?8HvL9#kt~SM)eWl)`J#mgRc28W!nan-$uB`8CjjdPjmk6D7 zNWBB7(6~AY>3w{v-Y*q24v=~WP@!>YK<|lp)qzs)HF?!JP(n=(F{94&PZphDx)fbLKAb+0XobbqYWeNBD!X;Am6 z_UQSj*#mbTB_`GS8|>Dok6tTuay)cWiT6+eRA^kCj3k|$CUnx;KlpT_RBWqEfsWef zH3xbhrJdg9SQ>95nR{jTCp_PvCJnreL3{nYWg6PoXG^-a`OTp>bsk#nH2AoV$j>hOxdxcmA;VHE`#TjLA0%ey2)) z0aR$R_&pc=I_D0-uk&n``JDmH`Z+={dcD;`Cou3`Y`bpRXRDI`n+5;pOa1{=XtMaf zATR$vbvOUh1^*XG{sB~IviP3{{+;uZR{zmi64t*xOCsvD`p&6H{of+^zeMs6phA244xTRZAKDL{2X7TpPIw(5h>n`V2R5O;_cY zBjMw8u4vOaeI9cM!lU!Kz+3J~dF#87G2S~|Siib%lDFCy*KO`b_t6J(w>yR0H%qwz zRA?HNdwMs^z4)HpCHGxI?pvkY04g-D+^IFqZ4lJt=guB{?mA>0A(u>CocZfXrsCz^ zcMCc0ka7U1(71BIZqM-iFu0PCTi)r--%j}U6gd-o)UjKvV7Z<(94+LOcKb)*c3xO^ z>?!&qucSrRm8r^wWd&v`Vk zHVz|RqGvv=hc3Sh{-EG@rsNkug(i#N=RJO0Zf zE0P9)3QZP`S3x6j&-xKT<8?^`K!qlY#v7?L9u+j+lr#WTXtHR$1saLZJ^m(WyaO5& z$dAm~RR9$lm&UwgduMrm@GgzxKJHnezYF~DOBn!EXn3r72hR7i4TP>drgyo_^x);@UEe22;?TRk zoz#PKInK}UyL{Idc|`P%rv~cWtLyLTGOmwE0PO4ULH5J%5oDgb0$&$G_XWkc%KLMmPvKzySAH~7#)*=QxbB3?-kqV;Gpc=Gp5W@3$`kdZn?qe}_Dq&Sj^os$cAlgC z4Ce9pDDH`8y6N|X$~^W3!SB-GmvcS<6&jacuXn3s2 z`FwpW&@| z8tZ@t`y7A@jY}isbL-ML?&JF0EP;Q0DFc8C4UY}`+y+91j%w?ERA*fouMT=g9Zq5D ztbx=!RA;?OJvjc)MY?L$@gKj-It%&v2$P>{ppMrY5K+`dIq&I+Y6TvDZse;C)K<}Z z8jQ=nry+4=zNg{j*^H~3>IT$+(b~_r8(8~otc&tM#?|#aka0DZ2lDvYo(D3i?#crr zuemDr8l6*tj-OM#1%KE!UrvR->{FamW#eG~(|x;=Q)vV{6T>;4LwSAc&8gldc{!)r zNyak(6&gRDU1HaOOH58R7V*r0dfC`OE1N)Pg3L3P|*!}8V5f06> zZTM((cLeKUzbLNB972yy$|2yR8xgKxecIkq+3vPNX-KOYLsK$wCu+m%Y41--5)wEvzOF+ zv>vb$_UH)ZZkc;WUD5k>AX%5*-xoUBN9r9wg~ruMNbmbX?;r8=KO5tB>Z$h(Stnlx zb@FlAo}u)e4+Os*l3xH7nk;_DgWpe>UrFObLE`|>VE+VAp>b)zPA>QDLfM)k#qR5;CG_r7eIw3i{FFu@;mPVp*gIB-%kX;hk{?W zIRF(JmtWZ2mA=i{dp-^$1d+{kC7$dAvFeH^p9(qtEad=Dp>gF{jpVq>lOwpBO0IM` z#EM^&YV=$!o7v-#FZKs{KC!-YdY=iokC1W$sL;4_WB#u8co<<(V0+ zJyQrl6bBqTnnKWA>%}C<5c@|xcJ!5y<3uS3fC`N-$929O_6*2LEJs)3*)wKNwxBtQ zPo~-Zvv6MewUFZ!DF=WGO>Q|(?H)N6KQKEkcT^9dUY%FR^`PEGfqnY*;J@g%y!9aZ zhU&p=99$3TzNz)#{h33gN0_<(z83yAo_ICu4}c1d>u*?pZm@CVGE;w_3nhqs zUh}+l0VCtTfd|EF`9Nx*rDh{!^{kZ&6RK;p6(*F=1Ec6@zI4?*34fQ*r(fqYtMrgU z+hEE2_tb-VzX7~Yh~E(hP@!>oA40s}D0rv3UfpjeibX|}5yVal~E=!n;;ubH#Z{MxT`CVjzRO?t=SX!M~k z7~r2B!e6+HyIJ)BeW^T+^wX=Y&yYe7Pd7ghn00fr)D3_Njjx-Vl5}&0)y?^7y7>`! zgSxpNx_K?u4LZ(7-2i=xZhj&#>*iMIhHV}|g~ruQ$mTDgac<7lFFIpzHEQtYNk0Qm ztP9uXx0pb>cxZ=WWGCooCl!B3Hs4&J45`-Uf1w`C`yJqYT-+-D}m!Xz3qU5}acU*L@8aP56p$Z;e!#@^8pCoA&WyOkN^O63c*qidm!IeT&H zf7FZRz8iA0uLG#ixN_(7^@|8oqObo7yg}LDhwSX@=r|kg8R%2&`8NWyZtjC__-rJA z3XQ89oQ=FCXcO+)$Z3SBKyjs5IE(r}XyRXCog|(70-f|a$l3!s7WJag(@{;*ZP{^r zqgyp}7%WYUf3lVWjBVvR$x_Jk^oN7ZTIjB4P1J{VF$20_-v&^jadi>$?Tcw#%6ire zJh5H4zP)|BSkKVWa*w~$*RvMt!Mr~R-r2?hRA^k@VdJ+Z%_G(|y`C*{ZHkQ-fj5@L z_3!;?Dyx&?`9w!&BD;G%1NsyjZzVA6<`JnI02P}0b+c%iZc4x#)Xm3IH|RJUbp!M% zx@jXY>*nv!O(k9v090sP-3%bRxh-fnv?eS@Dv6c@`2Hc(H_Cn5fh(ww-=L2d zI@&mjzsnaP??raxzpvegpv?1|;F;q;fC>%sW6nq1>GAvojSJ;=C*!+L&6DN;o*>`r zPVOKnk0;tgBmi5U*S?30> zpsczkVOi0!5m_-VUDkfogJt~)va(GAsL;5wA}8@}@+le@vdIIQwN1_gJh7avFCD#I z>xAkL^IBg*M{AS#JF>|h;d*0U>cPB!DtQM`p~>R?=>*=RTB$$q1bJV4BH1I?O6X{L z$KUC-(tOl|dH({uvp)f-(73#(`qMLnAnZ@`16Rzy>rW%VKie2OHezEKmu_PVP!E>% zYsk81ycYtXLgUIhH`!RUhV?H;vHDpWhYcpI`|A-r+M`+!<74?;+u8~8;oz-_7wBl` z2Y;9EK(g-dIW0sG=Ji`SF90euF0YuEyZtz)qbS9>=Mv{-Vc?4ScIV|J@Xh%OIyN#d z7?(aTi%<`i^?S(5z7L>6UI@(U9~1rJ z55N`MOXL?|tlHyX;TP!Gh+kk_x?c>W9xQ9SloddQCbz6VCCa)4a0O*uM9PYejmU~| z>9P)@9xQ7w$jUJQK!wJY6*1sGF|Vb{&oFN1EQhz>xFqnzaz-&g&*?D8$!jP&+8BVp z)7Q|Ys0Z^thnyz>6&jcKRGa)Iah}S+74z@fKp9=309NyeHDJ`534BxPKNz%1i@kdYXR zo>c*;(6}<99{r1uu~fO4MB_fD9$n1TqsszEESozwYe2RwV%gBq&JF%9Uz=2q4kIY@ zyr8rx02LbM$JC>~?@v#+spWtt$hWutqod^;fBQDoQ5{3h)_Id$|FItX>;LlfTi*2_ zeS_=&3Kk&Oe~r6l{hwjxv3yPP`agiwo3#F)M1p0l|KP{yk=K9xCf0xakh1;{A|BG# ze+*Ap|5qds+se|~zT+GoK!wJ&73}{$VD0-_cm1b*eB{U3`@bszZ)`h}KZD7txBrWd zvvH3T=u>=uWdgHqhDzN4sL<4}o7DZ^Re(3B8*l#?9cQC%fIdYxs}h)XGYq=nIu}5N z#?{RLvYWpK?S^81^8W8|;0o%)+y6yJFZPGtvaVSGFir^CQN14lX}SzZ2oT=>?+E%S zZ#+WZU_4sQ0%SbWxNG9kgHb%fcALRw&Sk7bx{c0;tVC0h6pud55s$!+ACK^xh)4J# zB_53+9@63wh9|_MkpyD9T0`0ufC`OoR}Wdcx-N=GHm6vD5QKAz)q%^mD==2|atd_x z>?$j#zz|_lGN)LBz%1k1kdbq902LZnM&x`C3mHq56=_^beZD5}#PUUXg_h4-pV85- z&-lA`eI9rSxx=l}9bljS`n(qXme(K9m;HgCsbu4ri*(V7+)3%av5(-KIX$T<97iy7 zgsFcyqqpmzx7(%OfX3);U>xfzyO0ZzWzS*Ex4b+ZYw9(mU0c2J9>i3(t##_qGx~<~ zoQ;F^toz1#mN8&m!p|{a2gHD}aoz=>LgU5&)D@4|7;rt}T&XgK#@Rlwf9Pfee50T= zaXm+0lRELv>n()8XQ}3$@c~@z6bL+&~WFc z@1bUXreplvh3MwEV_H()|4+oVL1VaJH#Kq{7U9Yv7tWpkUCV`)asj%S-JCw;kGVMZ zcna{ADiD`17=pNbQJy`oO9q3tabXW`B5rg`WnzUHr2 z$$SQ^jV^V=VgBG**G+_8j)7kGj^`IZg@*M~ER<99(mF>`d!efu=;cUXFAMN;A-;=Y zzjIb(Yi^tW1+%p5xI-)ds#t-)V0F0PK~{&w!ZHaui~>r67R`J+v6}fA|L0t> zTH5EPVjfPwJaBCYphCm*VD@f3KdYQ*%`)l;-LFRSjcq~hk+?=P@0T_;!OuR!D`w6I zSFCTXv~nm${88|JisT(Yg(i#lQ$60Lel`;{P6v&xVmk#;p>b&pAi1CN{TF@(|2=~c zM6L@RZ9;ul3+RZvD&al^R@rHo?owqGapS5ij;rBs)Ql4HoF#PzphDxygS`NMzRyn8 z+2(@ARM5C0)){~bjY|W${L?~brOLT9j{CT|{1yWL`M^Iej;R1DG(5IN$NXmme)`VN z4Eg1#x5>3IMHg7vdgGsRbs#P<_h$^$_$+O(ptp@}%WD3SKgnr$g`auIaG@f1LXhIL|WFQ-lrUZ>?y zi`L6ozFxXB=FWL|;|e6coH!iN;Z{P2mq3T3DIl4(8bF1Hb=ZPEP~UEgl}l-0)CoQw zjMWR>o2!PCv1n_--xc7GV>N&ZjmuxicdxV)8FiF2wh=V0292v@-vv;iacKneu4^O_ z=%EpR*}_csbmG9zQM%|aqlKK;Lr(S=02LaRvu=O6!D=8SjLd$2Ic0YG%eF#?H$jJ= z$NmDKLc=<2(H{@<))Gp0Znmn@U12LuKAUkr0ms&-l5Hh3pG7X#ruTTa6EfW@?E*lB zhGjB&>2u!NV((l);JnRB=dAlqUTWm)&KSAWq{J906d~hbPx@bPP1#=P;tuFyT)fT# zsL-%3S_-ILI(=Q(+~-bD5!4rRy)FG4s>kx=Kqo-d^ztmuhr-`L*g?p6H)Q1e4nT#* zm2m*^o0#9-LkOIC?n-|5sgZ3|efixOAC^SovNs#TqAZAG-iOt z5%C%UphDx)SeSHH>-P@`D%jJ-S~AnvPq6|p?Y6gGP1~!|rFbxwdpFPE%WIX7^~E zS)1eRJArxKhIrNc1I@Yi2Q&-UB(fl*h^0rmiDL*IuQvMw%|qLp_+)@tO0kQ{==oL@x{6~Ajcf|@lh}N{pK;u6r-5IK(JM9 zO+Q}-8eea_)S)-@4e2c#2kTAu?TX$sf}DEu`sUGFlOny{BlQL}zTU>xp*Qpm=`9-v z>rMBK^(NQ&T?s$$zkfi%$=SmJP@!?xcM4 z#Z{uGvMDV#t)!EzoydI zN6;u-C*%N7p~<4rMB|d>*jLbKku(5QXtHP&Q)%ocXp|%k02P`n8f~dGIs}a#k_LbZ zO%{!wsWkQ%GxQfkK{nrOp6UXk2+h{@y=TXB9zXe$dz>UK;^a zXj~dt+h+-#l`0F+IPT*Qn=r4ez+)c@Iw%AdDtuxq0pSS$|X74K3tmiWa37sqoo$!7$fC>%k z#Oycc)Csm37t5iRc)wZbC9B4Eb|?~_iL(NC>Vg8v#%%3P&&dPNXR1Pni$jO=#C8jy zLc=;V&u2WlEmremFyv53(B>V>p{7V7J>`1{BD0Z^gw@q0OMu`(nH|Dgi^GQhuU%s+q%jgQ~US&NlrlkguV z@Gl4aC&u^zRA_wsUd~#qET4q`PXhmnz(0Si9{?2^AHSEg7Aq?;e$)gwC-^qvOhK_9 zOoJa#Z8#mdUVOMub|yMG;f;eq_OC3!ELNxlS<{xQddd^o%p{%4_|;n2?)v3>wl zXk7hZzt+n&iH&`HvuBRu;PF~>O)BF^DBDjYFc$6{!ZH*C8l79TF;Tpe<9ECx`a zVL9uL#cNm%q%2XhKNcTi6o|8Hbt{nOD?JuZ5;|N9I{Y%W6#x|))}eX!=i5qaWo@e} z-BrfpBLt0gL1SE;M*yhMxHJY4-|u*NM4a2LXGui~9`%K7cE#uJhKl{?Pj&g+kwV4| zAmi0>%mYxNab*np+=f;*(^KkE2^t%N20y0-P@!>YEKItoovTd*5lQ1HLF130aaJq` zfC`OEBPhpaf`nJ6P8Kva2aR)L8UQLZE{(7pTL>ajj-v&Qtw7_e*scLoXj~dWIkpxg zJUNaLG)9BQ*D(zM6&jaDSdMK45h=&9g2wisu}!Qi02LaSMo^9&1PM=$;{=TzLF0&+ z27n5UOCv1DPJ)P(<9I=17toj*(*RJR$)+(jg~k*?V;pFl8`A(#p>b&hb+wxy;pyrG zL1Pcl_*XpV04g*tjj*ov6hx%1P82lu1`Yb&e6*(sphDx)2+FaKAmPbzlAy64Xz+d% zfC`OEBUGPuND>r>%`;t{BQ)o#*YpJ-il|7*t^h=1Ujnc6RFO7U$#JUtJt8onw)T)FtF!F6k6xNuhB zr#_yoe;47Riy^aO#cDKu&ABk%DLUz9XXl*`_JNk;Nq40R(7K1}P5f;t*!K`nHvn(O z`wfhDUV|5*F%RD1fp-Fe{2qHZJ?Ae~5Hj=N{Y2YJ4m}Jr{34X*!5eyqA;|9)hF^r( zJb2g4tB0-b(Rx7W%!BvKUODaIk46s&sabgOURh}GX5tVUY~Cwld)UX|MHu4u%4Fea zZEkJnozyWg4cx@C02S%}d$06`4g9=AF-Z1`Y_jn)(``ocyReC}T}BG`WqUK5NLOVG zkzH(xcHK0U)+gJk0onG*Cel^eLS%2qCR?9ulLI#SO*WCP$`&HK@(JBMZ*(}c#wI6a z6X~jKA+j^F$p+`G9zQ=LV5a|TkZz)%hls3mV&=qkRi}prWIHySY*43(vW1BJGn+_A zHsr50c~75{NKaH3$(%DYheF;n0_QgiPK}lGjAT>+-WOMZ2a!)q#`0s{d&j%9`k93~ z1-0FN1g&mDY*xmQ!a4WX&nxU5?x8U!rH*m$LeX?+t2NJAO7!JAl+RLT!>ZA+K$JMB$jJ!Fjs9C)rpMjv~I-pOk=p<8`1s)^VRnh zBV&&Jha9;(<6RthOL|))D+h$`qi2CU-aZSI{-60Q5b^3Cp?sZ_AEvRQ;SnS_pTzX? zg$tp0g>}Zz$j&E2WXETdjs3^XCxbS6Lo|O+AaN z7x}E#-rcjG8n2GqtDahW_7l5HfjQ%|pW<95^Vrb2%+pDSd_MX?xepGYLgVj)e-8PY zTl$ypAYSQw^h4f0xZKY_L(q6c(g0AQ$)fRSDvdJ*jlYA&R+IynbI1THG%k$+HcTu`h=2H#kek^SIO*fC`N(51vo>^YTQh z&dwGzo&*g(yAGg2k2UA#z7qK9 z{M=Wx4^ZA619zvJn-9J_IzRWUmCZezFf4q(!PmgqQeHg$egmGfe`3!3`wd_lwdd!` z_1$kURp_J>I^i=L04g-B6LV%Gr%rHwZe|X(#Ah~yUb3DMWuKp81@<_taRri%nKiz> z5I#S5uF&BN(BYKW*8x;$Scm5PoM*Si%8N8G>LlaUc>@2-z|YSH0aR#Q{2||a#ZE+! z#`%KAYoKvfECYZFjY|X1I6eO^R$iAx>=`97ug*59Jfp1E|ojoORp#TUG-pVPN*#`)RY&-Y*n7dy#-%Zc?D1b-td7^u4=kzLGfIKnDCJxr+vrTF*gvC`kSm4H1x^z( zegqlWuK`qOTp2@t{jn7->S&+&YoBY*wZ`bwZ{+E<&-|^+$!GpGOH3Re{b&Ayhpc$+ zJUMdCLpxDkY2|BXk8GS-8_ScP`QJ&)s?N8fXa0X9Qk^s6NcO=D=lA$MabH3M8`+nLo)h!Wq#qH_%_W9yh6 zTE-mb8n7>s@$8TB&IFJ7p8Yxd5O`x2p8G?5=%Fpc*Ok8)o^2A`yT2}2{hrVo)_ z{7kKyG_r9W;qOb-*wt=8R3Ia#=&tx_f4w%HL#Jo{~N4_^7*`5_iMa5o?bz7;lJ~VlOXx)e&(^Ey8lwrA=mxI z>&03KphDxXh2Prs{w`DZx6(N0h`e{k?lM86P0|2Rp~<4ro=W3#L8B*VY!&B504g*t zjR9oO-w8RW?$@VqsP6AY2)b1F^R#?ye7DZJ{|X^bAE`3{6&hC_mUib5y4LgfMq+j>LHfrnsrRuBuuNFG#51nuw1fW90Ix%%n zPMx6cpD%}6;yOs^B`Z&KGD0U$bnlX71&;560?Ec~t{ATSuMs+206OIN!T?lgScj(W z_w2SNh(m>ts`FF80 zKoYTaznIs=x}T@(Rx@3)?(Y_Rzh1~W5OT7;1E|ojoORp#5>^8#VPN*#`r$U#K?w|2hwF*3ZF~ zRBhcK$c<9!ezwtJXX_kTUR|D$D~0R+n}m!*AtU=WfC`N(W5}eT(LkKA>?_T~p;Z`O4`(D-%# zbogn`x*vVn*SYS`#=&tx_f4w%HL#Jo|3|Ec$#uWRtK;cUG#7r|kGD4R*Zs_6Lv{Zx zq(iRzH|$C~=g!(XiI z$ONQa-6inv4E*C_{sB~IT>LnD_Fut2?JGPg_Z8lXzL&5I;nRCrZb30Lysz*-;A|-` zn!c~VHgObe!rxbb?bYrp461Km;clUmU7-`Mvj9|RSSO~=%Bd6VD~!vbmblImddbQ| zv-cHPf%kVofn)(G2V#`nEFtfHch(su6^H1-0GZDQX5 zP@!>Ypzil*6f1j6B9g{^g2uj}aYRf5K!wJov2cJ!Yh^z{#O^JKxlP<#;3@mTOxbke zfX@_ki_PCJ8;D|9O8xt`x5OX9yXqkdgfw zK!wJYF|?*mw4y~FZQZZ^p*hzYpi{qRNFKlLx9%Y8{+cBqj$eM=FL=m`x7l^SR=#Go z$N3F2Yh!Iv-G49Ye&kzG-MU=1!6m;DWMoitm0d)*L?|*=La4o?3J$_HD`!%qU zx<7jVn#Wg&>Dsy<)0tWK*Wh}n8*%-wFA*p7-M=*Nl4%Q1@rNJIi>_ zm|22j1Ff4N+dA5PH`%HCd3+b@{!lD(-tT1^Yh9p&kF5J;@Ui^*@3k5l*>yjk;b*dk zWs^;;`)lm#b|9;H-k)isPTkLp<*xg+H$NPEv#$Gr#;^PT3O~(R_oFZSI@kT#I5;lo zzM}3Y*2JCkcif3c(_Fsz_CiU23cI``HcU!Gn}=*h@2+VCI(B5=N$>TgImo<|{&SkF z&PQUs=_m*^zTO_JLvQFC(pxqT)|>7t^yb)y1~#%^@*DDqJrKC@qPftN$by!~N8<044|K!qlY#gFwZs*U-6{$M=o1k$OXj~W9QvfP7E)DFLGz*=TDp%7u?&I#4{9WL`7Whw$@dK#P z@L027;^8k=u44kyt{xNkZvg&ragGn5LgV7ceo2eqpY}_>mir|iMdvVXBz!gdCCh~O zONzkRQeG^5zl3e#cG!f!Ujo~!-7i_PzWtJa2%X#vo$MX!96*JJbz*AAoI1gN$@Cm* ziEBrpm#q9fd%uJg_+=LqNH$<|`0#$o<3fkGLWf*e0jSWh4$Xdv?|ZjdMMWK@?LHxB z+yNR><9Py5p>b(oFT|hwd@I^7IfY1dJ}N5(Fk<#g&Zdr`{gP*>2iF3e z-{beh{SpmqWWOZ3V~)q)Nle$)qL|Li{gN77trvG6t_>Q)g&HWj_mE}mH^l6h%%J$1 zW4|QhPB6whb~VCVssL>r`z1WS!Tl24M_|^i?7fULh&OY67Lz>*sx9f;V)!Zt%y^)7 zbKhM+4jNi7Cx(bTmQ5tIPlJ7>8oTduy4CVP`YnjOJdT%Y0osIX_GLf#|Tg$k*es8UVYgke5W8Iow??wgTV{t*K z>w2K^>-tXAb~)>M^bOVZ**LhC)P3W+URR?n_vvaBH8Zg(&O{hc;+Y7IOxK>-XCl15 zdCo-4cPSOs|A=*{i)x_pbvUyQ9ineYhuJt-hq`a9L+H&p6QO}xCw1N#*{=6SoQEhq zOYYqf8n51K9z$yJ-yy+QF#`K)YsKFS7k5T7j}4uPc%F2~XCfB4K|Ch_P@(ak6ZEjp z%^tuuO{uadjZ3~e;srrtfTRJSLX$;f@l+Zw3K|1JgU>_&sL;4H29SUB6mrm+2>nG8 zIuo%3A?VVX2%eV9Xo~AU6Y-LeXGy6u02LZn9-N8r=Vhr>oxLn*EDaimQ7klfIs&NB zxHNDkqL@=rNa3*5K9BPT5oeI5VJ)_G$6Tu1`bXnsHBpa~L z>B46sUKcuC89L-=rvNH6tV8qc)c3trtfHch(sthvG=_r)e|rx=g~p|^F!AltpfeF8 z1QkhRmY^{bG}u1?RA^ipI1@34=O1xQT-}nYJrfaF?^4c0@HFm&Y4qOY%g@)y<+ppKN8gS1W^JrZIur3%N+ET= zrBnHi>P#Zl`M9hUz=(O=Ha}@UbSB~*>cO=D=lA%%_IX?Mj8_A7eqYD)COnIbzHi6l ze}UcBoX^K}W}b*ZE9DHV%#py057F z{r!^9A3~%_+%M4xa_*OSee>*>+)k6#`OjEydcOo{e7(I_hu+XPq_=DwtT)|P=H@(}3whq6By0(-zqMQGF7R%%5pI!yW_xkiGP27pR zNjqAP=$nCU{FBnOwaQzsB2zB!LY;e5#!}m_*gSW!ygmIjUwLoP_xtv+Z|w}CqHZKn z#;!+8zt+C3L;DumisjAlQ=5Sl3bXLetMRLq3)SliNQ-sudupt=rmKzKwuIcJm_ZxQ7Fm?P^|%Sq z2)&ayw7sPQI~&rfEiGs(i-1h2ax?VV7T8w{f3xEQp@$0eP$Ba&dH_(Nu`=S@I|GQv zzCsVQpY#yvqZjQbO&|o$ei8+`;CGbr$TQx^18d=RM}Af*vfZYFt(lOc;#*^L`}Xn@ zA*-<$&2&zC`B3QTVCac+Y5)})S5Mfd>L>J6svJV&bXi~7tbqz3XRJzoPQp{FU{+!1v9UIvW(Z(#OG?> zouZMx@0(|SD-hAIi6LRYc6ok_h0(<4yx=p6uM_{pw7szQ#)Y0lM#nq_*_Hc!rv|0RaWIT5*1<6}!< zBN{&^?5#OJzkRL)zk8GMlkLjsj(J>hB+qxyA3u4$P4g(%t~&hjW8sfS%lHAHLgV^l zD1ICRH(Vc40AGeAUDCPIWk@G&(24p)&^S)g08sbHqH(-OBQZuz|D~xBoy<-AQU-%} zP0J6H-IT`@!KfzQisq{GNtq48P)tp{7j+EP#Gg_R&i6Qn!|$>t#`;>HUuhgV7dw`C zqj-g$kEdNd7JM^$V0saU(Z zMge<%uKgMGMqw|{_d?N^bPq*uj0J^B@g6#5niOB?=5(7hUTId=z8p>gSA?Oj;VrMq7&m8heQ%{6wk z?v2I{W$vEKj?A3q&G~q4E(Xb*b7OO9siUujj;@D}#>MplfC`PPBh(9v2p!Sf=r6`n z9e9IPR&Bk|sEqU6q-BIwGwm-dbuzGqgp086U$cOETU}2nvIB zjexxLB;+)10-ffM&iXRd$h8G=QYh#|U~pU$th-*wkG>Id+#=-wP@%~!$F1EX#~e57 z`Kd#WZ-pGUOE~~kXnZ*q^XEfn;WQt2upArGd`!c9WY&o6L+611wo1gmQx;O5ZRwAAkyt%UdY+-ACixy2Hl4#UVq%;qjM^NG`qygAl$ ztigZKywo2%r-6(gJCT(K)-@Yf?7H75&CPFVjHXkYvf=i+)#yp)EvdCB_{ToVK3iP``+iv3H-HLFmVG~x*S?p$&FH!g z`|haTK!ZA;j_WS{i~}k#Rqa%wjjC3@SNR`;b6v%?5`LF8?O~)>v!*)F7}D0B>|9W3 zD!Tgl6axEiM2oD?=EMh8P5g=EeI}My*O|cR*O@;+7INJ@btd|P)X|R-FkS|1a6bdM#OXbgwq5qhF-1a}>)9>7#uMzGG^E*M6O|cYAU<-CkQx zx4UITTu!$y5EmEDvoFOGop(E#nJ%*1b&=htdF~cbWP4rPZIL~In8p*XV&CG>xeFzd z;1BX3VYH_^tZ?%ig#jdE{Cq1~Zy53G;DOfHjP*vwpC8FCxqhFC_;Yu>_5-NUxbdey z@vwwl`~N|)vuCMTd7cJFoiJ~!QJ;GP`@a(}BiyDiW4?Rdps0{hOj(_$5N%Jonj{`p#+cuhJ-b3hJiCa*v+HC_{|4 z3dE?{sI}|KN~@cFTF5elXsq5F>lanp6KCP+SkpW`DOQ1(UL`ULdKTM8p$pGR+sqBW z&@I-XsAgm0U8w!*dp5u%8+|tL`_=x;>%qpvkYQxjUg6sRXJKz|z}`j^HdFfpsL;6f zhT4Bg-`;e6NwvRzhJxCE7GaXLKjs+uV10Ea%ev5=+MROAYV$$qTfYcd--fK?V&4K# zp>btJExnX4tKR3Jy5=1#VpnTvmhl`TBeIyx`3%eWUm@drkdbR?02LZnM%2<}Uq)L? zzfTAnuBBP7`fKU`2{}HLasa5%$cJ9{fD7K2c^olG%jWTf#<2~ z`wxukASfa`AGGVuGT_-wbkb@tC-uD$Wc>XHJju(k|IjGS&F*fD=9)A&zfwIxdp@kE z9`_hMiT#J5)!Hqfcz<*F2vajchjf;!uq<@g5)~mi;>Zw?_V**8yW01Qyt07pmi8#L z-GT??hS9TDmhX&^eC5<`|OYHt9YK|KSeIMew{XNgFUf1xx!=S?Wv+e#*C(TD^XRKRoOF#nMHW$hy&oKD8YK3n1qgksidSA~8 zl`&Kg@VN-=F=>}b8gpRkn5F{jU(?Ashv*xc!)zQphq`Y(hcXtF2tV%^^u3YRLw?>5 zphDxuf_X__%h~ntancGs@1L8-**=I{*gucn_0Yui#6C<4!uo}kJmq<~Z%A*Dm;*Px1$#LX*Yc{CW8Mu@U}y2>uq7`~j%YWbwC99{&2@ z-@yF#6#OkB`2$d)$>ML(Jp8TF2!FiDPf8dkfSP6nPX~i&oUPFoC%E~~1YI2;9*yQF<9TA;@_$ml{2kTNf1x#Frd%_iQeHFk zvqsg2elu&v=`_MyGxTl(PDa`_!yofe17p^nkw(W|XEbj)*BSH;tuxs;c%9LG<8`K^ zdI53T`MlI2`uI7`9MEA-KG8SCXEqMzQ}>Pe#CkQAjIlTE8QAlEmj}ONL(e6ehg1TO zCwsTMPZ2bFZP8~n+f=6JDS}C5ysq(6gq~Dh>bGU+l^ByN4k?U1iT9e9A%4vn+c`-e zynYXdZ*n~gphDyNChFN0t#3YI*6$HCF6BJ{X7eqYQmoAh4V|m#OZs3tSQmD{>lA(Myd z$L4X-I>pRQrs;$YWUNyi)oU^DFUolb8jhj*xrdsYels!jM;hV9P<>9#jiLUS_5WJ` zm{S`V)7ik7`5&yGw{fXs-1x5bmNRamZ^&P=aj?JWzOlb_RIemXJ71FXi$1=pl`?yvT?8- z=)S@ZX!A+j!xw%(I{r4HMxbXp?H)e!lC#&B*20W$6UusOev+5x`2fuGxVWYSP@!?> z8P8)^we$Qm=9$hq*mI`iG2wU#i=W3zdJ7186=_!hDl{%V*wt`BuT+^}$>@$9)r(;X zuS!dRV$2The$+ekZq$O*gXfy(55LPjTAT;e?*axAZuuNfkJVH65%EO(@7Q_edw>Ej z1KRT&{&~PH%(DbWxckE<*8xV(cQ3 zWxerUVm1!evF@AdBN^ZC)Ce+t#3Zv`-)tYDe1eqS`FgB3y-y1?zTOtDLvQFC(pxqT z)|>9z6}@Q$IrZlC&7-$(p|>}r-hjr}+ah)74Shp;%f`Wa(|u#T>H2EA2@A-{{P=7@ z!TJi{j@8I=>d@<(M~9m}LOPr!bqF-R4i~LMhv*y9VKxrdq3#>&Fr>E(pVbI*>dot$ zM{id{Z*NMy0gbP>#p=)-`iAtDjf3^3`#O3v@0O3yYg&2U^fQ2Ztlm2PH%aHeTmB3! zzuxik_r(x{hYo}phTJ!yBkLP{w19{%hBED7!U+zo5bPsX*JlI3<$%mVr7b2Y-JDvIK z^;qrvf$M-CPdU||b7(0*k88{xJ-$jD`R+5I9zCx4f1$_Y|52+)aGj#Zj_THrQyhFt z#zDB29|s525eLyX6bG|$a2(Wq<2b0-;FFWrU;|2AgEg|8Yl+u4&suUKbojQ^A<+0b zT)Yk)qHjot**I8-x^Jw*&>Ea^XPHKjQ*U11JbHT%dV5Fe4QPD5{hIfU**I8l zx^Jr9GIAGJ4aoy)99P-q1Isw`?4&H{CbZn~rt2OxN2G@LB)dk^wcB<$Za2KZr^bk*p;z z%1YDJs(z2Ol5lRx>>7Dpy)EG=m*8_tat~(^>4*1>9-|QMoYMhNp>g+c@O)=2te?$v zFUNCcZ}1;9j{CTG^(-myKLPx__Xwau!(+`Iy=!~;|4HNAbFor}r38(qKx16I?**Vj zxp{R@`8s3U3+ z+&%YBALOFOP<2tW+CKw#&&>&?+AXcf7Mlv?r8!STp1&UE!u5^Jyw;(6CeiiJp@3{4 zud?-p)YD+0r&pjS{?-J53XQ9$0mSqAzWvzuSY9Ork?9~lkP{a+K;M?~x^xp;$~$80 z$O}BF_Zv^9*(FSG`DfGVRmUOZ5avm~d!JkQZ2Ax(-y4wcKd>8p)(Aj_hUF_3)+e4f z^yKTj*G6XZ&cuo4oe6wHU=}3CYZHBX48>~`>wrIdL|^K9sNm%-@G>s;RR9$l=A}hn z*13_#i@6(x-WhtE5Crz9;X51Cn2E%q1{5WFyM6i4> zSXiyey1Vxd!m@(rkH9m(dj_CFo#g>lKgxKC&bE3`S=G zcER$W!2lOMSP89HDY+bz9Q72Lu7Arw!dhkDN9-!i7aODrokeRr3$WYM#`mPo#3CQk z8SW#j@4jCq`8SZHYpH0K-PgY3T*BV>3q2iAbi`WgTpK2y?b&@gXU9uikhc%5N#^}? zX5=?8(pH&4jO1FBi5L4kaF@OK-5c1?C>_(BS|IfuDrRAwX9D)4*A{KD?ewZ*tQXgQ z_NU*C{+-RtG@5qXu$Xv{nqsbQH(Yr$WbI(Dy=|^nEKDLkHizs*y=eDzuM6+h)-tqD zOUjnAoilfDm6=%NSv@;2OnyWQ!}K>-?VRjWv3si~K5Svu8OGQNjI_>3TYnx2Lt1?3 zimms5PS3BWNuJZ+&DKYQk*?dia~_-ZdI4~gUiYM_if;mA8SVW}@aN%VFDK!hTUi^l zI2ZRZ-j|K?T(s5(S6s>1V6;ws5U*1Q5f77r!rx<95o=J+XXxn5>li;n&&I)Pp6)C6 z7^d+a1FMLlAZSt=D3OSj{PV=n%V+Dg@*Hv z7Tk+m*b=^m{eu_u{z0)aCk>=S{J@PodMkoYJUhyVKR5aCXHg=24ie#GXx_@lQe!Z~ zRfLEncb}O|!X#m`0s#zOGGQl@uR)~ORCnJ#%bl6<-uL}JetPESba!=a zT~%G(r<>YI9W(DU+k!t8@Gp)wF4tWA(8X`jD6&g&`hh zAJeFh11uVdXL{Z~jQ|+Df*u}7bq6nt^ziRW5C0bF;pLtQnT_9;7JlmjzqewUqALtmIX9t0e(h;V#G;rKHCl$QJ>LiI`ys_}R8R=i|{Bv!m+n3R#o zO@Oxt1Me?Hc>h!3{c42pRX}(Jc=cN-G#>(P^L8tXx9fwqGT%XAh==f2&36uQWS^4L zm;q)d&3AwceTNtv3L37CX!y6H;a~VuTJjqHl$X37QFM)mBKHh|tu2~108KI`Q5fPO zH2KHmhSW~#m}7Dq3;xD{|8}g8C=BtCwrc+UQHN)BY*dJB%qCz`O`SQUd2$$d^2LZJ zZz-Omv^o?M%QC)-*$Zw{Q_iE&0@h=+^wJPYU1G{~{rp}SHlR~xfDI3Et2 zuZwVAsc>GQaDH3i{7!`P^*M0f&cb;%a2DH#!VnL^Il=bLp@xRT0Dm!VjsUJ-if|3S zNm^E1@@|CP4Zv)As{cMkZ z#LlBI#6$W~cef*>3_*oy41Mi*~f|+Zp(YokwAa zhlyXho!>}{3$Q#iYWSO zD@C*cl}6gKXX8l+C&v(@s^nNVVL-_-`&`VOsaWO|GEcyJJ2#eNj>L_4KCm2PzG6+i z+&L2LMT6vaEYa-jH7X8XNHHAeMdAd3@ya|B@c>;hl+IsMont;N=T{&Wk5_6mF7pQ@ zXAlxD$9Zr`Ja;||wU`D2wH<%We6dmcwuxGtSNZrS1h;hwx0z+|$$<3)V9`7ZiK3MA z2*BrEsr~Uxn-O?XUPhQ|!2OpG$KQK#+21 z{W#!2p>GxB{Dc7`l=JiI$vL1fpPu0C+im$90wbY`{9S6oY$yZa8pU?#u90okeAnm7 zKzEaH5@}}iKeMNtlI=4Tf6Sw-3OR6UYdn2Yfwjkc_IO$~w()m9WHN2zaK?5!xyBJ5 z+x?IIUl`jXpW_s}aRMmJ&T&Se!E@6eD6y4@%B7nSCWh5N>4y6D`z61 zFvLS*Sv9}^7~%uuN}nKCPiG>XNbRJKIlrH4!9NM`WgQ-cAs*6J?X{Zkz;94HW7^5{ z2jo@i#mVWUKbNp^!PA?1vdcg3f~lKcuQH!n7f;;M^UUOxawFDJAG1OMO%+{v*dgV zM&*dm&s)7S`ir*g4(V#Dy>o+}w+nG4x!d~RXxeFTQSN&985)$-YT zrtO88Hn#NuC`P*?ayXY>T)p-Y9ud+Gwr$Aw1>JLVC_Bk6mvK#i&T zlQ7NwK?UpYI5%N)`b+2E6TJFTQrY_D^c8jA$`0BDJf*p~g5z4Yr#H?0f7`XNegaL0 z2T!EO=>;CLfIW-aPY`_M+HHa`O5s?aLl6RWu+S19P1j5wgCpQI4j7Z5iQb<_IFzi5 zyz7@yYdS=}KAZk>^JqJvT7%nw+NyJa_9DpQvo0b)M(z!TAs(i!nMQ3-(zfO)FveJ8 zd7c2oxwlfVkm^pt{JF4rZ@{9xpk4Ko=s`!?PbnxuoBKT2v9NhDSak)EMMcb(Zy6I5 z=-vj;E{1LCBd@bitQJTW>`MJsYTd04$hYn3J_J!{yc9HwUq)ewhe_k=gm=TDvC{Y= zwUat(ZqIQ;Vey9mBc=^nplNG79V~3_yLk}NhKd?#{H|XOoPBqoewa!H=PQ7-_y81! zcnChl06rkn*ST+CgE)kqzI8$|Ifo2-JXY(IyBJy z5$WWzmtwob_8fM?wM+ZcyS(-sb-i}!09|0)C5GK%mlj5L3Bg!`UAm6MkYtzM&0&{- zkK*+qG+vcm!aK_@;YEsFx`}W|vrA~6V3!W0BGIW^p;IzuQ5fQ3>J-N8B0XmR2*#w2 z*@FNh)}?670->feW>Ha(0sKxLvj#}j9>{5NObet(9J7p{-pNtpfJS4 z)Xg18uBYhn^tAHx3G3;NI|*LmA`8KR|3M!2G~9DjSUeB?#bb{?DuBNP@=dnm-vm23 z7C^=5vkJqUW9LFk41lWD`fcQ&M%f4bTOU)@#+B(})v}7AOdobQH5dLo1pdf66beH; zggDkp!iUFWVe7J)x^34e}2f64rLG3E~{M*KnII0~68{!sb_uMa8>ZmGj2PQTzK zuE>qwYMTL=?J&}gwT`6L!pHA}j}i-@FvLUnsMc~%b@VLWvy&VP90gc0kD^#WbVy|$S?$A4lxc^uk%@pXI?Dr$W3JN8X$|DJr)E4FWf zsb=3~`iA4_WnSNax?bP#FH0 zz5y>%e8aB@hqPD=%@cgXd@2&%c+}Pn6oz=Xx)JfEul^?$YyF(sdFC1eXz%IVASa z_pg|9oC^XNcg}TE8+=1uAK$WJ2;aDFD&PEPKa=q;^kdI91IWoYr*0m;%?ICJv-t)v zD&K>BI;YbZ7`!Wr(Z{M7eOwfk-;JoeWe=38r;RrFjk>~bBlosY7ua@}VaL3MuSM={ zab$O~9Z^AR$-TWu!#~OHevcSZ&&a(2AJ^{Uon?3NBE{~$OgN<3T{KUyyNjquY}r3y z%OqApVTgxm%cc=u&d|2(e^g8!$4be$w8ti-fA_8Jwny~b~`*U&3-E^rE!3eIl=XNi?i7~)~# zj94ks*S4 zW-#m)n{lSnoBE%VZN|GK&Lo?0AaOR!W&j`8X5gJ=Gw>qCW|SzynPxN4Ji%ssf{H{p zYXr!c$D=UB!_-a885x(iu7LBRC=}f?gX^VUl)8_alRMfT}zmt8_SyU=Gj|a};n@||yVd4zm6xqeT zI*v!1fIcyTvzr zCh`r>Ci{jph@DBk;f)-=0r)8X$vhtKEZ=|^DZXJH!XeE!pm~CC_$(EPZmb90knf97 z7~)~-2K4!}TA!Z-V=9da)K2QCbK(|>n%PTaALgaIv(Vk z1@E1n)cIyqv~A4bRyu2{=|P=J{R>3UggSI-6di@5=JjR_c@EVQx@Lkdv7aam@i6I{ zM);m>(PgZwPa**Rb@k5!R!m!DKbbaXT^$u|+T1OBEje{GNwJ^jQnApu5oi>BLt%)A zNuy8SCR019W9i#@fDzLc*-xfz)9$LNZ>Xr{gWt*ec0QE~&YJ>f(Ki%^cnCfT`Zk3c zChOY;fD_|w>f3HhXqEIRDgp58+eLsC z(`M?Mvj&ffHf@>uh9)Wcb}=r+Nu97!@ z5vriI5p-dTPgFH-#cE`&pxpGWfqKYt|^iB9bfoszMR z!VnKrr!dyf)8pWIH3y7i^W-(QF924oU(r|xVrrdMVslh%bF8CD%2>aOiiO5KL8FXy z6oz=1G-9luZ_$`K)~^PPn6_xFGi}aTM@2n$@H=^|UqhvW^FF{?#ySc^JWQN1)+2rG ztFv4ZWAiVfy%%3+tfQjF7r*1NzR6QG*59?qI)+e7YBp5)>+`3aYPi}n)7#Gk{`1PY`|BX8P3}D#+F-FfQM&Z-Z~B>*HHC4B;Es9S+|ZKu*3nb@T9Ti$44pkdtpt-8_7|6nrb%d;=JlZ#T5TH`MjgM6w7R!lmWt(pRE)L)=rHU2~_{zhM)FKy?nZzkSJ{Ph{cUkeC`+T)1A5Dzo{noRN6g*s+@ zQRTlrOYMxQy|cb>i`B+ z$9wy`D10k&k>WQOvTTb_t8em-wiy0bli~WiaD7Le{ub{8kKgg(nh^X2THvaoyDMlW{&D1IRgkoVwZL$JY6;5WS-F zS3)0Uo`k{>58;*i=JXP+^M6x1{{?C%b<8~GS1tHg+wf5s;vsGQ@UKaPf13sWTELev zi^32O6F$c5r4IhrQM=?Zd%M-gm(a(@#T=%9S>-!Wq7-1D1tUr`c{>e~I?Y4!JI^e22nVTgy>pO0_1>TaTn z7~f=ngUfk*+uzK(*}FrDJm;twIaOD*`axKRN&_GM%AqhX6Pfx@7;R&YI$C{8Ytwm` zMdxjx^R`%aC=BrsI!nO^2>&a*d@YZ{NnxG1NQ#ayOqw7u;QyeW5k_!+tc0e)Tj|3=im?Pnl{*s*IJF#Qb9`uGCt zAu>yo=%Z`(HK1`afb{Vu`fv~4{)eGu^3Aq+b`Cj}NZ0K?5_R1m>!d$?m=T=yreKKg(1 z)4lX;`}_FltbYNf&-%wPKq=qH!!8-$W=s3r=Wy__>x_pT#~J|R#v0$mn93PzpstKd zi8Zoe$Qb6jsj)^ztj+*(#u`rD>{tVQH*A8mpZsT~uNmiKB(~prnC*|q*WR|}-y(TQ ztn^dZa*35t7~s(=3 zwR0udNj505(*o?x2xt3@j#N8s^Y=cBzrO%~CI5}W5D$~T$bVns@b{N+fzkTY22`%T zQ@`JWy$rA=-a%oAhY1_;&KDinzovG{apD73ACICB@%1PS@i6;Xo%*=e>EkhKCw0tN z`r8)#-va*OaV&$v5D#fv3?>r%>n!*sM2Eklro8RI=Kq5h{3mSuQ5fQ3!uR3-heZ6p zW5It4@I?kF4Dm4G`(*G(Y9}%nXwLo%1w>u3W#)hgN~r>(A5d-I-1i}>A+}fSDc&c> zL|n+Wa%g9QNc*X$RP&q(g7FQ1e?4Rvgwp<0BD&SzBVbAO_prs04;5IyjbP>Qp<7b> zFEK8*tr?7?0RzW>18(cZ9NM02KFjOd1+R(EDjIX(1s>ht@@Uhjy&V(r3@IrlinOUa z)+YAzK*{y<--Vv!^z*1Ix+Z=;8;0m5*By?ZX8<|8WJM~ZHC;v(9q>gC^zi+{R4e-TJpfJQk+N!fHZgSwi4$IKuCw^eTegm+@ zMxijo!-NeRb+ZHeO=?$vm(Fa8D(akNq@&DV&RKqnbd=a@=PWH1js34bXZb@5-xW5# zC=Bt)!uM_9yK~YWyB}G7tVAE;*H9SZVfF!e-s14&U1}$FOnLs;g5N>cS`1zmpW%(d z5D#fv#MwD6{8FPp4Wml7KK{glUjlrQDGEb8O!z*TmZ_a7Q@fA=JUf|etmRk{PNOxb$%KRpDz6V zmKPVxU}`XcWT^R%7)3ag7c;UL1PrriX+Kn^0c&AQZ zePr$m=6-nSW!@F+RCN!)RJ={PEBImJiTM4sZ5xHc5D(Wz-Kzb>zm(r!$Ffl>Z%yY; z1z+KMD=V7-ZU>Fl`fF&=k5kq3Jou|T*6r9dITt6y7M|xJVkeom^WPDxb8)u)|8I-- z^?>8G@!SlBAs!~}>k&=2S+rAfIl5!G+<3p{LY%RSp9B*e#I}NFvP>`7e39^ zmko6rBbblCYE`r6yz{1Ujo5Mll zpx0c01Mcp-13EEMclQZC>%2(#R5`gVclQCGym$94=;ARW5dR2>G-&L(VTJA`jt7mV zQTq|lXylLu*2vyhCvbD!SI4?KCe~Hrcr-iOX}}K1R(xqMV)7N57ixfCHi*Z z{p#C=^`dVVUd6WypM{UV3QLimJIEfl@Y@&oiO!%f#KXkTr!)IeJE>E^8JxkrOvB2` z$$%N-pktw8up!lnd<$zm#|dlw)e|RJuB9bTK+Lfp!TLJ-v+vj}%&Zj>*7~H&Mbu@5 zvm3H@j~?~%g0``H@8es$|E$xHySqqm z`Mrh95x_-aKoo{}2rk6{G2pixTDdy2pEGvqbGnTda@RWt) z0^lg)356jZCXUmn@5J$R5&;$suA`mwrqPGCLah4qP!47`S;hwa=UwMzAH=KqA6b!SM%d4~*uecO(7oq)Qv zi4r#RXoA;W7~2tj-l6Ucaq3dF%sWF0FO#nx8}p5QHNd!hd!`M(p{|c_*)W7}Tz5Ep zV*ok%=G4u@w~vBv<7~bGjLWy@+u$4O`uLU&L-@vZQ~8#$50U|7@=blS$TJz?Pt^YJ%{5?J8m-eQwv^?0k4XMmX5_X z+uS$Te}QyB@@qFDc9%UJC=BtC*j?@ExL?md|E=A-_RKT%=mLfR#MA@{>9%UpwWs%GVBov|gY^>+(7#+ETBlJ@$$ zg&ge>yG8q9rM>=cp^g2ppk-HrmGRwz^bvixU@u%|f45-hvcS^1oM8*>oWe__gEDTv zWsh4FhIqK+_5nR^-%#WBJ|4GjKKXAJ><0jQe!QlN!VnJ=Htneh9N4ACw-s>k7V}N@ zZIYq4sdGPJPxQTp&Fc2P*AQTO--xXn|A)TU5LBb@HFD9dzt(!bZhf%-5jbIejMT${3NjH5-PEC$4Mx zOgC=L$N@5doN=pDH#=^%?bho=uh`djVYg)80}4Yt#BLP>?0fi*wp(v0`%0JoS^Kf{ zxEescAQT+O{ZrYHBaym^4@biFuZe3?HopJ1@GVfk2EHf^@yNor=-_Mj@rKn$8GRfP z@8?2ch=@hRU%6IvXG#0V-n9Cw*)*Xr#KY{*CxcGiO;pjQ=|5H< z-F6=+4Drb7V^nG%Z&`hew);R~h(}f*V^aHAVfE2#_kqF?kE}k%I(_Ip?NMC7`pSFN z5EsypvcHS7(j#&FqxZBAG#8PQFIywFOYEHiQhDdMBkyeQ*M6JI#qNkL!F$^`!(Tn4 z_C0VR+llW*!l28uoI6_ClA$AJb6PRAYo&j^t;)=JWdzg>Ya76_hG;N zB|ZcV(Ya{?>koiM%(iK;4o=g#dvh-|V0~BF8G*IVYd%;j((H`3S3qhUWJc92$!gpX(=98spewx&=aWLhw#TQfP zuQn0GfB4$mm!r*k;Dyo8i>+;n(vNvRALEuYRzqFUZHd*gVTgU@x>l^Vl=x(R`<4=` z(J{(~-K2FVV-1o4vu)nuT)l6g%G(A;6~-2#Z3Ai<*Qx3xG?ZB5FWf1_BROCMBsnV62MRR(2SnRI_KzG$r${?Y@LNwHTSUNad=7P0 zX?)4rE~jnwu5*R2?e8%Xa`p!~t)I8X@qz5gD+b8Hj8XQYML5=8H#LTshTnfTSXgZw zN5Y{va=F3r&KXf3wP3TYG|!8C51wb=p20H%_>~?85ssQidaWFB5@ezFEe=f}M!4pYTRkTQVmf99#~)GDmw?#V_-FKi%2#QN*q^h$VE3 z<-gtbdW;kU^zn1}nLK?QMg+JYUckd-^sz7X@v!n`xyQ#f%qv9d@@*cvN*XKM%~fLs zehxW96+aZ~Z&Q$1-$qAL1I-l#ciCET^u^IUM!n9j^-xSI0SDi%}a<2>agBZ`Go`FKycip5m<>Yj2Hi>dNHPq~W4 zRQUv_ocvP6OD<=^b^M}YFx76N(++$w_*kFhDOWL=YCqXiu3|7%KE*0GV=yj1?}w=| zn1V6Yf}v!iVlY*{hNoP`V5)pgt6arXDmE(Yq+_uBu@Se)85^Ol=$ynx*)SwF;<~A^ z(TZ;%)9hXQX^oBg>6;=xXfp+opKa$B*aEe)gi=2ejIbgM$&y|Y~)nU85^a< zHZi{>wuxUU7IIv$)|;y;wh@Z9qCWD*Hn83Qoy&GJe5Tb^If7mipc*T1ybR z9**$J*wdl;GE?onm-e-T6ki_1oUhW7b6sQ2faYb0*;S1CNSkteiRHK!S-pHQD)LWO zA4W)N#liZUkD_tH8&k#V)Bhi+kH6bEHr{n_iH*rW`r{;@%oY%IH-^a>C;h?~C;9rg z-O~pKK#n-6-Ldv(W|kc%Yip$sa zlt(!;E`Oh=Jj$7I`E*Ztlr!V<^*rTK&Wy|7?mjuet*d^3Y`Km_|(^eN`J?A z+GkR~h%9z@g;-6OJyvN`2$clYp8kLsjM!#`WP6Q;@Bc;F{=7X5SD|eGV_`BJ*LFRVXIs zNkY>#@WPGp zH<%({d z5rFH%x6vM4HD-)8U2Du3I(II^wFgKFe?8}X7-P|Zdk@347so~d?&Bi>*T>&?MgXo) zAEvwu{T&`3eE7~80k}SV_ZBFNV0N01_ zJ0k$shwu9f!`Cw(zPpbATpzwCtRlFVjsRRAAHF^UaD9AubQQt<`v}1G@nKAH)#%wK zBLLUO-v#;MVs7o-FBZdN_Ens>O$W`4k}A#tvWe=JKDeCauXrl){;=X z_HoX|vgWc%^T>a+P#i`c`SH{|GIC{JS^IQzy9&lqE?MKO@L&1%UiftLXoiao5%J;R z%dps7rzO#@`cbqa_T;B&8BTA-(7s2X6^?v(yyj4>tF=Nar*EWs^gb42|9$5A+$RY? zQ(cP23SzN!1ySK=ug|rU-}bTodS+49{(0qtbIbEb`Q@3IQ}xO7Sr4)azCAG?>|;W; z3jMS6q@H6RP+K~_3-^&r$J^q`@eJ1%U;x>*1I;nD?uEEACDegXV!$ zQlCMF=FDB_-_1|N|J)V-ye9tVT>58-2ek+mHn*t;3+q>)*>3bs^;h8UKBizTe%VE1 zXm1gWSfN2Ss;h5h2krD&t@(#iWnuH@1axo{dV6}IUMCO}X?suf;TK_xJyEg;1xV)o zejasw`&hDJ$UYXXYwcsfH=eZ5p0;F#T*!M-R`2Zgd@qU-*|M+E{a*C*;~iKJf3MR6 zYdUF0Cam>bypHtZ#q3>9&!?*Td!3HJ#j6F@?IQ^5jiJN(HIFZY_d9j@c;7)oBa>gh zabex(g;mG{>rofhgl->R#VlCsl75lhv-Rt=2v+9zY1ZBHqMug{v;B{T+5X94wtsb) z?R!TlSqznbn+>!5fx~QnT6^uIz1kxGE2H)~_G)|W+e6X)qDPYjm+y0P*|*2saq&Qe ziw$e{tn&eY*W)g%6<%2D8NOry2#o3h75 zMEoyw>7F@+9`$5_VC(sUdG`bQoW=Vy+V6AU(Vjj#v-@0^`fRarw*wgMhs+$K#Q@)R zkdMZG<&1Cgm_NMv@lOQa{jLM-$^NdR7@X_&XU(b136z?IA7p&`YtE@=)=CM-SO}im zjA;+g(>|%cB~WL%4po*9Q@<_xlS7u<5^sLzj>`|Pret}vX)l)DsRK?mll@R3m=e3_ zST|?S(cgWP0y^F+`27&a!vjFU84t^FkccstKDDEDEornC>!Wxp2V{ggi_o=uF$W?Y?B=!S;#IPz)^1)s7vFw2owq3k zpzjZ^?B4X!_cNPwAI_BBaO}#wv8}SJ4^yKpW zHGIJz4O&V(e7nsp`PP{hwa6t@jbkpvYcB;-H9lvkCqCc;^Nn$(<S10DoWTcIGG- zd0~4jZn|9@imoh2*CVMbdrt82scl^WpPqJQaJ3iq6SfTY%O!&r-}JT@cH8!7WOaPU ziSMb7KY{LA?0wrh4m~^_-{N`>tx59F{gXU;cshL>;slw7FOF>%`g_K(E9Q|FN&TJU z>u)-J^^&7M?-(vm_VKRmF$~y$a`k?$7xt63-tV8O_c#~Fv$mdVj`Ve)P~jPdci*?1 zi!+ov@x-c^r@S})e7KE%Fn^Bj;}AqI1ps%faHJI*X+3Au`9b7kM-i<5fqV;%`|mN% zd6PWt2iwTgqOLDbn+-$qv|KmN({5Ox6V2|R6HVyoVfeyDgfFd&#b;EhqC)+PguHWq z3oTED42*-2?0dGHy2Q)FY0eV_oL)s9T=8#uu-gKeS6oK#iH8~Znv9kat-$^&p-1RDE8IM6tQ(x8k(3X zY7Qwx{o(2&k2_kBG4g4Y7D>(z4KyF8!Mbc+Z7&D;^dEqfvlpYYatfsRJfJXEX>zH~ zUR-N*{Em{#`rIGXt#3+;FKPtJ`F`_&bD_cIn|aEkZ`Zkeb5Hp$MtjOhw7`$f{o(c> z@RS?0)VJ`IN9X=<``Mmy^*y=5e~za-I{$~;)3+=w_(kXcaQRlA^62~@F5lWy9-aTg z<=a^0=J(``-+3>SnMgi^QPHri1;hNFT$R(6-Yqml=l?Jc+gs)4_v8nV4yiL3^Pm62 zZE}83j=Dbko()6nJJ*fvJI2*g(&28>u>zZpzPkTxorLen&x^k&XTWUhAAcz0{2!-k z=J({Kz_s&!9CO-v=|08It5Y1Es$P?*{8HlChyr55R23s+=4Gw5Cuu(`Z~K&Q5@UJE z{>=DQ$Xy*vmbAG$byeXH+$Frz@r&%w9Ll$xLe8-uC+FFU*uOyImdve{TQ3aykiUhI zUq+fK$Wwcbf6F(CdEx##FI*+R==>rfcxdMrN&AsFzsSe0;u@{O_VUX*zew=PeST5O zeqJA5YcXEOkv`^t$yh$=cH>$Ps(Rds-B9*vIQ`s{v!A&{&+g!J=K2=1i`o4Xf?aKZ z-TBVD8ZOT|*TnF%#p~l4#ex3wtzy|227C<$YVV24v9GPIK8_rEAAjMTMh;tky{C@~ z%@I6nvD+EvnPOe@S)Nm5t!s+hpQNtbbxm~Tq<|tnQVWvK8m&^B`iE!&!=c(hbIw{c z+jyTn+d!`~_Ab=#p*dR+G!LaJgF8@Mc{<^3@6$REF=fv95Osa=VKxkj54mm}AM*VF zTt?D6|5rtc^M3}GbN=tt9oqcgk5A6HP%ub|3)NKFshT@3bm#wx_>S28Uog#_|2tK^ zM3H_f+a&XU%pu(SB~1Bm9OWq%H!hX)$Qs*wXg-8$t4Tjq~Z4uH#d@{~t8050FzQ%-gnIRq}>#Zw;T z0JwZtPkEFB;PSbi@+b$u<-2*xqZ|O2lRs^tFUkRM`3F7aQ4WC1_wbY(ysq!*DUWgh z+yshR`F z5zSLb_bL9!#gwahO}FA{VxB^J8(N-1+K)t@B9@oTH{w?zcg3;#JhI}eCQl*coKAh@ z%TrkMegTks-mm7z-t&Nb#NY2BKK9QYft%;Z4fmP6a237LIm<%tNaQJe^p0M;RoE%? zzOcGyetkSyX2TA!63t+^A10HYYknQ=2^M-sBLCr|_altg@bVu%xF@Y5xEJJwYvn0~ zk8S2Dlzg2$MNDtH-MHB!a^IXAbNk`+bAQf$kf(SJXRc-DDVSZXwvQ0(Y6EJUKTk0n zT1Kyf;b#vMAI~UO_2(&K*%$_V9R@mbc?w@2#|^!Y=X`kzUmrJn`Z(OWGB3_QyLpP| zbLA;S?#rnwH&21C+Ranckf*p%@)TRHOEaSN>=_Yy#oBwmy$bUX`{s;eQP&s8X2Xy; zmg`z^>>|Rojr|D>AZLEUsXMg%gnz$8&isU6kP;87>9A8ZS3Ee-JOmm*yD-(xZnZ8B zNHQl*->Y(X8}dh8pZv37i2S+kaOBSba?0PS`@bN6!5~xqPSu?9|03kSzAb-168T4Y z0NimD=Rag$L}&cY$cdot|L5*Q0(}NA>L0Q40V<#H|KE!g1nVJh6&?e-&}L4A+vM~m zsOz&O*)YVGa9zum3@hIt^9%;eHfF15^aiYibM~F8?{&UGx=*n$D&OE#&1GM3rUusW zz4K6qUmV~rCv)UZ?y0?wInDVk;&cVqnGeKpWj+wUQhLc;HeTuW>@-hT zt@dpA{hXV#pSJjPy$2|b6^*}X_uGQ|XnweJslQ8j%`I#HfQ-D(_rnA*(mL>wef4)Y>b~d~eYsJeeD?BmfWS1z9xf|JGq#IaF`A)n=TcWg zi-AWhCVVL;3bAe0F`;`VSts(dzmxpzUNa~=GsDi#!26i_*(m4G?a$A2`|>lWTi@4{ zzlip%aQS|o@@UTrm+$W>Cp&>XD_nknr##xT!sQ2g%A-9iTz-(JJleCuVMu<4>stAl5#4LS;5kc^nfq|6=FEKz z^E(^a7cSkOJ(%&GjZ-xMZ zDES%T(O0RDeEU39e&(;a@-srivjpGuO z@8|iP{UpvwV|ol@yn=z|K6lug@AtvoXoKAPiu?@i1J1EuMn?a!1ispU+UC#CSbZ3x z_S+yMKO^1VlG1HF#@+l(Zk>Ied6r`=D&L+PZpVg@MJ~AT?Rm$7Ob>-Y(>+}ccP#k& znVYkpw#LE<3^dnRXopX};qmF5_$TIPd_b>cpvjYelC747xo@ehKK}F`^f7%S==@xPK~<0IdwJ+nNxFJYfjzf{y7GabN`f6_kUsklwgoD$5;F3oT|Cz_yf&1 zpaC;&4FDwBKb0>36WWkJ>iXoL4MXJ5b%!H=29Q(!PTl_n`3nY_@^`A{l>e+vNd6nx z@&_c5|9H-cE?%I8w_Z>vF2TRZNa#Jb6I7i+s}BCvTBm8$nXm-^qB>JHE(C~=|Hk== zuDZwkB zE@nBHwIz;PJ)Mpnn2YY8*p$H7FFAQ}qG-BUoN5)VE}WG(H`{`~g0e ziFj8GaGo9TDby*_a)?DAgy6bCL9t2ozgkCOaf7hwTUq2SxIKNV6-XeZI&X3!RubG& zum}BBGN~Uxh&acbZB{7M4RB9Vw9~#Wr5NM*+ZzPJjTh- zQlG)!S%xe%h3eoQG=GtC4`GxbgYaacL%%Nuo6!3{rAH@GfrWGLl;-Uun&vMcpFK!& zky^-^TpcWA*3}S~muR>hI4e9T1FjqZ&4pTbm3}u4)Lv1)=Qf4LLGr#3tWU6Bj&-#0 z?{5bc(#KMD;t}1I#+&r7o=*DLgd@7E<4XMjPG^NY3c*_R_aDNS`iTHqp)<#zM6`GL zX!58ljZ28A&lby{KQS^{0iKaK}TXw!__NXxVW^H5M~tOQs;7U&h~AEWBQ4Ei6B zrC$+EucH6rUNSmKVav1crxG4tMBN%e^Fy0JcvIkps8fZ|^DIZ(kOck^_xd{l2~X0HT{Z#+CcVReH-~E7D+Vt3gk1WoE6n ztXoWJo=GT`&%2rKrD^^b{jAR?$_6hW)|^h`bSfDg+9^AAkdHc~-%EovZpO7QL2wj? znz9x3dffZoC;@Oe!=mz;CP%fUpzjaeCR15}zkLrMWZJEi@?Z?rMISe%9%W_=pSPe=P}0 z<-HmwQp@hrTB{vSclHpAD>Fw0g=%@P`o~yb3#Yt5j$>2}ClptEt21l0YU6e28Vi41 zt+zIFQLt9$`S&PX?_ks>ltmSQ@b?wMV>`^(lbg@*>nYUN_QaDLr%!FJ{uNnkI`g3#G>Fyzf*isVVGB%u!f%RW3ylV~A+kt3>jx7C7t+6` z7bXlYqQ8wMJ%UlHX00)Ze+9EwBbWgxX5YB-?8oV6KpNFJnaaSJQhh$LWL#%&=geur zgmI->Z>4bxm91B^V9vgq+7TN^Q}L-(d@`;^>hBoO?Cb2UHhSp%*62V)@K223%&t;z zt$qpdqQ9eWTvu<`%)QW$;&gX!_sp$>$<1|$8O`nKF}5b$98)lU8(glxNa9w;H0Ylk z^p+pPeuL8+Pz>^!GKkS!DZ&^JOBT|C9prg6$z|Ccizr!p!MbJdxqVYREOVQAI`O z3UGuDk|`+luUm;UlT?z8G*i zlAEZG@1A`J74aw=)z?#_URA`$Z`cAA*Z_?!@mOWmIDtlBrGH;yB#j^*e8fZM{V5nq z%))hgYdnsO!84{1y^BW>MrygY*1eqEbcHmZ#xO}UQhgd;8+;MW@0?k!MP6gPjy04F z)(S5FhN2OAO)*69Cev8&WY1HokD{q|6lWCJd8qPYy+;>N8^nNH(BJ>G@@Lf8j+Lv^ z*qKrt)jz3FT!x?O_KJmMX>P$kN0Gx+zPL!^?5$Q9;PGGEBsRh_P`z-tz2~M-U z+K3KWt*=d?;09yJl(B!}>)=Cg}t+Nsed`{%-zYP*D=n z@_FPXEg!Y-V1<$o;^F#eO9lnL6ywAK`HO-&2ew4g9#g1~p=uKbKTItm;p^CNMiq4j z=jhw_ocBj2ygxVL{iAxvj00yZ^=!qeQNN#0sK1B2PoxR^HYW^j@%0v(XoO>J;!GO( zR-bB5N&PJMz1mAt|CIawKn3U1?t8U&rT!WBz1ovf|E&97?WL)IPTm)SiKLK|7{17f zCSgmd4oe7QaZRe@k>zuAzOEz7#JVRkk1V+-)}2DLk-TtmCu`oiYqn8$tv2dTYoqSk zZPZ=h;~C^NyUQL|orT6~G_GQKq0ZYpHcgo}dfhr#wZa+e)>(*qDU2~peT{SLe6-wB zXS`eIomPBSck8Tdt<&e$dAGIB1h>w$t#nP4I_CYCm@g;iTCwM15%JRemKZ8b9@&=! zpo9ZYz#EylF!lKqcP@4F<-#^1d?<>c$%@g}yA+_}-1$3^78o1wlypL!=0nNnUt?U$ zdEKWFAC#{2jbB;0if9~MfLL}Gsq2|24DpCeHv8Dgga;)=NH^%b?n%U5ISX>(wQ(&0 zpylBHpp(zH+nwrq&Jj(y6G2G(_X;Ad()bWb!h4R0z7xUb|7jLI*Mpv82!i523PU_h zdd3ot%6AF>zeMdQmB9DatWD+WKSNLE%u;%?55XpnPYUuBRgc&9rmms(_S(38+`{cf z;I=U4H3~yKOx#u{m<5a1mBwf=q(7h=QWbvd(%3ie!wpe-VKSIP4Uc`$XxJ^%#ycM#~T17DJJAf{8o8hihz+E z=fI8LA&x{D$6}P|J4Xjm>qMDmZeI!xh}svLKOpRkobMX&=5^D37=@e=rW@yQjq^C2 zy==Zp5C;25mrtklfzyE_r7aiZN8|IjUu}AS@(W?crl=%FW)e<-nx84k;~X-t|tkyTs7Bv68QH(UVKOFyimb3^Sn@} zs+TCjUyc9t^FsY{pdnG{r!dTrKzEgWvH!eKK`8UQP^YT1H9Eq1dLZY8{*{K=vQ6x@ zJphrlz36*{(emwuxySxYjK%q+zipfg$!&6uU)1%D-)tB%ez~qSe%! zC;0AOqscUt$U4IcbRm9>&MFXuhqf19+PAS6p4OOsd@Xo|^_WLk)LzR=zGb%dN(){? z+bb>Y+t@3OJp-jS<@gHAaqrw`<qWW$vkEs#twCoelNzcN_7x7PxzA|IYVp z8omVkwc{}t3iMM6dWE5T=W!x4wdd^e*4Wq&_iBdQ_8vu=AJ7ss=G*zl*YBA@=xWs1 zLKHUT8((TKpVi;cWVHF5d_z2zm%Ep*44O^fpCqqKs3&(XABb&ZFW(fZUjHdg7ubak zG#??5%Qm&WJrrcdM+(iqQ5j1@$Mn(s0dqSuXV%?(nQBH+d^ESiJYy==qdg39Zq2H9 z!F;ZH5~c5dPv{iuPtdczn=yl!F^^L8<-v1l8en6wBemg#bTrk#d>j2CU$7nb$EmBn z`Yr@5n%tngPUUNlL9BmP9HYERm^Ti_Ts+PxokU;kGH&+#fZODZQBcprIpsSv;pRz5jpraeh4^M+ z6{a{<<1od&Lwp_Tk;J$aF`h7>%!{)B8wT^vlRLz}o1YHaToBV?j82OVeOnYKfU*y-9TZAuKT?|v`RTsYse5(x=;JWRrK%@h+ zg66HF1E6)Me16NIH86j3V8#ln2+U9ck6+wx15tLB%g)_2bLVELGH_HEmLtk`x1 zBWeHtnxAB@nn?0=$C>-=KOD4~hw#TF$@#4;`MnhrlW>%zh?=W9X^BW5CBKDv^{U2s z)2+1U$;6qf=D``c0POjuHBq7X)Rk&2>2AcY>1#<_Qu}$H9EmrAxUPf3!Aj$61lF7w zD*1N=o6nLpD!}#SUc7Km1Y=q+!W=f-3-ZI=E5_F_FIbO>KSB5bIk$-c@|61)Fb;rA=jThSJA6TesK8e$-cI zn{=G2`Z(H}m}3RcNqlLVw%^UBi8cj-Zx!0vYRzDh`1TvsA4WnZ-!K>KCz`e%g+Ay! zg~6xbMLNcJ6)N>N=w~-=vM*AsR;@I6kA0Pw&Dp+#-|gZybsOgQ@NxT3I&R2=ev7xQ zS-GE-JgAtGg}|}W0FLI6kM&xw>0|FJ4V9pSVqMD9U~f{Ed^nNyV}kGIL6thJiLEz9 z>~Edf8&nGQb#1Q`f0M)a5JrBs7+mDyV0chVN8)ocWQ12Gf^He)jBMAoLq=BX^T!rS ztY_$qI{(lRkAVwJ)Yy2T|Pn>LkMvN;hpRQ8~#>AsqtUph^1$x2}JjEZ%D1MI#_B~3+o5kR6jb~(c zOA(%iij1liX4VS+=uzhrjA@uL=k^ox46!nc7}|ZLXHnIXj~GqM$CqkaO2M{7%S!g! zhH@<3j+BGefnikc?$}BWtR(=yuuQrY$%xQPd)S#>^EsgxLJ+Y+ZkseEfi#e6Z z_LoS;hhS~_)Ss$8Ennp0mgAZt+gA(rIZ%8PAs&>_zn!nmWn-(`vyBBF-Fl7Rhlft* zD*8Kud53#trflzfAhQF3cY@3uYweX;TQTBt6?-B8G98iTg&BJeH(MI%JD{Dk&tE#8ZhxsRrF8|(DkeMF~?Jy;SD^zPuXG4;$nSZ&FA zcl42OJ}_KapWyFm#AJOT;I|RCkCd!ay7kI>UDB~=Pol_r%6)1c2~EwIM-C;M2sS zs-~p$O&xuMR_49j2CW>Id$Ppd1Zqnt%e1Z>Hm#VCj4Vz|cOEYPffFfFFb8)Jwvmq+ zzYFzDJU8wtkMd9r>rp=6NV0&KVyHSk}+sO4jdu|u}h;4gruXy)cXxoEvK85=IHTuOT zhHKJjru28M()bE(38o~I+8_aa+?DEi_S6^?FT)V-2kKp95RQo<)OK+D9mEbM+TWb{ z&b|Vtf^8ny-FodW=B@9#^VY8bSj)WiL3=bkO`|D&-s+84F9UyE*xB(aZRqgIAo-M4 z37dYKEs~fw`+P`b;>CaKx$imtA-YUgsr>l=WhnTk>??}{FEs`@Wi)ZO*8NWjx|r(> zKPTYeKK2`0A4AEBUPN8}za}U8%b_Ey<3h=arpWy~9TysMUv2l1mHU~rjZ^J^=E2Nz z-*bffi0!LE$Js;c1M4pyKarflG`jq8Mwi-W?7fe+Pbspw&?B35KG?Qw^ja(!p@X7Bh7?b6vry;I*v z$u~ov#XdrEAzh6F=%G`w(H2Plo{HASqjRfJ*S9Ay8;0x&Qc4Csanf7mD7XW7HHim1=kQhIrjrlIBYG16leAnPu`HE z=}*gtg3k`Wu0^;fEU-IOodtHK^V5Uom4f$o32*azDgQnO-dl<71A4}71eT*}83cIN z6%3l@(Kt%ot|l~b)p*xNm!5y}hpvjY4TH~qU1I#p^3qo5&;Axn&`9|f%vGTFz6JX} z;hRf`%CoVA5ts{5(PvZMZ6$FEXJ$_+pQ7Cx3nf$0xT>vaN*49tvhRqV{h83ssb>@y z)5?sRFx43ipF1>pDkR~&z2~r-Z1#VKZGw2?TLHlmNr*S zAS`u0#nsl4tr8N^DGCukEK>0d!UcKDgIIC6`(N0 z!|Vg|{!Xh8I)7n0)xRdm;F7+{o`!E`xfyRXIUDP^b z&0ux{j*?tA;9jASO8>52>D75-g@>$H-=MZFdUb8tIC3MN&uYEGewID__!VaM6f)fe z_j};ph=K3%@lk)LXzSM5mTv6}-MTf_Efj`$n7Xw(;n-#AR;95YwbON=SCG?8oKs`! z)!T#{gZJ%6nw&^>^qVGV^H!r3Sg&`gqcjU}KU$;ZwK_2>A^spY`hto(h z^w7w=h)sW}pw_tZZ!1wO!G+%hs3ATl#W1^ko6*yRx+? z4Dm4aWisL6+Vi8RU9vqt*XrX)^da^fg&`hhAF$^=mQIpAXLCaK{AdDT*mKhs@%-wl zTWF5bV$UsOj2xauTxt>8JBz* zLn*eI`s^IwX`HnpI`sE$MYCzVsUO|HZg0!}JWDReLoN$r*`qMT!;}kb#b`?|^id?W z({;2hH0fiRJPO_rfthFTDF3o!P4t}k^N!+=9kF5tSK&SnF8^=+g+a+#T)i{alN{#M4>hJa)E=YXVQ3pBGsCTnK)O z-9TZ8hsjT$-B?8J>eFDY)ZtCgAFN-j=GwUjBEDKN+OqR?0;woraEJjnK2NI3@omCgpJI zveGz?2DI$v(z>K$Oq(YcSv)xnJdrVi!VnLWC%!TAacbu|CroVBrHhJe3v!GR*h(|* z;4yMN5k_MKlnu#NelL6kasPprsCyR8=&TYB+HTQ5);;*q5nXJ+Ze702h+i!DemJigkv8_zI&e<^h) z%@H=;Ol;~0W0;m)447Ij<}$I2x88kQrXsOicG*?+WApVAi?5%t`HI32k1W1^HjA(8 z6Jqeand2=Xw%8_WpJTkF&58ZzDar8J2i@4iC+45FSBZLkZeAP{{O(QEKEv-0H1DHI z%Qn|OM;-14{Bb^$x=)nmCcSh-!g(Z;Vx7*>uhid9h5{#g-b&VL*(}|b&sC~Y5$d&Xjx<`aQk16!W_lWRGWiv>3p<8s|P%xHb z7CF0{GUui7qx$y@zevp~bwhibrUc=2^bd8E=(y3fg^lwm1#~7V(8VZx{|DEuUqG+N zm7=eeyXb^DUi0N+thqm0{|Lr8{o$DS@pRt$iQ%=XLv?$B+2s?&NYy2(#9iVas>=%9 z4MA&EWZx&$X>Q!#T|MPmIxbwUF6gQ)zK*Uupl-_g>JEJt^LWe+3yUu&V7%x<7s3>m z;9tZfU1x%-bCp#G|7xuR5okCQmf&AhN8f)lo@ux4D=%>pwP)nkW0`!Sl&Y)BH@gFqMFXG=hNIf zqkrfgg6a%)-^Y%@q(k}0L^{8I%V6UHEL*5CVDRi>KhM$zWz0cDUzRg-%V^D;x@Eiq1qH0*Xl-Ehs%tA<2rd?;yi61 zWMqtQeS9xMPyO)&##NEV6$>}IB!x9oUy=e-!(*Wk%px2nu-sMNx4Su?6eT)y<`m#e zJ0!`-bQVs=KSuR;76$)J9}lY2?v+ds`%g@Q5y#F6_dPA3?h0oBJ-Haex$o%t_R6`=8Opg0_MGKYVn0CatE}_0g`++D`|wR&)3EWq!NT_;8($QLcx2)G-MsiB_;2NJD!#Dq z?a%XsMTdh$8S^}wCpTI=`GL(76ozXrqH}k8W!Q$!-DKhWV;f%-hInM* z`xD@soEsH}jzDe{GDY5XGRCPn{@#svVXZG2^H|Qi9@a+Q^=6AVKLc-$ph!ZkH=!`Z z!{p6$!fT3UKWHt8r9o>!Ki5KyE?7WaqJ@H!U@FsM>~o9O=CkbQUI(y#n&GmVgvxgR zI4`01mfQMzi$&vqgGR}tqAkb#JfO$VaH1Cyy#}e-Maf=XGq{zHH(4OW-DJ zaVQM&Fmc0L+!`+bA1~6RocRAMg=CgZ@NNn-eAb^8&#eqqdan9bi;iF0bf7TA!=+rNYVe8r;UF`Et)hIp8CY)SH1%b~-&5<+A>4)Ijg zhyFD>`e0qG@^Jp56dXiwUWLCcvXx0$LlTu+3i_%#lSm6v3Un{hUGD>I;{Zw}KVCnY zN?ip5&F87L*bbFH18jA^xy&!VO7HUS?L}RgOSc0<_V#jr#155I*%03j{h03Cq6r%G z+MUa&qQtoj1LHN%?756ncW84NKR!9<{!{`PbG6e za%Fy78!|^-pUksih|IZeEOXmN-cIl(#(frJQr5*$7~)}$Nvw-c(_?bFigBN#cDfGq zh+LLl_vg-8M=p3*?SaWy7q{`d!@}~$j3WC57 zc4c1rIc0)(bWYigl--uqMLl5RXi}|1k`_qjT2U!~1Rv?^l8M`7ysy7~)~#johir?{edx zG2+mZp`8&RB8bj$b4iI~D!o_6)}60ew7dpd7R0omFvP>8h4!EX>$p1qIyH>;4kfPb z9#5V?t?dfZ-%@9zn2ue?C;F^*8{c~@eBS`RbK)_I!VnL^w;XIw_^xZ=JG#`j>_N{b znw3(yI=b9=6SPFmy|YT6%FMv|UF@^IK(N@im!osSj0}qRd;;SENA2)8 zrU>@l8KEsYPX;=h>x?_uFa33kmUlqQ)iEt74Dm2&S)1@nqNUteDa24cj7RJRvgk3E zuPu7wk1*tTDMNhG*)?7gqp?{F^f%tNyuM-47~E^g3xy#bCXLflXl!&4fMLojIupiA zjE+n7S&lX>-?V5cf)AvgPGWqc&$j`Z#%3LDJN2D=whZpG@aqJA=f`6Pg&`igZ^So#ztt6EI1+vPy{vlf)4_Gve0Syacd7v=F!=%CMdskx;*k-lmd%uDh*+y9FkKgxx+roD& z@I52O7lk1nCcc=UPPhCA`PjxdYN-yd!R|!p5N*&H!nqdWN1}5r?A%hD=UOmYo^vg1 znLTLnpbtFQH|7BfLp)3#AkX9SpfLd~ki<85Kzm$#-$a|6qJ-e+>@^#;RXW}Z&cWCTEnG-%>qf z(KZ#dNuCgeAs!}e$P+p-ZDS2;r*k^+Me09ez#s9|O1?ay_3igs1ePb+^zHZY>f7%* z>f7%VFs0wZp3;LYGdOedX9`d#bE5XzV9!GdJPyB06=cpX^KiUx#PjfhCIg=x1E=Im z*O{o}<_o@uc9iDzuR-hm7OHR5mA)lMlnq1huH1bRT_2kDXq~FUw9YUdN+P z3ql5vGcV-S9a>(rbkhs_xlj&e4YbbQ}ibRZq? z2THJuPSsV7qny_A z*XUDhq~a0#UhrYrh6`y9t=0wvgR=*7k2|jFFyD=t2AZe9H*IbECUocerXRK8n^4#1 zo3deuZ{oVCzRBjV)(Da^?Kv zHsp-DJ~?N@5IJ+*Sk62LTKo;3)%)U3Rg^dfVqiIC?$jNc%>DS}oL>kAnKE~(=9KxL zAoFc)nFEq5^PjXKbJX?8JR63{oa@FiAA+12Ku$S3b^jOSEEr_U*{PaS&TAh+a^B9C zGa$Kg{;xLVjJiHKXTuOVbKO)q`_JEtZ8!tSl(Ra9&Z(PE&Tg!ff=?TbPrftb}j=qjROCqXS6=us`!oiW&3)l@rvdRGj>#%Yl?nFwd1z=UEti?^QT85d{Mt!EnF zS}=c++$DBDy}uG?hsAeW;gWCb0^zK){;jW3;;D!IHA?*2pyo7CQ)5MvOAtVfd1Due z*SO@0uL{=pBJhn}O4r5&XI&(BT+xZ&UYd-nI7XDFnt2rm-3?q$IB--1`R9=!JsKNh zg0I{sv|mHClU(-do`((;$zsxAwbHp2GdPYZY#+61_)T?pj(beczWppk2 zRUO^gS3jM0QID%ts4VYsBwI*GScCnW}#HVWbtkRX&GsTy1PEx*~k{5;3=P z`4)O_bu_4J>gtnD^{2NK{Vhj-^+xQcdSTGi*q;-;v2n*1qyqfyzU)!@xur*+fF2z| zPDkxgKw*f7=uwde(G0I1(SEDbwczbt?_21ISkerhVT3Hc%Wd7)ivYRKvDG7 zg6*TbOzm;}dm*5_jgq*~hvjkSQWKXx_|Kv6 zbK2qg43FEN&Cma~_<5$yPZWlD!h zHhm}z@yJczXOig)aTJ06$~6al=lJL=a9EQ%9)_wf=Z%QI{KDerQk$PB4Dra#&$E;H z`SCXOBBd%{g(Z#G|mNC@25CBstB3ko4lE* z7Z^ry-Vrp2X)*w;<9WrhPwBa)It%THHonRGm4*NLwtP?+;$h;CZ}JlD{{_kNX?HyL zPx9FRw#V}_i@u9&`cN3+k(<7YLEq{);i9H)r&jxLVUM5bYjZsN=$lTU+tR;ZTl8IO z(}%(kkKFWKmMp(^?bXdtRo5QpvRB1mU*ae0OM#tj%J*qJTi|JO-;u5Nx_Hzjiih}K z>n`es_9UwQSblBvcc!O5kN6V%V}7>LU*}P+^m*9X(x2_$eq-s&RkpsMFvKIbzFeKG zFYU&AONqV~eNof)RR0G0`bmx(kgXhCK)cntDupFm({{B=amiNnC#bBfoJ6k&FT?z( z9vfMkFOOP$xfXmmHr_Ld!VnLWFY8gCNp`T@xUPjUu<10xx8q=A`=Ni{DF;^=Uf}th ztcrDE-$P{%xhdhWA$Zk@c(tA4)i(H3TC#1#vV|U&@mN`h+Rx#=lL{jqe7hf=`&`Dk z)ZTM`U&`6(k`eeUb<^JY0gqX7y$N#NKb9*BLp)5mP9^*{vi!52Cs(TF#?1sl?Zw7^ zV9Fy%3^z1c{v0I5pVb84STblyk4nsE0dJI zH(T~@h%nxN3=6|d_o=x1=A76Jf+AagxKZJ=@L=3CEj*QEXU=?_L z_vHeTE9WQLkTdG~ctFEb_-*t-zyDxZc-^O5C-^Dy$qa<_qX z{;2@DkbsanXPrAfjqp?dh0^xc?6w2Vhp5uBoou}V2v@KE(1u>2u1~MBVTfLF-B_>e zc<@PrFKcEG!&k|?9)%$urmw=heq$XstgqJ0{+rs#xkCfZKZ6rH+nfLv>hp=8!Jpyt z2|jaA?DSJqLueKJ@m}mS{1Mh7DK16MfD75S{il->jU?cs&746Uk#&4vy4LyiqdRUQ zOm~SfWt$I>uFU=j9CF%x)D=3!=4ZnYnz?Q)Gthh+(QKZV=U+4Cy=tGLsygFlL~Gt< zF5|1{kUM2w&U{pFwyW{=eLaP-#VA*=7Lc8)UdyX<@*4(=u9vgn4A}{g+dC;DA=%mM z$f>f^da$Fq2UuX8{g~1N8x~Aoq8u+$; z$L`dJ$G)b_38b%ouOPB2d?S+g+svJI4v1eWPqQxlr5G6FLjb(_w&Dx0P5Dk$^R>rq z|H2=t9vNkxqvpkBcQB6Ror#M&bNWi);?d~tYO*WT%VcKk$;@EycqAd<-i`|ualMPy z;aYIye5Jz!%|BAxWpiVj!SMqiE1MzqY`J9zWNhQT*s}=UZZSNzL8#-}pr_F;rwu|~ zpAE`}A$W3K%LcjoW&L|0vR~HrhtCk-#2^0M z_J=48@o@d&CfXm)Q2y{`_(S=ml;@nVd(oH@On3j78V6RMJN;g98{a=!_`YJ}i^33( zEPP)DzMgXfBOfdHp6|ss)lLsIe@cy(?H=nlj~9S+_4|M5U0(f0U7vnu!w~)Ex|V*^ z&}-*RUj~qKUggv!+xK3d=_?py&a0fN-l3%Yo9y+4-*D}N|J>KuK6os;KSsf>6#toq zf@$V{dZ((FD3ZUTOY8&adXCd*8Qd@|4Ub*g6V zSsZ9inNN1-gSOoP5ZCVfxedF6x<0#;4MXe>*G;uM{{7wY{!|8#)9yHRhh}&D_~gvz z2nLyU$EoVoPM_Uz_tX0EW&V+gw>BYg?CrNLf=#AwI#siD)Ar$iA)S(#qe`D*8*^|J zhIqI>d{Z5B^sAVoM(un){8<&p3xr$Hm zA8>QN8|i}s#;OTy&lN%``XdLBt6M3Ro+16)z1O6?<~857b$k7PB^656*Nz< zEB~M((Z!k2ML7=$g&`iIi|UTjh%bHh4VAB3huW$0cS^xdq<4|cdMXbO_B8bm(7HBsw$)IwWTUqcFt7)FJZ8!Is*FZxs2aTS#hACD<>Tjt3iz zV&D53V8nV9`6VFK93<{E?>nFz=@BX##u|Ppwo+QZP^VJAffP)6Bs=zdol1q4twGDe z*dL)V#KWXzb;5Hio0i6xg%r|Lb$;1eDvtO!V8paUV}fb9?u_!nCYiyA7F5(Y<9Geb zgmTOu^GvTds8n#?4miu%b0`e)FmawrIB#v^Od%cykeodSygyF$w&8k<-vpc(Z&L2QHhr^AhZwru`GRfNtRLFa;4HYg17FzLkF zm_sKU2QwE4I`^b{lazek0-TsmQ$7chXqwwpwR})fBah$pD>>BR{5#I>gKa=O`x~}T z^<4;E9{zN;*&^EGG`+B7N80j4Htw1l*|>de8wXRuHqNwNE9hlj+l9Jb+x50Cux%H^ zZn0h4DjlhBob3PR5?x9D@6jB#3-~C0i~qwr%XZ;KitXBya7goiXs&J7Kyw9QwQPTz z-ypw*-|x`Ny!=L8FTYpn0-N6qyM^D|Mf~0*ncp8y;rF^HX8Q`@J;8tI)xW0I(1ZrPN8{%P8F$0bm}d zCkuCDJX}RY7~_FL7sS56zXDh>{)0YKTTq9QVelJ4*LUq6dxsqz&p$S;6;l4 zIgM~giy_cF!T$76k?6`|TUSsR;^FGbu3Eo8kjwsz1{_ycfRt;0P*Lj&ey7`?F;qiv z4}rVb9~6don7G6K%(ZaOWq(!!tQh~u{xJTI{XxYx?GKuy*q>f178=h2jbeXL7~)~l z2>Y{}MPsV{84DOOZIS(9+8q0Xidr`Koos)`QK{hk8C$1N7~)~#4Ey8iREGT-4>(@D z9s7fd8gKk=wLgDE_;aXje_#(>`?ET|%WHp7*K2?Jbb)Pu7b!8I0%d0D>E4m`_b~cRFh{iJfamaOJ{lPv1%qPq{rTzDw(SR@fKg@l1fE`u! z|Kz>5Z{M~gyPIr!p(H-D8$bxMp%YqY3897}y=5sc%u*9FEKMn)iS%leCcTIhK~xk) z#1#|~F`@`!FFzF!#ozhdJ9o~#_uVP)?IwQrkJ)*1&zyVuJ-1FbiAo~KI1el;W7zuU zf!*|EoCjtKQs;p!&`k5deg4tV^C6L*#X2Kkvh_T%20a7TrRQ`UtY-n6sAu;&x=7Cg z0qagIf+GbULWz4zu46>FFjwy1uwd)cvzwlbdS(hz^=yG=(z9!wQ7pZ~c5WwAn!3)& z0(CM)ey-No4BXFaqwRGJZoY(FP^duGGJz1$j3|BZ3cV)xItC^vbsd8RnzoLi&%YHu zcc|%eKw|scq#Aqe&L#r04%lY-LJQW2*(~WNNL( zRwgJlwpyU+v2~M^$mb3>eGW)$pPN#H&jHrubLlwP=LBq`&)r73eZqcJfgq#LS+Mo_ zoSUAE`3zH#>T?#T(>$wVYd`dSgsEp>vh_T*20a7TrRQ`UtY-n6sON-rmgt`d1R3>g z!Pci|H$55k%oL>R*#ga|=dVG}N1A#DCR@+bYS1%aU3yN(!Fm?3iF!`RL!oDZAfuiw z*!uMBrYEDGnSxY3Tc8>B+*TnyA7$zpm~1^yuR+g%b?G@B2kTkDMtT-!p1<@J1Zw9u z;AN2ys{((T2QRfzHeL8p3lQI4?1*tl> zKr`vw)rX3uci6_Kn9|fflm+T!Dq|nY%~!4CQ%q25AIbtv??Y|6l>F~l)Bk|P_P_OO z@IS!1{4X5``=5Y~{Ld9<-Dl`TW5NPKMxV1_>+?A`JsEwDDM3)E?z)qSX=q37dF zJp+@i=NUEV8L+J9R`Ln#tD&_mGgW~(A1H7~Iz~$rnGgIJ6>)y{ALM7e9twp4E_!~3x#K-l zezt|24@_APRR$h=J`hCN>k$B`<^yq`ydL4>1i`d>^a&tsJpu{?Ty)x}6YUEO+O^y= zem&GI;EL!E*CPn}t@Q{1tZ_X8UP)Mw&`rh6V;(#%jq+y{2Ds=vVm-n_gU7`62tB|N z@kSvEYrO<-)_Md0D&62dem%l$DrK6BpqXt7g#j))%`TftS&y&*@HpwV)*}E=(T)4+ z^$6cZ{OOD0k64b0cwon$4e43dd>*jQ__L8JFyoKFT@`=!4CBw1@$sjb#2XiX{+uEH zfF3DFUXOrhM*P8pg!nUxXh@1bcs(Zme1eMDRytuTi=zE)C=77XZ3RBONZB_nu^0Wr zyTd(wO@zQ&(>S3)#QlwdE3%i+he4RX@Tn0?{jn#jJqZA;(TDL$QLOb1*EII|I}^Ua z6HJ?ej%}OTgq~%!DZn~yYK|%}ZA##-vZ=j7o7y2yqI2(48<${HCqhsuZ5rsYZ3@o} zo5F(xo0^VA_VjU1b}4 zhqkdze7spN!8V@AU>l&vwhcTpYy%GxY@?iF8+bj&Hs(?h+eQy;gWDz)2Ds?9fwpNM z6>qkcwvm$WYz{oOjesaS-vOYq5!@%|J6jM0)4m~S=k=E;3~i?;!Gno0~$=(P>94J;2aIrdT>3xFY()SSoa3#Zmy) z7)$X=LM+{dikZjVz$3>}6b88HJR+7JXz-XAOLqm1h_^773f`<(3P7bB+{ee#-Kdml zUSQf33Ikkpnh{HF|450Yy91AtZY!1oP|=P1>R7rng`7d(jHQTeh^0Ak7RRyJmmcgv z&nio(=kBkdH!26<9M29fT>bfDO2q|B>YXz7C2H?HRQ(P<<6*pG*Yj5OJ6b*ZUSUDo zzC>GPKe{NgSjHo~7Lsv6ta}D5$9Y~mosMHP;gD;m1#A@iajx_RRQ8J!@fL^9F7oS7sO+I&BOSYMp)r_X`N zFUl9kM;{C<#C~bAI3WVkK73l_Zx)W!&n#xaFRx}qjuVgY?zofXj&JVJ6fKS8rhRjV zQNK;7?bBi%pRfyU$^7OH^n9?b=Y^*_>~e=xJ>#1sJs6A7ZRRr)*C4_{vD!}fd$f6P zvq*<%C7>N~no^E6Bm;&p+-F9>u$?AH|Zsp;bE&8W8oQG#>p9$3z^f{uWB)$&7 zU)zO6)7N(C`y28Do9ffLZ{SF&(6&c;dmjOP$ry$+vp28l`vmM$N0RJ|mD`}#M*Eut z^R{REf{payn`64ocmA!p`diVjV*qb81=u&}v(wJF4qP-RW8!*<2%#ylqbobP>%g+O2wMnteKapf;Kg0ZnIyH0>DDw9HLYJ$`bspa~jD{A6e(vu$=( zdnodrGe-WL5R#6w#K`F+bNQz$PQITO&tl^%e^-bdVA>g(;_Faykww*2M7FHwBAVUc zqkjo!-!u7F67H;aGt`{w2O0So-WWOR%$6a>$UgrD!ZFw%<@RDv8f0jXlPo}PpD}+1 ztSf&`$HDotfYtKn>b-~W(V5^0Yq$l1jO!09*!tEVxarBb{(vb+U4LMKW?FyXTJsZ2 z@35`;VMT5%JI8bwk_&-gj}PmfpZqzo&nI-nQ}n zTi{(pUtr{SQSa@769kT<(y=bb%MmVkUYs%XedeHf?STq3_=xkQgNxqQh{)sW@#4F}Q$d(Ui_uV%+PRJr`lQI$(Bs7J;ZOa4)O zVfjaoH2Ig7BQ%&H$5l^F_A^r;&E&r|;q9#rZ|3;8yTEI9CKK!>b9_8S;2r+>cvEe1 z$ZX&DuOYn8WycG9mU^@7Ib%G3T~uYN(q+%6XDIRfeNm68+PHd#!cW&()lGL?JwxGV zj;JS{ANZ@&uUx@>F9-1ne&xjL3RCZHBN3r@!yBml71dvOZvHFE$QbsHRxw3?dVa$Ro8r8uu{~MZf`Zk z@kbrRC&b&#ar{*Wu`zgu8o%BbRb^{Ov&Ju1$}v937QZ0>?Cpm@Y7!qKC*aLI-m{N` z*aW

0P>p=)EvIy+gH^+Z-&o;x^`MZW$@&rhVWjI9WU%-DDC_gMOCKB$Jyaf`pYkhdQ6vf)l*Y^ z`FnOb)r7Y=Q0<(xaL~KBHhMGr&1tpa&72=xDDaxW&LIby zCnmtbQ_XocG>7&)+g>%yvjNsM&z6pZ=h+0THqTZ)PwYO6hZge6b7BO7jPt}6Y<=^@ zZhA7#6Eg*=^TZaYb4pdl6aGeWpZ_@Ye443eV6yeRcMW<5tV_@7I9SgDHc`*+v$Y~U z3j`VUY{Ay2XE!|=^~@Bc>e&L#sOQ`{r03I3Jp+@i=Y49>GhkhMPRGG|7O;tWcAuvc z=~*DisAmhdK0UkX$*5KT}9J?~qCo&oF9b2<*zvw$6no&|!8 zdbVKy2YO}-QuSz{d+803a~v8px5~SVm!h3-1led)PB}DE3I?@?GT}<^II~ z(t8R9>+9Adm=D^-I1$tL2U1s#=<7EJic~*t%2c`j$E5E7gT4`8Ci;$w=tE(Ei>e#n zeFc4oS@h-TJ%-W0v2~z;9}!H(!$>oi~myw{x;x0J;IN|02dqoQ5OD@8h< zZ(`4z7qESl&XxAzC)-D#Ka&6lmz#bMG}7;R@7f{sjD4B?6VEG#f5KkFaZOPud~fCc zMPaX(Cex$%xlN9X^85FO?_ZYf{Z6^pf!}{2eE)Wmw>Ge9`-`eS+-t<|mljLHIJWnS38~_?SjvflRWnA|RSe8BS8%)Q+dJ?dPo`^J0|K^JOtmvq{6bMq|s65}& zf=!R3kh^`prJJ6N?Ilx?+Fn|q8QaVG@S7Epp2hlhV6ydmSPgmxtV_@7I9SgDHc`(B zXBW~CW*`t`)UyR!pPt?HWYjZLkg8`3G^3s`gq{Oa&%k8s`S2R_3|N<*({Zq#1#F~e zvz&E3Fn%m>HdbR5jHfQ`}F(S)CMww0+f6b881Iy*+` zY-g#nt)VmRJD7;8kZZX2PY@vF`b?M~9B#-}d{aA4uBMG0W6-;;NiPZmT+-;>E-SrV z=gEAgZhDV3=-u9=7li>XY4p-I#BB0iI#ha(Gw9t3^d1uBiYN?l(dk95eyn8=JJWj# zM&&j%|AJhRZQ;d`);*JR8&m&F4ElC4<%z-o7gaa<5{NOjz3!S-o=@jw9H?9WeFnX| zoAjbEz$J~|J+jjK&QSG#yg~0mlU@`CxTMj$XI6T*Jb#G(b%H_fUM9UL3~))Kckit9 zer~Aro@mg!FX%li>Pw<9z(uEb2HEd%hJVo+Hlih>@1ySr!f|}QdA2?^F5afqdy>RA z%l3QFD|R=C5sQ90e<<8i#cuh+C{jtW0*h~nzIBH)_SL3w!mZlAg?qaC`zIMZE;e<7 z!T=YYN0*Nt0M_Q?hz5LB68ql^-quw2PvqWoCV0_khYbzhr`ln89@3sUIuA)TF%kW} zb6xaT4Ehf;b%eqI7oGk@9UTlt-hlv1ZQWiIaux7$6#aiq@M4?|kx55?f*D#m8r;C- z__Pt;B&9N?uR{)X@w?RE_Yjj`6b86t=J!zWJG?e|!3EX)mTR)flMNmZ2alYaqA==3Mrr>k{Ti%nwhC(bT717k3$ zXT=Ej7h6l;KeYNxkzER2ciU?1zz6a==>z6jF%n$^%yt&PL!S;G3|$#tQf# z$(V{)dY`i;pYt)B>S#nA!Knr>6_Xbf3J9B*<85A+;fO2ZWvR)_P;}G&nQXeDbBhU* z4YXg32|+e?zwDgBUPkYgaiT{EXx4FtQO8+k9ViTNNvmT;VjX81 zb)0S1fx-Znv^oY*#{mmt_*iDtaW3lMvzk#D;G)-ovzkw|WOW|BC(mlu=W>=CxGw=MKqd#XPNO?9m}QP-tsp@5MfNW|uO7=1=MZ{< zC=|YP)L$ALV_D)XLX{A!{7{W$!B;VUQ-$lrFXV>}*K415;aUQ#OQLHXqD%g1JZ`^; zf+hJpCDqNICtgRMt@z?I+2p)tI8Vbex*Wll-p@EsQ}zBm+1?Kg;rz%D#26vSuw!)q z-DVsk1T5PJj}fNhU|SNfMy$s9gWFRdGAFukhYn54mv^U*F9oVC@Q(&% zRgSlTcgRX_Dm@YXEPH+@mXBO_C0~9GgHig)BXLZ8Zj%vNnGm266Ixa}OWG%|S5$uY zMLAZ+a`J<4m zh5U%`?nUz7hiF(TX{Zuz91Tk@jHN*npHUyVz0^12)?9gJBQy015R!kJ^4p#QbfWw) zj&d?+*Da#Cn9xV(Dw{5%DvP2<9!G&3Ri~VAtN5hGQI!6}Ga4CLKaf??ZyeI7aOp98 zJ;=hgr3XS>55Ux`W35`l0a|v7;lH2HS7RD~kx!-EI5@TnSR=ODd9eFiU(p=6K#-aT%Qbk_dNR(9G6kt~qZVl982JR*Wh>dWYMWx|9k#Q-n9|g+iQTikNiML$0x1CMflLe->!^_x|pK&wbkTIUuop zZlDIA1FXyE(s8iQ3E0Tz%zoH8grEC*k0W1SfP7u7=R#qCi{1yAM0)8*jKX@k-O<;h zG5ABmKK~QQ+GmMeV`qZ9NW@!BH;L_qpi{W^hX{Ga%0i+f%3xKzoEM(YYVvWe!N*hJ zV=4K%;Ds+0foV8F^ztX5{J| zV^17pENys{x6hG6z2c009)G*Qkl}NX;gOLHQ5fLDGAwwXA|B7IMTR5EhLGvCkuaMo z-%`@-EC_Le^hliTh0Y?$v#8|xV2nH`@M+#g|DY6}oTr@uUE(9ysiKCMZsGsM_F@+Q z#}-`6|1UJ;{(Z=u{U3z^E-d$g7Z8qM2y!>W!AnX5odux+5e_1Q1>4{)QUL{sMzUcw zAN^d64%T3N`2Lzwlom4_db-Ha(;)P8Vic!Q7~sNs$|HyH&NlQ^EL46-FNV2NFO|D; zB|e8VV8_R|5v=4$=Zr`otE(}wRtfHotmx4i|ikRykkhi^w^$&Sbm?{2W z3{l(hANACfw_R%R_lC(I3IkkH`4c16#NW@sA0|s;`9onQ{>EPJ;1Bhr@Q1l`d~4xc z=)jYHBj&R2AcUlTob1oThI{D4DA5>{`nHE@3zr$PdK0o@zeiz!i!Ljt-~W*>mxteapoNr$Vtxg!!z_5kkBVnifAYafe|BcB%3Ikj+ z^Z)M9_{X;{YUTd|@V_GDpB8w6|M?;RK`Q@O8vOqr{Bzt#VStOyzbo$lf!$0zZ(t8Rf*1r0nkXr5QYJe#;<&4)KNQHp5*gTEr0N98w zmPVwf8_Dtd8iU>sO?pun;F3!3zw4y;@pO9o{9hB$;AhM+POxl`ab8Q$vd-B8)-}eN zj$<^%g9eN-1_Cx3#$k>7@^F8sqo{xz$7;)oN=h@?z$u>QNXeE5Xc;o6?egG5g#kW}iC?xsHM{ z{mk45*d{fDQvIPWj1x(|Hud~Fk$cg%v;5MPWG@$*_5z%?y{p+Milx`EU)^w> z!-wKqjqbS|rZjaP$^vyV71?j{Jd~TSTIZpdpwxLN3p9NmYFqf+#iq{ziS2XO*Wh!2 zb@^O64)!?#o9J`y^(c|g2?VJ=C&RD>o9=UFZgT_i%kyI6AEVrX_kN);z(sG1k=uMm z<)#ZTFIKEfp!XDv%57*s3H?&0?+j8Ga+{j=e%)x$HwpCd8ch@ixTw03+hC36g%*92 z={??G%4LMc;| z-YI%#U*%$IjfhF_%?7>efZn^J+!2KVE;_xFNxl~u^5yxuhRV8x!J7peIDp`czO(kJ z3S+FlF>Jc^FV3>nyaSEIbf=^K^iB)7Kh5(@w-~&w58ilO0EGcAI&T;kxY*`R^}A*W z)sOPi9kU6{&jmNm>d~Y@Q_?XED3IkkhJ}$BO5LQ8BSLNa1V`QVfk( zcEJSR3j%Ak!7m!LeG;^Byh34si%uKjRa`8tY$l0>4Q3z5WEOsvLB{$xCdb{|4L;_Y ze4sGEB{LtJ4~>tRpG&tDHy?Kxd~69mcpMys0WLZp7+0}urBK<5>5m;(;X}Mx0mp!F zv!PHi%su~gr$O&Frrc2&;G)x;Xg}LB-Sybd`E|?vE`yJGrrc2&;G*;4l>7Efe@$|K zu2#9^EN9O{!-SGh*izPod%dkj8y z10PM%d2uKVaMAgIj^g-esO&x*I_f40o0V$7V+lR(Y*$53rroMFu+CUEz$26 zvX1KU`!~QqOroONW_P^3&){Q`$p;DpTr%^q*Uvl!K8E5m>mS-=Hz$!@xqapVgOB~e$No{?h{6CDosad&XRdVe(GaDLrOIN# z5aQdCy5n08m@!e;^k7dcqj@`cdsKLiECLbsaaIyJ_?MocX zeALq>v|d-QKE7=5u>^c@3_@Xmi_QmPkh|}y$DlsJ5bO(UQg1|#rPg?8sg}FnnkDw^ z9?P+61NZ%utAF~K!S4yC-cT6eqVt>RM<)(VZx6H>PtHFtIK z7;7%*$&f~KE@(zEVgIa2@7D}^KV#C1!T^^vdM}KjccwibIOawvQW3THkEWwH@K2cW_-b|18g(dzdB{qwUI3U&DRo+}92I zF9rP^>roisqSFswyvDF!H7-xF{xU*f`QoS=eeqtfSl5|K-!OQ&0=)1%G71A+bY5KZ z$XC*P3P$;2)jaaMp&nA^k^B7Cn`nK&B}zZ?02a8ky*}WZ^epQdF2K6h2c+ZR^#KAl zaeaXMoa$(OfIx6Cg%W>WSuJd$;B*K*X~{+BH_Bx$7A%3)u_nh&PsTMlOhM|J91GOB zd_}g?yr!(r-xhjaY3do6Y&}0$gPsBF(sMcv*0X>$^!y?DZ!`I%+QaT%2SWSj8hT$L z(6C1mu6=6|OW<0)iM$aJyT`OeaP5WaRdDSEo?9#Ndb#$(gjXc+fs04#qs4+~VOz^c zta8y@dqJ+6Yshsp7^~(iV1f&cYdpnNaYReFFSHaM*b<%BvZZ&&ue|ZZqsZ+yr2lO) z-ZIMXY}F{*+#^Y5ypcg<9&zmhVulmfU%(65evP=03xx59>Du^aiR*#nTtLMynwvm7 z!tX!XEzcLuaPE+km&IZIHSp5s-$E}9UTXRXNV0w8`5Jr#ur41-$H6`#U^O4fL*8lM zoE9&MwcNiuv!-u$zB?AW(2~;TVy=H68ii-P{}y;tzbT2e=b+d5&CX-VZsq7c;~lvS z^k)8M=hoHd`R4jBC%d!pP8WCwsl?egQ}cz2-jr{4GQArMyygdsiC@)M((%^!OWMJv;3z$7(@8>XCBM25O+kNG@s;EYFVuuIDI+s9g2bWQXTwms3r6ugQ)Va*=wq zLo8=Nc(&X|bM^!_X%QqZIW9+9UxxAVk?@;CPJ4aP6xu6~yUo81Y@rC6dJ<{Y~ zT8_|Qh8$NtHOXnFK$^*aYr@;RhVb6BhVb6MhVVX@9WU&o_HTA`+PhDZ_U~-RUBPlM2l4d2qF-+pWAVCzz$w}B z4mGY_BdRh(gQDMVZ->&Z+@G&;WDMH8pjp|n?D zTqj$5HPpCw`pmTxCtm46J?U{`sQP(mE$Qd+wWOa*){=gHQ-gkn(k>k(Ty@R2vnxeC zYu?`87xiR|^I7A8t4SOmWQzwi#ra-=)FeKkoz2|8-^W300^ZE+$I>-K?}gdv9cp~K z&B21J{aBae6@Gh_lhjA)WlWQqpH7YPBDMFT=5dG@97HAP%QcGa`4sArh_r<*&7kC7ANMrQxs%Ry`c z-pu~pR~x;V@t(DY@LrJ}FYIF|?dBInRi??u+2K(7b1#Z|OqX@lQ&T(h_v~`232$+r z+Bt{A4ky-z*BQ5>@ltINs#oAOl{g&qF0PH<%zkrPZFn=sj|&A}GuS!g(C5E;GtH}9 zX3ndiIke|hzEi`z3SeFHD(N_QUPZua^D5Qf;dzVBjjlc?B${Iu2vX;m zxM@`L;6*x=&N%YTIOrkZ>Q6hFW;T;PhGBtbng_>xqkR@kGQIeCZzg&Z=Iw0*5TKdq z#oD)Pv7W`8lgn%08ema)x6r(+{c(kJX`wZLTtT%1`nLvR>$o+VN8>tns;>^LA-)cL zabK^>zhC27(I(_R$Lm-yul6on5 zOHSr*w8ZL#^K=&0^jn8l_nfnH9mfoF9h^jS9rxB(2hPpBUfNexkTKU)a#eprRc`yz z4ka{fiI%3w^%yJc`i9e%j=3!xVMK#wH-ffKig8$DzKM`UPbuI32EJ@NVoY8>i^#_4XS z&u0^nl8-v89&Nx-c)TC=*1=<}FLRE`f?Ri1Y9(=T{GAp@TjBDv<6L#zlTT|au-+$J zufz0S_TS9wbvCE>52;?W;m%iX89`r@Dpnq}7Hufr=WNP(2=F>`csJe?wh;2g@*;gP z$dK_~mL2aN5xvG-xJIv<3)h#PvB)2HR~7l!&huF|2T)zoF6yi6*>qEh>fL)Et`|0+ z*&a(@aM*mhJ@!%^a{srnW=WHymQ_9`?dd47#Bg;UA4gL<=lRHjcOBvUE7qhngt>~g zp3q3G9q00B=X7Yx4jW^Z60$z`-AH@0ST{c~5excE&`9%Zg&*^?K=Zp0-A$_~#4P3}P)S^>Yntd+lvD<$$ObywV zT&ed9YoT6On$U53ef$zG?*`$BklQN7!SjTAkK8)UChj*h;*LBm?G*TIYg zYqlBY?G0jG_KiYjw11ZK_I$BnWT8AMK66KmME^Qt8y~+pmqX^RcciFYwVOvA$?d(S zbD782r}IZqcfC5V#lKyt_tZO67$-R^-t}Ckp7!_h?F6H1z5Pw7Hu59A{dMO2WRGIM zK!!E?L(O&fohNi+r|Xd(^jsJHa^drGFG#az^vfM>rX)Wq8Fpeyiscb}y z=S1-cdlhbie|s9v9|338z6-P{(Iz=%Z|ZzX`1@{z%XRJ%x2@cNaOEbuEfzA>Q{hOS zytXajoO4%WaTof5MU}+H=GXAi-->+(T7aN4n_RTJs(Jg8W=9)LyEu86GvY=0DE5wG z-}DbrZ!TY`bUy4AX(+!`tlag07$A|m>L6S6Tdo#+QZn=@_Ss1Y@<{4a@CR+N1&4`I z`qRf;Ap==QeKP3EiLP-{wN)|zZ`yttj`sI`NXV*eFm)f1cCH`eI_&PEz-3sL@`n+g zTHkNiFeWT(dFj!5o()-Z)T0~ z_`BZUtzrHMu&()|bR0Z?Bw&X!eM_ko>ROPlW zqjRcsqt8LCf%zjQ?3s*&nRXNQLlftZ=Ee6y(uii*lO!=8w3pRj8{@ z-3^7u)_d#YF*c5KCzhEzH@y;9PKr8i7X6dhyqD{E!BxjXI#xe9@74N}jB9x3j~MUp z&L1(};hjHXylZ^^h^wk~{z%$IEqxWPYyJBiHgB3rdTKtW4({kD``uJJvXhe?n4Z7Ysnc3) z$(4F<`9OWPR7<_Cbo|qG)=Rj&Tcr)xK7YjG9z^wS8#Yq(sQ+Zo9~m^P1$&+UU^ap^ z+cf5nZWA(d%pV;bpSh#0MgKaZUB}NKvD}{n8+LC}Z}L@JY|kHs@~(aUi0j_yp==^_ z>bw?vcctDpq4FfgNzRIQJ=e)Tf5eQg)%hc?_LU*bA2F6SK7Yhj)jEG9Y;gGIkC>2m zvRbCHk?Q%Q&x`(9z&Q7Nm<+CJ>>jSR2Ih~r+F_hOVx((y{)nsjKQMp9#H`i%Bd&HB z=8qWJ(C3dBSAFwGOSSo<3*`LKo^t-^7V?k5E6n*L)K)cr^g<2uM}T$BAEo2q`6B_F zIDhowBXa){zIn>uDUS9Z2?VM0NAiqI3%0)bqXc@A_8)QG3G+ubnF6$q`6D-tYX4Ey z@^W+k5mTBlA7fLReLqj1{}PPxO4Arosl6BOdo|c1U|qJDj)QGcz(%%co+11q;pgw4 zozN@?^wM6v&({t&)@`*Gp9s-(meBY?!e6tP|2Dqfv zaRKVsLDkXc@9dMbKWj=GoX*;S766pbCTP#2Fd*iUX`h`}z?^^Z5<##$Sw?tXiDZPF zd24#-+-9+!Llg>MT=x-2dp!6MwdiGXl4f}Z@?U7MJZhe!d{CW%tmf%w%5yOp_XkaK z%?)P#`Ml3OPG%OXnHy(CxYSyaPzqN?QaG939RSK%Q*+CIfdA{}@+-uRIiEfVerc$? zxw4;D9qV8O_9lih11!so=j79IuzUrqAzvcZ_zw4bv}6POF=OJPK#(yWTCnNyu+Kk` z6gzlzB*)LtjW4HOLLHF1e-SV7UocLvHpQwfhX+j4@H57g9}#iE@vl1)6z| z`U%oAtp!Or^OxwA-wT(A{WhE53(v=HP%4Ed{_2BVOzHUD$z78+np&Vvrigyor`y0A zxS!XbVy z9>?|1Bj)mX73-dB*$U{vzh>j`00^ z)8CJk84pe|-WP#4S!OC0hi5PIyHDq2EWQskb$H=6>eMw;Sbr6MqndI3J><{CRl_%` zUomuf7j(Ilf_8aR1Su2-xF|iLjfO72XzB89hc2sh@yMRierx*9!;cL5?lI{@VSq~- zefMUeZ_7vPpzp^9efNXD`=W0jqA42=06t=&`mg$ml~0W6lA zV1YG=CA6)QM{C8!9(z+RuNiWA!n6$(2Ds>Qfoy<_D;5qeX`od zo5@1hw>I1OsUd@}nzn($02f^bu#Jo|XsA4$ECkCoqzvk_jh-(j+D4UFs%#@R?p$?p zK1SIuFpcQ{OvRp2Ds>Q#kbS$G;FI_`8vIa4qz;8%fL1D4Hjxi72$Ek)LrPg zE7r%RrCK~%iE4@!WQ6*59S8Rt z1+39;wENrceq%KLC=jIfw`JGRf=%ylo3`?E;+Oj>KZLEE80EJp3~9znn~20O{`svNEje2gnMC5^L~^sYAO{gFv83Ikly=>2h4 zdY6%jAx_mz?=K8`e*$_ro}w_oMW+|>^h=g}U!(UN@s#B{_Gr1!B*te{j%v#CO@p@A zK^uP`5rqLRI&IkJbB{qA#R;K3N-BRQi9~$BddC~lKhF!RNXQ+Tg?%5TG&|#WbNl>f z;QQCA3`Y7saM`~9OL~^o_W|qj{d64c`vTVReR~Y%D>xaZYOF09gK>Nb))-1xgD!>m zNGfO$;bZ2@)RlIR!N|dO3pDE(jA=)|BDrx4`8Di_V+aZZTy#4^47pd?(f%@qyiM8f-=U>;LXTZAj zoQ{L_EMOD$y!=sDT!{265MD(8L%!rr{iEf3)o1{Vmj<_F}X4ezGVBhEQ+0X5y&#?+=8u7=Wcp3>YOP^)wuA@J{@!92e>H*MFRR?k3acfW-E>-_+o9fOYv?Iu7NL;l_Vg6!`DRnkz+~(B-5T@^SeKsDaj>2R zY@(i1)-DJH8TD+z)~9DTJsI`P6r}3e0?njnS8R=?SFQ;dhW;p1ni^XzP$yFvW2>95 zT4O5{lp0$t(Dc}P8+`5-)8~Lh`W&wT`mNzd>>GH_>!$jAf$!D`AGILO1Aqa(oL45f ziFHrG@9-WC;Wqof{YUfC$^phadtQBw-dwXJ-pROT39v4|PshQ$3E0T*`}{W`tJ@;p z#2O*M*zxK2;4LGafOXNCj)UnGuo0ai-~Ytp=*WqD-_B!XQLelnjREnxQ;H4B*RaOU zT7RR>G8$t)z)?MlF6a^A?q4Lan6V!@a%_QS^|e0#h$l!FpEq>@WVSB;P=hW2>(WI! z4%UT$jdWp-QT>td^BC18q#|ui4hjQY^f4-|HXI57$XTvXjyXM%C!`z`u5gXvYzyD@EDhsw1zHH{Ph*`RH% zDLWJfxahRGWVd-1**#N_?EYfVw&W{e9|?S zvTzADW9cN4~1p>YBz8fEnojQ`vXMsA?2fLr? z>VL%2J8U@-Q<|C+S)fj)$oA~9oj!l`Q)Dl?^^G}T@#P$yGPdzlY=xx=&sx*W5&K(pG6nLGZAyc5tfX(?uQ1wrhw!rvnkLTRiRXP)6mtG(Wh2zw)gh^QADBe99bs2aHtSV$yd%F(-W$Cn*HVIJJC1ofW{+clWtrnV@-bKsnp-|X6<~gWyvCld5pZ19nzVb~7MORaZ@A_y2B|nq=jy6cO-00`!>%(v0@Xi6w5afpDprp zjb?jUq+-_3J>ZcD3wcCgfQ!x}#=f62cq~?Kp!XO?j$ciayfp$x#G9_0t-#yDh&KQ# zqH$lo12m%*g1&XVl&F+xz8^I6csL3JT$rA`hg{FLsT=7%J$F(zH9^wd1Uyc<_Xpiu zMK%RMMK|t4n-aMdsPFTyK>WF11+9M3CLx@4ws=$mt0(VvX`Dz${ z4vmjL4?#>Z@n@On)AX{92zl_yPGL1BQ4 zZ7WYJ`#vmF{AmLo+g3o79e)6*Yz6np@ni!Rs;cr;Cc%R(@dG3JL>UY+L!dvhO1@#h-D&W7`Udvf~c`m95}DIsS|%2&VmI z(9ZD(g#j))?TA0$Flf&de>^mI?+qZy??Aw&YP$9=j|3J{Lankh&f_Y{7@jP~%R20@fPAVw66X*W_nHpdSqUXRI%W>OK`-iRlt&E@_(3Ikkh+k0Nw-Z9el-ZN~kYE0;3z+<;xAjB2KVv#+y+$2G`E>Hg~9+Aoo3{7wm+oga~lGWlWr@Y1E8WC z_tp8_DHLJ`A2(wsVwoK~H=<`*V<%vpvGWtEz>J*&cUA0sA&i~J#>dWf5^r4Wd^AJs z1U*uY96RyMh@E(l5IehwhNReu*JEPm##F?%GSRdZ6b881w(>n?-^a<=IT}K6jHkaS z;FfO!JhrWXC>cBd1~G~8bO0(_!F^~eOQ;q>f|+y7Aqb{@ib*>P164_f0!PGK7&`@TR_p|z(hct8W9Q~n$~4b3Z3=|} zE;`MKowh%u#Lg{%$4R#pI{~QZ#(j0{+~GNjollyv6S2&Wom2|>5CV98q}z(6 z09172zB-l`zeTb1t7a@kY{U8V^YI_&(~BF#KOQ68h03zVR={#>tpx{^5E#g{?8v!NSZ@Ios&>ZXme#H8^n}}p{!UXts?P=%eFEr4z_${esRnWy7mnG4uR=4KwSknnT-IL`EK z6b881zWthtA1BH9u>`(tJ^ z%J+U5nu|U2OCS)sm{(Ri@W^uyp@80!>lhJ!4MFYFUgM62l%&mdw_QumQqplSO^T=R}@nltRraBkpHTYR*W76K;nmvD)s zGc+yG`sN+?CfnmUb+#EpP#EB1$B>_@I8~8xYQTsgd=Bs1n9ubzrZ)SIYaVaCq;q)t z{7dPj!EZ&rC^8x_Z^!?A=vh{u1FXyE(s8iQ3D`uR)0gJT8)FM^)=+b}2$aMAUQe$VSl&r7AASJHb7qqjx-8Tc;&{w2|#YZL~! z@Vj|@6UO_QiN8>}lwPEj&hR}l3iYiW=Kbx^ep1f3!27-Q{zbz6v{-_@+Wf5!#@qN^ zvdf}zEWDck-eiu9VWvFyH~76A{2oRzP_98nVStOy?+l{n4TE3mD~qg_&M>}$5Qs)N zT!>7t;DH(tZ&PuWwaJ6Mx|qf}!tLkG(hH*mOPJy3?dMH6Q(ZKnC9Ee`JTBbR#p7aw z$IpUCo)1J}fQ!x}`kg;Fcq~?~0&DZhenLR-g&g1~a_<%sylAu|HVodU{9Y!Ddm722 zqF?0zrj8CU=)c;eAB6!fY4l%{mHt;dhME2Y4f?MG{X8Cn!T=YY{^=yw)rR~v8@rwm zgysbu>_V`$ecymp^~gkFTkyh^?;GU3KC0)h@WWjBWJD4DD__R@8i~cpUXDKSLIX$id6!(-C$wZ^ThO|6s_P9hY-txIZ^u2n$@IwU^KYit2fwXs zNoKX+$8JLoqGws#5Wu?HkaQf}h6q@#4as}>PP+7Y?ZY0;#avG*S8<-bq`q;G@8>UK z3A93PZxQ1~u~8=`3Md~s{0Nn+O4}F~8n$==G#rCS)EGq{Rqww0ne}cx8aczT z)O)t5cN%@WCquo5h&Vee^*$}?-7s6dy~9`Uhoas+=sQ;#_BJ{7P7J>jTC)iG~-%XWv4w+}?MgXz4%SO3^DY`Wa+ zMd)%tx(y9;oH||9iw%V}#3{<}yqDXEcluTsZLqT1mU#85rbh31vBrN+q}aP9kvLU< zSZoGWsJ5_rW#f-GFuF-RU?u?-sC8-Yw2g{WSHDXlNUKqYWu0&Xi+U0#J<6+|wlc zcSlki#dBPu2d@UDmG7!G^T4$p;hJmXI=xlmdVu7b^37o9`#&SGV!S-#`{6fVnU`zB z`fpFKAF`nJ<z!_tm#@O<5$a$A>IxAJ5<_!|@E%7?UBWe%}aBjc1@vj5W~Mi%I`` zq5KT`2iH}0D#scgra>4!z(DC%jWsCTzmVe?Oz4h-4m%nAsfl}^#Bq#R+z$*RZj2M? zI-T%C7u^_e(Y|wkY$m#^tnW}#nQ(pw<9`d{YZM&v0Uqv@^f!dlNJ*vLmb`7}t9;Zri-;@P z?PZ4?%ZWbS=U+`P4Sq+-T8^s#r5)ctRYQCStSi2!%;m2d-D7 z9Wt&TI^~zg$Y;j(fpN`vMd~7Bd=J|fe!s@{C2Sw~{rcJme!tH4!KtI&LRlF8El19i z*oT%UX|Pj4P9V zo|5$-8_Z@0Vw|gXe*Pirc`9o?a$KwSdOq=EVF#CIm0NA|AZ*vQwEIiQ-Yyb(s4>PI zuOBt8pD^0Plw7fI6Fm7S%8sknVT|yOI$Djf6g--Nu9FUJWQQxRNKu;=t6Z7K_J>q2 zkK%B>kF14ydBle6{p(t&mq%x~-VI+BCcQ@G%p);e@5yVSULJMfdLLQ~^WU zVwS#^&HcSdT5K=Z)d&Qs>uTg$HVZa=T}_{VBjomiDL0_8<#uQdasw>OP1~b>m?|*$ z3JKhijIi#3#%R1Z<=lU{9~15Fa|=Jfa)y{a>hBR_<&?cbpvPFsMCXR#nXy+04-)nY zeMB@Q?G?i7F?)p$ry^d*lzY-xcZ0$J7ky0xjYW9BRBIwmfnc;X5&wWRu=thN-Qc{r z)99U9MH(N;Ek6P{qkR$KUKJ4NZ}nQsQvU$D$bCZqM5a>18Gv}DSiX*`55Gk(PXe^h z)jN{FnCAxY%csZ8d zU|w3lONH_;xdse{0WLZ((@EaHHuR#|;`_vu`y9&SfGgrhx4{Fz&$WNfhc*bn8f_4- z82hFA{BsED;EPdwqu|>-fOuoawslGWI^$cPDlp@lz+DyJ-j=c}pBf+EMv)rg z;@k7YSXz7oJyO=;Qca3)cxJ>mJV=OdV~B>N_=eYG;@k05#5OhF^bZsUxac+oUw=p0 z)M*e*u`&`uh}QJ;863ZnzJ3DmMD`T=I*9VyUMG9niY_vy0Z{n|?$!Q5szs2{=l2ur z;7g{hKzFvSoJh~I+6rKuwsMjxFl|NPuCkSPLt8mL-c}|j*vbriVcH4`16*ud`K_{*Go-Cdf)LJB8s&YnzmvAI6nJb~0a1Sb zXJjiMql>f^04iI-eHcq!?tBGbCS{k~__`*W#$U@iP21=iD3XOU?liG@nrKU<5@#CW1`i$vEct20Kf6!ywKb{%(j|U0%zb(;_)Xw7d82dky zirD^lAVgYDjluvIwtsn6^`DjfuYh2RmCYaoM>{(S<9xa0%YY}c-LRbnQU1mxA?>Uy z04l4(y=rIST?m%uy7uJ+!L;uT+IcSr3Ikkp+Q*VV{l%iam)>I-c{cc5N%vX6;iP*% z(7pE@b?!L;72UWm-#`u?A~k7VL8VOduAq5olq;h!z=i3_d!YHR7R_@VG>7Mz2f*Q^ z`6STH=a~ag(Tw}}efMWmDbu_MXy$$w3IkkpnvsjyHnKUrr=M|Xoo7A(JWjf=Br$8} znFCPKjr-6>wDZg_Bt{2cH6siB+m0va(6g-Z1hCF{a;_>c9TO4svP(tdYIK`0qgYHi&cT?vjTUO&;BFySu9|X z*dQ0<8z@IZY%xCjCWMlb1A`vhXYtJNSv*Ma**>Bn$!GDp^4UIrW%1ID{BSzBV0_0qm0gvsgAj)4x67uhW zn8Z0x093w;`!LRk9!+)5bvZ#W?JG>$Q5fKoMtcRcYv&zXxxf{`t&Iih8&zC-XUb5|613b3vfGGb$l8|OQ093Yv`xM); z;?K482J>>I$qNbtT+(7fXB(p9VRaTRJ`Cmg_l16Irzb9(+^;lReo?iJ4_ls_* zL2iI`$t@iR%T2%aTYi7&>unj=f>4%ge7!AKS?}6c zZEpu78~(i=jC=U^b};VY-`l~shktJe;~xIK9gKUJ_I6xM@k{IzF31T2{dfV#3_-Mn z*|krYiTf-ZC2m&+Wg5|3K*5{~@ZP{iVYM&gh(71O46dfGwOwQ1qBieMv&{oayUn|^ zhBgndt~M_n2e)|w)@bwWTp{JmB!M6`SCD5WS+ME30`_XJOSTg3hY;_JQ#5uaankEJ zYCzkr7oDFod5T(J8}t5&Lwx_%A-?~u?C(?C<~kQ9r=2dsa`}IRx9VgMW!ob>b#@Zu zS`*&RU#}Uwv)2&bg=+}!@oNb0MQaG}J!=T>^J@t2TWbjKf7cM+kG;KS{9>2vc%AWa z3B8{&KJG~IIR)BT2!Ra`-4HmFQ8+;?t)IvH@ zXN4xT!L&41(;Jefw)`nr_2E98N(x!D*W=zHA&Ubo8^y7rt-0u1^s>1YbTO!PK&O=9 z49~xo+uD7I?hm0$ou;I7RU|p0Nnb+b*ro-YE7MYYSQaeg`e^@-_c7F$FPFsLU2Q8* zOJi;4%?NGPOqO6;jPfNbN0$)G&CTMQTcBms}-t?>_&W)z6XKX@5ZEtCj2IxxQH9!~?~2CT*^}lCM7cyS1br zdL+;bm%B2jPW>$j?`+F;xH zJWmkECWSt>spsE`ScCHf{|$S2%d{8NZ`;e4YOoi;y6hz#2iuE)HSEPccR67!mbzkA zY%k?2&ZCP1QI9a3)N_|DP%Es5vYp|b_*oTarOoIz?xuM-&s}CBQ_o$tK%I^d*~|vs z!2PPt*XKg-Azkxa#P7_x2owgmsQd$Y3)U9>Tg|InAm>$nkGTkKE>xX!@V3aWG$rlu zTRFaJe(!ZXtS^fj_wDmn(MyBBHf^cpreBK+^4IN@e@v=eOHb%Cz{SdSxDo5# zXbpk)Q7!f4y0=yc^2N&agouI*ZH5w+R*s}F$s~_)RX=MdI#ZO=F*+?hU;ZnJ*u$4g z?gi)ga*4Q+Ya!N_3{I(C20K^FU=Gdl2_a~*c1mT>F_jx2|J;~G&_UkYH0OE$B^~r% z@-&^YSIn(g{AI7;6_?}RnDRQ5@REod$F%j1B*5T4l9Vj#7*V;A5Q#Ohjg4)+e;z?? zfq1KO6P{xca7Xc@;z~l>e=|L4>wS?yZlMP~lSBAh>Bry(6pH0xG^n$CL|13Az1TC$ z8@!&@=!$|6`Zj{De4Z|yjqQ!)f0GW|dVRt?c$mTv0upo0ou&3t&y3(eVrItdaWjJh z=;ov1<%*^m11M?h-8hM|=?brq1}JN4ZvtgE#!}YY-W*c)8mV`XcJ@l%bjn)VTZpoQ zOv)vjVa;<8zMz)XaSvNS? zBVJ9%TwR%(^0PsI6YEHPL%PKD=iTp>lM28>L`3P7BPjEmN)c5!nyJZZKsD_yb_vdCAuT)#^ z)SE~$(g`7{-2hRntlncpF*1CZREK;PT7U0j^s0Qq)d-a<0BAcGVSq`E6m={2IU^_Y zq(%-D!hSkDi>vMhM37bq9JjTk{IR{%IL>g~>0v)1r@dl(r_2?=eWNDN68!S#^pHH? zcCUQoUT{=JC zh8(%X9u7%Co<#(b?hW(8k)=f7fUQa*RM??}5!EN%QH;AyCTdFHKX`x~G1uW$?t@J? z_7sY()Ks)~d!;DfYZ7u=iAZ=Vf-i}m07vG;lT+}dwR^t&C5;pBZ>FiBfutpk4BK%= z6(wxteyXvxJH*rfb22(nt)P$kkzTW)??IxE+M3D(OyBkrLC>TBg`>#7K%0b}5ki2ZOV1+tSAY8&8>7Qi(&z&9*_Yi)o(TL9PD0B=|T*V_PpvH)(d0UojdZnOXf zkcam_MnY?8^gn#Bc`1vw@)d}((ZBv*^fZ#EdOE5^{k}*>>gkJf>1iYw^>mL}^fZ!& zdiv9i=xHPZ^>p*~=xM~adOCL+J&l-EPtODm5r^T^0W{(Lj}z^!C1xhHlbgW)6I51t z63msDuMps78^E@cTWo+x1|f!9ZGcD|A;4`mKqQ$E;PW;>B%}~vl?@QdD+Kt04G@Vg z1o)y25J@ovxZMI6Ks@e$iiFnIR3+6r0Q^-*^=U}8sYb*9AE!F#M09&f}+W@vyAFu(U_#cY>K?`62EeVDic6d$<;O5ICsnHTc z4G*CNLk;3)UatHMWKUVZiic4m=Z{(`hHry$p4@Ug6$6KuSDH-EMEp&>=2gP zdP)6Swuls=H77E~w%)H(5hoI~-{2cmspt}PdbwhG0_iA(yp|w~m2aXLSy-P}^e0ot zwmb=$8s)ZOPKMlRy5B=3#mb2U?4JRkYpCt_1G?+~1U*|exSUuL*+P4xe;ELtqsOP< zDKfKMrHw??RrwY@Z0lafUqujM{sxp1art<{*}omoq0@~%5Yo%BkU_p&MjuGc5S&Di zB$Da=UkFh?o-A2!w0@lidDiil7inx==8mXazAfuMfzU3KGoN#*I{M~7zVdC5+|;w3 zm)E325)Y+=%woFV`};&P+6$vcc$BaTA(S^I`HCDc+A6SViNQ*53E&4LuzuavO84y}!g`seV|m6bR*OU8TzFRFIdyN|kOxAY4OK)YcSA5go;bF*Hol(o~eAdU7+pK2AH8G$VrN zBPw``8yPDpS@*_+zw+@I0um=GZnm`MNRBzel_)_?-BLHLY)=7(`Y@ zhF0imp%%e+j`ooQ+ z@p1hx(OcyL)JAjhKcF8gMZ*VOmv_U*O}z3h5UjvOe$g*+brvMDNueS7rx8*z!S+Hj z;#D)o`*#V@3GKAwq^jaoGbZ}aqP*P46o~dNkMsD$_AYo9gDuxmgc&D}r}kfPzq*_G$qxR982)zf8TT54KBeD5+5(W*hKz`_j{*YcF&Kjt9y}Hv|-9iJ|jpcs; z<_&asMGsbvoiust^$3#@{l!fQ_axyn`2ZRyUqYRr=3>`J1qzcG`kas}-Y{+R$}5Dw zg>D|;nN3E*U#?QC* zCi?5nA?3bI${khk@B9R{j7Jbn!MDi-Miwe3(0ylfM>Cg{(F%sP+dGx8(uzx~Nm(f8c04>j^Cv77en##x0ug(IUUa}qO0-TR2zlPT_ zg5Knnn#vmzD=lm6VYbYkd7I*a5^@m!K4k+?CgxoXCQk_fS@%EWDR=jciPC;rm1w0*Rcf&3+S ztn3|0rhRn#D9Q3H(RNZxIb!OZ5$A3~MuD-vM~Swn&}siW!Z`dL31#J7x}TXx(?C&W zWYIr5df2@eB|lfIpZTsE1V!?Najo4`ivBB6VM#A6ja%GW%EPYOnr8pB=>JrK%_M{y zZ4y>0+Yo`y|9J#alnh1c3!QZm#r2O7{nJ3dzsX;z!T;c4j0Oqt{!yf{menoAp2lK0 zJlZH_kfT)>j-{njBpM(mIp{;?b{&v(Yh!bLu1bvFmGurmkFd* z#MRD17fGbh(GZ5#?rmtSdt)K9kOuHNS_a`#QFi9Lw{0x1gnJdkLBsY4sTU5?9!U1q z(;=!TQJ}`SeHc3^PRzd1Tir&ScedKfy@SZ-fSWpnJmpb2!U>EB>NN&LOmf0O!rHFi<14_=~iSkT7~Vc z&EA+c`f_ESbJ?~g5j8tUHkD_Pmx@)Q+ZXnkVC_{{wK9mjOs?aLn{U z#g)eRUqO<_C+f+ zRW1Iet#>H~j%IZEFOpoTiTB?S|Hu1X|G@7F{wKx%iT+~of0Dma{GaTqqF3;zV% zRDY)UKds5%UEVbN$H*J%J~Tjb3I|2y(#qW>>>Gs)lJ1M${mf3duo z;s^3(s(+KbndZMLZ>Ib2%bRulIsX!Gt?TcH8xq_(6scx(QFgo=iMs!{WBGkM_Hne($UO zZlT}%X}??P_x{@NHu}9-`%Tflc!2hM6#YI>`#qX|AEf|KE=OD{GaOoP5g)7{zuq%vww%YY4P8cH?98GABmzi|1Nnm(*Kvd z8RhTrUr{vLzee7)`+tx(9sb5%D}1}tKVROA@n4oVWBoZJsAvE@c>%7u@~$Ka*^$H? zTwlcZcNE_}dw5e7&&%*S#i|{1_&?r1E|32c{HqH1Khb}(0sklYR~PZ0{JatWr}$fx z=>GsvdI7F_wbX|$cxOfRemAQ3P;XkZs(7a+AR6c2CH{~1H*Ci53I2WJ|3rVw7W|&% zKP>)F_RFpKJ;h%o{!jJCx8XMl`ySj3pb{^@RigxSpdT*v{z62@SZ|ynW5P(hjUq3= zReKxpz2MQnSNQ(-)cbRr>6tfeio$U^a1bktN8$f?zk4+PPw@XH{!jF8Z^!RR{_Y+4 zKiU7i_&>$JtP{Vd`cuZ>Ke6&_dDHA)J61et@$cvoH?97napI=U_r{Bxk^V2_%_#p< z6U39zzBf_awEJI>Hy!?dlf;uwziG0#8ROq8Z^rujPZ3YL{Ey_#IREyk;>mb_{xoqj z!T-IyndpCex_C0lKXV;%Guhv0UAh^7NW1{oD!EaHAIj}TB{v$bnyh5@6TD9{J9j<& zAMbx+ef*!`zbXDt^e>-*-;?~kX43xwpzs1*tLnKds^|MrJtuq9T2)1V1p=z*#gF0t zc)#)E_&>ovWETEU^xL}ef0F+l@qe=a%^v)o;=eu{|EKy7ZGiuzoE6VdjPqHXRi^vs*quE?AH31A)PUnTyJ_x~gQPw{z-Au?0;6?wD=$2Ogw4zzaVeg{Pte)WTd}b z-i-2dbH$U<{-wAX0GVEZYXUDnh~s6W&4Fy3|2^@4yno0R_&ve@K>VNRpT8x3Px80e z3jZhjUl#wT_$O?Q-&6g@ZSbFXc}Cte`v+_*p0xOXmp85cdE1F6ZT`f0;%20OpS&66 z&);4=8SVcJHv=Hk3vjLCWv@stgNm1)O}$AkGwq5sd^cfd(eEdMWidwYok0Xec@02dB0fh17`#VlsU zoWmIw`^-p-Ip>^n#+-8w@0l>?oSx~K(^K(Z-|n8N?%v*=*@O3ce?A|2=ccNAzExda z9j3ZRU-TA}Hd1%`h-dUgU$OGW>P|oLhQ8=8F5g7m86f`B7mJ8We92`tIt^D&l2*v8vd74|Qj%cvxSoCf3?h z-C14Sqc7GFJ@!&}))Xh|i?zi2`eJP%i;A?4=s81OtSgH8Vw%YAt?sNR_RtsWi$#UH zvw`?GE@s2e+@UWzi>;4VcbY}NW7I_#@sqyjDh3>< z?kpre(-+;u-^Z&v-Nl>})I|@m(~0V0VbOS!y67pc*B32f^^?_|UgA?+%!ZU1iPYAF z9#74Qb@6JfixZSCx<IdWl!mZ*Q^b1^ByS)%^PuktFJi)`3cvwi}2f9oQdDrV9iLRCFPBe<$N%1~&dO{Pq#ws^7k1_T~7ypXhc4e*23j z)$agt@s;>{5plp(_(g|xwYq2&kK$rBo|chF9Z0GjvTSe1m@L`OzXm1s5?f!3g20lI zNS%UU3#{{Z;&LpV557*9^NITHE!wX~d0@>*q!r40H&otYb98xksNddV+Z#|GSTho7 zNqH>idvSS|oQvP6%ex=Hv%!*)NK4B3J|1_xAC)tX-l>w`+9RsQb#BsS%~ij>#ql@e z?>=JKE%@y#E>XYzM3-CfcYkrP`W+y?RKJUeZEwSUs>av!MWa~zc6FyoJgP4`i|Kc$ zJI&%JebGgne5bn8RkYltE*26e=!o-KXyK7BlrlAMvTa=qsk(uSosG1Nx%BXnjE486eKp7mJ7<52`x@#fkc2kf?h| z-C0!ZtuGc6OFXRZEG}-+7fXoAkElC?#b5ejh-iOQ-C0sB|CqWchdr9H z`h>b@6~E|<;o`$5)twRI>!;MkNb%#->S8Hz*gw?8(qfr^s*7dBC;DPpQG7<-Sx$_6 zR$Yt|-{_0c;+*Hyo#n+^&#Q|u;w^nKRvi0+x-(9!Jy%_f7fZdUE+&Y+FR6?DU4Zv#RL-rn;Ca z9?}=9iFMyncUBkg>WekRhHtAoYl<)R#aiOPchsG=#aH@b9UniEQWrhE;bQ!^~I)Q=Ev&JW@52V)Wvl1 zgud8Z?D(m=vxWFWUu-F^`b^!~O04s_y4YI$rZ2V;7ynD$*;Z`-g}T^I4E|DGY%l($ zFLn@@f2Hp1D5id`E_M<>>x-SmoNv^fUBn{)Ru{X9Q}o4dBKxhn(bJMJ@)!KwN38oRe*22Q@jDw?GZJZq z@;?fdfBSE`{Py4ROY49C!EYaNkNWK^miq(cBWp$?Eh(SJc^^mR`{TR^Q3lB{>QDWQ zhtzK$G5Ih2P4j*A+fN)Y4}a5qU;Pdc$Ni1J7ZF1<&GbwD@@#$4D1O%$O`^S%B6Svx zS#{AYX6TD9;%|M?RqRxwNDGPg^+h*vSx(*QE+*EhiyqiS${eI$c_1j;J zZ^8pnR7N6o9_WtGK8>Gejn8gIetKSeXZ^g>n(^C5T-ycZB1=XhEh(4#($C^@t-kb< zuDaZ53!xmaWF*oG<$NA0=S$=#eEWApIbg|1q$TC>*yCSuIo8-?Pw+KRDO^$5~-EHulzUNp#9Uc)o)+Is zZa8`>rIV+x+C=5tO#fe?{}eQr*@Ut*)0!`S@qaj7(|JJZx{ZDjNj7l93BS_i*r`OP zzc!grOBaf;`Gl6}a*L6*V+Ye8nLHuSTiDbq=#f#ZkXUMARg3u(9;G*mXdbiFjXqf& zJ=ac)o)qR=LX0pG5PWUxya;O0_63W{6K)b43nP-kh>F^b{M}vq?$F0U(!oL1lqLB z%TnE{SJAA$mx+g36YFniPuy_zSF>i1`kHPOySI@RIE$Co-Rh^SxK$N%sG<*5;GtNK z3gADD)>@3#S`RWR8$(>4Mq9Twv?&4FWJ6mgKpP^qqPvlOQXpL6D-u~8j++JQX&SW^ z(AG1u`C8R?wyJkwDkczb!DuJl${Y^3lnDoHX>O&HP#W?L=M@enlejEH4S~*IQE%s| z6^!^;iJ32aO;6KX=v4Vzlk#=>1D8;Nj}#3_4{6NyF3h50I=4>dM=imR>aHKvOEHx^ z>m#LR?^!jOG4!nAN*2|6YnE9o+oGCj;Tr;lbG)F6Y%d*DOf3{!8;bv?d(nHZY^H_E z(0eFa3WpHD!6WiR#HO_MD2}7dt9{iY)N^!<55?*>iMMk3D2}}NEsCt89R!6VAmdmB zj%9i8k_zCWNRB3fJx!g*BDOAD{Ejlooudu(JJH3w`~%n_Ler_n!LvaroInAkFk4di z@UA)ruBLFL(xb@AUEItMBJ+C6S27u zyE9=!HPBaPJH(vU5H?aqF5A?)wDwZH=4B~nq`Np5=BL`A3inwkGjNNV_MhqDS>*4I!1wXM=ucKwz{G%IrJ6m#?kWgEN@g#%^PSr|=q zBR(~|QIRj3=|!GwDJ}b-#HxfX{Do)1%$mkhOgEX?v*i2L_JC+hc$0XUP&SQyOOX-f z%VcGRuPZVUC^xkVi>wT-NxZEX&QlDuQO0JV2%X{e;(ai*9-N(vj)zNE-BZ2zSW&mm z^8P>Gn_MqGSJX*a-btvb6wyZ|f2F94WqBK#rXrTFUVN*lxrNz&ZY7XQLq|1@`Cijk zrJbaiTKbRh&o$`(p7eh#)(x}bN6M=rzo?})iJmRZCa6i=OP8Hn_p&&YmOf&RV|#&P z?X0+sE_C!5T4a-Wm;TnFQDW$F8R99}JkV8>IH`BcvsxdNV|F@g+gO~s`DIic&%Gzw z=h0G}N0q$KkreGhQQ5Q+o}y`grhsVWv8l;LvD3XH0vYd8%6NO!kA0bpCOh|Ev{gyf ziz(|UDyylE%BrKXj=S0|3%czc5$v*#R%LzRm31_g)w!O^s;9D^@ybHXWbcSzmo-6^ z^`%$VF;rG_1C`Z4Wp%m6#f1><-Vwnri#GSc@ad!qTgGFlEEw=f!+UhgQE^M07tGZ zLCE*n^hBMdbxC?eErsBtT(#ZJ#P6fz)`jy3?V}gl&R*P!Y8*dhpnW`;9P@?&Wq1MNY` z7aNFCoDbEYJ5h1gG!v%3Df)S*nBlgV0j`HY=UZ3rQk$oH2PGv$+QZg2evdh2E)44w^&+}$NV z3UU`k1|?hUO4r%qLX;McrANv=T>i(v-%as@k}Y-z=SkSwqQk*e-_#sqYAKvRr7*27 zb8Jkjk$bv@KaRrn7zGr$mrH&E$PK|y92j1!-yVvYV5_^C_hajDN9ev0!vj#J>V=6vbhmA=8G+Ke?%U~0>P`RUaqc3 zEsBE>vrBu_5PJVp%>OXe0O^O#|@W1x5qDTty6VGs5> zy+6>(MB1}I!K+(EwPo;Gj_P@vLCt7-(OH_EX)Ia!oL(B@IA>|vhiE#-f7Y8rG;_o2 zb7hY2RT#D;4B~UDK7D*|nFB&S*0kp$LN2VKq?GGwVvUY9wN9L^Qm%SFakjR76N+v> zl-xrn$s&yIn_61M8kSb~bt5xpJ+Af_DBn4P1gOJ&K>kQJqGC*kBl`AyGP-vDjxUIc z!}d)*DeqY2!)jUzr@+DGix*h_3%XpKc*ddpj3v&dooT-U9nejSD>RcRIrDMAA{o4~ z^YH!T;Je7h2ckrhgzw@s_>P3StHt-TgYQz{qY=OPhB=55iH)x>bmQsoGRkLvlP@|$ zllnMUhtW57wnK}g<%Lb@S8qTq(dW=%A$|Vh;JpHP$*CH=AW9@QUexz^5AW5MKHcy9 z{pyr|mC^^*xBjL(h!Tlieh(^tf?Iwr@_vym5s#~fKStK7x>~2QEg}C{Dxby!l;1j6 zwlQDRz6;6iH@RL*QMvizG%A+1IgvfSV|+h?6X zp*qBud##ss8*=NPaF#zq)y4a}gZBpDy)>>L5G4{DFY12k~wY#Kt>_^f}SdC+!YyKn>>Winmh%o$J-e8BwKXj-2p5=YZ zU?h>~TLxbKs=j4Vqs~82e!?ne7IaYDMH^uJ>|ACLVbK44=9=QJ#O=5Je*Gg|g`aa` zHP2DZ9ed7|)jUTrckDU$RP!9gob()f46EvSV=~#|CX_@L64^#{CI&5}8Jh}?VUx?? zF|6Ws#;|8l<=bPuJ0GCIHm&7^&#&)EJLeni-oqK_X$w-r(}OmMj(jgOJXJ`TH8^0? z?bAKK{<^eyYsVf&tThD<+4?es134aZTYVry8+0x;UiFQPL@5+&P>RUUjLhtPu^xA} zi6_Xa=Kk(_5?Wx^szJpb1u-*?ihqHOEl z&X~K>M-HWWrZSqp#zjU`<`X?0YnpF4%t?#6cI*+vN(VK4pqC}yoY%Dy?C9H!Im?kU zyfOWw`Fo-yiq(}w+kGK3`ndWx4(;V=Z-XR(eo@2B@*saYv@R(OlHMs z+33g|!I?`*h`np_U7&#=Y_0dvcPT45d zt543+_@SoIUpXslm8PlA`h-iM0<8}L)ds6|J5+0(8d%d%{XJT?z-lU9$I&uhO<{3> zF&}WD`J*~}UhAtqv(--eTR*P8Iyw6K82aKh1P~<>)|a01Omg&)C6II=T$9WqN&rS)sz z4f(a?GT5&vUe~WRs&g-ceod3+*RQE(D!+E_#00zih6q)RiCaufWJ7Z3)U3o<^KX6nwc~f z4#$kooPB8bXL$$zf51-xi>5yVQ6gddxy(c=e~MG@75j`Op?35c6de@z8Dt`=?>m%! zzsG!Y!SxqxYhUU9!c-@%Bxn$!&H{L%zGBNA)iJvCov*q9lRcX zf2Yce3m$7cnevBOi@C$B=$xyOnXOOYZ<)W6UJi7nksQ`&F=^ezd5Onw6j+Kw(+jLv zQwyy9#K_FicZ9~2^<)>^k9N7A{OJt%U!3JR8$^kO{b^06Cn;c+$e*6B`_b>H-Xk8^ z#p1+c-o>zl-@Hv#N_|4YyO=gH1%B)=*N>qXfBmO{?#++?^741se{ne}{Fld^o+ zRNP~AhpaKitq%{)#T%(kxUCI9TjMb+h!RQEj?hBnL&Y(tBUaUZ4D1>(H6|S^>;zrD5?-w9*j0{)^W-#*PcseY1mq z2=H$hk6S^MNNoK52$zRHS6mVT@C!@epGtgZVoYkkd2rubv+nVYa(dYZu@JAQ8=(7< za^224WhT)v_*AqPXVJxxV<_a`m(-aViZ*>Za zhRoN@+M9kd^sUW*AWkx#4=O3z#Jd%e{n%}Gi`D8b`smBL>7QuMmeb3yV z!ule;c<-495Q*M1d-*#&KHzdvj1N5Kr1610zu~M)DtRlu&-R!*_M8;+8-7mJ^Ba{l z<#-3Yq47>~89d%myv}&XpWlSvVW=2JJ-^Yb$W{=BGcV8?*quN94~%DgT1SW^pJd4AKK?1IN!Q{W$Y%mt!E z68V8>%(ZspAJ44#{(~WRXq~W!gKa9X@%s-DB@)J_-+!#*V5_*6^}l%k!8%z0??2ka zO61Ar{_Q$@Jc8$f+Se~k_vXjfd-*%;>$#j1zTRU_^1=38P-RW&8^Ig$jmc%OZ&bXF zZ}jJaW#1`eTQL_@1*Dt{db}N*3s%5WX)egmPMiyRtX0hgds3aSU)tF9OCU-l-1hZc zaNVfwpH=bw1q17lUuto%ZRTPFQ6fpgR_6T$W9!iSi(U@4EnI9MN+e0xwxoQ4IW%MI z&>XtAgKcYIn-R~AK$J*qY?wn&^XhaP$`|oq{$Q=8F}@DXq5C-awgWz%LxU)hM9+@q z(Cc~lwx@jRZMk6tM$DmUPao#cjPaVRUhi|~(4n{WDd*6A9sD~2Kfn6{Q6gdd`rXg^ z4*rV$<^T1&AJ)};zWZ_Ku>Bl8?E*dVoDf8bg!NRD!JKddPfvwGCf0aYD!|MMS0lb- z18WWC)65C?(R0FfGbel|G$*_o!vtC~(A#Wv z@G%~(=7e^?*`IEvjU@nYsNYO3gZoXzTe08#>LF4u0l(mu=!=J&lhcUTP*nkm{pMwq zIU_yZbp56u;~K_8bDV5zF|ZutObjdpry?RK93AR|Rjl!N-(EG)V|$KqZ47(y+mWicWNn+ihdMyF1NhYADf32X zlSb*e!e?lZcF38d`)E>DXGQt*gL@66)>mKLfu7sky~eDLtwN&+`jXsWa_AFinGGY7 z8nsEeTZW>gKBvdg$GsJW0+jHDZe1T;GaK!Y!LpuO8(fxtH%5DX*0k6Cb$i_xKe<`^ znP&SOn(ZRAuu?dio@(_S3s%mv|EqFt0y&>Iavr4RJV48Nppo;1a&j(3dK%VA^^sP! z45DhGc8Yq50^EBQ`lF(wPEqTe_m#jlP?p*A#brhDT5eg1dsGmA5yfjAgTBIz*HUYk zs3Y1tzkqCUEeP$~B5*DcTig_NG}qM8EL}%4bsZgS>gYw(Q7ooqi`F=X_4-n%j)GB# zQI*C0n*A;Sdfp7}nc`fIg`NkZF`R>eyoz%{y`D!r)4{Vq+Wap8J%?~trS{kd>>ykp zusQVplF|EYt#_&Qeu&Zg%g}o)wxxI2^RAt}wz1=)p|TweHns}_K`eE2Al^(^; zmPB>9?+5q^cOay+t~iI@P=rEay;u!?S2Jn_j@7VYcJ*_uC=BPh>0@>o;4@VMBpqn~ z%rU#r4d!fSUo)5esIli8N%{)=nxp)`H>>u*`9CuG2jT5R`F+t*ezVV#^Z#k`e~Ddm z$@worOkPHE{+7jbd!*BA(&WFy&p*oK|0y{?HH;|EF12l~hvMssw~}^gWaWm>d4?6g z1EhCR)Yq28_APk3no$Kf!V}q46x$cosfnrKIyuAW6fG*DPOUKm=a0q=Hz0q!1+(Iq zA;L1e*0YZ}1`C}=l!OKC;{!bwVk}RZ{CA|wU!seT((3}xFUj9|ac$on)#X@|zbakU zWTq3A!2A2`@aF73BWdBg%m!Yix1DI%CU)+^0%e~T%$0HkV#Pf^s^xV*%VJj|% z>*giMmRFA3-Xt82O-GH^<+h3Mh;eR>+y9~%yNvDUWF1|?<&Hw-=Od?G6FNr${-$i197)M#ZkDc0E50Ei#)OOB4@Jj)jJ;C9 zK0AtUs2ca(|2^EVEhyY4P>a=PVX#tq51zj|q>n%WT(uVKb( zs;U6x8Y{)6>Saog_kXaa$_NtIR6W*IKEF*YF@);5)~#ohgnG_q3gpk#T9aH9^}HK~ z9P3h!;`GunBaY5M9t^70{KLv~3i2$f=PnUnsO-BtQ1%ZcW!r213U^BT1aHVblgnWH zRJ@LT-b4E6Oz%yieG==_nJi`YNt{ZoITQ70?Jn+IUsLuaOSJN9?N`-$S0>){Si(*U z1(#WaMnjHqIH17@=M+H0A!Qvik5VFS0?+$<$^+1YGs0Z5l z<(x^UtHW7&r}M>mnZ3arO=qvXGs0CzM=wGeROEXP`f7U434Ql?8=}Z}+WDnd-=jtN zcj$GNsfW=SaW&>&dhY7)wGY=rwR`Ou*U{V3x{Z37Qzk6lWA#EI3})Vw>b|dBjM^N> zLOhSPQGPECqC{f9uf$nSTd1{EI$Q2s9SiXSSOzBi% zUD3t6xP$ja7cYnsNfO?dfR{tL)jGR1M`yen1@Ts#qq}&QaPYq3;ssG6Ny7VTTK!%W z#9M`a2RnFQckzNKktE@LBdvZv3gWFoze60nZvpSs)HmuqR3J(uHr}3Ozgv3t`!?l^ zc;Krr4>M~lYzrd`+IEjc-&=kS&#nI@9enQsAD`U_qC^rs8*v}Nx0Q$Qy#PM5#>x0L zT~hDusOs#-f`jh^7axccNfN#f)8IShB095(+J05|hC28@cJYBIktE^!Bn`gxO#N1c zZm9eiH^ANzL@B@!E7$iII{`BM4I`9Aw{xP$j=7cYns zNfO>~(&C+Mbn5m;RrsF~4&HBFydX*>NqD~l-c{%=tYL%?LVr}!e?Az*TZMlg>EQjr z#S5ZDl7#oiwEF%2sX!cBp$h#j<>37pc-g;$D3REBL;n32$`|pJ_3wWg-B#t_mv->| z=HdfUB8i?I`FFqn`8^H3K|?#x|19I+`vds6{{c}V@$vcn&z}K&CH>D-gRd(8xvYb4 zo{JAei6jZ%-)Zpe*b#ioIruu!nQNB*K$J+5@MS4q#1q+HiT)1m2)$ zB+;{Be}l-cZ0(FMXiuQ>AhZXqmI|1!vrTz8au&o%dA8{Y!c>RYMmgG%r_R+kh>F9O zCp2EFPowYW)9D*$+V4mBwoy9Ms{=Yj#F>>k?+T(-fs$FNdTI0nJ-A-IG~#eDQ~!us<+}$$BN9gvr`CRN-iMRiz5}%wbgm*XsaXGY1^4al2#V z<(<0j?AA4i5=l~BH>auVL9N<%R^^+(0emI%vb_wx zs`~Bm4!+(lJ`g36Bz%3+;5(%w_$D~``T-x0+d-5_YY?z9u^QS{(Xf zn*dQFvGo3!pQ7*fz!^u!$X^SKB5g57$1^wTXQ6uA-o9;u88|RkBU&WNcz{ zU|t+HabX#oSkaMjN$_tQ+XRRbi7g{+VrSnbE;2Szh=eV*iCvVu9khvqpc~&N0;)-2 z6T1?Q_ScL}9HDLEaAOm%!zN;Vg=}IaM_;Y3zCe^ne0`N|L&N_|`g&`@>1#LW>kXr? zqqM$`H2Qiopf8Nya1Nbq-)b~7c|`LJT8={SP8@zUH&BOc-m%XcGnU&m-U}%Emd6l^ z!6SMNk#yV>eWvrB2+ZKwpjala-tF<2cal?w%b*TIlBc4!$wKSB!lIh!Tm7ZxGd4o9{ECInY=t zz?%czsp924Us3k^4%~HI0dewb#nTSmitWh$z60CC6i1%%kmm-9)6o4Qh!Tk{PYcQ8 z={r}PzzT;wj3=Iu99C=)1Ai+F+>beP`=?bL+!KNO{unoi5{Zo)arr*(+Tw~aaNu4i z#%;Zl#Th&C=a}-*=c)LXHMGf$tXv1HttIz!mPwH1idYs9B@$bfU>&R+i=y5! zm8}DgZ{a#9gn?JCgQ*VgDZtIP1ENHdh>2l2AW9^*ETOUdhLkV#-e8-&Ho1#P9g)6~bTLf<)Ow~0DQXk*sGfLur?)BNfjIgc z^JM&DZiMk1%0hh97r-UgAub(z)qAOu*em)5s-8)e%dh}A^rttk*ER^>Vv;6$WsY2jqZ>s$6zfHVBjC1RvIkL7g6ywKjt_zz=S#RJC)mw5ITyKikskgI8 zNljKfR`~qjYU7sFb5!;28E--_6Sw5CCdDnmSO2#$=a;5xt`uv(mtct}U);Nl&)>a8^-&CSMJS)z znA=Cak*^RN2AjZpa^)J7!ru&B&yjr}$UYHTBudZ;?=Q>s{Z1Vtn7SKHW>}TfiIgEy-oDZ&AFCZ}IztgqUzuKw_Vu zW5PY&bbW%~2E%w#wn0Wvp$+F+C*d`j6p?Yp`>lqLA>v@AJ>KVMDdQL8b>sj$S z_3ZoO3THr*Nm%PAl|I-c)pOGIAs%ZQe~d#G?S8K;<_>?4g(t-fZ;9UZm3tPC)s;m1 zD*nz?s4pxlM^)eWVi<{ip~vbXj^0^w+%Yiw?J$fvWjo~OS7?WNAnCEDYKOpk9odS# zcc3iZ=o@x=H=DIk6?_Gsvlglt+Ai@&)ykaG>9Gc-i1g0ibaeal4apC1pMIR%r-LYw z*!>#joqI<8+NHWrKfZFG&OqnCPv^4cyHDT9k^LkkdmJkaqC{fLj`OAWa%Hdfd}+p? z;(X~gF%`bQ(e?c(!uS0f)4jBPJa|LCKe-I{{fgJ|{r8Y=?EM@w&&Qwsx40I>eh&3) z)gL79=kRztu%E-)2f&3bK7x)6rm@BjGzN@c7FCX8g#TEBbQD^1FT0&c@*{uwLmd~7 z8E3_J2Y3$VtY%L=7x3GkQ~+VVvhtjDesTT<)#TO8xFXIraR6+)$+d03^=*5TDr_6P zA=^$agKb;!#3>W<7oF@5pUhOO0Jl0^Zs>ffvpRG+?1zYay+A>P=ZF$owY#F>ETTU*6ZCUZUwmd|AC?;sj znl!(*te%<9mOa)qw(O7B%VJ&t<8_9YI9~TyT}jf6*UQRL)p(s@B(_P9)kPeQ8!M03 z!Z6K^M>ch9w%Q8Y$a81F`+FVFk=t2%exeg~m&q+H7eZ^*|b zm%%x>LB^*ZAZu)i*@{h=7&{x+w3+Wv+tOG~%jH(u0dZFGpC zZ-4rr9qHxou>GlWQraJQL-v`Go*@FMwNKZkjL5q``d!_!S?rr zJ0}KFBC+icbK)71{avo?ui7~=!%j6P-jb|qZdcbHQ3TtgI@?ulN%yopo))mj{y5k* zY>(J^N8cRs@^{!CRXHi`5xgOLOfG}%QSmzV=#T%G#5d$i=H}JTS=4isVg3~_Rh4 zy!;*Z1*)8sz5u+e1Dw}aqjZy82J1`l#`=Qo`@W#Uw^^!qN28vje8IUBqcc{@_yUi$ zI$y9I>4bg3C$295Q6k~?rhP$s)ZVVtzM#yv<{4Rse8Kh(w$EK`AW9@j*vfpXg|S8F z)>pMZYzGJ1m%zr~>i|(AVQl()9s4+XtLUfxufNy9`k2q}b+m~t%aMQT9{Z4^@wsIb zul>`9q^nZ@v?I~EZE}0VecL~&vU|j3EB^!@?eDlv?}U6Q{Q`LT+4Me2&*QQ)ca8|~ zrHo0H9s2t^EZeTguVmXx%hoTeg%hjNcZ&rMvn!khfMC=s zYT22%F5C*?hqZ|(6jcVI%}@&LY-)KA`$&$&i>h;@ZVPgQ ze}C}5Z}^Wh{2zdS32d^uh9rvX3H%3u|3kxnyy5={{DZ-Nt=L?oK53iG!&iYcB$b5{c~-ds00frS;NMxDkrU7w3^rWFGz9 zYift^`Fo%Y-!B4?cfO(eIvp^X^%m>~>dOn#Ft!FSsm~maWsT}5ZqB7=XfO)4FGl&w2kNG$c zb2fna5RG{slo7;yHZWfwV+Lb{8P|n5%}|K&THECUPI+&>gelH6lzgVpN<+z78i|Q4yJON@va~{b3Z&MmWy~X zeo^i8PT0@B_jfXN0mhnw`V0dC_O9%j$-X(SE57crB9(k7{*J^3YhB?sk~>pF0GbP%W5qwP;wSQlfU3!ayND3P!(^t>dcE^52vin%iCP~*8PSsw@BS>^R{ zXsiz~8hzksm5@H@YbUt9S+0G2q@udsFYB9|Z&u59BgLW2M8y$S*DoGOxmb7Op}QF{ z2jycxlt@^2y1ky@*ipV%OZk{b`OVx3?H5ZTCWu>EQEkuL{hBnz$!SCzB< znM7sG6M>ocIe{pVFrJzW;>}L3L(ZZJl; zaa}l@aQD)2JkdCeZFLrLF!o8n&S#i_D3RFM(RZHYVXq75`*eJ-GdokFj3DmEpzljR zjBtZ7!j0>~wdM4E2vHgH6ky&z_B9|%BtGVoJGz|3|HqD10j_U*bMfZ5pfVJIVr`JeE8Y}a6nFyp$sT^~+V#=M4$ z8AORB33Fq4%txS%Am*=K%wUW#+Tu|tCy0BY zQKV~bi(rg!_m^fek2cg@`bC(;5)Zw>S^vjiprSV+nxJkN@C{zm^+<9 zZLs|hGk3aB&z&wZbEiKscPcX%J{9@?GWjmn`7XgvZq}vvshxG1DP>-u6y3+*`KO_r zzfC!p>vFCzIWrH2pO1W}BVQ+CXv}A4U8(b3W%6Y!Jcb&Vn(*VW{^P3ODaF&UdHD*S$i%3y`me z$#<8|cely6aD{vqB41CF?;f4+UX!mSn9p7#IF=es+BE|32G1} zi#39q%C8aZ1(#T6-E=c*`AO@hz@vQ+ubbkYvqpd$71jva2}7kd0%R|o^!x;6CMu3> zz}4N!l#6vY3%c7g?xR7JNLY6@h*{5=_GRoSpDS(z4Pk9xf9LWM-9Mj#{INbv|IGF= zffnKQS^^l8`e*Ru^~BYipPot-mSHwz*e#X;M2RF(hK++VoQC{C8D6}f#?E7ok7NL& zC&Tj5%rY8dfF~@&=|o`}4tMJTM2RF(hE0MpoPqp78NPxHTn}LMWGERYfhR1(nM7e3 zj)DyAlR%V6Y#I8IEnVXIBt5gEMUqWfmNw#hP}|g5C?}T1_Bjm?kSqvO)iwo2^I2d^ zq~MweSWVN3-L2P7&L$R??O3;dK$J*q*@Eq4GnR>7#Ai%9IS2V;ne28VF^=W>0iz{M za2yMsaQ&Q16qexxw|+pBNNgD@*3Wd7#j2n4P);n1T|cKm7Oo#KrmP>ZCe+XQ#KN+j z4B2*$*BC*RNNm}H^|Lw4WYy0F$REpO*Utm6xmPLCHU~zpekS@p06gLPxsWIaaS%5V|#2W5C4GEDw5XJi1QC&LQ94B!dNa4}I>hBF}p_a`7qB#AO? z8I<7?und2Bi85>zl;JYu56V#YAjxn{ zdt^&s^kkUe*8_OMGF(m+mf?K29zc{x5@pyrD8m)VAC#f>A*UX|=*du058w&Qa3xV# zhKnEr_a`7qB(@9{{na)si{-DbLOHQ4w!gZ@^;cj_>94@*`74ToqvGcFbC(k^d!gk7 z)z@HNektZzz05r8K0VL6-^{am2j^M(jM~ePuaC+1fX?@z$=5fS&z_%MO(@dN&%hg; zpIs9X-1(U*yJUWLx$g4|x0IisT}ic7ZhrOwsWNGP20Xf6d47g_&io8FD$LKWBMg=1 zXUHB87~FC7wM1guz0tK@5G4}dcCU!WLbvMqS>ZPN#S5cL*>-7}H5xZuhjL=uHT@Dm zi7un5uPsob`z0{C?J#(fa>>ggxshh-QvmzqD11$ccm}i?MA-Kg7VElIYIe0 zhkX0R@`14<@*!U&Uz@m&%A320+d^T#ejL~hbT4gt0dKIq+!ztu_M*xzX)jlq_JSjl zb!qS!P8`@Bq``9SnD!E#2YWjeV9tZZoD^+_;`s3X=4O-?+m!M5049bEsGlL` z#Wn>-&!)W7V@sL~vg8Zrr+l|-`??+F#`Z<8 z*YQpQAhmt%2eqk~Lok{Tm*VV^_#Ji0cS~b4i(Xj=-s+>UI%RpCjWX&DzBch7OmH#R z1Yr_1@Iar1n6&Fi=JtMO{P2(&IP@|NCfF>pm$BKqh{QJgCTy1DVL_BgY@5YC8l#t% z!rf3zzW6-li{eSFc-Xs=z5~@nsl5HFJ z(9N{A0baHZwy)$e79!be(e9+;jqL?{C@74(nlmm{0W{}tRAIsTKtVc)V{5w8l^eq_!kox2-J|RH6UrCyKwj%S5ysblpgxmz z9rAmrzkhk3gYPrf20@faqGv~Yxo+_AeQs>f+snn+I<$Y|eh1qZz{cwfAW9@QHmvh_ z*mA`$H8@}!OY~!5L-tu`SXtw5%`@gvWdC$G@*Bz*@kDh!PGQ!Duk3bpU?W>xubR4k(82dD@Ubm|D3L_ZMqP(&(ca4p zTgMsBdvwQmYhFG}$Fgu}bJWi5Jpd0m7=8o>{vH~L5{ZprWh(zBM@Qw~W&K3ubw;cm z^~G_lUDP{LInXE8`cBRfUh`7MHU+F0Z$Vz*&^{E)XQ}&+%jg@=bw#u+8fm__hzh6c zk?WQV1k`2TX&9#Mq&_ohh0G%KxOmQgGs)3D!1TS3=(+pDrVCyKU9cM#uJUob)5DJL zeueIMZzG5j3F}VpZA_^o!V>9utDRWS)K)ULK+gk>o}bWqeiT2sS&!kTcGlxY>w^MX*Y(AEf5g%IAJ9AZ z(;!MDtarU{#q&eOKPeyjY3R|~@5=t>n>KwOlHm7_*8Zj8Ba zL)|QD>gFk3H&2?{SPZq{ZoQzzv=$nN42j1fYC9OTh6BOjjLdkXiOSBY@xfz6jC_y1 z?+W*e&bYzqM-@@|*619DgmbwJuq9()YA+dz@#lMw#HV-w5wFr$r@o{z1a|8>)Dvsl@X)Jl0g_AHe?Zp}M3^e%yW*X^F<j(>vMC6D8~W1PdWnIK9ewx8`wy16~_v-j$8d=JWJ$7aITt@8}I z20qwO_XXRL*GPGup^NuP2X9Z{x#b-m-ZE!2FwPE*>z{J4^#(Q`$ABo2 zFg87oxzoW`aqsj0;*18?$pSf};U}`{xrMlIQJo$hfxe|it;^6{hvvdh(>;BTLSZb< z_}N8I2;y^8a+yI?ulk?QTvObYxHB1b;<_2L(x#REQGadE@zrxu_F>=+^_^+3z2dMRxEEjP#4$AGJcF>mr5AMMufQ^RymZM9qQT>9;)qWDCxFY+0#E_dpbec)0(iS z?ite$st?1*w&k2zrUjH<{tlnZp~^{VZ{Q8tTXGp}Z;CgzH+2xo4-aDuqRwUX>spht zg$r)Um+Uv;pi4j&h`&V18$6Mw2sZBfy z8y@D`Fv|4D+y8_Or?egLhHNLf47MG`8{1CEH-z<{(q2^Y>FmX0O=T}_B0G-s+Un{R zB|)$Hoxxq0vn_7sY)_lX+7hKxXYgZ=cQ^P48~%UjIo>}_wjrh2)N{sBzI%{wNt5px zo$p!vDdz=~Wf-!&LjJ69m3?ji@ZJahR>MCRPpX;q zqRBQK+1xoP;kEn5XR5F_@Up$pTp&6tFilAq4pPk0gYj*tOe8f16g z5l_ZYvrNqUB&zVj?&Ps5ydwr4c5V8s5ZrU#jo?OwcO$D2hDz^`lSb1%Tv|d^Y_v!KW@|2HxoV}FKqm1b&(mF2$fW)q(9c#}S7^C+i zxGukc>jk1R=5>LY$J`)FB#cL|6PdbM2W=4+LP?g*YDW!`h5vy1o2M8o=@J>2gV35uFLE9Wuh|XjewcgjzN@2 zY|L0Ye$cUr@@vQAsJu#R$9VUP_0L}TR(W>jD|lWkpLzGI>_^ErorKiye!-Y>KLl9o z^tLqY*DkZbT;HRX-bUBbvX@ty(@IxH6Q&7^C)qYqJlt!9Ht<+x45o!PvI~c3uw#Q6jOi zV?Fp`7kjR_0%bHzz>R&Fy&Dzow@^lmn}#rmc~H0yhTmLe*?MF5V02?@+Dl?u!ILjs z7wyCJ?D=h?vMk#|7Ji=wqC{fL0w48=D@&!bQQkoru`G5ScxR)4F{%Sxmp>cjU7|AP z9e|n7MgdVG@i9N@VXkmC%6ljyh}kcjQ=&5FA~17YHi#05 zjT!Hbo^&vm?{ib0jq(|u6U$}d_>|A_&PD-a%Dxt?iCgI0e&KVcjTcR>%3Cw&p z3WySkkNGLb*W`;8&PMqTWdt#MXQO~I!i?+kXQO;iRK|R$Yu6x3BtB+;9#!FNlpjz= z5VLnS3K%2IxGrzkKN6KOAK_vKQ6fpgT;Xh#pHM~+vv)QM7$eNME|2+VqB7>AftlMP zh!Tm7In)*t&PMqKtO$h2<|$V zD!XJI>}lQh3-^~_2Rn(>U2Yxh#uV#dz@v4GC4RjQhI`IB7;aQp2RofGR9Xi^_A={W ze-Mdn=WN&xuPK2jk=V9__qawcErkd4I@pPnFR-TcC-TR3WBN>h5np01$7kk(F|v1D z$1%e7s(WA##tT@B{U`XBGW;*=wb)lo zwxvt6(Ky3ii~Wlpp4JAz8??cB5y7=VRd$IDK4WYU+ndU)#a>*&23H{sCauK+k8gvx z=hz@_RItG-5^NCJ%h=%GL}DAf#E>;jFk|eC>hp}dn-)}Dps~1xb#t18}!&qyG!dPzvR-RjdD3RD$ zvFG(!ZEr@exfTi%(EA22(4etiLu>odzQG*Ii7}hLL1Avk9^~_HkJg#M==Kf%S1{wv zDUoQ%5^bsT#{0EIV%ctSWdl(nv1P-&@i|Yna%XC$JhLW`=ftv`d83luJF^CiDd&w~ zO`QI?bDuiO!n(K}y5M;uh!P3wLeCph>Y|!6YwGc=^7`O;BN!L-yb)z4DvoTx)m;PS zV%^;Z-SHj(5G4}Uoj$Y1^F8IxtZ794SRZ!VQ1&q)KC=dlZrdn5Qw}^)V{m0?A_~iJ zFJ#~|Ye1Ap5@iUVS<@N$gEDw$)_~EIq2$aO@PuV(CJM{&fLjkBN+gLggwL$$g8V@l zyfbUS=*dtreg#ihhOR_m86JiV>~BGoNNgG4Z=d&kQo@-v3!$7?7Tf1|XV!o*Q6jNr!(N$^b`n0braSV-GTH6KJF^CiN%aGsaQ*Zk3d``M zTR$L5B(@9{>nD6>&B7=rmc_0g@5~x7rmP>ZCe%+)Vqw|-0onM>8W1HCTee{RgwL#L zLH<}KyMDYgYryE$Psy1z;0f1HFQTvv&q4+ovzvGFAW9^OGK9~p>5cqB8N4%V!05?P za%K&9!ZP$B3d`_<+fG1~ND^fTpIOrv`GYceXV!qxlcB_qfhR0OKccV^MUX!zgLh^P7(E$E z>H$1q83q!CWq1QJaDM`#L}JTO(O-qntQmxIVp(i|<(*jr#+3dFte(GW6MJDQznnXj z$BZ|MGbm7h@dElnxdLS`?nbL2;vC9TobH5(K18!UB{If9p*)LDD4(ZIoKDoaqg)ht z-moFr!rP=_eEA7uM0?IZ5qMI@`+=9|{JeIRTn5McDc*P;0P%ij5vC?NzU#Z{`@*&SOn(bKj!Pjd9x?3h~?AN>#Ku@N%28;z=h(1a}Qnl^wS)_~>TR?_52{DLh<$ z4fA_)zU9`@d##YXh6y~nALDg&+;i42aihW-<}ZYy(mFb_M-!wru`;2WJ1$nYdT#;o zOWs?oOgGc^AK+zubN`WC2KzY08`nW7Ui?mc!Z$*q^D2R~|5Nf2PM8Y<~V; z5_fH5GUpw5K<>!jE*vm0Y?Nzk){IdA>w(9+M*x_H{>u8Cr;0bWQ?)1N&HG@OYEO*se>F)j4Lc3J z%$O&n{4eTm4%MAKPAiMKcI*+vNQpgn|KrTyn_AMOW7pr7J684x8ByPraw%&Sp9^_cDlN9u0MKck1?txu+f zbGNEGqh~D#+tR>xL%ePdqC{e2Yawi}x!7{WWhkRzLSKOQ<#*znZ~i!R6B@(nGkO^J zEa1+oBIJ{f=*;W-NRk8GP+zR~6M+WZ>mJDIiKDHeR%scRajP0{XnDi-)ykF>Q}WSEJ7j z9DJ*~`UFuTvGIlUIkk*F-}Uv`V?~Y8)#nrG^|_&gcXi<9{W2g*BsN~?^F2?WYXtOp ziLcL5MxO^&(|$H`@T~=W{Qd_-iNwYSpZ&grul(MawW++&ce!A{G>FK24-}&&}&ITkaUr(BUw-NBMe+5w@iJp!AGvp68rhFC7v|` z|GJrjcT?cyJuM(gBsO07gAbhcmM?A=(C2XM>9+fVIYys2)UZN-8ucZU{r+x$lSX^fGCmJvWDtrOVrIO{9WI&c<&1O>MHPV?%>@TczN#*h!Tm7 z7j^TYS2x=P>gEGA#Q>TyURCphEgft-0voqO5G4{DTd1ygqI{|9dKrV!ZHHCV^;QnvU4WPU8i*2!jTd$8 z`?XyuU&K?^uYJ@JzqYl5ug%2=qC^rsJDL~x_;yc&uk+%%zN_-P+c^041U{~B5G4{D zU#PzKqI{|R?pTA-t?w%Q?zRrz8NhoD`87Qc1W_Wf@nX>Mk<+#*PW^t2{PK0R#l5Kn z{SE==3LLBETGm24oiiK!Voki-o-aLI*lL3N!o1yAF7dd1^DRQ-_U#<`+9BVz@jMqq ziNuy~Fya2#mruJ5K79@KCY@DpQjeGzJr?PdnYLa?#_b&$_j6?gQ6lkW{KS`0c?ptn|MD`94xAgD zM#e2Bsd{r|#Pd?ixPv3(fv$`oN+h<7Q%P^1dNR(vg>+fi9tN;IRpLJ1QT5@oOb5jx zTL+A9NgNqIU>xmg(OtJiG5)&kPINErdl>MB)@_r^Scqh-RXS9>71wR+ zAE~%*s|whXEJ|&uD|Z&9UbpplJGO2c#uKgEPNz=`I%esfMac-hoKrS@#|NueJFsrM zGu02T+a3-3q90_3HjGu96642&9o%ODH;+X@lt^sc7>j=4;x3*|`9gD#FTt0QjB#J1TX!t_ zRQff+JsiB}0`Io*SPevp#Kw!U+E)%K(S=VzebLG57_zGH{%{4Yd$|*m%6Mlu zc&`Lr-Y*EEM3RX2Dy?Dok+OLCT_Njt)Dl(dcW(#pHLiX^lt>csUYi0hk1rYTX4T>q z4&Lj5m&Y6+N+dR3j5)q>ZCHOJ5SBcLabrGlzFwCv33hSE{tSOVz>nAE8{@J4J2a__ z)|Y7=zLARd*5TV7Ic{|I4x&V2%MrBen;3stI|=Fi?rQbEkAwFXSMMN7BsSiPdcT!% zcSP^6by)BFI&$3Z$^oK8;>+=G-+rR?f;(7_`5Cjem%7DxO&~mG-OrKZF37=q53>YR9Gr zIM^NlHr^WvqC{e23+nR06uO*E>)yUD$5*S%10B2%126aEAW9^OcppiDH{?4uuNLn? z4&KLrm-jq^D3K)MeLMx;lLNN8Uou|wv-8t_|IqFCR(g8$Nsff}JJZq0Q_uac%b0v2j6Wt!xG4-C<@6ZP2 zY`UlS(N3fs-agu)Ia=$-r&ip(t|||`N=Wl9Iq-(oK9kGfwNJ&n89h%G!|2&PgyL|CI%2(k%mI9#GP9MnXJv#2%K^5<@4s-B+0K6PO z0HQ=<FM9+@mF?@Y~ z0(}PF`43U=*|gCqecop z{U}BU`uatc?W}uehu3Gzd?QflZ6~TZaSuVr7wHX_^_mgWl;{;)v~IEPv<36L!K+pG zyf$$*<(NCk^{v3~zau(|?xlT41m2LJOfG}{q~eYJB{qYK+zm24_~^GpeTr{Jksrs7*YBdS2PBXOyJtxrua} zQ}5=EcIuAn1NVz@eVFnl$K_GwG|mPO%G2M|8>h-U2Km;YF}SE(otk6u9=fCeu=ty2 zxy&GXw*DtQ=9=QY*5EyAEBrk@`@4OdwTF7nF6o}5n5+42pL$Np@d9{5?I5`f*1O`h z^gfuRn>!`eyV~0d9>2XF3%#er3EmLS>2ZoU!#8Z89mPGte3C-`37U_(6>B~cd&JFv4JR& zBw_2Cgzd;fbnIwVadjs+*t!85&xJsgNNjB5NpHV7dMh8F-5r<_3PNY{#NV19rel4` zuu{fnv-%&zYl3)=QGI-ND?Rgf!rp$dIXidoopc&P&8#KpCzGF-za)5euDzG|L`Ppe zp)Zc>22mnmed)OFl=?zkcS{+SDVsdh*V+8Xb+d9`t3tViBU*R2Wb7aeydvafUGTmgq%f1x%xvzyU9ZNV8-sh=I%72>o zV>?`*%hzTkDNiWceciTjgN== zk(9AGs(7WP#8@1UHPtu^b#)KnrH(Ehr-t#8lZ(y=QsF}#`Bo?+TzO&?SXAy?>mF~F z-wKW7N>vYzT=t0%PFPfZ6m(ktTkDMZ{>u}-weGP7D~swyw}Z;xS`XJ3+1GzTuI(^Z zt@N#RmP@gwmCGIPoJ#GI$2-H7UnJ+C3n}{ z{WJ&fQozgW!5~T`HeQU+{_^k+fS)kqhee65|4GK#q4C-24z^`oY#>S`N!SJ@Ve8QN z><28a>~W7Fe}d5+#_e0CqT6KjR!eI2ih@y3#XZ4J?eQQ#v~?2kA4tANP) zA8&A7eT5@m$_(Zf2MUhh1s;FA(I#HUylHCO->G>Mir4eip_FH86V{N=qI-J2+Pntl zt7~E&8E-fmL9YrU{qHljgJG=d@Py9L1dU z9Q#a31u^9~0=%JdL~nYUlTE{Ok#Iyn2~KE%mh7V|9;3GHqsXX6wUwjq9xR7)iY@#`1d<7{?gc zT=*PLAF^WgAjg>ZJdH8WNsD;_oJqx!?3-Q^#p+6;{Z+X$sm`YM!2S2?@asJ922mo3 z{1VnH@DB3t$ge+#{+r$lJWs!PFTDm8VB+qoe+S7D-vNo;Fg#NqoidYyG2Q1la;yb8 zX2jzV5G4{@j-Dh(rVsh$Y)wl+$&s&g{sn{U(D@hVI{4NFKAt~pDl{h@KxNNe&F%j1WHTq_x!QSj zGwpm2ydgiGTn77T#aq!&*F&A<*9}zxDgCs^o6b-BKCl9wDtsVAnTBew6_B!xdA#Y`m_HV(fTz+}h@YJ}7V=oVMy363<*`r&j8*sn#?iD^ zf*8fUyw6o0wh_#p+5@c`S4hwFmZRZSVuUHUOeTV*3HC4b(<{;6?be zd~rDJy>xAWMd;Alz{L)>JzZZ5qC{e2gRjjy*l3*glJT{B&5y5TQT9e{R5eb!#F1kL z9vG)NF<7kd2bPQa!-$3x7=`bc8|B5&|t48Y_*f#6Wk_lBdyL|!}axegzxJwrF&_8 zJ$OUDKDi9`^@_KmuMe+p#`9iPKuTZl@uu_j{&=bao+|t(LwP&N`*^Ib_emO0T}E}p z{%5A^e?XK-xNYcn$MsR$cv<_OGHa8JtV90iatE7q{SSx|iH!~Zr@_HS{^u3re-4=+ z|HGm*uU)PGxx$g-P*=wwN+h-%@bSKm%dD|7unw)UUg=;v0@!$s6-0@IvFSC|Mo-5T zeB=N18Y}B#zSmf%QBBWX)Aflc-uH=D(Y>@j5xgOvm|O3qZKXM#$C~7WLhs+gnB(_U`h{Yn`~I!`;V9ATxP1E-v?Qaq!!XFE$2u8# zO1?Xy*XcagwC|}Pm;ZjZtX%5*F9~NYFpk9cyB=#0vL1`JX0|?7?-vB#>&VyG??KDr ztsQ$9vDOqcWa~hl@O#j9-aE?BZa*vG#iz#_lp^ZWMrQWDnB{nZz}fGq!*Zzi)K{|{ zwfYrc#(KHa++Z0^L-bmg#cAmMvc9?bW_3a9+8;fHYAxm7UbB>nx8mDtU1y^+$2@>| zVEt~YIvXq5YU)&&WH1$CHT`CxScA0_vN1n~phDf8s_I5T?nn#)3$yCz$Y&+jg5s@M z3z5x@&WNjZJ-F*qSCe1oanu>;N3V$I7$8a{+>h!t?WU+7eN~O4a>X+#qZOQw_BoXl zayHHjvfoG0xlrvFQ~ADQdr=Qg5F*Y8K^>Ok2<=FYPMJw7>vs&%8f<66(tfpBgI!9m z!HzU*u-9M>b{OqADZGZkl!|tB<-f*}{~XA_ZM+r^qC{fLk68a^M}8WsU7y!$`sYS^ zD2??$SD&4fU&lM7#@#>7cFjuZ|%?Vjq(v? zbf2qLqLk6Tj-f*=URUVziyz89$xD55dXNiL- zk#K$JvsxE&>^on)9A;z1ieqmOVWqZhdEsB7H=27^b(Z+`4!$dakJphvlt`jyM=`+N zJbYJCzQ8&X*J;mnHMXkaZ09)Gt^u}i>=6Y(FY5}CazP9jw4TU{6^r&skbgRYM2kicM`t5=8&7PrL;WKP< zbqAN$C?Fb5hWq>Fpp<%bI$Lx18gn|^tMu3&x%UP~ksQ=J)byzBR!fUAb-BXl^teo2 zVFC_oqf^?t(VRlJfv%a2cF4drDnGI;{Vq&6+ix&-JXYKB^4gBa7z4f$2HXnw{Ce!3 zRerRgI@p)I!Ks5esDmBiIsj2|a2@0_TT|YiejSW~nrd}jbnZgIHG#@#rpjn2-VoJB zk6c3}dP75(oUV^NhU*Nzrv-I(lc}>6be)aUbv7P9wX-Ies=GNp)8<~{jX!WfLd4UO4%n?~mCF1TvBJ7uEy+o;d$1-WlAa<8c6o@gY! z6_U~nqOou|Mkj$W#7&Nzw?ocp6osVMX+e}o66L%jg`AnDS~Q6E9q4svC&a~a zcvg3GCe)HLR4wYq?Q`KVhUyD_-C^`KS?gvG*ulu1dK8FNEiNw|y-j$Zv z{{t!Pg3lr0KJSL~cF_-V-eu%mMawzG$a#07oVPl1J`6eej1Ukdl0-QlNg*en5yEml zmR?Rep0->2Jx0!{TFzCCocAWmd7C5WQT{s|`JZ*=2T>yNqH;q9oztu=Z$8)$vA^$^0{_;PL%&nNB+5x|An~U22mohrjPs2}c)_SH29!C{a9^c>X)WI9510LUlD3Nd-%=h^I z&8Rm1KONuCOH*kb9p5j3I(x#@*~YrgHqdppA%1FSZDgwM$xzjKOm_UJvX=KJX}f11UQ%U-u~C ziO22HyDNKN=)Dg94}hQNCm>2BHvXWW`%nvjacWsV7n+|u2D#GtxxuKnr%b(Vs_ShN zQ&Uf)reZlYT6c}}K1a?^AScgHK$J)l<@_{-oT2&2yXoZ|0y+O-5IUlql!Jj-0&KiRHS{Ic_tR>=Rdk$(p*|Mo`y zR}$ra#F76`SAGyB5?}tZ^OL_={*KH~CLK^~`LT5Kli`s6RU`jSTK*l4{I4a-|EME> z2K_wGPe7DNZ25zJs}p5RT2~CsPcAI2=yL0dBOvGNM$TQdoI4vi-$<16F-OiEl)bnV` zQlBk|aiJgQv|wT_)pOFtIeDxdiE|2LUXXE43^Fm!$zu%$bdVkDcIloo;K!hpl`Bo0 z6XQsXbMjb&kTu@QaZY9Nc0A6Bp(VySd8|PxSnqb6(|@}SoEx9LQCFmQfQ_BA@fW9b z5D-IGtZCYSzlSxfdx}r&@V*V67&5%y;gBmuEqbi3B-(~}4=emnbvB<6cg0UnjJxt! zgVqwVc|Yzdtat0|mJY{VF~a1yE01@+;;x>ceum?&dZTaWxC{^_lBj<~zluG$BWXOL z*4W=raaYAYlrQ2zJzH@Z47NjY8BaR+`nh8d5G9i6*->1^QXank;jsr}>rhQ87Sq4+VRjhX}gYxGio`sdN_=e;+{q^q0>GZG#63?@G z(o|YU*Skld&fYe4wwJE6-F2PqfuGu0dzz|yCscLbdiOI<-3>?G@p>_c5((Fxj%V?F zVy-xXGA7MCL&Jh9;#o#R?stvcGql`ABk6mPwBma4vyPlgLrz{V22mnOlyjLBa`JjH zTSOJ{EXzaA_l=xF%el9a^Mgb=pL66K1vz;g2}Fs+mJ{p6W4yLlW)D$uG{m3p^IM~V7+-qF`s=!@5jL6k^rePP|D#Qw*nunS%%|~SB#CmaoI*}sFJ?Kbh-aAqIX^dY9;D?w(8&3(L^)q{e8rJ-J;=%9dk`fOTh0!R@7Je-|0m=7 z=^Onw$M-8k_um@bAFg$OD1LIY4l`Bo9jc)6`2JO=4mLs^@c14?iG=H5zQ^|)N44?) z>G=MmG?muT@%?1f+4rW-j@ET{gs!tA@l!kNC{uMmgsRRP-@oS6-Dapee%}J3M8b8a z<5|4%O>sKq3&gXqKj>gQ%Td4+kK3bn6m~qz>kj@c!O!y(5G4{Df6&iur3FYC&%$z5 z5zjIO_4cEww_|m^9b;v%KNRxh>@6`3Z;;Nur$FrI0f;KdB;~WfjQz zvyt<7E$4AY&R-JceAAJ0N65+J77!&8Th40cCp$s>1vo!h5b-RlLSMfceVwTFb%N2? zZ;ASP%hA`a&==27K$J*qeFg1*w-j~}nx9k=&oUKq{%+(vS<88nk@G)^a=z`zxd-Ir z`3Z;;Nur#4rjRo&Uqe!8N{A#}pqr*bWCaK2HcliG;D~^Mq2a1^zG2Y-fGU_jy7m zZ%lDNYrAnjC?0V?dbAtG{phpXKO&lr``P|XIyS|N`$;~#-OFE9+>d>xI+t@#Kg1tZ zJiFavuI5a2l{IC25qP7qyB%MYTn5J%DPAYO$bY|oXYd@Q|3}?-2S`;U{|~z}v%A28 z3rG-DM9~!x6DlUmIbcE&bJjHsE=G_Rb2>BTc&0PwtYtjVzH?dcdBwRP-70tZAe>KIm zdv{MFUVEm+Ku*8Ahx>7cHuRj7yL-H%K`qM9w8;GN0ktdd=bw)J!F@QG3WW1VeGX&w z^(mj~HO7BqKR@}KTr-jLoU!`C(FY$eMH*(j`2 z8(N=!Bg%RAkiE*kb5pw93w-;L8!zXj+y}twtwi3Pl=Hm1W=Ggq4(Gg2h2H;w-aJ+W zQ-QGFCg)|;8#(XF1l9eV*Hw4&vXQo|!bqt(?=xYit6?Y3d0;9Kwv)+uzRo=`uLy>9Qi{;Y_4EW(t4DwJXnKYYaLc zrk=<4iY5%9g6FaQvz}qSy5g)SgG@i`>6NYWtS55RqSRh{_NVb(PO-3Yi%}AycP*}? zcUk#!R(H7hA}7_hqr&DI;sJ z-PZ!&1Hd<#4#k^0iNI7KKE6#n+dUY-M{7^gr>pqJ58lt-s}DU-?`QX;%jc)u0e@Sr z8%=&j=IBx_Y2*J09Ug`b8^`_$rUG$wScT+oDs)JmQ$0fR+{^FvoXTE)PjcYPl>F@d z_bGELcBk7e(ce4XfRKi+wfCl1P4QS`%nIgCd)NSXm~2LROesWbZReS_wsWJkwj$Qr zV%r%DNZWlQZ1*^9$KMVBQ-QGU%(nwF+74rsCn}i_wsXE6&{cCYHu6(d8ky{A$8`4F z0k9YDJevSJH$-;6$k_RO{K-$h0DlV8FO00-7_hqW6X)DLV|-{n6Svo==RCy4&FCvA zF6KmB90fl=hu)Agabff7uYMo!epJU$I&_?pS5e32IyU|+_D3BH;GpuANa8y7Y#rOw zd-46>sE*I^WyQ+58+B|E)iD5d3`ZSTmDO<}?r3oP#s0&h9G9(*iBTN`QOAO)rUwmPKKGN7D64@h&r;byRb`a1PBeKo2hl_CX3p>g+7UJO=*h!_3y@C zFOEF4J3Q3eJ4d_Df^U$sQj@Dtiu}XIp}S6kINS<)^@#Mk+~{=){^X}$ia&+vmql9k z3~0%5Sk^zyjN1L$Y;kD&r@7GXagOB}!C0)>?*l(VJ}Mj6=@WBF<2vLY#LFuB`+$EI z2cy1i5ch-1;=XJ=b#0{6@!5QN>&TafppM_^nbucm$jLe(f4$qyi^)f$I&RBW$2L(N zbEA${#LKlJUQkC_+q_>}+su>DHo-c2&Tn!{mF+)oLLI^O9~;#n$MsdU|4`KDwZH7s zzZHG@r|8pppAbw1!hO1#PkZCxeCacKFl|1~=NLK8pTZcv@*1MV`<=l1g~SV{0!hXD zWsP{>sTS||0`J$ryB*?jDOwSq0j2_R@%AU5_QuTl(tqf|s1R~5*1VR}eX6rCk9*L0 zxsGl80{p00!r-w-LrTz#R-b~?`KK2JUWOCDc;k7n!io&}rczRUEudOVq?=Du@#*sFJB zud9r`u8iz8N1#`c_WDuS>nGTY*Zsg$AZ#zQ?w8SC7*qe8U^0K*uj|LtuT)`N@`0p2 zd~z#=ckMPk#C}_*0mEZDj2}0c-p7|DS}te}ldEj^hzb1;X}D$alZPs+rdh z+2JyLYZCr}INT9>_l@+v!RUQ`q-no^rpOD4`#1dV7h@T-fX)liz_FgL-j3#t<#!qH z1T1q#SZ*>{Zj7+>uNF%vM@`I*WoKX+5MjB+V7WQMGB5#4_A@(do&x|W9#?0(gJu_C z8x&!?&0xDV!Zud|w!}6I+3C*gcG?wK21i)#Fj#JnunbASQj48lsliUW0o&XWwz~|r zJ0ooKBw$Ol6Q7&p#v3?1vv2PXEb~TK?lD;Ij<5`^77L$kWGu^N$Fc{o%okz#r@?Y> zgk@N@SVI0YDLa-nV3|L{a=*cHUxa0WYO#dIeg|a7vL~<%kFY#wusjf9S+H6xA-l}X zj%6=kSt!EtFN5Ww2uo`MmRjQKRzRvU|LhHH3rE-C-3>H&Uv|Kr?i}m=dV!K%zOJTR-Fvqo745t@(?o+_~8M?N1R$JxJ7 z8}Yu>NX(0Q-v>+u;*R@pPIMoNCw-RcEi60mw}qwbUxn<^kj-OCFcpX^8)t1j+4<6< z^kDWeC0k?6GPn|}&jh9dadp5x)4oE7c9-9q;{SSkqZGkHf^ zlJ}X~NslQbqkiZy(+@ow^+Ti355=}K7Lf7uhp^oWupRF+fvG^)c4nU`qwO#!uK0~= zV8Pn)6zH%>q{CB2hsW_JKm7^(DNKJd(r9!*BY)ocr_gC-=?`Ek5Z0+aHW{3Ut=FNlq4l8TZy<1+e>SaqXn81_k9W(hwz^y&+8=gVG_uPx#x74s zmRKxc3E8%P2|KI~J8EFrQn`OVfQ|lDTMg#}x(RIS0^1c>ch_r)U@8z78`csJ5I#g_pVnjJ!FE`G z8y8wjp@77B*Jx9jdI5r-Q!n)5u75=%ide|o8*cN5kzH?K(G{7Lc zr_12B&}Bti+(mMV&e-ma}`{4_6B^Y63L7Tz(q%MPdF;*mD zpzIa(2Fk{7hUePP;=Imd!#uS&kCV4Sj^VKvm87F^3?P<%{{2YzF z7+l7&S6h42L`n*q#D0AYwoV|%_v-@vmesFOHssgoGT5(mS>f0IJ2R!TLw;@FnMt`5 zQ;XNGn|ddvS2TE3(zLt02iA|nFkUAPYrYec5vHG$^vYHlhi&bvz+X0%{sNi4zZ9$R z7nBY8OS%m97hP8Pi$BNz?g8U3=ilV!!FZ0Z1!#|`G{?V$9?mJRY_>VR@4sO@8U2?L zRPbLPtS*|#f7{v*MLTaM+ZmOjoy|LY`b?1Ofp%Vpy4Lmw>5011B6N^|4jskoNO?Wh zrZh(X`GxCCqp7rA8Zj|MA6cbiHYjb^uJqXr=h5eMJ?m1Hd>~hE+{bl_yU9%=@Sm@0 z?aJtTF!Hb?=P!+;;ya3L99_7YcNF!b8OISQ8;YNF85}>ltcV}qU&Cus)?ZWJQPkpf zbfvzd=oQW6ujmJ7%^Dh``6KNeBd@48G>FEONo#05sSSB-pfEPzbuKU!h>a`62G+Tz z+OfeqdTfv{9ZC;oU*}@Py|<*`t>&yqv%q^8@bcX?U@DMQyoYDN%loU0ckycR_7ZrH z1YRC{fvG@Tycl~;llCngMbFtX-q?$=Z3Ar7Ct#%~<@_a&4SNfG$4GmEsX%PqiS2)E zjrN>Utv%-uc#oI%1XF>yctiF)Az)9PXQM=`GsZc!*t138I}!Lep1@QfF1}zqos_|z zyywL}a9g$Z>?81=0=!enf6V#=m`SFnn`8;va|kr2DmTagM3@=a4}( z*PWPmjyAChua~P3uUoCTmhGe6b=kf`htr`0ukV1VKwKTL58&mn(oAD=e|?96b(>`3 z%UzTwId=TueqWB`tDnGjro;xO0!hPmRvNbXYr!_Bz;+I>v9E%uKwNA=Up?1=L)(vy z+uqqL5^Zk=GCICi1mA*>bB|Y&k$+y9n60UjkEsxY&ZW zyf}j`L;cdUYHc}C;JrlR1yg~f;=Qy+yw_BVcaXq)Iq-6x0#kvwc*A+>3JthR@>IDB zaV`kwskwv>S4thgR3Pa(T-9Yd6t*f0!7?4%+J{rAjtO#3hO}trWD8Two4L|p`pwMA zCP1!tpG*2&$$P$rxe~<`&6QZr^z{2&yuxX7CHLMKel)|qF<#-cdfYPy`q7MYGL#L? z$=`y(8b=ivTz7R4`*_wXF zcGu#wwYyiehIXHa?7{8+5Zax`gkUNVx7{&Tm~PwsJ$W_+{e`pF#PIB1Q&nTac?Gsd zfQ|RU!BilO&FqCMfi3YILF!&ObeRSFUTl+S-wV^wOa~6g?q&?#nB#q~ClDiB$QVHt zevAyI-?GLC%7$VjT?WU9E-PZhU+)cngDPI{)dF-BR9f#f>CY>hZN2vxvZuRWRRPbA z{(hA+A>+E2e>de2msiwVfHG}6Jh$x;p}E_9)FvFK9f*a!X`9f@KfzQW91Hcixk$f5 zZ7jTR;`DiXPG2=16@-uD{j2i_U>>R%;P)7qkR5lRI(QlPn)=LlAq*3EUzB+TOa8gExwnwM$Ofi(xF}bCyg=8Z4SW$hSm%^j|nfDNo zU$M{Z-ZK=&OukSUdny%;zTD<63X1C_8||XtsK$ILO`qpueabGJ^!3q2gAPNWOy9)c zeQj%BXdCjGNz!Lv9N%Xas={YbHsmwuGT3KyS>ZGOxFZ~k@wh_^NF8?=>v?6fjXSzD zH!y+hEJ3|uM*}S7N0rwfGh0)IXJi%x5guiyRV(K@@z2~c1yK>ih zw497Vn3+uT_x}Nn*Bh_$>;|t8}fs68SDqTtndTBe+i$%i2D~UAT{rpd97DA zTi)@oHym!~ zKOaQrEPB&}&O{gEur;aNS$dx9j0>^n#^0o2kmWl~7 zq|l$ft#?iIu0&sJhvAL}$q(PgcXZ$62n56k_ z=LKYKH|@48J$p3lzf5HRSB?E&!k_%~ zm+_}C{gtRS#s*r$e-~)9XpbRi4_CwZYo8Tb};Ho0%HUsvCn@-7>@%y!g^ zQ>;d-?ebnU??txwzC`zKX2k1pX!m8Kc7NTp`)g54FNc=)?nRUKT3py`LD-AevA|Ry zY%jBpmC;@Z!^Cwg;DFyA5B$qV_}?=4|BXNS>2KgqVfveqHY)_Q@%?rQq0b2D!)HLi zR3NO6IsfPRZN4-T4W0S!6mHNe?oK%YdaoGi{f^Q5?MTyc0ZnDQEh+RI4L#Y9?dEJB6K2Z3v)6LMkP&U_*-->?bMCiX# zr2l(H|92z(S5DP`jL?4x=+Ax&rUGI8^ZJs}B>my2OBxgCez)Y?pey@{8ZAEtk z#$QOg&DvYy27BQ*-tn`FXnzpW*q#2(!qwoo^q;5v_kmFe)cy!r`>p z5c=O-WbW-^bJOU(`wWO5v1VQC>hLmpUB7iD?QZkbO&bT!u)6x``X6qQ)ohWKY!Uqr zdWObq<{AAD`e7COgZ>Bou&Vt*|AT&5&HkYOK|ic+f6)J+AJ(ux=zq|-&Yj1vNzANk z^(f1J#P8#!%V3|=Wjix}(*iQi-@LNv^EZ0mYdZ?5UE?;^?|VUvzuvZ16?Q|}kloT{ zu-$ao&e%;0$Y?jOY!S1o_K3ExS8Uu9Lar9+)H}E7jx^4p|DY2cKR4r^I)lmG*%5Q? zhG=J}!i_PE?X>NiCpVOCBJJq?EHN;${l;cno4!8Lu8ZuT+c>RV+S+%Zf*rfd*a8wi zw$`a4woo<{Tj?@5wshIf#FiG2F}A$2>9Hlp)$5YJyskBcdSK`L2AB$j$Cc*%#wm7O z{gFApu^&CBy(lUu>sU|JaRBO=OhISPh=8d;+&XZE?^Lgj1L-*~PTx zE0xcUXlp+QX`)k>!!~k z?Ib#)iuXWc&18PkTc2^xDV8UejInb@ihvUh`o4KX)mBt-lmdG+5&gK{myr zF?GcG)`j7rQHPAHT;sXZq#biZ2olYmwDY#b&bu%9(+mjr`>;*mml^kyP?mk0=OgJd zI1Y4K(TDv+cqx+Ndo;rPH~LBkujbTVca2mew2782)q|dykIJjG`xQY-qpF^wRq2jUOB~hp9|vs z1e;;{a`pxryZpT_iFb2>_fm-$Oa+pL_p+?^U2A9K16A0!t^EjksAJDK*XTJsOyK95 zE$FwbxdvrJxh7o(=NesBU@8!|oe}3} z**N;t#QF8~oGpWS5azmP8=utp^j!CTYA%8&=enP{E*Z~N?Oa#-KO%f}Z3dG_- z%!jbv>|mAhCkgqtLOv}dN8@@h6^JW;DCv2Qumz3#K8H%QCVv|Vi0{u6b9T1Lpj|S} z4JFR41kO8wlgGYbDi9YZ#=hqYoW;^z^j!JacWWX09?0H4wgH$5#FdSG@$-aivVq-~ zxR(Uz1k3y4QkQK+efLRSz*Hb^eIZ@$59+e5ko_QJ^BxPB3dEI-J(lx*UA~Cg^C44- z#J`=W<6(&(OaI|$iNLN?n5OaUart@Z1ti z1>)AR0M&7!Ux$vbf{8OdnS41=*Dj*2S5eo*SRXJI2-lU@dHbS@b@ig)MnE*v47REC zny$62{bVwA$6m50Mnjk>>(wZQRHOGKc)w~_D#3j%_n-J(&RH?fjMh6fQ}>NeP^FmX z-B5YlXvdvp&wrBrdE9+^yZ+9U@Vg2thzzr7SAtp8DBbHUK+4E`vj_Ov<58S zRH1AZyT~4CXsyk9=O!O&@J3m9?>GzV zwHL_5e8`+FzZkh)?T-Aa&z3)ndc1oPzQk}Re1{xnp54oyuj)*(!SQzw#{zBTIKHX^ zhkm{)9PZw@wnxUbD3s+si`SykWpMwd%f|CVy{dcN6S|AEbEivSpUBX9?zBA_sBG@^ zH7sPO^KpM-=T4A?{@_wA%jpQZ7wbkfCS3umvFR!wqAH7ew#FxOQKLPXYxB>B<2h!X zJgEigetMfdsd2OQ2f^ph+^xP-&mY{$`p@X(^X>0sUe6Bde?zwV+uGlvf*t$B@vqlI z&sAP!M&eJJO5vU{nY;!8z989qH5&c0X(o zC49xGw}gU4{aJcsToA|h= z8QfUv&5nC-fx8EAZyMVhOabHQ*8sa~6-=*~Px>IV}JJ1h)Q?VbE^Y0Sbj$^k!e2LdRz*Hc< zFI{PU>089Ev%WQe1klXZ`ck%Yw``96NgX~vE{>PPdu#5wTaM+)LXSaG4=@!-W5*D}FWAg&%*Kf6k_2fe3Y;Olm9`cO9XM*v8ESJk~Z?E>4pz{YDe zU@8z78`f&B7TBz>&{_?aP4rsLP>mKoLt9qzthO_`5%YDsXPY0@oUb&6V2%H(&?K>M z(Y`I6Yx2*COc8nygWen?U@8z-Z{*u+e7)_u>HMZ~pl^-yVAg8-KDys?o6+`pcD~=% z{wfvfm@IQHMEE&(Kl&|e&PCZ!&P|uWIaimBbFLouZ#j|9w&my?w|o9)f2xaf)JWK$ zV**SC;@TfEajmugcY1tL8fDDx$Aku<^R_)_;Tn_VSbN&@f)d*S0^4X{4 zi=`##Ia>xgI_sGX^$0+v9F_7Nv$pnsQNfOVrGG<=@81W}Z(02tW!b;!9*tZ-jEm}~ z9c&pmPtLxqWyih@n>EujHyFKJzlRIbQ4zD|Tb~<4JQ@R&yw;`26s>2_sHy*--RNcA z!R^zEc*lBW`lY?w&gk!q*BmVd?CV1(`h7XVkQX02Y@JC@(~FX=W9hGcJUZqAo4T<%l_Ya)j)Ole ziuX+Q_mRL_H~K=s~e{ox09{9xDbv8JvUTzf^o^vz>+y(QnPSQt)u{ng`RO z-sQb>b##!WZ@wj8oHC9+eR3FnX~`ST#0K{_EN6i`X=0=MGfuOZpPSsD=Zb&sRhY88 zm25u3WAtdrx88!5ljnRJ&2ir*^M?+_{g*WAm=gQEUfY5Xj<~z7^-G!z;GK-=htLmo z`RUW~r!ZaNPp|y+L-pUn^cnP*oB@6e|6a-X6Q0qo>irHOq2D1j^gC)1zu(nYw-svD zzkglVzQVrLHW)6q9!u}sw$4p@4-jtXFz1C)NTR7kDn{>o5&UTp+c@0PZ%oY3Ot^WD~=)-=ZZ~9 zkaI=}Oa;QZ!kkgM#pa5iOh111on!>(%nx$G`qZX0=0Yww8gk-XfQ(9+0HE6c*^ryu z{ss|~2~f}m9{$~WmUchdBQeXpGS3}DB^dkWz|LnOz*HbE_MwF7R)L+;8f`}Dvk>Qy z644O=;GaxoY3&sFkA58*v@Rrv@3^e}kML?k#|O#n`7%(Bj6w zBcDQNrX{zvzfWP>aiGlG$OryduIXVCAK;})# zKdtTQ`3HE69cdGd&NgDKg5N~`!4DPk&#r`_QvSi?3Hj$_VzIBZ!BVMY~Px!)qV&} zrbi_xh^a2e@|5N5;DELd@$~I=n2JP^sv;zuu-VTrwutQsWZVCn8!7}&|4Enuc-n%-Te##nqC>xBu znU*1APs=Wgy}P2=`#m}K+F|5`dBPadE3NMb9zXW*n}|L9P$BjXBn*{e5059r-WkMV zpPL4s+boVfFcpaFbBj?N-ECv$2?!HVc1)9E=2$Ll%tYu0#0*z`4)+VSpTB!DJhh|M;XGvliBAt&~|sDA{g_Lay&?YQyFcpeJY>#nxDGvvjJ za2%30{!p|*OrdGEybX!#m@a(@EnDtO7tpU+eF~_NAE> zeCezVz63nJFX1=gOZcIJFP)R(OL#oNmo6d}`_cvQC0;WGQ-Qd?gn7jS)|YaP6lBHH zN%S0-G4qOLjUQbM8L=Nl^9lfJe*=EB=@{!rC}&qcoRpywN>(sLE&Z&yH05chXKi}@Q0THN@zKYx?+ z<$q8K#(tH=4yFQ0!+sjD>(Pdt-yQE_zoVeVj(#*|^R0zT-2-Y%)e}pt`vI9!C4|7zj)S!Z^*HppV%0qxCwTv(WobkD!if&qiph zx(RNh2*`RiqOJW~#LE$}?X{Oc7Hn_6k+m$^Slvj!nX|8p97ys@cTu{amrmpJuKCH#~lW%{iq<5d%4; znfjd4MFgMBB;R$+BfZ=75!>9J*Ojq&GhyXed>yg4eLPM8Q-N5&g^v%Xc6`jnV!?~W zf0F>S@7HK*FLvQ#YP%%}9{dq`i-e_z1|c%B5N0&#r+^Q0%N zKNrnd@@sldj@R9@9QTSkzCj&)&I(Kg;?{w4R!@3$d`r*Sy>=c8|5M2RUg8H+fw;0m z_NCGgW-$v08|@866=!?&NIm-7Lut!e21*Ap!@ zmAw0C>D_2-GammOPr)2|&63~syq`+2|FTcw_ww=h)4-ThnyLNmK&lku4mlpz^CjD% z+A)kBk9%VnmUT-c%YA8(@Y?6yF_3e=5I_G&2usk47FsOZyUH(Omju-grcMnoKaK3DOROCxA6^NS)kZ+!`xuC)1%O3QcTvu}Qp<7=x?@jGMe#&!jeYU^`mW^3A=GP=y z=VcnJa8+xVxQb4~R&x&jU&1E6q}{<(Ag)b9c5kU@_lHFtb4a^`sX*L1D%!nIirv3C zzlYAXv%&5s*KGGkgiZQMyMw7fT$_aKKA@uA9~E`T0%~_s?(tK=_wJ2ZG86FyMIg|0g>AI~b4V%~b zIB&j)_$}Jg^|U-1-wD_)x9VzUT~vq`FZBRZf%tlK_9S%B z^)cClhT>W7H>B-p8bQs8FBBD87pJqsJ=`Hv@P5NQzuxKGZ|IDo#QlbR?V-{@^>FE9 z*t_C=hF;lh_ZeRF5`5XLZ_Q7CN0~dfS=L1ln7dBzF-yPxSi-%Z6yuWT;d?m;ckzuv zU@o!*%;w8-$0d-}s_&3-WIcVUdAD88Ylc%xRFnn1qI*|auZu4*dZpaE+Sb0@bn@Zj zqz^-k@54`5;ln5!^5JwD?8CaO@L`&wRI@&z1!P>G@XA)ZKJg6c%j4~_$YZ=d0j2_R z^BDTU7i=DDGUM%K>ABV$(As7L0&`aQ$tPwk%oz8fCd2$!_EFbY@)MbNpA~qQmw6XV z1>)jGpZcP}OJn!$QQlpF^KSM12di}%)T*lgcuwds4tnsK4VVhV)dOobF9|)0rIieP z|J^tS)_*%Q7OU#rxDJ7B6=1uPa*TO52uuayVjDu(UKZHM#!(+#D6Ohd!Y3wCIn%c} zFNjv^qxlXVdYvxnwpqKc17?rcDC`|P(tn;8x~&e~chxYY&OB}+n;zS`Ns*;KOoZgkC*7Ttp0(rA^%91!TzDkcE&%nfQ!-TGQD z_*$_v$+}onQ0B8&L>*hB4$fy_DiF60?`ULoM>>ZAbtX$5)v_uJkwQO0bMs z9G`$vX0O0K17lc~<~wedMzgWGwGJ07h*?{bwx57T*9 ztf1RE?7S~B#)+{pXfW4(24whg^&0fdxZaGiY%5-GPM5)U)nz*qS6V>Exbn)T$CdQc z*GXTFg}vaXe3leU1>*YYoaCo(T0dW;L4syeHtlGAVT=nGGRdt^R5q_WcKKyV3 zMO}t7o+!({%zawA4EB3nHty489{zyjb02ah;+5yjU@8zdUNL8W&&F#X(}$d;gSG5F zU0tz`shaMS`A}dxM`8n0fuvzOHx1j4k;`Y_42rByR`w{(?wS7@G z)V}F5xP5imxP9T<!}G|4!isgeh>Bc-^Sxx=J^DF^tBea53wynBq3@v^Jho z*}V$1NrwCKS?)nvZuF_cda;*d@5_hGPUF8hJAUUomyC14qxJj}25>$X6zgx#@3gf~ zq=Fr%%27$6wB!{IF@zU&cw17kTI6Mve{z!Jo3>GL@eubHRj5oo;m0G z>)_^)yA2dPOQSR@9q1QRBQ@#8g1-4a`RK3=4tew~yge{{D26@)N-q?faaI3Z+l<^m zf=la1CI>b3pz%Uo>tMQ1pu(9d2C(HZW#@}Ko|Z@A=BE$3HNQPiu8ywU(T9%c9(7;IOtaCJ`;#hNX3Oknwb_=f$ClaB+-xO}|HgK*XSLCG zSdZw9eUH?$;auObx;|urvLnWE9rpgrTI+anHq_DcIM{90>aodesN>4nP{*gUp^nz$ zXMKCL&4xOzo(*;UG#lzz;e_hiqn6yIbRE^dXVTXGAwAh~njB{!NBQH7PpTMaploQI zkuHPB8MO(t6?Q7n`K-NLs@QjUJpx`!9JqPb|&{}0U2|jSGL;R_aD-ibKl2^ zInGUBDiAm35Z9mC+|=LXzE4ERnRPn&_2jhJRxOkD%z7+PQyhhh?lq%MU`IAED1x@!2mh6$tB-&n-w8|KsbU-)^z@LDPkAg~rlP zrit|VnCbM4`%N_SqEiodK_>V;vOFhz=X+$%GL57E#n8Xvjp=rsqjzrWJ<(_S?;`yu zZ1D?hv1EKlHkb;8ZBfu?9>4Kzp?wrrVh=(eM7HRaZ!G;v(&DS{v`x;T`b}Fq-(=5r zHZJ}?U6EI*3cRmZJ6348qxdyR?h1*QUFdo}3$)W7xZ zrF|#9Q@o*n>s(|ve5VulLiZ{*mHw+e3Gwl&=STM2dPDdNe?dQTJjU^(0-ptMbWP^` zjC;Tbk>5<3NLN&!Oo5@_BxoGWKNm;!>Q$_?0M1rE3s$b^p(cm+&e2^m0ss72*!xe| zoA<-OR3L2c`W*Jdz7zH?mj2S#EZYxbnERYcFsYwS*>jS4-YJHvYkH6P?fE_>3B< z83}F(wUWK_ztl+b@s?`eB3+zGUr<22-a+yX!Mg({Q0XlVy&mtrrO~r7xp$-MI}v;n zoflu7@O6XQ4c}2sz2pVFTTusX-T>kzzY7L!)ZeT?T7J9y3mbGrY1H<;b2Bdu#pCb7 zzTKsL!Bik!W#1nEQ}&&4dgtx?Ut!;7Xlodfn=D(=6* zR3L2MVs1Re^N-o{gWe9KuYvS$og0~=V7?AQFORpt*2R`$-v-JR4JKE-O|l=wJ5MrK zMBn@9nZpM^kPYaAAI(k4IismOXQaO9<-9H5vVaGRL>EPoPhQY`hO=WH3|VXW;eYu1@K1r9os zfKxw@8H2MSZRc_JeKLvfFM+Q=@bR1!Oa)@=#{Ev1lm0C5Q5P}~`2*%Z14uwLC+*BU zZds@zr=uzJIGSoXYZrs09$+ev%zDh#HF{iEwI1Ds9z&o9zqiLhX?>uP&74 z){4Mq@J>Ug-`!zvTjH$pCW_lA{O(Sj&~0Amwsf4Iz*HctTV8Ko{~~-1b5hJF=tBU7 zhSE^eOnPjxf2^N#EP&=;Jj~~pk>ZiRJK;+CDmJTrN=Wrs_sRQ)=2rDW_hHbT$J1ac z5Z1juhw=2ULU&T#j@__Irte{&KW^VWV*QI|AB*0R-E_jKy$}B@4QP$=e*E) zxYQX;1>)=cTawP`eYDOC#yZn3nVCaGeN4_#y+=cGr(&lR&Op>zdAJg~2B!}ump0}m zY!kXKtRVDlg}&3{wHGiI26#nzRr%jSE+MDaJj*;!~*9eS;DTp zH0Ji460${6*kUAX!Tk!D3WRN8`jwi$iZ-M+8%W zu-^GxE9vpyu--k9wV^szftpH7#JV3D>+U#lrkuqKi8ZD0`^qh1$4Q6I2-%}a*kcUr zu|_=i22+8!_Q09PKYV-G{EanyZIz+1RhA-|X23~fXgXI0-#CM0m^H;}?Niw|gv}b$ z$HWJoryVG9E&AkBjLq8G_dB09SkH*};qIHJD~*PX1Dbsr98L;G;)GI$?Om+j0x zoEDIAAI>XV?LJ%&(wFz)#=+Nk9}Y|f!oFtC2>fY%Z9Z}-dhc*0dM^2lKu=M}DyW0c zIe@7^+&XYZ;4iO^Rp~if2L9^oIkOFJCYQjx1Rq<^JTGY$_*R!T08@e3x-l=oUZih> zHDCkreKGeeMlVsvTCxr>6-ZhgYgeqJx2R)XSqGR3B(0A1D%LTFsAB_J2bc;Zt&R;* zM|`JzTl=GknG1)KkT)&Zm4 z_@!N&r|ljq{0_33&3u?;Z4{KHSEQ5nYZGOi-G#DVs$EueHiUKTd11(2I4qH9uc&3u zid$Bnm4HY;NB2RSWjrf^vfS=`Rw7*n`-m>vnH;SJWX#cC+4LNZbGxI-&nVH*UXIew z>yzVKQyb9Z@;&omZWF{~t?+y1eaUv5?{`4_@}2{j3dD_H>^XD;j=K8(t@E3Fzat`& z&VI}Foqj_0&XCRHa4;2!D;w)ObwV}`-gMN^`pzz<5?RNbqK@5U9bhVu%ysM@s-wTC zqYZVijlfhOZXF>T?P)}NHX0yg?+w{J#s^b@xUwW}R_SIF;bztO!9cRZOt%qIkP?M~;K`G-K?z^jlr~t<-$02@~xq3d* z*Zik6Q^(lP(LI4XQ?9ljBcMVyKil_TkW+E~>pbM==zdi9S`D$+=ZOCWsjZLMQ=butS&cd2(x9TS1kmO&W7{&$Cv0ZFg~YdqqxpPVAJrp8;UM zpP38(ma(5fS@v1(XVPV`f9tZMpP5Pi*^~U!e73#6_!hR>66b+v^^}g`jH(-13b?R1 zqoA~S9U-S8LiEjYjrtzm=DI%h;u>DBXrsM_*Y$Q2Pa|{N9%t5B(00!d-lOwrcX52m)~e)1^fPM#NmsX*M^i8(>u=IMn@KY27g=gtXW zPiOqdO3e3n6W8*5V#V>J%=JSA-eV1EEULkuXWOIKFrUG$gqrYwtvT6LZ zFanRpPiL4)B>thIj1 z|0R?Lj+^ibiEsGq|nK};6SjVi`<6%wvTw1QF&B@(zc8@1&>+|Crq5E}6@pHud zXvd8GI?A#yaKD}|gZ)OAO~?@okbKS&*TDa|?*LPQxc-m6qr3J0ktRo6OV70y`JPPp z^AIYx62`W5C9vuBdHuI^)~O! zk)G3K+S*^FhU>T>ZV;WcVGI*|S5ZLMBO>1nL76RUS|46 zxlVIUvBJ6oVg&1h&AzNnpEUQ_ro0~$sd-_nruI8P^8Ich=#bIxP?qh$ewQwTZKlh{ zeg{3*??(Mg>iA3#g$iSbQQ>%mrWY&i8JS)M{ejBnUPXN=a^HN;IT(xcHqQQKi{0IJ zj?uNa>-@Z9(&8K_c8G*}J8KR4Ch_F82CnK|R2AIu zxBZ{~ehs;rzrHp?*yK@ZcQ6%*Ym<=OpMc#H_bEn-Iv$sH2UCH#b-?a(_;$Bzcuz{Z zH>2;$IsW_ZrnC6_4{Y~gn^9FY*?p9-$fQmMeIcrgY_hpF}Oa+pL_ch=Z-->qk5f>A6yox$FFM_E++&bVVEq;9JFGf>d ze4PY1d2!DMFFvmf`iXwJ(!Q4CC(tC5pL|!dpDZqH@&;_eV_Yy5h-(v!ar+3H6iaW? zbG8h81mnl(oo04s`@Mmx_Lr9s_}&J-QhZhmOa)@=#{M$K`7)={JlN#ad_(CS-Dto_ z%Y~KBr13B;bO?>L8uyRn5RKP!*WA#o3AVLgLB%^RipR!!3IJjL*mybmE$i4AWkX}* zbQwH0)@8-mn1=1u+!v<>=uzgXso#3^%BJt>$y~8K>C0oNPvH}MRvSzO;`#)9wy*Ws zMa&rL3&&@r{1t@!&mo`hxCK*zxbn%@bN!_JeCbQ=YTnxDibD3+5<8d*#FZVw{%s=m zaYFt#5<8d*#FZb!{#^+BN<#Jz5<8d*#FZVw{&OPsm4*DDBz7xj|+bXQ-Qd$L)h!-IWFV&i>nLy zb&${g4yFR(XU(0?W&WP02ld*aD|-zgyC|`PsX$!WA?!_w*w+;D8zpuy6^JW8X!q_R z>}v_xJtcN96^JW4guQnn_O*rlUJ^T)3dEHk#6Cv|`#M5)AIRo@9ZUt{$_Dm1WezLN znTUN|A-^Bw^PSFMDiB|Oe<5Gr>D=F-_vdTt3HbxH{CMpROa`)slM9(F+!A7Ev1yKjL0hkKJt)pTa zw1)K9Sky5Bb#N?zsX*L1Lb0$2J;!C-HrPbS9|idw3t%b`em0>EMu)I(Dr7Gvv4g2V zT-hP)OD1C9OvqnCVh2-!xblNJXiNzE1R;BAEjx~3FcpX^JLEsh(sRlFv$?2aEb3tY z0aJmvbyW19H($#aq9@_u@dx%&u#koZlb7ToYVtM1>)8LJqG!?Xmqr< zxN=C3Ekzxxq7IG&FcpYfN644fpy#-Z8wZnw{M8|!;{Z$r!q1v_DCd$oVE1)RgWk8% zRzm*Tkk7dkOa-f)9$+dEw~mk=+f>wJM^VStQV%c{h+9WRJ+=+$v6HA{d(^>k0Hy+Q z>j?SMPV^j?apQPrA%926=QsdUf$*~l{n^eT?7IlryGra}DiBw82>Tw1*mo83cbC|~ zR3NVWU>vlCu(vM zVc$Oydz+BIpTrKP0&(RBu^$k^zNe6Vki-tA0&!)Buun_GzL$_cRbmHIfw=O6*bfO| z-&@F55<8d*#FZVwepn**eT4iO5<8d*#FZb!es~CbNyt7DvU$7!rUG$g1G_(mJSGwQ zWFh}($mj6_mZT5_VE%smTQv z`xJ>COawu-%Dw3D+>nzEnH zRXvTWYT8eqE^KnWv^$sz#I;Gt?l)DmyApNWDD4iW0&(l8X!o0q-DNx;D(biub#QJ5 zQ-Qd3gyQiIdXCGubB7s1{_T*@xfx6a!p|nm9qtTaKTOEJTVe-Ofw;0m*#DV`{cs`w zUWpw{1>(vN=92qD*pCphAAoF*TQC)fD?8*r|DxxT;?_~oe;y9$ zag?azQK<)*3dF4=q{kB#^*CD8@wn6jOaUbJ;@Yohi1>)8LU-HMc z&(U*S#*Kqxh5TnBpU1XfDiD4)Ar3l1*pCykUw~|mVK5blD?1biFDGI@UdVq5@;QdV zR3NVWU>v++uqXDZ{jZueed@}PTg~|D1flP1(w<-{5Le%jJ>N*Q=ih|y`iAWJUZOou67t`b_5@RbxblPceBanp_KznE z*&jkS=LIkoh$}mk7d}bEeu|L)G30Yz08@du@`KnvHP~%zQ5l>K<$=y}SDV<{pz>WF zcs_CNvK#HynCn|v?$(f7O>CVi^!;4x8}9*usX$zPL;b~9^jvbkcbcfxj5DvM&*E$K|B z^rN!`-amks`&KX&h>JHE|9{ehWoK>97P50sknHE;vyxyckW|^-=)p4C=Lp&Lkj*g$ zrUG$gSB$ZIsE%_*9Yxf^wgFRtxOD_=(-4wR=xQQ-Qd3 z1Z^}VB>NH}dmbqpOa+oEd)|=jONH$DAe-YCOar?C)!>(J~@n{*QiFlUQPrDk^(Vf85eC@2kv?=7u z7tu4@>AYEl>5EQaTJgGBW2X}2)@Y~OXOTaB+6jNUbQam^_3UqZkTO0+zC}xX+s+GNI$$G!rRq;_zC2u+t7I*jh$n@8;uRS8q;{lO~(|B zjYA_$vmrL#K~+_>EAY;T@t~VuR=LU8P~sh3X+B)rn30?9HdHCiTQ+922;qB@+U-Gt0Z63sQGM=3U^M(gIf$7ItglVDMYq!%@ zcy<=p>GV!udS(`3YQCd(JB`P)v%pRlWye%DHu^Tg)YW~`ymw}{QyHf5c$Vzc)tFAm zj%j|s?|xzyVfr;Yrm}U7k$24+f7%XmYwRb_h%n8De&;Jx)!BY$t-EK94NH)lZo^=| zbIvTn^k6nj!ST-*5vJMDuFKz3UAqSHo(Lh7LuLcs530nAHZRM0%inA8c6H9%3UX`o z!|4&Gt{#(JlMPd_UEhc>&4zXz`OoV75bau)qo+eiwmu*FF5ve&w?xlNef3US(w;Bo zpO7`&mo@f2gGI{HyIPfGC7#g;tZ``D#A1E_Ta2=&8d*4>gdL zS}*R@AD&x#Z*yMDe#d4((}(Ei^}(<6$?o*H{Ep3%?viU953LJ_&VF4j7=(}Yz={Y(kr0)ftkND<4#d>}d`Nw$bPbz$OMDFij zC9s_dY+5zFSt^&iqwq zr%m^JI5{liHsw1PAEn|Qm&E;#zH<@bfc~dGw=iM482jex2KueE4rQzMXZN5AO6%eP zO`lwJBlMRDMe}J7%6Wy{7<#TB*8J=B3E1vs&lmeoS&t-?=#p{dzw&RzH0I`8*xU3spo%~{aKzHfC!O1Fp6iCD6qQQ>>5h#;eN9Sf-Z`;~EZ+0Wujr-yo z5o_ERgQ-Ald&5uA7mu{Lbt%&q-=rg~tS@GS6CWXEXwcv${TLg48)5EH-oHs;yG3FH zQ-P#myEP5lHhb29?Ph`Pc8Lv41(JsCjx=m%?p9yD-EI-s?vmKRR3K^C?oPvYa4mMb zRbabUVgplwq+$DK8n!cP!FHR#cE7|1rUFUB_COl8_IDbxv}s%W0TeVHm&$$vA!X(* zJ&4Te?My7`T{B7bwOdy&4mMjAQqu~hoVz0!5+wNHqSQb zuQ2qi>r*E_!r&Ec@Fq?szYfpseVUy&<#P{Y#atMBHWj5y9p5#5!Rvqat^_;l@RK3m zjKr&ZkyPz;QK_BLtu;6EUe@iE?7CgAb#p#R-UYff@Mkp&d`Gs^p2Hr^tg$XCHMad_ zYwqe7Sm&>@>->n;d9E&P&#=x7gI+XFGihS4{1je&_%%UW(ApT(fC+qx6nmXZ6W7s_fQ_>an$qZJNSJzFcpZ~ci=t4QFa`)v>8XeM9(F^ z&vvh<<3-fLYZG895VsDjO)MhnptXr*uv9~H`j<^dW%mk3qg>7jq(fja8nelF&Ggfi z_6n+B_vA);A5~WMKE^+VO(w<-{5Eox4&fbGP zo$u&adp4Uhbd1q{8(!Ko<;q+0TbJLL+H-F z4yFQebr1RaM}f8}^Y!8rHTe2N0^cXVw@bWk1EvD;@h#!`&Zhx<7x(gV(}EGcsU*L9 zvCOyUp2zf8(s%wP@O=(^9E)Ho5Eoy_cfO$KLb14{)82YuxpIV2`p&X$gWGk_g-3+& zJ}mHlCGmo(K+^Dj4ZK-={p<@u`M#pBOZz?|@O~rlf~i2#@P3;W?@OJ<`>4SCJ@9fo zfvG@TyrFpdfu6Hv68nxbYl)}F1iqi7J;78Uw(g|9<7e2@x%b)Tx-a~`$j8oHyL+)dI2pSU zxQiNgj|O`)gq>q`%Z*tol=q$zxa+8T$F5*15EpmIuJsIC?-4qC$lUbr)?(ME1-^pB z2c`l^!&l6LukNWD+Wi@UuTkOyQ-P%6Ys!Leo?7rdEAaIIKJJIXR3I+CP(R$0o(tu* zrTl()g$SeUhnLIV4?idH_5xmh=N?Q2;^L+8RBmaJ*NXX4Z+eh6tPw+Fi67cS4bS3% zUrvhbxPjk$uFtI(mRUz18m_c2t7AcrPj97qilv*(Zjm_^VCz|Ptx%kH2)p!wU3l*R zOa`ml<}0`CG6FPI7>4e#&-yvz7Gc-3c23`@Mr zXUF@hz`GFeZXd7nfT=)Syu&Hij1@W9IhWIFf%j}|9+_*RV?;Xt;6AKn@l5muXm^Oy zqai$cdYj(HXn?~5NkZDQ=Qp}ydCfqxO;=e__;1>)il z^#!Bpxxkq&?h8JSa97nA{99mKOkx95fuvzuJPq4w8~4bvuZMGWL#a*7e`dW^_rG<| z>GdJE1GfF|;2|NKzajJ*1HE`X7)%A?>V@^-<@}f!1b?CR;H8X$@R`o6;jT_0fT=)SJwm=SHm!Zm2C(!q2#M|UPVY5x?cbfLo`A)r3 zRpFb%x)L2O&r>B0`V=asU8w7&-MGG$)(Yj_w}qWohMhN#=g43x5ZBH_3F`_$J5vm; zLIR>L1vXxr%AN+js_0Lad0rb2y9^{L+=q-=A*9PYLYLK`3+Dqc6^N?~^1+Hpx~#5U zMfZ!@-%nsCm}2yZGIe+An3kv3F^7$<4=lNSNRM}g9&17mo^OGvKwLe7^R2ZQe^v9X zy8yiMd`qr-z9;am1H4mX9|BW>xOnN@o<9%D7fS1D!0;QM%Q*)F#2QO6Iy;sRF1x&3 zu0ouH!*jX!g%0aO2kyVYR3NSnp&Yz{F?sS_?pFXy&%x5Z9|&yYfsM!3U@8z7TWD;w z5j__gTaSbPyZfF4UN9KtSapT$W7Q7@-c5jav)CWNR3I+i#mFC43dW(k4!S8c*c&OX zsc(K{t|hO}#~e-1u8e1+9Age4_Hd7s^lWs7uJ+Vn!<4N8+vF!e`9?jOZSGTV&cSrt zL|MCaM+~?1xbPbqEcea7-C{$!!A3SAviZGtZl`wG)&DljN5VD}U>o)`FcpYvn~y zctf__I?a{`)ndy}1-5M^HZT=P8n*4yu+6Lm+h+pX4!|}sj!!TZ2xH6VMw1_}QZYVz zMU%_sVnbt7X-5b53H0ox&KMwy&w?K5^vpS@qnewXFl~wwyc4EPeDtX?7`*qv8cp_) z?LaR+8*P}5i28#5xvkrC1IuIdb77yIVV}KX`+%uH*gi#lH`=P%?9(gCXnpg&iv3$L zVC!3e&06v;h0-pL-QFQ!J7Awd=C#Ofy^I-~dzt_5o6imABUgP3Ed|GvEroJhwiJTK zY$@=eswTE^OJT0~tW`^%e|JvHtnm`ro>Yj&I}3%4-(=dLCGWSzLb+4!$SqXf7GH?A z*bQyLV>&Pu2)9LjuHu+(cVl4Wrdq~yBVHyYgF9t5?>FYcW4bSe9&ONr=QCg`5LXY( zXI4w{sdva9_1@r~S|R8|DK+=Ah_kn;P_6youF$m6wq|)(XJe>$Zp{gye(o!w@7_{h zFcpZe@9Mt3diRwg27k4_`^5V0LHe3K1UW`b+ysq>jH4R!;cZgKogaYyvNNLk?0Uq` zyM*TPUkjZlOP#?~Al2)C!tzOe?KzY#hg0G)XZ z2c`mXbq#~0?Q2h`=WH3|z2Ls~_7T3S&I^1m@Et1gfvG@j-8e50!Z#xez6)!?_k+N9IPhH; zpDzPbfw=gB=NXP*fUw_kl-Gji8A2zjUjy!H&olfea33XcgQ-ALaUb0Y+&|QU`zL|> zSm5S32UCH#xI=M%96eWYuGaIl8shwCf$aof8nyEpe*YS+k9IsQXSnls z%MI4u?cV^tvEQHd%}t{k8w;%qkEbOpvxk2$$t(15$ESmdS?hRX6pRp$H|DpaM>)+4@#I=U zH=4374Bbe_ZuD0-_-V0@vvz#-S4icQ@zrla=b6x%*G0ipAg<2A^@%gIih7MMaeX3` z`=-BM)=IXG>^T(af4>X7X8|wg4=@#oi#L=%&Ngt9*A#c(E7SXQ65D?TwsV1v=T%@T z5Eom;dDVGr(^}?Lm&3F*&8z+pdR!p&08@eZdL-@vUdVcMW)HCN?=n}3eLK7d_@~h0 zVyOq13M8{0fA1PSwyRo?zl0u_LXXLD&IMC}xO$AFytKBTm&QeTX|--qUb>7V#ml}r z7WSm)%(!J%%>QmMnq&Ov9Ne_=zRRwmoSa+NeFy3a=)Qe?MgvR*;_8kw8tVjgr@gd) zkN~}4FVAR9pl8;_Gw$IG+8arn_d2uM0dHu(#L7N@v<#DW!^colTy zoCc->adiykw5#d4iesY70JPerZ9b@-}{O0dHs?y>zvBn+4uyBwjETNGjfEYs7m%wRn38ydA*H{V)j`?Z^AJUnR2rtBkud>jAr$s}aw$?0Nvsfi6Q>%(|j@x3JECFG?Q(eT9T3 zysxyxlA*az)I58aOy8w#bjNrIeXZ$;&MJN=b=m@I8<=yWtkLbV3{_Gj5q)=0<3+*;#9 zW4^vZ$9JJ4&$Gc)Ag+#~dG>pziF6+f8<_tbgdIRw?L51m!1e*K(Ykx|UM-jk#KjiO z2_G78m|rC3gc&5)zscsCa)+^F&TxM>r@;F$@bbPRmunfvG@j-AVh7pJ%~0PgZ<|+{)xEn^4S5S^B|lMOt5)e(-~I-&)-v z0|-mqpT(~LbD4aud)@Fq8!)AqGM4_Q_-An$Dn4ad`giMUlqm3R-9m09lC>#hjg4eY zWm*0HEUxniJ-!@d{aO6c5w&bAYIQA&_IJABKFZu?I+mxbMbGKW*H8!WPCy;YMRiOw zbqq9kzk%H4BfOY4Oj*I;T^^OJ2)t_uyqiPT3X!ZsSQg>^{Q-JpoWc8(BWlH1)S43S z76$LH^qjyu5p|4<>X>fo7-aB%54kHvcrgT+va-Ru5-M2*c-Inmw}h;fBUy@N5#B*~ zWL1OrXGhd3v8c5fZx6ELB;cJg0K#xJcU$|?7q2!8>&Tj{bBX{}QWLd@<&~x`yTXWGha+EB$#qw!gpKjuoJY5-=rD7@fi_1Q3FzL(pXZ?jn znjZIQU@8#K0cOo(EA3ZwC-^$le%)!Q<8#dMqZ5YM&+A3k7d*vlt%~&5YaV6-)?Kc7 zBrhS`B@kyu<}QIa!xJ{c&PX*W>py!=3H5zLge~d_zq5`DrUG$of%Bh*1!#rn?m zQEmFpEA;Il^#xObRIhK(S*-6xHR?N5=-UhW^4<-Y3WW7FdpFx8#eBRrg{$98%=gxs zoAY)j&YC=!CDsRhoa7LM$;QCc!$Wy-K4GI4=@Vco5Vnzt`E8SIv@Y@@^%12$u}{p3 zGanrL4?}f7&Bb%Q@R{0SLg#+cFThkFth4cp?UHo<3+ITjX1QMM7jrs(aeD22L36&s zE zfzUl##qHs);%2%1-Fbtrk^4<&q|wOhxz5WV&fsj)r(~`8>{#+y^*M5for-;Pe}82G zVY|6tJ6;zDQ-Qd)!2l?@Y*wAX0TKT=H^#qAuqQ!WnK zbhxnT+^{Ln-+fkX+%72WG*tQ?m6dwB12GG3Nb4z`~hkUQ+`(ED2p37gI@eGg0p!ZtO&w{wzBH?Z-%VeESg zIClI$Fn_r9i*mP%`_=ILp;g#uLD*(wUwlw* zAsaj0a$&z1A#5}XHsX0DmYU)BLigpR?qDhqU-!L|bdTd=g)-gIN7kr&)|hDdHedi72W@+X;$ShM|2U~X zm_u8 z%3oT@-x%_FFCR<=;>yQfe#x`XCiGm6a<|+!T1Lp;Ov(mRfuzZv5R^Su$lgNA22+8g z$(|U=#`zZ9FF6@{$#)m(Ml~jVHdVW(KJIb?MQX8xukP}z3-~6a-@k7--sH8m_95R> zZ2v>XHsp=apV(RhxX7T`Q^uZWUhf$$OMH%9jz|2?-x9-^#@YYZOdV^Js7jotxS{g? zf8z5~JNf+G*`IgLgD`%3*YM6{<_g~o2L9mlpGWoA`uyl0jQvuckJ|RixNT`;xBCpJ z;pgq;&~Eg~OqOq2qb#>Q?^~zKU_a4i=5ViUwK;rw z(w%eoUWj$RV+>3M;>J4e7~9w8s7*``-oI=zD~;CzuMv)i-3%qZ92pS;#+1+7nC# z;>r)&^OzKS-Z_ix`AxO<+*jy(9Q0j1Ue5+ofv~=X+)(nL{k?dkb?jb+Qh!R`+>0T$ zj;68)=swJOMFsbf@@jQ_A1VLDyO{;2Aa8@vS1aSfieq!cPdYZyHS$PzGiN1>*E44v zX2-e*&_f+J%DxdI{l2lCe#_c7qHL&dOqaoZqb@7^#?j9t_Kk*>*f(ln8T&@BY;ApG zBA!{)H!|qdzR@dMxo>Q1zY+d%lk^XW@cm;-75;&;A^%91!TzDkO8?j)dF*6ZiT~ubIDX-^%sX#cFn)Q|gZ7!W)#!eT| zbGD2f-$dW_Vr)Mk*OBe9Mw|J({Qd&pMZm}JSAnTOY~467k9T|y68Pu{(B^~_?~q;u ze=}pS>fiBURR;cCHl&L8omLIr`+tDY;}WR{muGO5X-kf%v{X&Bo}&u8dJuqxu+CLXU@~9$+ev%zAVxMp=(+G5Qi> z^i~<8km1MZq4ZnU7)9AojHb)r7}aGv6Qf!{#u)X={%^!6gHDZ6uV^(fI)mDhWAr)c z+h8gX-?tC3F}h_}#we>%eT*I^^msw)0j2`UtVgF}l=a9KqYL~>F?ySfQONLP^ldN7*5I%fk|@14obGpuz~ z+{@wlFUzfZ{(F?r_XBB9FcpZaZ^)h>C))F9A^#(3PcRjTD>2nSf_N6t`-{`@p&lyYhO4k9NK0LbHi_!_C0|}780xVc088A^Gz+{900|t?U zKqBZstT-7=Y?Cu4m>i7BIp>@+m?I}4z+fE6#u$Tb`0DMRp6crD*_qirVgLRg&*MIM ztEZ>ls_N?M>M&@+?^7qxZ+ZI^>W2DMb{pKMbY0n}wodO;hLqZ;bYnUDlvg*qPhl*7 zfb`<-w@Kw^4y_q6)0r`vSG9JG*3VTKIY2ro$!vmd#6ob zy)&pO`ON&TxW7kvRV9n@8rURi#nX-aB{->5^lgd1+bI*-HeXLcwFR*-Lbo z9h-Nc$fmQk6xvJF)4L9A?=ES3VAa?j??XS8eq(!L8^P~#ANu#OH%Y%#+f}?bX-c8J zNgDIr31+=l8%_HC?Ki+SDc@dg)MfebUhV8QSeCkO&Hk3UH`a_3x`CYi&8u5qe@o?O z4)r%?I`&`CQ1Mys8DXMoQ>P3#gZim3gF6Ewl{dC%%eCV#OmS?}rT-H$5u-7EbmOv(4BXBF_Ls2lR9*=?{t)pdnGr65S0Bg@DY>jrYh zre59b*i`0<&nCPa3$24OnRCS;DirRRj9l?CHcr_Iu@J>6{}1PiS-|z=iq8@9oe24I zt{6mxg5_&+#m5TyQm%M?j{nA|^kL^b3bULeS1j$}T*2=K;FrIL0-{3U@{9Gw;{?AY zM64Scj?JB&sXXsSe%{;>&pcmc`hKnRZ9Tn@pzq%&`#zfR`~G?KTi#d-bwhnWyAAI9 zx^B(BpOL@R4dm?mUft}z58wO%>Fd9l(`KeK=cQg%8C2L<>9l)zeCwzDCBJt9}H_qc(mQ22fAc-z-@HuKPJ=sB+A?v41ZXn$+jmqAo0 z_*runa?#tV{eR)x`pA%6hQVhOx0FBpVe;d_43j+Jg;S0FkacH;pdVWvuCRC~K ze(4L)gzpP3rr+}V0@Mxpg6uZf7wEb*eL?CR#pI}T137(xSGPW2kjl>-%26@XnZCfQ zDm$9*3uHgLgmlUMY!~!{%gIhnKLb&r@cY59Z9kY|`q{2dKZ6~kAB=0!{eXEpEba$b zPtJWN>Qceq?z*2QegH&;!sQS7sFOVYrqOe5J_tIXp?F^@7=G?h>eOq*j# zd0r;?-9z#VqC%0y@180Ap5pWSS&-jd^7DJS;CC;{FNg|77QYqnyB=N58dtRP?ZVwN zkz)DY+eB+#)c>S>ahq07`CcLT-CObtqC%0y?=L+0N*!J)-Z2yJ;QSS@`_<-S`i_XDNePxs|MsyQTg{q&rY`&oEp zA-P{8WO6WM!u}aVg~F8y<{Z9%R`i^$lj@&`mW(_K`R8i|e}{lSUM~Pqp|J19nbnY8 z97@lX*QI?}aYgGt&hT}%Ld>J=E9>FOG@Z%5eVyRr0z`$v<##moud~5N6MdgZ$3NujcaMF} ziC}zfd_cCnYi!g(rlD9=N8#vuiT;?2h5)D&d{3=wHdY3i)^lO z^GTs~y_*EilO#?M6$&5cxjxQs;%_aV9L7nD++m#U%_+ML8REaPAto3%-Xw(aW`Xfk zVB9Q;WkFOZT#Oh$yjZbR`HjV9YNBtin}W;P*TX>eZ_TZ%)z=8&xJBSNUFr%%g~G)F zn>^3gRdZzGk25SDX_JlU>cwn`8M?YvU_47=1W}>zF`n;Z)R7~_SZ9YZ;$Ftz;+bY0 zop#FQcK5bnR^LW#q(1+)VRW^w+2Xcg)8E>o)h9-DrJ%pYeVf2{F7WZ$4iFUz7azv$ z3k1H_%6ashtz*aS_^t_N_(?EKF?FH4CTVdVc%`9e0X%T!MFS`~jju;l3jje_Tq>h31DB0hVR3fvD&%3JlA*goX-U^=E)ra%T^{PV(m8@-fdupGBa)X0fFsKsZS6U3Kv^#8@|h8oRc>EbQWyeZ^J(6L4o-m zi5WzN!pEEzyR}sA4PvI{PZ_&8?l|*X7 z%u2qhUtOwY?-*D8WBp^0LaR=0^DJG5XkL61?pKcr%ufLGjAX0_QK4`#k0o7P=EsIQ zCa1HB`o;KG%ahd7oc}%vce&jLYcXIx5;!-w%dR1PKPIq04eXPXJPe2mg^Rsr9_E=U zb@xvmX34n%8g`>Oj(Ng)n8yXq-%FezDil7>wDG_4To`8~bNer|Atrq{oQHWrV0<1J zIS&J(Lg8Wz=3!p2*i23M%5}-!LwPigS)H|}1Ln@Ht8gCXNrB@fsVfi_3KvJsJj}}$ zPvU~KO*W#dH?kpS=;|qf@l}ZtM1{h~m^PMIUJGNaCl9mD5K>=`f!o9?X?d8Z1->_c z@ASl{f~Ziq_=2|hrp1-R7Ehw~&Au&miEjanKQe^H)b| z3bt6n7*MQ@4!MS=et;6FJTXF*gbT>O}?T`Ta@oJHrgTT5+~e_25!jvcm+-0XE)zjD6D z@n4d&Oh1vt(pqiafVB1s=-i#JEkit94_O@=%j$e1t8?+Ebntnx$PRuuhEcb#Xs9a@;hK(<{iSm(%)gtEqxV5F&CFtabbCwGL?B~1m}js^Wkjd z9T(+%$DEbr`&C@{vXuVmW$GjBpF8PVotaxD{s}~dg8h^EcKQw0Kh1!Dru9x7BE!8; z`Y_pG`T;R~mtJ=ph^u>JZ$q^CE?KMmHBf&ZQs?qBJ>$M&!EHAvIHwBuQ7{s80zbNCzCuL{g_12fO7 zKvXDP%!pTS3Sy?fe26iE`r(AiM09G2`~GF1*HB#R49D?-)!~2ckCB*&Xx2(!suVV z;|=kS1@R7EI{;CkaNmKogImNqS}P0Db8aqPzT-{tj!}3ApH&1=q2PCzd+lx&?;v+( z_Z8^A3;zaSnfKcD^zI5%d_3cH13h7o*}ez1@BsB~_l#jGKXd3@ z5i^~6uE?ueu$6Ds26^O_ipJ0k9*8RzSyzkFBlx4h&JM1{h>8~fkprFZ-Mtq|ak?);VfT~ZH!e-QkQ2Y-_j z`GKfVxcnhcdWVo-9G)U!xDquG*q4m8hdZ@Ay?x24`*m6DF94RGVw*{Nvzxi7Z5y+M z*NNT}7$*QD$6g>R6fQ=@UU&Hz?bzGU_pTUM@%x3}7dTdvI6zb=a^q;|eqqLu=YCczTb}l|H{bF+n#r!Z8Ak z4f+aU<2;+=e~(!(pf3r=`T@JP)zkYCJ=FJD57-!0K{^xQmV?PEV8bweJsKp1@ig8VGzNGe!dVNZeCFHku#n`-B3K0-3G@~ zx^B&QDkCqb8^{??d3Censh-|nlQ#Mumv)3^{5bS4u%n!EL*0AE%LmKyh& ze5!6Br`)`{*>d||h(np_%sAAmS|kqrE9sKs(Cy(TXCz|*hzf=4ClTk}YyIReOdL9y zp5r?1JrW;^_IE`4d?yTu3I#uF;>i0%``QohM2}*Mto<+I-1|`{QjGl-I3Ch%Mw|=X zj;H4XxpL=5EvMa2(5^g`YW;QiJCh#?%u|4w<2Dc#3Kuitwg)8UsG+p z_OZaRtHc4KLXjIsLvb79C?2QVSo9FGN1D$;pN!(aP4OjzYd~8!FF%HC;y1` z>-!+~jhBFsLyXt9>WkADO1vH;7N%{yY1cL-j(-RoM*#<~pMj`QxHzzW_Nc&7y?zE9 z&YBN1XxDti8Q)@SK9c{h1pmi^|4kD;fT&Qo{Es639~1mLdN__6@Zz(_Q8#yd#!z>l zUQ3}rW)#k9PgZ>PPl4wIi3dc5A~&8BtMRO?zmJtS-ef#4)rIG4f#)QN2SkM;H=dLG z56}3~`SjD%dmh#7dn)mlI-dr)`2P1B`i*@c`!)Q|{uh1Ye|^nTbF3X{-Ze`tqo)%Y z=`jVZ_+v`P2KmPn)Ma_{n3CNF%U;*5Ii`Gd6Bf{$%IDn}wd(J+m1&1NU7|P6Fjx_Gqmi>dtd>bp>9ZL*=?}SblpT}a$Fxo z?Q?u}4aSWbN!|rSg~A;-kXwAhj_doH+~T$L9M^Gki(R7q>(M^PJs>I+{H(cK?Mbiw z8|XQ{+oY#=1|KKNaZ8^~S8Yv7uw?dZ4kQsgc# zrAVX3-Jj?OI1jxT<_eMG=fCbS_eM^E+Z!6i2H1=nj?(T?i;=#VAl3dJO^#Wp>A<=0 zcaf&%gY`e;-s`!6Dd(I5by+UtBhC6#(}6=Q0d2Fqblbw7y6BmwjLyoxgh^;GW7eOr zo;3`zXe!?WHJ(n3NyEM!K#qSz?}4r8nyb?sTz<)PFv_mxMfA*Zi^s8G1JjK1=;wdMUxU%8u}<2q(t`3DAHH`<^(O*+ea z!A3|zO$K1^pGi8s8@ER@%4dK{R5Y`*rUUWs@@4dE+^FPv9-=bOPk?9ce;_Ip%#Z1R z&v-nab%)#kAXD=V2+E0*UJslX?F9M0w=J5{`z95JZ&b8=zUu=}C<95t%XmUfL9h3WbX?WK-u5 zG_E6TYJRklU~_G1RbXSALPg6o{+(`93lNogeqP!XhzbSs6Sk>yVN=e1yVj=WH#!-C zc7l9w3BFfNYzh@E-}rZIQ~Fjl*i`I8Uy(i(KFlAN7op$s`b^YipUE+Eb{p(Rb=|~| z>R77lQk+oKu@t#_@l6p!GDwYJMEtB9%Z#7R*%hyDcKj@Dc2UC4`hQdEA4G-1*Z=Qr zzue#W!CCYikLhO35PteO)Qc4J`0se!6}gP^YSc>VxGDMlq2PD6x4brrx@@D)xW1Sr$Z=h_o!BE} zh;hBo=&gJ}`ndi9M3XYEzed2a#&z%`Oq#}Z{3gbA{7_?D|B!g7HLm0FlyQA=BC$Px z3j5%-U=S4w*FLZo{Jgd210fh1XY4(W?@|L4dBC6bP`&$%KP#i1#Gl1u44CR&p-f{t z=7wgBM8$Yw|hKeyZ98QaeQGty<$A+J`D$ShW52bjz3a*EDEY)GW zUjpy6Bu@#VLgC`2IN#d%u(H-A?f-j^bx1xndeG=_9G*{bQmO!Pg4W>{(BX>5TOFdJ zqdZ!9owR z!Yi5nyByj`>?V$d!BFq!B%R*Pmb12xiZ-Uizsu*O&99axD)T%DJoCB;hzbSs(;ST= zo?j9?)7XK*73)*q5%bO*Wgn_LKfXcIbl?hTE8#sJKQ!izMLm2J-tn1s587NI|Gc9{FS?(b4B_oZ(l%N?h70@XScy|v#y);4;?qZd~y;u zBe6(pwMh=rkOFaY|9>Y`Gp1wkwMlX{KY;30mD>U1++sO8DgI8V>?h+%hHP`gU~@dD z2T`GLZ4PURFI$^ark@O_=gJ%7mU*-3*XFHWLA^*ZgAV`;%@Jfgy9u65&s!}tmP}_> zVmdmWMU%cCU5S3nYdfgRw&VEGl`TQ~QQdZ8CpMma)ySdzt8_m)KSYxf&u&G)${Beo z@ZngpHECVAYqvE}4ASx6tMvQZB2#l?j8abcU(ME#J)s2_)K}D+@ z{5w78vj$O_=dseJKvXDPp5b$Ro65-ftciAle0w<`RJ45K-_<#v6X1VlC;msraqtJe z|5=NE%j#=>MXl!?BHr)tjCd=`f zUNmb6nMFM2&J}I8GsZvUqne|0>F=y+p3H)!SgGvlaMme1s#)s@uTnC@JN{_!j1J9k zcWG!TUL4XKx6Gc;<2YG`q-*hGzK2CUhnRIp@U4jN&k^%Bmp`EFcc&}Ffo)CWx|(Wy z4%&VY-2vnXcDW@7&uFs-C2v{#6TQlEid)vKOxvTacQW^^fwzl@x0Zp3X^oysn#FRhyPny{3>%~+M)d8(24(+n4Bz&J z4C8Y+m_-~U{iAx1hwclV^m=VeyVBpU96p-Mk5Y23UY|Gd$Bq`Nyo_?b`YVNbDd%?`}3Er*|7ZwJcU7_Ow16J{LB8;!nMN4qe94hvc)I&Zj2j z=W`*$C;rsS=PK!Zii3oWzNAl@=^^o3gBK<$6^DH*@ zfSC>~X*2ELasDL&(P4+7)vc{cmbDdI(PD(^rfv9S#qA|y#diF6#;9S@wtMR%MB0w4 z@n}0PmGP&4@hq}zHXdQp5|1X;fk)eWN#73Jzj$Wkz#~jw;?bl!@SuB;z2Q&);<+ye z9??Z49!<)`a~$=bi^Vv$Dbhofzo0+;i)Yj29D7R*jFYiW_lxh=F=Vi zgRy5gqI`*1Nur+I<8A-WbCy{iJp3P;=e$b{_uD+j(Ik~;Ny%L?`Av)cAG z4|8IUxXg+T*nY#Y^~>~jnM(M+W9vo7r-Yq0=A?OMXP~dgw$VszeLB6mcwet4w*F5V zNCIYYy0P_~&E2fAlCN~b!+^-mA0ciQ^C@Q!cknw$>9=LJ@jSl9g_%4Rxt9q^wrcpPPo6c^7bJM!6lbbF@vq{c_D6X?-X2NT!v=OFd{B2a#oZ#q` zsl0S^uo>L+e(ogooTQA>jOumP7fF;Ur*F(wN3Uw|^o`ZglF_9vT3=C$?#z$<6sl^* zdy#1!)Sit!4C|Xmy7I!(Ra0Qa&SZ7T-rLa_SBX4(dsFz6;ha|VmJ+w6 z1q=P%9cLJ`QfB;Y;@>nIGZ! zQuhdoS@euIU77Qcx&iIuvcE;()y>||-P60u>Lj;!rQFbrFSm&WwvOnScB)&yrzJ`(nlyYNFO@U1z~Gr|%`4l0kJIf+l^PZ2%r7 z5w)@f751nZ%f-ckx{QO@w6oh_%(`x(Gvxc{#GFLGMLUZ<$#&&LG&Cofvpjs1i-$QK zL+@sX3&qmeeGOkab_|d)^qiH?2UT2zbhIw@jo^A;+Q8}HoW5o{&N=-(6qfdLRa}H{ z;_SJ>=?t{}IG0N7z`2jhy=RO0-EJ*kYL?%VPUg5~&f3O@sXVwjg*nT^L2IYU!R6t< z(SQG5#o2$O|L(O;9{J2!9ewmaz(dcv|9v^k%EiNf!&bLg&zH`B!&YCY;==m0|8`%V zIPrf$J`YrJ;mfC|ccb-bKJdpRw$wQ(j2eDyxoLse5_LndWp*1JTk5(=Y$@jhKd1J2 zK5(9#4}hppaNKL=1Mk@Rz~N>-a6aY(It?7mUuXt&%>FA9QT0Cf0{M&01iu$ZenC_y zviSX7UViVz%`{c}_6zX4x#0IA@H?3TPIIRwhzfv47>r}$ z6(4Y+y2!!ML?v3j&|O)qlBebxSpEG5WI<|tzoDo1W!U^9ieb=}0)A)7NuHZt2idWS; zrV{5DM@Q37wXtJ$-Zad!&KaLV@Z#g3nM=0mNn!`jdvvWs&2%v1(N*iqn{Gk6X1{Z- z?8hJ~6mGx3Uid%QesP5HJJ;3j$IR&ue%hel*;4R(gY3s3Dikiin3ugL_$>_!-X2KZ z`o^SN<73XWmlhv$-j2F?)ZSeh8|l5(uw}%G@1xCT{ROZZ`wSWS6hQaCpME6CuWR-~ z?)EW@k*(9`=OJ=ynXIc}g`f85xHe#<*< zpe~OawAN1g9~GtRVak9Pd?M_|f7(}s%n{1N_L`%K#oRD*ec47~H1HV_pGm-kV``(Fj`xz4oh zh_({`<1=lV|7LlQ5h@lu(}qWCoN1d(WXAX;FwRI~MGzGV7bDKJeJC*2Jkz!l+DNd) zXWBG2?@SviTHWB^>1Wz@CMxs%jI=2b6$+Q3?+F zRsQF**#8`t?tk7V@uvBoO9@zc4;rp&+&u|?j2zkj;5Xra@Iwv%^B3ZwmjA)yDgI{$ zk=Rx~mbL<-LgCxW=hnWD&*gviMmxT(fGOYqprW-E{JXaQ>7^RX`)A;t{SSx=h08nq z&))>^x%|&ew3YB5`yb7}=YLSKp#Q-mHT=&nh|Czj07mvdASx6tM);pE1jd^FXCJhY zV2k~a#^(7SRJ6LmztjECzC>l7{~>J(M1{iT8UDw&sSN+~OSBW@+w(uDX!*v!tNl;& z#^irKk^Tq%!1q7<(QkSE59$W}&;FJm{f}ZJN(aQ(*M98`2OcG`Yo^jLEWJLIouMY|Iuw% z`JaEr{^!@}{%0_WH_iWaZIbPOz>kq5`yc!!{11Mp;eWb`hg$vzkEi&bBZ$PdGF;jU zhzf;oD_>jtJ}H;~ITG#owgRSn|AUIwR`BoI{^uyF!Mra3-r4_vs8G1P!~c9Ec+cg3 zjz(Jv|FQqk{CoZf6$|3@zz8ws}9|7dKU z|3O8o8~i)n{~SkD=6RH~DG(J3muL7N-=;GB&+%v{$hYTzP|@;@e^>jTY1B>o{wDno z{DJR(PN3iN`XAI~|HJz~v)h=PWYL0stxDGwKIun9Ytyt7seP955>mz>Dipqq|84E! zWYcfQ&~xsdU7ZR0B9VmNtpF~}p54W%c4*J;uc-!OW&ZJd>YiOqtbfn0=Jf9gr#fec zCVicq1Rf^Q6g0=4UDRb9th4Mk7_+XMqO+5!eb(7{sWT823SVdcu{t}&=xilVXF7ZE zk3^2y) zuA8E>-%$Ikv-PCTKvXDvoqcO{cB;|YL{DdW#zlM8o60*QJEC<4E{x9BNzvJ9RD-cH z|M)#sXPQ{Q&NQdrB%ErUp-Eq7r-O%_IzwH?!8*%sgE8y6DLOlY+Gm|@A$10#LgDM| zJFBzb7@ckD=}bqd|4t;Kbp|es&Nffc*_l*>u`>VoJymC#SijCRr~gSf)jC6yzRu19 z4>@&)x{QN$mfZ$p)^$^Kb~d%oI@?9+3`B*(*I6`z#>uAUVdc||&UW>5rbqVg5=m&C zfeWLvDJeQThiWiZ<{!VO>P!>s*O}&&4qwF{LF)`n`Z_xoJml0F>M{=2S#}$YS=UW; zrtbv)`Ngy&B>XK6Lo(5p3C`k4jX8Uz8`CmcvurmM(MGx*$OjH=8ag08ZD$UcdUf-h zy?PXJTvH-Lt!*^p%kaDcGDO{w471x{8S1)HhBq9SDnmm`m7#7drwqNi*)k06jjO>A zSt({a^XJ$b$E^HdPkRQpO>2HoQ*zGIXx^)uXK&o70a0{7iTCq`dDh>@`zM9a@u^aC zta{+!Qu%apAA=(23<<8|O5f?1d@s-03FCe*&$-rSNQsZQyPwfxkR6-Sz8U?Y!@y_s ze2M7F{29F^DSX%8r-(1L8caU4xw~~p>$ss2eagOk2H}dFTZYX3$js8FyEE=4r|iUwF8d?tJ_&8G*@-+?XWyB+w}duW4OS8H2) zN97sn1>L0%dl6Sh2eGVoxD6?Fx6&3j`l6!QUv>%o{r6z<^@--DTFmx1d!?AZ@zlt8u4wu}5w>1=GXAZQ@u86M zWO9E-#vm#bEaPU~NK;V8v`O$)lAzvXUA_1BbbU6`>7VqqjB#nlq8;E{{+xif>RZVN zCO#Rvn``X-m3!1K5EzdD#?6!S8-^P*H|C9PjaaX;OR6h}UO6YRHat=eO`Anoj=$2@zyQ1Evg_&Xxu z4@8B+zPo$r*63_%qgC+7eLmFH;R5u2!>++CL0`~a8r*7Xbhp4Q3@Ht1seEU3-QC)b z4%arMZCrbMi**n9seMTMxXvM^!S=`2?hZ1F4(l`KqcNcke3s0>}vG{#*ew9Q!k1ZhhBPmM@^!*wpqrtFd09t zy_kN>J2ybxP+Xhc2FJC!u8eC3^7le0I289X7*c9ns~gK1*Lrp9i)(A}Qy{KoRx;yS zuWD9YE60&bNM9VAorV6mW#XqnR4BMVHb*}s`FGgsLX*m+6XIa>1V{8IWYubrcA z$j-CdU^~}!rJb)t9x7!HY)Gkgt{cl~=U&}xJC`?Dz6dnd5?jp7b)iPCtH~K17jDT_xQRk_j!-Y1;3X{enC_yviMy+h2KFw zzZVDjJ)cll#ZF6%3B^uV2!5}S{DP=ZWbwOJ3cp=Gzr(i-$@jPU`Mpx`d$r^jM1>-Y z-*r>?T?zL*yY{e8kl(ciTzaT0US^Tb_!f*V2QMTWw?(Ybk>#X^GQQ6L4GgDZ@eyilW<5r>mR=|F*6a3yK`2|s-$l`ZWUVhJPl;7(GzxPUhK~yNR_}wZm zzwb86?+t?A2f#1StwB^MTz)aPo(pz~HG_D3+m`sXb-cMX`-Tx)8(Szex4u#E_pp>F zhzf;$x4l=(AAfgBk>}ig|C$u@D97L5-Y-{~px9pc;X^dP?%=C|M51ivpxenC_yviO~mSH5or`7I#d+XcTbOMXFAD6;sS znU~+u+cszqcL;u8ll+3HP-OADZ;Cw(_3h!{Aio#ow}(3gzi&!@K~yNR_}xE+-)^7Z zH-r3MoS)yj1i!N-zaT0US^OT9!tXpjzpHK+vWH9Z^Lw}8_g(NiBU#G;QK4}8#rQif z_;AMGUlG5yjvasL+u?F9acRu!Mn!Vl_Xz±8aKP}p~4{0;GUSRVd9t%tvR1%H16 ze=5o8fT&O~f2HWhB)?%oew16k6dI$P&SmtMlI><`?MUJp>Fn+n%9hgC?99CVDEfOF zz8B@LoaI|9=_=Luw4HMSxqCexk3}nPPqx;omnH_bB}*sCcMc9YG&H}yPsr!5kPm+Y z8bpPH&hq^Z3gOm7)dkOyRY# znaNd$4%`)X&{{*MW3Acst}V6<>Ffc4^E0V45ETj+=P2SiRcF6$TxS;nL|r<2P+<8& z>I_7M!o`xMvs320&i-9oXAcRS{{YTA659k(p<;^u?RHF8Fum8TjtKi- z-rEu{Y`1lnuyi@NWpFDk-kwhq!y^&}y*~6kIanVR#f6lX1>2wxnZPHnV zZ0EH}SAy-l^gP(X+y zPDc4Uxgyrdm6q}9eNy%6WRsm6)yY!=<6vMsKN)vHR481Gh~pRbG3xjh?z+8ljfLq1 zhR_lAW-Nl|Y^*yUI~@`02F72<4BrN1|5`IB)eD7_F?X|VLu2mK0{0MUiy$f#F7A*m zUJtB#w+G)Zx*Fj;tP_3A;d=Ke0b301R7#fplD;&4rBGjbM({rm_~&znASx6t|D%Yn zMT2@He{mB5@#ZCSVg74%m1ACV9U!*p=~cmb$+H5>aES#(g(5eWTN}sn&$_YvUSL^3 zVgXU1$c^QW#<8qCwO+kEC$KCCEWFV1cH?m_p zGhs=wZwT|idj^oU+i|x#Mi`UC2kTBk|McU7K7n@>@LrktLJ$=S##@TY)W&EZZ#+Lv zcA6n7tK64h#$Dcek4wB?%uR#Ty4p417M*E{6OuV@XY?*w_ko=+JSW*>X2?H2FJ!T( z)IEp_1K;Ueg7Fs7{UZtH?^E}y?pm+zUlg)f z0Fs8FzcTBC8PeuCz>cIPoAO)=T+ zs63U(=o;%Q;+?{s?oQ$QorNPS=j&bWOs$P)YGKc^+HPsqWn|Y8opoWzue>Z|x0LoP ziR?gBC|Gvw(b^<~#lk)|GzT8s?(X9@vtioH{cIxBe^7h+d)9IeJh;uAVTcywu(Ycq z{j@@dIdim?Bc2Zays2Y%9c+!RggaQm?p(MdJQwa5nM{%06FfZj-2;7e*s(ABd!WOk z$KHzOBT;yJ@m~@8SqA#yIU0xx1?$J$yYKH8=p$+8ii;25o!Iv0XpO|huL}N`2mh0k zc{GR$h08zYY>WH$W%Knf14#9~_PCq4jAshO#}5LkKXJiM18?GD^J{dsbtk>X)6Z)H z-+18T`5K4{g^LgKwIzc1%zW)N3o$TX6Bz58uPr_;AMA|z+Uo-M1ZkHbDikj6(0pwc zu%3tApmM%8bw2ocXM{KyTvyp;t3AbA-kFYV{Ni^_(TKeBwKoL+t4X^AQK4}8uW6TW zTcycdLOpi*bWR1;w#zpKzBMF15EY8t`2JuOCGkxmTOL!e->uYBZGe3NO?urhvB!y!x54M?dT5ZNdLW;Gg|Ghzf)Dx8Hp@FR47;$&CyuW-IBg6^r{6rI1c2%qQZ6Hr5FxEFdEnEq>?`e3QXVeyVczpVkz`YA_UzPM{5ETl>U5Zv9 z{+IImbG%-L9Pw2cBXy2=E=T~AO|fYXeftz@V`;RJ+t=|jx|1Ys8Q0ZPV+Wnn?Jo#P z>*~O0&OYGaBSSvm&q7|iLta}Y`5q7z3YJ$(v?gKwahAN0R=kGTF?$|pzr)Z(cJ8JJ z$nIWWc20gVYuz!w>_i@I+~C2rb}Bk@zG+6lDr?L6${Ry+{)>?F9*{HVZ9r5gSkB?R z&Ae8MaYe`vYwK0}cDs9tZ+|{gF0gO+uY%vbz%Sp=0ir_T^1C$gv5apQ*OCoj-|2Pq zSFb*gun3aD5g2ek$Fg|V9TaQrd&qG=2S-c?Ll}O@jrhPB=DmI?Glw1DyqO_FZ@~cfanoP+$2-$om(N_s)uVlBWM|HTc`ZA0(EaKc+KR-kA!|2lt`*t?@Ug)0OW@%3 zSr8Qp7YEj7R}A7HE4kkGp&x2Mz%wnu;|#jB@D%Dd?*$Os@nk?Wb(aw4PXy)zfcc6< zcOWVhF6M;@!+0OFvxj+cqdu*_ZR*C$6MVqDfnX@O>)q9V~4VM1{h| zSJO7f^p9=65&%-$Ha`&c!gK)j^=`;QXaOzw*4*ZIzveYKAX z%=BzrXzz-U`}aN+eb?TZ%ycdK1LqV&Qn#Oqea;lB7cf%zz4 z-YV&fASx7$xuh?ATRBa~+W#cumX3&*b^7Ls#7{%}CJK&EPCx$fFVl=7kx_eez+s`W z<_jUCW2Ieys8Fzs%sz_jey~Df7jvc`yq^lWc0c&Lz_duO`-{D zHlh1HYyyEEF7JwCnZdNVd2n02(%XtP-_@u>cN?q*cXthG9nw}=DUs3e0r6gg*jEgW zPp`U*z4dQ=ZW-6!5)NL(KIn0&F;4crXlFgSotJ_Kw^5sI;a5B6yT^WHzO}YH#Ql8k z=*yM?6ubCqj$aC$o&=q4ljsygg@Se35ly8wR!P&T?B~!alxuEa(~&A^wp;5I+V5@~ z+!1TH-PP`p_R1=Wepj>lwRdot#r%QMLcExtN5ARU2{}7WoEWwq{gTSktR=km?Gl>#@?k*vDtf1UJi{3quN-w6Hw7W$o@#Lgfp6s+Ioh|Z(?XOT*k4cKpvC;G90 z+yk4n6B1mfsvM>Dlglm_nwS1d@OvTnWq%K%LgDg@dFfAldmK)_0_T%{#(X!DGkK~S zMlxp!`}=85~0p4m~uLcdD0B{zu5ETj+$I8Ut8Xk_mr-#P3{hJ+4FJMO#!P*?K+UTBF`p#5)Td8~l zsm-2wL%dFY8*33a($BeY_6VFKqh`}IZP9No--Nc~E5tGFwDSwXP0@(oZ@v|{uL5q) zd4Z@i zM&Ah;T`O$^M1{hY5&CLsesdeP@kaXU+J{uRoQ%FoVTW^fqC&x#OVNsid2Ju_&1A^#{rB3k%_`$$ zLhmjxLJlWU8)EN(*h`U}`*(*^XD>zSyx1}Pp@(W07+z$zzTm*aLq4!c$m%x8YTIO9 z3Zg>6vTBX6hO~|^t6O4O=@lEgy95!eiB>7Zo08bdwe+kRU!B{!8_R_kI)2_7-Z1Wn z@>z&7HHUY_m7#IHS;+8C$Z)$vh9D{wEW@^F6_Ufcd1RQx{_&0KbS}N6vTGvGmlAn8 zG5>#Go~?zW{5=n=61%b60nu}PA(@wi%-jRb>rc~2q=7x^ z*aJ2Z&$xj|E%`c@^y9-dq@9Q>KI;vilB{U59}A!LZV?#o2gXW*5k!T;#W;%iT|W)u zo`f;p;s$@UKGijM2o+yvd%$3W!{G~Ms6DH*wbl;ltX1H72zWUD1yP}J@nB5-sgDQu zBO$=5=x(6boG`Zz#qHy|n)B_|nEQxS`&(~f2uqv5@~FfDqC(+g*}%twsU)!M!&n-L z4-Tk?k?3U2c>S}d_YUL5LTD%S9$yyK#EB!tSjXQNi zu+hDVb_CIy^hcc@xbTn~#NdFy# zm+#~zALZVe2BJdY>VICsvZ2-gt)zFlle>?evvq)XQK}Q)na2E$Ig)IX_$zd0TBqRe z1<4C;W ztqbcP?LFksdGY?vrg0Ts=|wB{9k#zqnRE%6ya}1`UArJE6s}BQw;KzYv{q)(bGDAP z+xR;+%-lz@JTOY+{*KLH!QX7jABYNteYdq+pTD>B@Yi{i=~spLn@jNbuH+9yg(8c; zKjh(WOg;R~E%MQt;CBZ3M{}1Mhzf^r`?f$-C|v$<-_|Cczy6Azv$@BGiEjQg0hb=TMjdT@ zq1ZXc@%+dILov{B!Q0o8HxLzyEZ)A!;_a&@`o<{5KZSUkPw@6{@Wy%tQK4{o3ypLC zq33L!)NyXjSayZ{;QWHW@4z3=?Lbs0?7K0}jUuIOD)dUR$@Y|IKx`5{AGvco+=)7u z$uI9fHEQISdAQycFxu+5duRcHrHNRXSxMGmKvXDPEF+1(p9?IMIKEBCS*5m0GqqsO zCv8LZ%)HJ?5Yzmd*JE;QmSl)m0HPNzB{5leFX0G*tp(V)|ADAbxY$DduT>*5clQSS z-^gR?=zk*xZ|&fXZ5%{}!sRVw;~n&zt&?iwE64m5vhf84e*?kaW{F*Zs8HBVMT?QLFq(D^U}><#OZr$Z-R9x!Nc^Bh}k zZ|43U9Wu4krcgUaTYZhtxVo^wF&sEJ#sg8IaB+lUy!ikl{a!uxirax-{~Ssq_lGPZ z_+J40AC>fb5ETlS|6wHG%|-ucEmcO)gK;J3U}dT^zB#834!@ORhSti_^jbGTY307$ z@*%k|D)?Ryd=E?3jX+c=e7-07d@oeZ_n+s@$@fx6c7pE%=(YLz{-NM|6!_jTkvE76 zh0nK_>nT+huI78?yz;)#$Qz+|e!fQwz83}G$0U4%s8INPZ{f@Pht+(qmY45MZ_{>i zY$3iE6MQcQzUNEq1Vn|x=X*<^@5QV6{&-+cJK4b4NpB%LSzPeF1o&qE2%&dwKB9@iB-Bh0Av+K3;*@)@x13(O1pw?~2FJLh-Yzg6<^_s@FxTT<}18u;V>1foLW@&`Xq)t`RC4B9v&cYhjo zoR0O1+2vA#?=_@cK~yMQzC(7oCbOMxm#cw4itP&7<2X8mRkhCx@w1ji^Ny$i{QwwT>SP9P3FOASx6-j%|D#cf>d*_79GC3gcKt z;P@$Uupa|ap>T18>}3Ob&enmQ2mRP~$Jb#m%L@KB0)LZ}9509pg?%^X`M9TJTVKw0 zo$Y7TK+0Z>?E>TTxc26hP2_AlzW^*R1zMCkyYzSWaNv1Q>bGB!~)yixKh4GQTpBMYMcJSG33OeIK~Sc+X2VKWL^ZKLgC`TJtaGcKGHHQl$smZN@?Nk zslh?mP_6e9x0IKllwj1}U7`=8(bg5MH%g&L8)FVt(h0*(_o@myTEQW)-B;{vx^yyz zrvN&q!WY6;k7n%m95*CtEtMC+i+Q(ohh5iikJj5b!clqeoWe>%E;~XlJ0|-BK~yMQ zxeNymA(z%tOJy=WX=6@g`U zjU~|whzdnEmT7fkIVoUcKlruwAq8!0Re@y>VA(mr0-{2Zjb+cevFsbbvPNB4RufqE z0v7g(ASx6t7OW5LDEdCd3udi=oM44okoOdBOZD|yU-%A(ygqLiz+;~$K8YCn1nuAS zQ7pN}{}X|6Z(!tk7>Ejmi!nG4>rK?9eL3>Ix#wZmhLvN-U7PRi>3yCm_R*qBlV1Fp zc{I85Ll7tW`xaNH-}3H#MBUKd$LuzE@1w5U$lgcYK+e67UR|0W7TWu`2I1wsj|W2E zye0~wLgDHgYoe2_P2WkeFYSFih@K1VNnqYa?$cI$-G5ENo07bNs8D3__Ny%32A)K{ zC3{aoPw%2sv9C?q8zB1jwif-C*WOS!WN+DRu)XQJiM=h^)Lbh6y3`B*()i2h@cCxm2m$AK%32JEnQ+!7o^H_=X zjAS+M=`3(Z+d6{Z>xVI~g>pUX3jTgA^Rx<8!6Abkzvs@@xUHgIo7Nv_&o*u@|+Jug~H_*xv8l_ zp3d6)KVb9b-ZAIwX~w!c!#Nai+U(9GXUt62c+<|FP82v!0}kH*1ENCV;uu9ZcJXoC z1If`Ig0BgOvxi`Psv8djgc-A_l z9y~u4c+LTygOj-dhzbScX^FNVneXcB2X`tCq|eiohV{K6j|sm)$AtA|JU9|$56e}) zgFSX&wn|wZpX>n=^dYAA3{s{KKi*cDtf=56AkhiLuV2!E^|n~9KbP` z+acbh3yh3fl4Hp&<@>=pPn3C{eCj!&Gq)QEnV%1tPfqfPASx6r^Jcv-V>eIc!JP}# zMVihbpO5_zoI@y;x1;~>E z>iByPdQN}mHoh;{OfQOkSB@pL;%`VonO~nZ@%miR#4Ryy_<59#1on%8{lo-2hzf;^ z9eI=o5kP_T?j`h!~2MW1a! z`j_shnMW%ceU=!H*Gim2_E~*aoD}D575k{wPuD#;WsPLJ?L&LUelGCcBy9jhg@W;! zwXeMdK8i>6T>~^o4TsXJzm+wK@K&^s%6nFqQ5|MbLD#(91~Zu4`&~B^7;lvrK~yMw zj5BUfn0<`b+8@ zD_O4%h7pUL6@dPL(@kwIbLS}`KeVO5{h-t>hzf;^8*A{X_Pdw`EpyF{_@Spm01Nq{ ztpvtLBt{Sw3Lj&t{Vvh}8239npu|ELw-y*5ml#1*D13}Fefza%3!b0`%2R2;m3qWC zPkw=C?6)wSVMW}(zF{aw%GGUCc$NdW0q%P`LO;5wH9EI<)<5dBW%9;c%AcfP%PIJx}Ap)?#W&eptu$ zt>sn;-Q~1{!19XJ6^IIji>0PLjt}dqkul(6VDr0NA$#0WV0>L-1W}>zF{aw%gfPZ> z>~Zq>{b7%j1-@Cp$MFk@3WbXgzVE=GJ(_RRu4W;6@eA!ehz@dX(+Ok57-09xINuC+ zyy({<*l=l{=_YH);cr6iByhhi^$Maw;o`1oyK4Y+Yt^^DV7q?_oW)6v*&Lv!{Wf5` zSGQ))qp)7`Jl@&VTmf61t>fBTD_2|}wT>MyPYg(|aqKK)@t%|ghzdn+S*&9XK*j)# z^y3K^1Y}XDA5Re&KadzfR49Cmsr`6j7-K#C_@BV$$2o<^m8k;XUx1It6%Z8)7vCtd zlY{+!Z1Vye5I$#I!TOFuUGJ<)9y>necUpJ;(Ul}$8D8JnMd0}ecsOnYQK4}0AZO>T zyOt^+(}Ts&4skN0>%xHH6*)V!tHALoaPYV1KvXCgM=4r{aQw>GiyrUsO$B&5nkKfi zSAJ$q(DSn=(DNd;aZ*-Uem2(y+>Vc$3Go!L-Te*;#Syy+8U0P_8bpPHWz-y{#ORws zB)bP<^g{x+8=MtSyeOdWX$4~R-368}B^D4BiX2!r2bP`ymP7MmxhRBXj{;bx2`v8v zmdQ!J8AOG`#ey+1)n{%AMAhHDh0pBBb^e^Y<=+9#w>$I^F9@*lYj|$hBk=tT_&D|f zQK4}0W#w+RN$Hcw-5jR%<^(-7PfYcnwR1PU7YD5LL3oCECTZu9;oQw00{6F4uOKQE zF7BFo-QI$h<304MzfD(Q&cEU%0lgxRTS%{a3VZ`z5OxcqLXjKaUqJpa;1A6s;<@R&_0AkQq5IR~w!chYOUefbrEw-b2T-+-u4 zxOlVXT6eH0dvkH zT;10vhxIP2Hiz;<)ov-l9iDUUEpX2*`z?qHg^N4bZ+iijFWNxA#oX%Amg@LC7~{ME zG+t69w0Xo1Ce*eaPr_%_dIhd-sZS6U3K!P~)aH@UOH=c(vfd*}8JFrKk23m(fV}fK?!KdMN8)(OR^c4O z4=)es8=Oe~p|Z&QX_WyhccmB2i z0|f4|z&$z13xKFlxVSNfrLO&-XhF-k9Wl*`TGw)IHC5M6;CjH-0mWYAD3;o`x(&xP z2MUZ!N{k>X6h6k(wbqmSALEa%X%yo@0^^S*Mi3PWA7g5M=Qm-D$OHV^_~_i{96kd! zZ~j$={=7lS=rC>V|6qY{IoUr!R4810S$^pZ3(*O<5P!ojoz#DR>7;7|s(sWkUu(Nz zzoZ226@i=2EP<#{xVS@SY|aMO$LOVTMc`bGaGtDjI-PB~>xf%ASB2eh$(g0TO}fQb z%HG9S%IuMwr0eWfPHhHL!8Pf_1}7Z7(;IT+KdM=ip1Oylv`-%iUeUso&aaou5Ax9G;>+4K4UV8&KNN zCFx_=UKi?PhY7i^4Y_Wf%tJv`C|It|(b6P~-_(>Vrs|hjStb?=zkxF@Mvl%zv@tn4 z9XPr%uPpZN4awqgA&d2-EI?E!d|904%L08Mu`$Tv%BtQ9Ss*tT_f_=d965?qTXJOZ z7s$XLF$2BQ#y#y3=jNLA_vlX7{)3{cnX_)tdj&e1=u%W*7}#pgShdlo)rb_e(dQNI zhJvoK5uG8Def9_;&kdyi15u%1dFJR!iv3?x^dsW44f%C-q>$0iAR|7H38JpSGBWqEpXuA2UKggld^eC_ob`I_ z1Jidj6v%n+bF;>U)4bGD7)y8`*iiz@roggoa&{3!g~G+MF!7g$rKNH+gQ0rpGstHN zJdPX5(y!A=9Xu&Peb>Bi-ZP%x3@tWB~yrczXE9hy5zh4kS{)+%|i+i(eL%5F@xF<{8 zASx6-?ppT$(D!5i^WN5w{huIkPXTU@y+Kqc7 zAaPth*xAm3$o)7BE(c3T@>)0VBia;3CH?QWmxb1jP89msRoWql3I*%K^uJnm_=FYp zob|(J-`5ETj+_XzR>sduhCPoNt(uf5ov8dQ8rx5#e2sUWFYZ;}Y;Yzk?n2PyF`^Ap7y(<4%&K zcKr7nfqOrR8$^Y|$6c%cy^(?&@y>;f_rJ8Wyyx))d9&~p@`aWIYR>0kp#QPvB6pXtREkgWX1iiVrMm;CT9XvX}Sb4{ETOF^^ z6hAuG-Rs()asI_XpWKWi9F^7gc2h&~?HL01p%OQU3WbmRVjp+Bers{R=ir_}xXoSD z4&Yq*KMu0o#3}#k%Op79c7VjJr9iowqoWT99j) z{gk&j5y8m*IH@WQe*U8D_V^ zGSqbw8KU1TMe@A_@{N=xYMCs59~lbaq=_`IrIzm@3r-eKtxsEGjIkTr)}`pPZd=C& z+xjJi^Z6Qae+c6f6sBbI)#b};r(j#!TiM0hki76MipzbzM$O%!Wq&D2 zyTkScE;F18?RGgq>+3dZ8itrhuVD?|I;SjaHdb}k6CdU

wrLyK~x7X)zd*Z|Bho}{Ph)M{{8o)7wW+D$&vYYB963fH=KVbu}D?7 z+u%O{LF-_ltpfr*22mYg7lK-Yka;a*u3{Q&UA}YuX`BxJNP4k4c!qZHYG~_3eA{$D zVu?EV6A-ixcB2mT_=rG{fvJO$jgMZ24id*le0y7BK#zgePsTX_zT)MGjl}I_;WBJ{rt-5uQRcRrS=`p5x82AX8T%Za zp9$TeSDA09JJY8eP0gKzK(!e}Ov|R8qA{OUr%xO1Fwg5n>ul}5bJ7eteH>^;cI0eD z)}uRe?0WYXP|!Nvi#lBq_I(NT7-*fQoy5NH&qED{XF{=W!M&0{SNeL5H0$f@?oeMu z^exS3ZY+HTLph>aYKV0B*Hp*sflr=yvX}a}gn-3veh-T^J9VC}_gB1BXFwl-B&o_7 zFfbgZTXyn5mGiCoa94j(oRljqwMb5`_K%j^AxTDUMui|bEOq1<=%3?d9E}% zA99W}hmzJ2efBxd!q)K+O(sRvsna#*IDZ6`eF-$`h|Y25`44Dg$$JBS(THXjV2GoY!Zx(+?kw3k@M4-nY$ea9ef7mZ0{2h&S(n|V>-5^ca}@at$x4&w-KXbA)G{uBq<67!Gph&_T)>6ErujPpC8U z+o%WcpLnPI^Z0_7o%)~Hm1RE7YG4q8XEt0K?D~*;3W9LputDJ%8%;bF0lRRzaX#nqpMl( z^*8zidJF=)4gBbDXlL}J82HkUo@vy3oBqEo`fEvlb=W^9&|_fIhyQhcYtzqE&O$=0 z-2^^*A>n?75j}mJ1_s%AB5uO(3^4ry(7!~|vkNyK3c~lI+-a>(NzyufigfJ*vw}X< z{2hWmlsRwvA4}eftxp0y2By69qfvcU>+18r7X5Q zqtWLUOWyUASFd{z=rJ(m?SnplXW36M2FE;_K3bE-??&>g=h+GL7?}J{g5LgY z=~vf3^5X8|ITc`asK6q_v{fjuKjLIL$}|8 z`&Qa-Auz)BJAymf_InKE)$RACw23ug`%0k4K-)ydSp=JSC9nxBo|cQ5?u7ZL%V;G0 z;tL~6e(@z!PrlVPnAy_BICuemYy!Bp7fp+0zC#=Picp1{eQ9al&f4JHAc<3U^>_T zGkCs)JfjTFAKU>};D;tnR=(W!LnVv1E6JN)_ax9`VDiSbl-DfYbiJ-zrI@7O+z)s+ ztMaLtxUkB{5aDi1?Tyb$osB%yUbGHNjt|;$5a=<8%JJ8z9NW+%qOHD0%dtQ5i0iYl zb&H>t&}Q^|%42sq!t&V5IP+A?(P_zXoh=7}9)l6fasAsP$D(~lD+f-UHGIR3ltcRl z0zC#=j#2xDn<&};6W?$nl@T83`xboz4%apGbPM&Q&-WzIV_@oueY)49c5AKo*?UrN zRVE>nAN|ZvHJ% zKm47I+eIt%Q)fUYf3MYv*}b*qS>t|RLyNs)KZsojd~n?4qVmUMoc)gGI5Il7*kj52 z5z4FAya@CdnDWjAjej(h_oJX>uX#~+u0#CuZIk^4B|H1X`V9RZc+@v}hCWViHtNQm z)P-)F2=o}3x?tP%uc$6u->2UtMK1N=VBp32^yJ^R)5ZMG{c9Xz(9XvHwjBj zYraRgrJZ3YX7>fSi_M?@u=)bQ*fG=JmPz`RL0uBBQ{vDY+g*lm%(#4I+?a8qCHK9Q zdu`Z%CD3D_<<2_0K#u>^lbiClhQ7Dm-;s+g^*Cj@l&RcjlpPmG{##q`{BxGum0NCe zCTJ~j5!#p&C}nDoTrOo|&s;8L#)n5SHyg7GT7~B-H zBU7C7uXC`|AnL<#;<#b!_fxOB-V*3B(0Wzh1=Q_}J)jgvJ9;a9vAGA-RN0!o*qZ8l zfwdXMY>o@5spzi~Ojy=;fT(kZ-y8&ia;%FA~1x`U-eR z`j(5yefy$L&H2lz0O|4M*JwBEz=t}sl|YYyX*Zm|d?TojPzdLPKZ|r4$NHA5k2IE% zi&Uh7C@IH{|-ZEf;|v zgNAZFm?+oQq!X5hDc2U3hn9m8WsG+p z3gip7c*CZxv#@58W+&tmhRsvWbB2u;(gqqWOs1B;v-l zN&Nx9Zj*#|O`DWb^};RJZelq;%jf`c<3s4AN;Ft4*3i8ezThzttf_(Kd;QL7T*Q z{WfVkKy`ipBYD=pvq_-GK=YG!`oMF>;@R+VKLP>2O0dqu{+z7f4x#s9@b1?K;r$}k z`D<9b@_PhC9ASMRYF-_M7xikP@8^CDO5vw- z;?J)^y1bHk9_fbV748kyQhzm+ny9|iZ+_P_i4;U1b-tRj`%v?Nu66Pnb)x$t1bPfi zozT}8ES=;sm1mK#et%>K(g}6o`+Cv9*n=!zPsB#Po;Zzt{f@xWa{bMgi$IS-L%E(y zlxru_iIr=XEf*0R$wi#Ta_tN(E!RJ7xd`+aG?eQniE=Fyj`NcWuHVM z!G3l2KkIm=sJ~u>WLiI|tmT^s^ca}>iSma9OybR8zpV_?daSciWa z$XB-x??sxSjAk8<^sk9H!a7XUQPg3aG-}A)LYZ|PCeUMG$~>|<{Bj_Cy*j)PX@|1g zby%d=b(pAcxek-a2Vc>>n|HT|9~=#+`6qL)#J+et(m65W#*RPs3jp@`Lul8G zKU$RUbg|E@-kjKY6k)yb$N3Pg(fEV>sB+Qc55BX;AAFH8{+I$DlExoQUT6HVKR~(; zPNzNUbyNa92HGCgI%;dsreI;Y!5)itkc?eNrC+@hZA_cc8p4sAhJE_q$&vBuz4WVJ zrz)kdPsF$TyB^Z?KNaIn40wjxofyg<&G|%}t!e0P26d;`TnO|SXx*uO7rsq(yP~^X zWegQ0W9^KyH}ru8EzI2w9mw=yef7s}qL0W~AVdttZH&jCv2YL|x}06|s@H)D^cZMf z)$csEN6K0K8dlJE2-hOycOJ(Ya@-F&#;9^Vn6yJVLcb%D{E#L4yRc-5YWp33!NT}{ z>#dzf#2lKf(>Lvdh-%CD5Tww0D^qWJt${#~f!3Rve;pgEH|+Z;DJ9YN*FZ;)sIoqk zbV41OwtwQm(9l(>!1jqa!gh(Mk*^=4{iVZzqGg*y*>v3}&|{!w8+G09ptNy&C?a+L zaOM>&znoj3>pl_R?z&H!qp$l*kxJ`sd+JWFX%gr$(7IFm21>DZ5!5H{8|V}Rp?A!sE-7q*1-RKB`(f1H-jsQbr|PAH#Q_n)=vJ`qP)_leq|?jH*jE!!@XO}AYH zdJIh2xL+XJc6BR}q|A)AYk=uPnas9JzW3JW0}(MO2gc*uu4RB|UKf#9y^c`lXSZX2Wl6Ok5?CTp?ON!!V_a|N zS$X&<7&|{$WJyPG+E1He? zw&O`Jv=!60eFh3O&WIqQt<^W-+ejqdx2>r@hx|4#wg(~{7D(UB9EY5Mmm?jA5I1%l za$*3m$00(yW*pL`Y}v)$yn5r1gP`1cyY!iOlnEa@6(Blxkv&JEOkuVN9 z96ThALzukIIOHUNw9Oqwo6~&}0zC%W=2Tx~Tu{gH5k-S>$lf%*5%fh?Ft5-aeSb{G zqvH@FzTJHh(j0wXm8i)8c)$NMza+Q6kAhC689I}$>Lw)$Z zT=WqchY&IF<&4Ms@>2lOye=oNy3atM$H3&3eTMExIjeC9`qTR=rX&67Q%NV}*(^gD zap?Xu5l7gj6172_dKyr)Y$s4QZNmh5476;cw&DFK?Fel6bmkQ+f22Q6#JAgqNptiz zd#4`qM;w%WV#c#J4$- z`Tf;E)H*nYI?#24K#zf`1J;e+s1Abu^b!$0+MixSI-%@-e_CXZ^rwmVX8O}i7vG;= z3y7BQbjqjw6oDQCQ$F@NqkifDC04Z0c_!0`a+!WA(&r>%;HMam_fuy9qIq3SUbQ_E z=rJ&P<(}2?(Xt5ooZ+6;1BH9q<5j@-$Ny)OUdX%YucT+WKbvov`y!%mk4EQ*J6ywV zU-;W2u{&Htv_J!-7;$TBs&^y9&3oBBA$Ck~KC{^ms^HZ~`$5Ew?FX$30Cqn}XxH?E zCMf;7UG@7xXG6jD`awS%K|hH6sIt)gAilHuL41+W4;lmyN&O%uuhS1Y2Ow>C=h5!; zJRN}^18sL|o^E1bcUUZ7KPYLQ?o6>j&IM)oTb#l8rb^nO4Tj?zvRWN;7<%G*o{p%t zSA4tY>6pXl#w>$Kq4l0zC#=Z)%J zY&9}8&S6)3v(@Wn?IVK9 zPbNy4g!xc^Pxh=e)!%^g&HLCcfps*xZ+Si5jnpR)H`XV-BLLVwL1@?bgeksHz`m$@ zVK-#w7N88qGh6H*Hv~8yy zt{F}ZY#s_TW`v4Bb6gB!K>sy+SLVNYvq<_)48_d^{pQsPuJIe>~MS>6bICw~ElbF1Y z4|q2~+LrF2En(5d|CWY8kAZ1R+_$`S-~;AUF}cczkWS-R`<5>zjnIz#@f;bdK02R0 zsX|cyi5PTf7_Yx?`8|MYp6|1HCeUM``AIu*Jl|fQ=l7CEEYItAuy`h7z%%3Zd43Kk3BsJ^cvqt$&M^hymY> zC;uMOCBV?Uf6nHeK#xHq-anGe`=z84%lj@i??eoEXFSULn(7fqu=zmSp|E~O`?#0k z-AMfjakW3uXM8rMF&5>MW%+o58~PZ2r-%;EXwF;{0wX-LC4$@d%og&){p7#}mq|@86ZU!tDkWNS$*=PyaMJ4N=q)pEG(L_-$#(FPu)Q3{@MP zw&W8|ozklNFMc^xF`k#>LR(WEDgU(4DC2^fj~r~LzV)8roOQK>)1K6sEThwL&5LBmY(GGt#~|tlW(GcN2h~=5gMNUf<0IO6TyEv@b>^Y_ zqy%~l%skj9-NwoT^Ct3}xmZ{DCJ6Xv@?m+zafxS|+dZ^Q)D50RU>tHr?p{KP#huT^ zdSaYeQ&S17@6-*;{s*(F^8vcDlY%pU*SPP`udsCTxUF{rJqD&u*mgwq{$1+bI0MYq z`vzc3500q5JBWhBB1o%J0iV=7C?#-yl_Jg90XA* zf*>6mf*@i66#+$2l%Lp*s8~QmET|}87Yn}g+1;~q<~(Q1^W1=M{+PRYW_EVIbLR9p zyABdQ1HZpA_WMdw#=IBjo7V4Z#eUy$pOoLTyX*X3cdmPXX-T?Y{i}8PT|Bad+*b$pK0@dYau-w=Ld{te;di*E?8#5aU1zJ2{F z?pwLI?}YrmHx>7-lDscmXS-T#XgelGR>#D_`zo&S3_HipbeH2_+CgcbI&0@`+3*Go z57O_e_$?t-aW;6B{hH_4*ptsK=F-n+@2lW9GsotKnmP8L1JvOw41-z!ee8Vm~q3;6`QP^_%+0Lqo>4HtRX74Jqdwq z4H3Zrl)Tp>ez$Db8X~v&wWw$f@jb#)Z2z#>U^+;Q?bR_hlD)w8gkqB=7LV<{=t*L` zh;qB5#D-vmtyNwu_j!PJ?D0O~D87GLd@vm(#`l^SADg(~`$ZDp`_Yrc_b2d8+uxTR zg8ks*zBIlYgroSLxANQ`g27#|x_;QM6~-v`i>#J8hB8=YU`L$Duw+?U38qi_@- zpR5VyN-!NH#C{_QA*|``{0GhV6qh-Ccd~hPls%Hx^e_^ud$(B2q;kd^}DPpVsB2Vo&a8 z?SuKv^uhd4(+5uz8|wOCZm;NrZxxot(lW%7uD`-`kT8}Q+iv7zX%ieXG%^7vRL-G4 zY@YEFo}p_OFdZa(24mZe%`>E*-?WI=iK3v`Ph*XDlT2>mZRjcEwOCIF_~^C7>qpCY zMbLNTTo>!4nRY($!T2HQhdyHT7JY1{_i^<8rPPaHR1aG9L)_;pgYAbtDjY4F08<-9fK7+E^G%gzskkVFeXUk@@ylg&>o@Cjqb)fig4P<&x+t4Wd!lSUW%Pz+ z6OC^W?5AwFFI_fw3P;Q4<+f~KI!NfZRN3rUTQ;9I&v=C`8<-9fK7+E^GAd!sO*=&=S&1cb*ESnEfHV>3#gP<=P zu8XqCv?t2uUZXcGn`m5#U_WKUed)6KoN%;k*2QllGI+_~9|_YzLch%tzik`)&9Axc zDhi_aUfs#M>$ruVM_1{)B0oLrQ={+HBiM3Ij%ds8)ZZtfigP`1&MR@kbdV4y@8#I8 z3g>R3ARGL2zn9~l9Pby8^2wR zvd9hdN1vDeV$q&<63m=b*S&WVj0;vR)~`qM_3IOh_3K&5_3Lq+*@AUv?t58r-%0s> zqs4uzCGQK@y}v3pw4HM!o1Alh%`@zrJJa1Y=iVhR%WS$=G3VY}3bSg?z1H03IXCv? z)yMc|`JB6c zUiS_2j6->bw)Zd{Bzy+#{ch$NGUu+J*L@Q`W&J7U+yEbq=5+}AR)FhgRReG0!;4mJLh?37>ig* z{k(1wdXi-m&Fc{KWy5vDyzaY3Z&)_bybi&B%7**WW%H15v}}&GWdqYeLcgWTrhZ=c zJ@bq=*s_7?AmKA8o7cu=Q$Mf!K6;X66V2-o^ku_!!@TYXMsHX)(Yy}9e#(aX(q;3o zaI|bruw?_&K|;T!%BFr^_e1lH5nDDe9VC1PWh2dAzNfYs?WVM8_4B$Pp(j~3(Yy{p zUp8Df%IGg8nKSgH}Z#1t%uq9qZ zdzjZfCgO_u3|l8)I!K6_Iw7yKPM2+ZUiUNflsJp|K~}EOybi&ZI1!CT!SNpY<07Ki z&a&8GI!KI7USVyq)z9mGj-C=*STCb_9fDE4Y?{|`i?5Q=Jm(2vDYkRKrt>ddIt1I|Zk*SlEONvA(fwsQvS=SWuVda5=iL8Verr3=LRRNlnseW*V`=ee zo^zkcmUFLE&ixy2mn9xKfyg%+b7#)YCrjgI%eI@#6dWSIjMjbU{6@LCOSWCk{ncXY zl0go8jXlX6_Vl+U)$H@6WGZslW2-aKesb8;HcKOuofGIv8MQg=YHCdmdu(d^9Cph5 zGvZ^(Pb<$gRN6bZ@#P{~RF%e0`wdW6n*4uf>Hmq@8G@kEe3PpOm_y?an)CcXX}|(?P;^hjFPKKhE2o&GWhTWpZD*zm4z6o0le=JYp@W z$p@$MDz^|Vm3i~?NB5PR7VTTM5n0Y7D&scdH}YHCHUimH8_}#o+lWlIY$MhlH-2FF zLUBYV|L(L@I&(%RXH~WrnX;DcMI_s~O$4ib*bWJ$HNzaN)vnUBjpCii(6{JXly z$d(0TGA*P_hx0L+EYiwePuDnX{(Rcl`)O-0Ob2PQ z_pY|~_Hn*x{^-=hq^~}}_SJ+@+*dy%zqK8QBb(~0n{{YkoynTMIv#uP#c6SwtCMw| zn5$aVCu*arnqS1ssZ;#gK zj9!zf@6Sp(X?yfV;#1orm<|%gC-q%kU6O+vP3r!r z_9X3lCaPdis&A)MC;4w@H;%z(b`BZM$6&U7`IGU_SMZO%dlROEsDJWz1kW}885(&o z@WIQ(2l>Ci+L?#veTi(2$XHpH*0axfm*2r&Y2{RG{n^;|HEffG&7!Y^=^&wPE6Rfp zwzdt7d|hq~8f)T<^T$_ZZ8a;?#Snq779T5pX*TQ*Y+no8hq5F6OD?lSF(zg~bxMX~ zqLh7JN0#Vpy-fwa19#uLj3=z%j2Jd%$#%5C{82hnVv4 zbxCsG7kNCI|3}%#f=)-$kIFh^U$YU^nxKg018qW9L{rK)YEVQ|ADirFC!I$pt(BM4 z#Lm_`r^Z%)Gx#2|9VEm@IUQORhd&kt#XCJ{7v9}t>>We%(ARr7o-;Teu{dBl zNQ~pK7zghV<_yWBibFOUIu|C|x8#>k4o}2pO=ZoeQI1^K$hXd>4@@5%`CVQOv+>~1MCTFcOpXWrD}ATs zuSuRU&Zj{`Yj!TXyCZM!jPnuxW6I+9l!cBlVLFJGMLxzn(v-!} z$R7f~24hUMzOOOn^TxJkuuYN$iZLck2MKMPCHRgqw)r@bHuzalP;`^Tv%H0}^R8C? ziNg3GuNavy!m5U7N{?UG-#j&b`LDt9C$Q*u$zeK3h-J3eCq(y|0Xx~K3CAf+x}GoWh`@rB@B*#SR61Nq!Gt+ zW5n_7SaFOqIR0gEz;uvC9RD68jxo=9#v2^ZgJWJf=Yi=UAr8jU$C$YCbxPWY|9U+A zj-@r!7SEh#z~EbAg5cA4h{JS{5Z}6j@7N^1u+11JnzD*iHXO8vr^&t7Ew*;!tIYZ) zX0yJjWexe7;1-si==YK;6#{`Q5 zrh_!%m^elpW1h!OFgPZIL+c()2MKZ1*1aV?p0U@x#WRncXz)!1pVmE?4ie&PSNEoQ zpf6zETYcTdTlXdzUo4F;PAJD=FdZcHh3r>#qA}vY$aJ}}n9FZ0{L~ycSmV<=cft`_ zznz-zuD5<_O>eTXcLw&psk9fSgQ&d|vaz6@Uli@-l72mTil0|ZEvFR&((JWiG(Q3nqJYDH^I~LrdTEz;l8;{FoFfoa)Mzd9Xi1XhHl{m zBUqdcCm3elp}Xc4^Nwrqe*g21;m(J?lbUxdY079OWu)swFdan8DE~(DadF=!gXC;| zWm%1_KG#T4Sv)azd3!<$*zf1arp+Kvb~|R*c;zc6Qt&HE)?}u&rdV!E})J*j8TL z*rpuSH@0a8+o~2DOb2O?ZPwz(wtN5BmNM8@v)EudNPBFnFK%oX^^a|7gKZ6q4W@&% z$M%ZFjqNMFV4FWW^mkt$A9Z#4JqA`(w$5TY|^_6Y%^_4~UN+UXaB$LP^Wv+6v ztP!p#%lCuR21eE;NK)VNq_00$eD=qD?zED;Az*SR*iAO?O!n<`kO4SB`|&XUPyKP! z_F)URQfK^2o*ysgUSuU^{P61XG`}Ka_H8G24taftZYElbk#R=gr`O;oUGIbGAnK=l zy-z;N7WipsWWB7$z_gQ#tJK7cG8 z2e$e7yr1v-@!M3^fJZhA?0&)X0n{72O9fvH`2a69{@ED+=$HwngQ$Psep!QKON#@hgS5u6)#Aai#SXpVSkBZLgm_saI#$5Fm# zRm9PuK^)yBarB?=_PF@0w$C5w1o5*zq+%kK#BUc)r?;c$FJI+!*me!Yd+Vg9HY<69Y_3(WsJV=E`qXQj6Q$#Mv19K zanW?tZ*A98kWHnWLnmg^~zZ1Z{wWg~OI7wXJ|+H=e9 zQi#KcN*h@5p}k17r`)%fOF8K}(0t3)yFwH{M>#ltdHvdduMAIpPXg=4%0zGpQQYLPOaZ(n`b!dcbE2&!^uL*cmi=!e z+uZ-!wS{#Aul8dX+IWTOAYm*Kuc!Muyj|XpT|~SF-!P&4sl(Iq{zh#)opwxYWIaH? zjXF-Wbe%1Jaau6v1AO8L<;`OftANe<&FdTN*Mfas*{8#F zkPth$aAzm6OMiPEg~ofd`ptz?bkBlr%xAhbF!a&H4 zZ|^rG@X=~jCDEIlZ)WJHS7RD;`^ERZXJ>QLuZ6CxoSrjhX4VVt1wheUl5!=p5)}6tbi#}oZ z@1K<|>M7EU$o~D!l*$RXZldg;vlKID;>5w>L*$pvq#1*=JJSc(%G#GZME{$EI2_3C zS~A?yZ)#t{my;|=bqAZ{swg`;WxF&;Ylzv|Ssv+L$IphoQLP(bT`k6fN{n-A3d`zoOxNA6Xm+ja-yE}VH!UVt1 zxkSg0?a|fezMDRGxmU__(`!xXeYY)*U+%TOhv^`pUsArmuh#clnP+_7`W~i(gwMeD zZ;5^XlEU|2u)dd^BG&QL2WR1fu5opC_Y3O#Z};l^t&Lyqx4wtzAfaDUzJH+B_uH6f zeA)UQrh|mf!1w3JzL$w(7We;WeSb;p`_%4ifq$ z<@>MK`hGj}jIUYW!*r1F8TkIKvF~RVzW;{x{X1jd|0e1C?CuxT_uKLwqF#Kzz46Pp z@Qda?!E_MyOP>4mw#Y9vd86OPQ!irfleRrakZ zVEHjv=9O4rI!K6xNy|l5Sbic3D%K3H=@HXK9G{NYMC7GLy{#GSV(>i*K5aK(I*8)y zx!w4wsQllw8;dn(a#!Q0pW!F1n=l-4)D9KQmG z<_E!akPrvotawL^!{lADPW$T&5bez3$k9}UW6jZgt-<>nTW&BNB*aVKa7m2U=OzAD z%Wcf_qce8uDm=dzpPnD>VX!;}7X7{oOa}?EtRz^f>eArI@5?fi!$_cFHq#g+w3 z2MKMXEZ$jF7O(VW@z=5}WJ#sRc$-uIrfWs~S87#76JN&Q+#~ZcnLoOawLZy33fKBj z7O(Z~Ex)y0>q9oR*4L~<*ZMNqV6AU__U_Zm@Nvgw%%i1082y5nFUt!O+rhT&26Qrh znpO4(!>`QygB9hy&a9zdo|RX&(KNYwuSFj<{`k&`6S61iYaDq}G%PHAywy(L$8VH7 z7s-q3Lm#6z_VGSF_!!xgkDGO{#4qQ|cygSR7IE^-;hJ~;O7rhB1ufT8 zBiaA?daBy!}kaN;{|PsW2TRY)e?%c$aTWc8~y*e7wnW zU-f$Ge&!jIc!rKKVLC|o4Ep#h%rk=Z)FnkhF~%fU;(~l_L!I#AuBYmAdtOi7-}q&! z^*u}n3H_4t{nE9*KfpX=DeHTf4iY{C-(MN~-mj-lx4tjdQ`HAA?s}>|x99cL1C3v1 zSl`2RkkBtF-_NY|{Xym#FSWjh=^)`V@cmV>@BMn}vex&-daC;1#a&O;=k~mwI@kDR zdFy+a4ifq$<@=RteSffd#){VWFdZa(2EM;K_Pt+EUD^7+SWi_SytwPB`rMw^Qx7qI zS=IU;rh|ljN%?-YTHhaPp7Ap4dzcOqJ_Fxh6Z?KshDkCPU)}otTI9mM{dO6?bnoG0 zcl$w>pSLZB{WJCb-+8W`-23OG=ZA+GzpQ~@bWIATgQ#EfHL2?&ztpT{zXDIah-=yE zi^aN@eYo+{Fn-dx7fc6HKjmxL*Bd_#jl41sn|Li-ZN89&U>WE2ln*n{*fty6^o%h~ z2T|MdcObmm*yh)=eI8wTE>0%IlSbwQc1!31L~o~H;|+vJq<$MkyQQ3l8Q76(iRX^mrp#e<{wcObmp;MfQp zy7vOpK|&m}r0%>gE{|;eN#bf_QP9`kiDESrL5o=j)+Gf*%cB*enr%loUa zY$giEwD+Qz7SG`;`;9Qrgl;sb$v;CZ%XU><2~<9%{Mr90f+7Zz;uuh2kXush;jHm0RCos0J~;@ z7T4aCA{^`9)Ef=n-NCEx4}s|*A>MTb?~RRkUn`oj2D>~s0ru16-sgh7^5QF}J)N6S z?2G&TA;%kEybfPzU4-c%p)Z)z-4y%6@6+v>6?xV!^|?={P2@15F2&$gK;_eI$G}2?O$SCocnYN zx!--d5rg+Y@M>JbbdV4)aamQCBL`(Lv$$-Zzo01ke;3S&2FJnR&^a$m2MKYo-x$w% z56R81p7Zv#-*}R-?J#W9cfr7P5Vb9ThsVuTF_pFZ<(#+cT`-3S815E~|KGd|MvHkd zy$fd4`1J_Sm%SlLaz!D#p_?svhQZ2WpGe$_S*rh}+o^Ko+JTE%g>j%+0@>1vku*R&Sb~3_nawcx%V8&{?GTG)t<(^=SZ}tz2{S< zoOJJbl(^M(0+ahtCbe8{&4(n0ghrJD8d1w`_TxE`*~Sgh;erx`z;f}eD30MkL# zPx*TIt;SD7Bd6xoIvyLS&3&zhpKfeB9ouvb1EzzhZTWimhmCFZ>)~evcE8|j80wA1 zv>twj@y|m1qir)x2T}jzZS!qO|H!)KS-CT4o7<016;%K0;b$5g4jfunVLFK7=((<* z1G4`~U0tkedJB!8&b8$Y(?Qfv4ds2_*vh;AHLJ4>j`J-Jm<|%-_(&YLe$DEwilc5! zkzTXX`0aho>THAK?cmTcHcSTzaWEhLXpFfEL#nTM>?R&B__P7uj-y z=^!Cq=EEP0@ybGTw)cLqmRq0eGz#slGSrJUuj=>9&oNjou~=X_NQ~vEAVu9%(F_t@GEIzO4%EgGK=Uk-o z43?`c7MKnaWBEjk#pelKvly}ToZIsjgXKDl1*U_wAp{?uJ#Rk z*5?}>@3A;wI!KJ8a?JEz#nI20ssA;-w;CMp2ZxT^VLC{NgEhT)+eqZt zuX((2OXk7FKi=qlO>h3_tKKAQHuLP74UUZ0Y%Y-B+OF9kn_9DJ)}d=QnQX9Tlb^{b z@&z+yb|&LAF~93fhDjGJ+o$+U#+_OGH=W7QM}0#c6`#rANzG?6wi^*2%Ns$$Ga2ZO zeSBdLK1Md><7OS|<4m^n@!I3Y4-7vcUpVS?)*?3J^BFm7+%V(%?8wIOTu#Ca%^5eF z^BI}4mTP2@Y=3KHHTIm^v4?EN&zU;D?#=LO&tZJ|z3zNQB-+y&*+o)jx<+;n?TLH{ zv&a>K=^$ZyB14hRr+qsu9k-m%7#R7C+*k-vP7;HiyO0SnPaXmHvI1%2gfsqa4q zj0qWx9?#0Z!(h1&EGL#_0MkK2EVBj6JxMG+=aV_)7erH;0+99ZZ)ef1+TF@pl?9 z`ij4I8Y~ZjMdJ^qgM?Vx#ot#&(+e4Y_kwtg@pqZQ{&ld+M@EYF52k~J*ky{``HZQ1 zLj!{&-;g`=K594NUznX43l346wr{BTSnELWZa}S7tDlsGqsbcg>li!klxhnvHyFNU zF~D??W(?n6Y#4TGfnomW2_m&fKDHQ+LGVL726>nK)^?nSY-$YBtV72jnXDay%;D&A zdJK}YD#sw1vX*0zNVa(lV&5xwg<#jd{D;KB@ntN-bP$b$p$_xa&-z&2nZDfjiM}5( zbFO^~-+!-syw-xlHqYYyIj@@PU-@v)AVP*6Qhx5vu)v-+Il?Wp}5(Z+)dHi=R*yx}O2l zL9{IL{fv8~vZ&d6d<2)ji2E7pvA2z89Zk_djq#g$R~bM36hG;F7N&!!pYr+a=ORB1 zn{@)lK96M)xwz)D3jP+rkKuboR~x*KgICvVU^+;Mmo=Nu8@xj!KhMy0z4t-QoVGyB zl=j2)B2C|4y~fz~3u_xp2WhhHmrb?}_hZ|&#H!2cJE4{Gw;#(us_ zUE*-b*w1%eZ~XIn{G&P1FdanwGrqH~VEkgOe`pW>Aevs7oM?5y@+W6)1MgW~EZ#bG*#;vMYB zkfn2fZP_QrFZrltgvv&OQ!hY9HV`}|VB&OuMZUohg z!DR-A50HyxhuQa@G4xo|XWj%-vDUas=j}JAzVr58Bd?nn*dUHaoY>&stRdlG%a1CyjPxk{3O zXFk7#EHfZuZ;x57o|4-*yoqS& z7dKAAY?oZF9sfvtb?i3nuw}lGrd{UQjfArQAJv+|cmG@;AG^_;LU~4Zo#x zqiEK7;#5%-thvE-kT7mob9=zIv%3~+zRyd%6hbp(93@G%oqKb9H=%V=q)j4-^{Qjc^Sc;l_a9J!({cVC|AChQG%E6@$mD36Z9uv z)F_#l`D1F~kKzj#{sSGh>~9ru^~p>d$1oiv^hq*~myjFNar|L)l=#Cqe%!_}f zxe_=vj$t}Th_hWBj~7jqar`m#mY8iEXQ(xf5gl_Jqojv8{3d=#&Pc^mWzbd|P;@p|5_V*8as z@)iiemhp<{gy9d-r8Kp>pA=EWxdu4*E^)$ikPs*F`t>Bvu-*Nk0Pc?02|4CZp|`|r z<26J5#S%55V~$spOw9bzs@=U)#MLLm_++2bComl(^a*P*-!MLrJ>wsV3xbcB60?#& z(YYg!*-xXV^g-D6F1?$S``sJ(a!0VK?L}s2_*yCOWwWKid?XR~v3H4-;+k!7!E}&D zTtBYGbvJsFxYn|`5NyJQOf#-~L`re3ZE?YLkVafTsm1jf^dxaTPaC7 zcH1Up=ofD2Yb2s$Zj(?lG4M-8%M{n)`{XwD&qg-ZVLC|YpJdzgQ}2#kGHRQ?fS%G9 zVcWF1t-}a5#X2(0vHnGoQe2x_TreG^5!Yk2xb8o80Q331id;h%YYm38>b=qxdYbvVPQbr`{xbr{he>hJ?1u9&yBbr`0DgqYja;m1Ar zsyh6C=q|C_I-H@`I*jO;>o7`M)ZzJ~|B&g_BI*2#OaPg7Pk!?aa&tZpUZS(Iv_s=* zhul}>*S70H$R^i=9`p>m9+c_sS`Yem-gXY}R=pmylN4dqdeFM3OSAY!0aUXdggtq= z6zPky9>i~EJ%}G_)`NBz8|v1BxV`9F;x&}73QOa0PvTMY24Fgf#$%p0@EzZ$NTy}K zc>~+Yvsm1seUdx?2ILtO>k)aL zLAfG9o?rk>)Zn;>Pp4*LGldppC^SsuTcIhc?P9sKbOMF>4U?ck^!hhO7=O= zVr64u{=Z52pXmen-|qFFuZspPqkSkN-3x;0AX-NGKKXZR%ZT-#?XwcV{})RgyFKsg zzk$Be|3w>_d4HQT#QQsxV{Zhl_xo7&LCM6FZ{j%prU;dV)NgHLXUA0RdD1N4ocFoGk^4EdETO9ZKpyLpS3q(pR!1PY}=lwCB$#i%1Dc{Rua`?5? zead0t+^Rn1r-H1hPr;tN9JEj2H`Ax^LrtG@l-N+$r*L~kpYo8fH0F*a=5(F{(?PgdX6N?ko}PhVFN9diVt#E)^< zm2Ejs`M%ty{+W+|bgvtxgQ$P`loEmc;```t4FIQyT^xmuLXPEwE0ho&mYeH zCd-GR-+Z5&`E7S`+2}Unyu6J=)cP&zb63!|jsgf;yXgbn&E52YWP3M#AlcRWW)LH! zyUf>gvhDD}+MacA#st|}k#F7F`LrxN2IX*qjZ>HoqUDh1n>5Gi*@F#nDhq(2zxf_H ztFr2EjZ;Lezx!w@QPLt#=Z{WaD9z>@Y_mx#miH@RyD1BJt=mmxlkKLgmgNlFZf3f> z+RY#4@jv{!>UQ%qLcL;dc2|Mc)NW!=+-~xlX*cFQW*_CK^Ay zx;#WmHyb|}d*b1qgsfo&zIzM4(_9vq4x+xxb6JX*nmL^LZfN8r9F&a_20Gh`KZ-qj zSrH2SQS6~){V{c*b^3o(JMZ?m?-bdV-nN7J^-DoBN` z*IQc=^tN)HwpG>@0$VS{R?Rbk=^&x4tf~Dtipe}jS8^{G?^X22be-SKN!(a)@#G8kNXc0zbb&J~nCqzX1;dj__faxG1Hu7=fm^nFJ4!_|3 z5>ps6pR?tFpf{T9bUFM|IBM%Vu~p|kFdal~&F4QqNtT0O`z^-|+5G2}07o$Y`4zfL z9OalQi~ff|qVpd_ZC|yx=RZ85xB1Vnd6uYpFU zV{Le^>i+o}@m^K`yy;oZ{WJFDe%5&nznT7-A8PvN_lOO3{WG_h4Tc>r{!UmLOE(Zp z`aLt44id)F3esLY>g(X%IA&<%Dx9#B^b3U`u_ViAo#pek@G10^u~f7h7&UslcxZHs z3BD~v(6<|04__lX^DWLyv$g&ABB8e5WNnA(AWgPkU2ppz(37h{`(2=zJ{`JJ?nj?Xrx0~zg9EoRzt2Tew z+6>b{)SmI3l+8C(+x$m#ByB!rePc6%-e#_=ZT^#R)#i`d7=h^^q0OoI{s6O|>iGUM zdXjdpwzr9I1ijr{*T=|TL_%%9-P#V*L7Hs8vEKH-q9`sEOd?$ADgc13Y z>EtQnmKj&1;vYkTu8Tx_dI!VbrOY&LKWpO_rh~+B`eDX!>cbEPF_WPG>{r*q$j4xTg!*r1F8MS_Y zpuz7CNt5y-`F**w+xva~=sb~LB-!BMS#Qdawr+g3zxz0`=B5lvTepj3lZ{@F{*jaA za&p;c6K}Jm4Dx@m@c5BaL|RHnwu&EJ%b%HFQBJ5LZ`;)DIr~X;j_ebPab7ZvnId0tTlDmrmQQu}f1 zWNBdXwUhuP`OAAOiImaOHljKLlEXHzNTmcB<;eJ?)pXF8^NhMkvW zx=TM(-=%Hp{5)^RhWD+Wmpn{0u2?sm=$hvx*rP=yV|LlY=QlGi;fI=e$s=Mz-Moa` zE9NCj2}}EspV7`7CgG6h5W{p3jqiM{`GjxZr8MY6z9aXkOg=u|ggP*8;nL`c$2}M{ zx|VonbRQXT=IdVw`f(4}!`FxNoUl)tE?l+w32fH66if$Ed&YNYe}56#yh!e|{hpai zErXt<-Ip^)*0~gd-fphr@tW;BW{8B^{wr%cOb2PQ{kz!CZdM`a=YhY>FfM!vdXl!U zkI(ldEVC>K1ikHC7q&~&HapX7ZGWjqsO`V8w!?IgCfgsXu>DuL?K9DnwEcW+zqPa- zL2o_4gM_v-r;6kJdvc%3m^fb!9Z9=?g54VD2ztA@u8#BN zg{w9{ZT$_?LDZgfoPQsGn>kfjmsT*(c$R1A_ztFngwJ4{@oQ6;g7MuCL_xM@ZR*mB z=t=q}%O2CZgrN5g*WGo=to^QJ^cHJpS=;g#e6DN12)0~1Lo`}Di*rR+77;C%zu0nt z=^&xcQti)QmrmE=C-Zu+3VM=08#+g@ttKR|!w7nxab5UK`m$6VUR5O2_P<-(VLC{Y z?SI2|6H}(VXQ3x)`ytq_<&B`Xo$K!M4rBFYBB8eb)7lQxL7Hs;dxhVBlly%&^dxN` z#r8`}za!{v=en?6ZcX`pb&*ip|6^^3=^#zE|D(e8-{!Wz96d?fzliORmbN44ZRfhM zT_)fu+t&~YwOvMSVcQAQK|rrZdc}@Cuw_jwny6)1ikHC*S9OL5(%|^ zinSf4gEZOxpL*NZMo-fA1M$1sj-a=l>w4SQ5ec<@DQi1S2WhhX`TCey7d=VaPq#6H zptqgt`j~mONT}`0SleMbNR#dVt@rzD(37_7-xSUZ!v1pu;i}EcS%1TH zkkIB-`?7@CZ0l(Fj1A2*R^S;ro`mTj;WKK-ljG!J-Q&rP(3AAdw{4js=zYU=cbS^; zU6%&3DZGBpK)IB52nACb&k2Tf|83i*$08GZBBzvG0NI5__4ymzC@v@#bdb+o#Dr_vCvTd!n=SOL0~y^UBU|5wA=t-&2KP%Qg&A ze-;?*U2hn%Yw>%DxMJSc#so|U2{98Be~mF`4Tt1(@^=d7WR~*aO-$S<_ZIEi-smo| zhxK6|*v}M_*L4Jg7-($Q+1Kl6E=xY8@A2t(Z<*|O+N5s@mJK!hTX)M}( zm<|&9X_jF9TkNN-?nrDbZQF^HM7DU(*S_c~{SwB+@9~Si9|^&hF@b2y_ap5mqKb28 zixZ}U#5n&RVrP;!FU&)XkeCC;$?mpNZ>t|cTde+2t!54kUY-&I+pQSS8t zBB5A!vshs|NNcRiRAN04T}iC_TdWB7gO&U0u^uE6iggdLo>=yCFdZbsI$O%>A91;M zwf!>$bXmp4zvlgIb2GhE6W+sT+x_D~uJ64l zQrq6YL|lR9QmG zVmvsPGmraAd_}Hw)`vd;K0TL%pdWK{ojzl6gmBc>xwd>@I!I`1?fha{%7?`q8V3dSL? zM|Tqcv*6cp2!b!*I0W@6H${Ec(ITdPnuni`D%)|G4x)Y<=xi>r{9IK#o{bPWgCpry zGEC+j1j~Dm(O%COltZh7YvHpmi=JZKdJNAgeHON3liw;nTTMvbcOzKT>Bh5pb0!Xq zgx^OlM{40wy*X0{Ta4*=tZyGuW8nFt-w_iR$*3z#eV!_JW%WDEeLhxxY?~{FY%*8u zIM1-TVwvu)T(N)VWkrHq)%$;sl47sQ75gL3m*Y8g?|Z?Xy!>RG#^>rJSB&3Gt{6Ym z8RtT{9=9YkX|-&6gUk73Dwrak`9GTnO~o8)85`RFL) zvuKksXms_rNqp))FoM2K=DK=M^^L++n@6x&_f%mzNNDp4QeXZZ*?gM+<~UD8Pl>ZwugY-#0-S#@aUy8@&h9hE$oLK*1DL&SI$py$Nu(6l={62w zI!K5s6^H+o`)nMB@iJMv(x;xg*-rLDWZ!w<9%49wC>bfw3En^SShIQdnL`2KQ;jp8Q;DWjT-2a-J{P zigVScqo=exERXGMc_7%bJP>Utk26F>v7HaLGs|%jOa}?Ey+mv-`raaj`L5ph3>5WV zmU}w)=l#o>++Sh}>-|As8WEDWZwT5kqt^R!ol1Z5#l~$z`RfPbb@+wCQe1Bb*GP#A zrh|mIRua2ynH6WRmmC_HFfvf$J6ptxGCK=BCBCrC7G`Bu;zO`F3=qJSgH4Lbzk4Bg z35$ox-Ce~Pjd#x$8O3`Mco&v4Pw?CtM&tSY1dS*9Zm$Zr(Rv6W844ySQwvf-cVDJXb^%=Vjp3 zaTZJm32~JL86UE>x2f zdl5R4c1Jm}2ztA@uAU2BEL^qu{nlof4$@?EO-}4P(2=w`%85nL+st*f&6fyQZNAaQ z2uueFZBDf-4LPxwq9)VyfMM7=A)!GizL7HrD$ccRydXlyuX!H0G^tN+dZ~GM@p|*d-+78n}nrv^# ziMl6HR_pKDGmg5GYft8-$n6Rz5Pr}Z~X2MKLXwJ-HK zvDcet+{H6=UJlbi!e`XZ%hNfr??zA3H{Z5(2|@20uDi?B%*)?n^oDbaC?^)dmh(VF z<6(0&e|WEmXt{jWmJ3V=34N9-mxi3!_n{~0vnVGPLGLrJ3!fdF9vi%0B-HlLTiane zNR#aiIk7jOCuw_>6N{j?o$LDc=K~_4wtvyu4%0!JY_HFWz0o}5OSV41bdc~Fwe=yL z6MGYSlKzQuViENI;kuzde9-6(>qC?ii(t$8fM`Q~xLHKBT)tw<1*U_9K1=^!C)VkKUaX~>EFIC@H~ z;hId86N{k5+MN@NOo%I;6MMTzDXt%YOLJmjI!K6Xmf#wwD$nYi*gMcwVhhVL%85nL zVry59+*h9y`w5XytUm&)<{iLvkPz#-f^{&)+Lag8m=pU+beGu6+^FN^=g}x97SW=% z_Ma1rl0I@`KP9)Re;%=Q8>WMV{;AzNY|e?j6P=}B!o9;NCl zE#iuq*Ukhn0na!s~fPAuxfX2Lgr zk)Q4sG4<2W@ssAn!gP?(PqY&gVn1bdr#2_{9(0v{31cG4iAAtwOd#4aC-yTUsyKgX zal&+v80W+oXBH2FvpOgCv*;>uhUFjS#3I;Fd&qtDd7}4lQrq4)=fr*youxm*x*g@jBG|HSBkJ4xY@ew}L@K{- zZTFn+7jeb>ti=q|L0V&O&WZgJI+K{AoLB@~Vn(zF%wHC9#r$V5Yfdao2MIBg6C3T1 zSLMV$!2Kn@aDOeziAB)QZ@5n9#QvXf)YiY*@`33fp{=#^i{_lzub{KEKWvAioLB_= zX`8q&)xp}hd{Cqm_jBOZu_;Uk330a@hcxEIeihwG{83IUf-m4W1obI5MdOgKiJ1E7 z-}p&$VqrRn`YF$eom|z9_m>m6;{!Ft71^Nhy4zVD!?tOrHg5Ae~|$)nL6Rs?<9&vnDv z)*_>~Xp=L&QC=T{E&EJF8`ieIDa~FKU|cS#4h5L+D8QE6VFb z(EE$)>b$=130G}i-j*{=2MKMiE$4Jz-}li|+8vfhl-Gw~%kn_9p*(&dB8qJ#uxVZ& zOa}?Ek=IwWA2WyZdQz3w_b~UDn2NQwEXJa|J_K#QrwMQ6Tw8zg#l~$Fd3`?=mf~6! zT$8ULQ;cQM`Fx zpT*lMukR=5N@9-k`Vd^)d41@NJz>XqkBEf&VGaDCd3`V)ME#KG^+oNz#B*(4-=pX$ zeGtZVl-Gw~A92lXew>!gx4QHCekvl0a~PbO*9X%AA2WhgsA+PUo^dxPM^7;_;wsYOxZ-#k&KNktLeQj$y zOb2PQy&5^DRat?e)!q{;S%yuM$eCuw_>*N33D zo$JE(Y*lY|XF`<6`YVx8+tV#F0@Fc4n^WydLtfwS(37-# zOPiyGptqar`WSgiB-HjTtnDxzq{;S%yuRO~Cuw_>*N33Do$LB`urBVB-HlptnDxzq{;S%yuN4Ale9g`>qF4n&UJmv{81#- z_8qP5Fdd}H_J+K^KcOdSdz9CQptqgtdcXf!B-Hj@uwC=|U^+->J8k09QJYwk*Y_86 zB<+s!`VjPXb6uU+_gCSn&AVHF!*r0)=2ZJqpV#*{^Nc-shR(}jI!O48`uSS^q5{r# z>@NOWK0n*>cl0EE6Xo?G=zYU=cbS^JzJD0K;hZAM>qD^RJP^@%*c{Cto)Zx*m%VMd zz;uw%XQ^^&$m{zjdXhei^7;_;KI6LZ*}>^?&A&uKZQsw@4%0!JY;VZx`!{-$wnuq= z2zuMOu5W+-BNA%+f!21I4$@?MeO}-5<{5KseSqm8;WKLMLprbTzvxN&C(7$X(EEq$ zhWa39T?4&geTee<5Nuf=5N)Ur@`>M|Tn@A40@Fc4pQY+ULtfuF^dx;2<@F)xea3Zt zOpO-_jj1E7?Jymr$@coZz5(-$qijsUbdc~FwK0{>>l;K*(mzpNAA;ULTsOqjkkK2) zRFv0;V9S_7v>~P@h=`WUvG{CWx%LUuK|-Ig?>61^*FEL+O+;tuzYu4X*N0#~`)=Il z7b@n`I4AS^CW(~do)2!#>x1baA#P$NTB~S!*X3mNlvu+xnJBLhL5sCJuMe3JS30k6 zNs&@qCxA=y`d~Uph-;SMTBfQztMmG%psU0dmSdFHhoHq)pU33u4ENRN^-UEC#d;!G zb?+3WgM?VwJDm|@?aJ+F%M-;u2%M|pjS7PYniygrolk=M7B+@}6nVCyza z2MPT{-F`{ZKds(%ximUUzZCnUnOCB`J_K8~VTji4X+~ql=_0O}Pqi@t(?LSa#KcQu z%vro%gkz0dZU>ht2d0CBw${!sn)CWrLuYA!*bYZ|eF*l`HgR97gSC6UtBaK4z8u^-HihXRA?|kL zkjA{em!mt0Kg#Pv@C6))pg!fMXdJSJh^e2h#7~;n2h%~+PkCP7@>T74e|dec;5ntw z!gg%3&Fe$3sM9ZIULTM3?L#`R?{4z?PO*7?q}g@l^{pwY+UE5ko6PGQ_6(cXm+9`x z>sui&tKlO_Uz^<-5|bnb#&_12zcaIS>)~sp*sJpTo@$ZThdp`u$vCaZ>*F_**T)Yv zd42B@8|w1)0Ee@mU+gFJVW;nU^+zj?9vK|y|KfvR>J_LQ+&vnDv)*Pd^Xp=L&QC=T{E&EJF8`id7B_dib zx8SoA%kdCQ2MK+~UewCQXSI2KYojCSuPCn%LGLfFtMmHS5w6<&VO!2H9VE25ww%*> zee0s9v^y-1D6bE}mgRwHLwUSfL=@Xc!KQhAFdZbsMqXdhe#{)s>q%8!-)p$P#8j-c zWib}z^&x2cJx$^(=i2&{FE(zg$m?5ASc>a*aA{s2Oa}>Zk=JMIW@BF8`sgX~g=H4y z^&!}QULSXN6=T$AZy+*?_mkk&ygrx?qImPXK8v?iUf+i3N@9-k`Vd^)d41@NJz>Xq z8;OMa;nVm*^ZH;qi25PV>x$jO!?`55Yd-n%n$1Et_w3=k;wOB8u}K zaBBYs(?LR7lSruT-?FyDbdV<78}j;gMo-fA zD6bDeZ#&oZ?aD49p|&rww!?IgCfghG`gTQ6()K8?4?%A`*Y&pVCK77<_pI$O9i++j zhP=Mr(UY`2%IibW+s<`;%)C}4)b@w1?Jymr$@Yf4zCF;Bv^~n}L(tpKb-mwTClYG= zkFj0z`d~UpXgh7)T7XYV)Jk-!L5{v^mwj)aUi> zZJzNM&(L`}Oa}>{Q9oZx=JoA^o}_Q0ygmfIZ@BI*Q{QClCCY zQC=T{-e+9b$JF5>p|=0g+78n}nryGn>ziku@n;)TFdZa(Mr}-`^ZJfJPtre8ULS(q zKU_D&)R9JS7*kPRAA&7o3ekp`I!Z*eT>g&F=9O!oFdZcH8T)RtOn==|Uf=7{S^6); z8RhjM*w4Nj_xXj2xirqnyuPDFN^$=a+?v-1(?LSq#7eYQ(UjMB40=ke;hId8*N33R z+MU;jOo%I;*LSQ)DX#y3OY{0*I!K6Xmf(6>Re4tD^&N+<5?fe~QC=T{7F&HDldm(} zSD)AS29Z##ohgD<_fBCtNQjla)74_EUAY~Nd42QIU1BfuJBH=w_o!aW3H?LeUOnlbR(XBLqqFo&u|Jx5CCckVuw@&DXx*M>G-fy0a`c6hy5^I## zhhRTgxvw7UDI%d*mjSEh^}%$I5G#3oYsTf;)%Mrs^__~|61Q#lqr5&u$K39tq=&q| z(?nc-@=|;(>8Hms)MzAzUPRP z;(i&pb!-aLK|yxkUhTpJWQ|{`@>wAm* z*fy^Z*<@bd`JQ3(`ZC>Jd3~?U%W9Z~(u%yk9i`Z-^7=LtWWx>b>%*SB{A8R~wBxPG=^VC3~Sy4Ob5{z&hz@#@-h5+95XbsCQjf}%7vgm zvp+kNTlhBglrdVg%NR9!w0LNAA#S=_?minq-!5}qtUDc@UZ;M$NT}_5TianeNR#cu z6}JB}|2Fak=t8xudD{{6wsT$BzJJ>G3q?Y0-_P0((?ObSe6#6~Pt+>cM z;{cwa`!+BgBzy+zL~~5p2Kkh0iGmK_aW(H_xEMW2|2%?!^gW3PdjD|Uu%`G9qqpb_ zvzU1fz54xQ1Y3?(5N%jfyhKE_Tn@J70@Fc4pRFK1i|fN|$|X@BUX|B}OVN|`*|HZ2 zwpRjQ$`XIvLPJ0=}d?-U8O{V;1gOb2PQeNKh#Yv;CKhMuJD3$Xo~(sl&B?OYeO zADg!Qa*s;leDeKj$2Eqapv*#<1yz9H!S!*zYk zTqhE0`w7^tF$2>gV&*k+V|UEFoBNYKIUJv8 z%pmA}!gWo|yvOJaW9D2NGYB@t3^M7Md9QHP?+fsY#tcjc3H_3anf2s88#AHr-)Ek2 z3eV7f7p8-RKp*Vi%#-h=dh^d!sRCL5Os`ZD0UJ1$MW#0^Go*zbM;z1r_0*s|Y6 zw4vYqfQV?hoPp2gmFqt+9VGM_bM19a8yf88Z9oCh0Z*AYb#`Y`ejaC_vrz7NIv>~F zh|bb~A8q=XydJZ&D;B$`%;rg+lJjFQi}U5iyNkc#JFD_Vr~ z?5gvcy#M|nI!oNed@*aAp8@w$@9?-0Y+1gD`Z?ad(!WosU-!CM#1->7VAk~om<|$R zW_@A3BZ>dO{E-*$0b^b^Mkj!d&{w>~BkYWu~uykI&=XnSppZstLB$LPj6 zj*p|W#1Y2m0RmxkL5TywmgR-0FE8fl4dr#ah%4qx!L02TOa}=uw`;dH_u#wQtxa<5 zcc8n(ZriN~LH}fl9?>zkTPX4E7Jg~jZhb;-Q~z9UV*;jwg#M|Gi7mWax?^I~+%KO* zXX%$PCJuk6c;#Xtc^{5o%a}ma$HW_&W8zaHu9&a1F#*#-Ld@-AVoMLcD<(F}vEPaA z61$CwXF$K^Wgb1EV~z=w_?VdAJ|;dbx2b=wu`vPDK|=r3#>7_ME!{Ekd_Jzb3!SB3 z!kGA+IArvyw|TE1*fJ&%^)YdHb4=VV;)?ltiy5Yaw8p%3HRhsiya%00%s&CMwv7n3 z#EhuN+@fv#jEF1d_gc&_9i%npZK^SEp2z=Z(V4{j4=}HGxi4n~TVh7kV;0p-{lUE= zu9$BCv-Srt9VEouuI_K^!FSdDEpqIiLwAYY*8S53_~!_Hv&r$7E~p+X;W!d=2l5 z++X4j$9Qi8_qM|xH-dhQ$8~z&`+ni5tsll#-PeTaAZlyAueoIwo8yc1Mn4z#^D}=I zda6v+CXMXiOOn_vWqxe+E z`Y;_teVX29Yxr)+1L!Gz7REtzz8FCdhwEajUva+p|3pGx^nPB7n8zP~$--GSCz75ksLfcd8+coEl zzln~d-O>4C1ijr{+coGgR=y=%wfSCaGfW3*vbpAb@wd^Dv^hFojG(uf>uQ_7BV4ul zJ{u!29VE0lwT94ezIYLOl6G%t&le-;?dG~ZM!qW&YWw}xc9;&*WP8K;;)l?av^_ds zjG(uj>-u)(dm^E>KVWT#=^#zEH=Hm2K6;Y2N9T(X^tN+dZ~G5KLT!K0+78n}nrv@4 zU;Hq7lD0?ZixKp;b6p=ZKNJbI{p;3tm=4lpd&BwSAE75{dvv}SL2oOY@A!Y<+;~ zAmKA=>qGi{@vqR6^iOoY7(wqJt{dvZuZ`ZYK1An>5o}o>5N)UrPl||^%M-R-U^+F`h4*pMM`n~5nOt{7^Z`SxMm5iZOr(~uWQM9y6W@A ze?nJ@EiA|Ad@+I+Tm4#S)}a3`;)?m7HYQ*?NQjx3*ftseJ)JN92f9n_VSR|s7bDo$x_rCy z#i$RPiHh^Z&xx4&=|A{M&lkgVkkC)G6Whgp@;O;cOKcQ77OZifB(itrG4W4ym3|3h zB067;V9S_5wB`BYe~GB#>`XN{VLC{RbNd+QTt@k|=ZpW1t`cWh{?Ykj1p8?Zxv&1r z?SDipGQ{`YjnOC!G5rEUp?0UiiBbv0;`@chUp+7R?Zji5SMFj z=ZiZNLfp39kIok(I_7pCB|V%kUP8pxCzJ5WymBlD(?LR?)VBA{=ZnXovy6kVZb#>f z5o}qv5%ukTi}S_fMO-mYv6x{xNNdc^=Zgo>nZz8OFGjE>W<-0yJSgIdc_}dKJ}XQI z2{EVkS!d=;Nbx@F5cik(!u_@Ad@+K4tj2YEpLK$8)YfHe`M`9L(AL`dMf3UMiRdit z58L7Bd@+Lkv`yTX>R|2sVv878w2zq}u|M*Hwzmj0j^w@%?X zrO(24EIMC|U{R-o?e`@o1pDd}immp6ITHs)_P?VuGU{CJf~@I$G4|x;C*!o@d@;Y7^Tqs7bG~?%*id)A znA@vb`biVHxx!ZIALE5cIZl-MwZO?q$yq3AKGKYdcH_X|lZ` z@8KorN!lLeJs{|9=en?6ZcXJ5yi_FA_E%ZkVLC{Y?G1SkGtrZ@J<5AP(A&;+VS6^~ z>3*;JvLd0juZ!)P_W;vDLfhHn+a-$kn!JbQ(2=w|%6mZ2+s$=#4#D!mRh!qdHp6s~ zCYx*W9#%j{(&i}d0YPsw*VQ(!C|tF9LmMM79VE1w_5QeBX~=t62|Y=>x3qZ=2ztA@ zu8)zGMM7=g#M%ziL7HrD$a`1?JxSZ6yaxom?OfNlE31lx+P=B99j1dc+1`-%Fbh3N z+oQY(1ikHC*W3Owkx<*WvbMu?kS5z3@*Y-0Ptx`%?*Tz?JJJ8j~wQJYwk_wWjIB<+s!9uV|) zb6uVHu%>X;=AEs-VLC`?bE>x}8VhgYH} z>6<9;0YUE@uDi?BiGg^iP!cfS~se*A4aIHAZh(AELYm z1Y6bzL>ubEdLp9bGS`+1Oa}>lmZ}d8c@OKOC+V{&?*T#YGp_4nY6Fo_+Yhz2!*q}) z+w1clHZ;#T+{P442MM218&m1LhmFva^iP!cfS~se*9|eXvC$jGRFwCCV9S_7v>~Q8 z5fLqyqwv|ha;+SugM>a~U2^xhUz$rRDEmUqc@LYSv-DqxGs=5Fu%C5F?n^DW*>%ay zL`rcV18&WGfaxG1Zek^xQ#9p0Y>u81YmxVm^_x-N1A-Q7cisasA+B`ZgXA^_xZVIR z&3l09AR(?8i%2Neg%&GJ2WgG9I`3gubS1Gyc@GHogO&U0vF;`kiq(Nt^B!P2 zNQjlZhkfF5?P~jL->bemdQ054-H-Af5FK;7kCGnp9$qWr>XUQv$-Htb2h%}9pVYSZ z&3O-dptJNxShu6R2LxNzZA5*0Pw6zgr{#4bu9(lam|;3dYs}4g4|}3Bi8;!9K(Hld zM0>!zmxwFow}V;p9$-31h?%^HV*ha_n~3bQRpdSF&HW|5aDOezdqB|7Z@5n9J?tYK zwe=!fJ}@05w6%7A(VX|NFFH&6!*)2zdqA+Cwu$>v9ju*S>?cx+`x0>L*c7INgt*&{ zLmKlQ_D6RTf0Xxt;0rhoL4C?i(Rl3u5mP^1hMzR=0j7hfpYptieXH8>{_-9U3bkS3dJ@~cMCk+eC=uR_q<%yqTR3xumSf5pZKOa}>VUP1gEk6#+{t4>Bw z((Wy7eiee=Zm#QN)VynL_%%tkl2 zNT}@(S=(VcNR#ai`Bi73Cuw_>UxlEzo$GqPpDhw<`wy^P^Q&MwNN784;(<|{Sd(An z(2=w|%CADu+s$=#e$_d`Rhxfg{SDJWLYq_VOMQOTo6R$R!ZS3#3Z{dE&tO0IAmf+D z{Hk-&lk`oLUxlFe4cFaeYVxbjGkS|Pt88u;oaz3p7r zw?A(e3AO!~)^?Z<(qwyme$@r$8Nasm0j7h5�{r>HMk-(UbH~lwXCQ_Yc<%_2D9; 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Ä`t&{LMr$qtHrj1Pqm`_JJh%dtNadiJrSV(!C` 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�p}bl3G~R!|F_RRFlxvxJB`+ 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 BIR5|u literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/GenericAttributes.dll b/cecil-master/Test/Resources/assemblies/GenericAttributes.dll new file mode 100644 index 0000000000000000000000000000000000000000..1c8e8d6b8529aa330a29d88f3f1ff01d005f6264 GIT binary patch literal 5120 zcmeHLU2Ggz6+U;?yS3BCv7N+q)yAE~`Ei_fWn;%BZ3zBZZ)zGlj(6iwvcjI-yrJ05(udhyueGJ+Db?yeCN*W zkG-@31X3Tk&OLMf?z!iF_s*TOnfcs{6d|G(^gDNmZsN&pOwo@fmtbyx__cQWW!sy3 zZ;DfI?oF?lo?ddDf@>7@oMGFJuVDrM1!c<3ge2#xoH%oKkG#6ZA5~V z|3TZQ^>-3&qk(M5X!pOc6X6bYM_zswL0bk+R1J|P89BEMAOiA6gl6VoIFtr@wTp3!X9B5N~NQ>erb5m2PP}=zR=}(S%rlW`}kS z^m~Hoc}3S1{iC8s6um(__PBPHX@u!-iRp~uZN!XGhhUn756}KE6J&)PL16h{%ZS5euoJsX3 z-n{*Y!9E?F13aU^@F3kEnFT$g%_C+%q6zeIn$zJzU+LMv3Ish}lg>kOYtj;==V}t$ zzEzWW+;=xgS2syNt4Vv|c_WZo2WS~9|8*!0(q2e!)I4KY-ETHYzuzP=zC|D;=qas@ zHZ(zK8?Vuq=k10B?=(M6|6n$Dz12jez(A_|6L)%Nc6n#kPzX>`*rs6Lv zx?f=y2i7Hu<3v_KAEcK+`{?_iN9bM9VTy@3JwctIlhh0Pl+vd_hjG>15F?;xVLMNU z#U$R~!y>2nT*&9>F>zUGF4Gl?iz|x1qO4aaN1qozpjCQa+#-)&5`UtLh!7F`5HljW z=;uNg9C=L9R-lBp75*Bv0at-25oCRc9;L^r8lvMfPQGl(6O^Qa^cUyIQ#4IQFXy#_<{z}cW zIS-mDW@SDv^R>)q(kYfqOS&p$glI6;oX&biLDr;jZl1KRn=M<`W=&Iub?0%DbN2X?xjmi-r%QVST6xSyO5tqNubwhOoM>gzA-7sIaeX}T)-Z!(RW%>=)i3)ac z&9KUnl9o}RRK@dUF&++zhwH)tQCq$BoGqSS4!%OP)#AnTmK8>;1(nN|%rRgT&-sp9 z)hA4&U^|{~=Dez^I)C-Fq@=rM=A;*%1>}R{4Y6rjsshBT@o2`(xsK;7`|(Nmk7K7Q zp6O8yo!|&~bUOPCGW)PKPTO1vq3v^SB_4czcH-I>AG`S0-yi)8wdg{$MsyNUFrA$& zwk!5nba$5?@HDnQG zB;3(Yp~M)C4g_{uhlz(!yWkJS z5A;gF#m3nntDqee^yO8qB+}aUam#Wp%#w-7D{g4-z+D0g$~0v5hT zsdkYR%jtG8CrUjELX1qciX>MD=~gj^`;~xgKv@~I*A{kMBQZ0_8XNsO>genI84nwe z;2P)%I?OcSaZC;LoBfts=G~Kvy^&r{1ZnzkO zMt=8;L(h3a`BX+&O?STbI8% z-hW*ZYQi3(OPfOn8;(QQq-Q_=?eN(#RAzhz!qyQP0k=RYRB{V6Mf2dM@k?tK@-%2N z_|-)lE$`kAzSX>o+=Az)13`VW>!&GDCY09#8RR04iTYh4rj6RmQ4agns5Gnwv>xmR z`S5ep31pY+EnJrh(_RDkh$zf)yE%q?-RE zo;Es1&Y`yQ!&$Oa1}Bjbe)Fmr)$9{Wn^Pl7@Tuqeuf!U}wIyo#FQ}Qlh8RPr-Ue%( z=kA6-BgWadcpAW{zJj~Y8K*o(SXf6tt^r&mh*MBe7?l$6;I$WM1v8L(8`5gd)1jUb z=Q*qEXDLAM-ZSBe+Dl<@iETv|Ec}Y5cmi5D=Pi~ literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/GenericParameterConstraintAttributes.dll b/cecil-master/Test/Resources/assemblies/GenericParameterConstraintAttributes.dll new file mode 100644 index 0000000000000000000000000000000000000000..e203e697005536951c74a9196d791c1ad9f712e0 GIT binary patch literal 4608 zcmeHKUu+y_5uZK#9NTFRCw0;^G;|Xu5U26!&b}lrlwkYLPF&(YlHrEOWNDZV3|0IwQ>O)j0sE7w1Km?=;2_EQ6ANqn+5LF&P>H|{Y0U?3Z@SEA) zyR)5^3W=ABIq&Q@f4=!<=9~S#@xo`mK|Ms&i|6)jqMLX#ObLE>bQ$8z1Ha7BPX}Jz ze^Wd2>i)_FJJ1`xSM!a!ZW*rYg}SM9zv=3>tCyC_dflt4?A><{9*j*d&k~){dgyo8 zGG9wpyF~}|?OKj#5S+e+DD z3)x(DA~%tLh#g9k1AGJVjeH*QV$b^VjFdy)c54A^45Ju0O(W;Zv}`LFX|Bd) z?MkYTUKZ?ACG`RN0o3~F$21B4gvNMS@b?8b1YZ^W8`1d=)u2-q{14&0LASI%nkTmW znwAH?onrh4jCs{PjNl1;(1z#)y_uSAQ&%vHsTAFS&QW>2?Evnh`+x^& z6nKd8f*%q*EqGq=rvyJL*Z|%|wv3+;+!Fjn;6A!4_?v7pQNvYQx?u=1zYq(a4ynozyZBM1=>ktRHSF8--CCWX4(L7?)%eY_+}YBfnO-RZ#RA zE#IzPxTC1vFx*yW&e^6L+I7WiVja_V?66BZ)55ltTS2Jm*;q3h$BL6I+3V)p25jZM$mSQ5L6w<~)zGR_OVOtYjNC*9$`13KCZ0hSZ$b zC@cR-+frM^NiDVIQO&?>R3+5ki?fu})SP4B*j}(L-wV9;Fk6I)Y1eRCfgRA2`8eE< zKM(W#_xAnb?PK#_dGL=$8PK0GU_-RFIyvFN$8mnd=4vlCF>E_{tj9=-_d4QW?ssj^zu-jj@8t9~(0!Cvsya za_h$NLSfPxKUT$M2K#y3b@&l2Xmo#eakkR_I*!K0@p0UTC$i&kG&9^5mh7P67_CKA z$1u;*+Y(*0d&R{lk@Mf({v2rw%g6_<;whmAC~^N01FQ1ghn9zKKz5@`#wwfI3OZXZ zmFI81@#zTaZ4^Jc8rB=D?L@75=HshUDy#3MLb8pjN#)biNCL9NkH!W+c?I@A6g$xxIh<6Txht6KL!%R09^FZ< z{Sc(1(C6%gqU*wz)8)}Aa9xqu@L?HJ&Ki3g>34i!K4&VVX*^NhOlpc=fEBB-%bhvb z!%nPu1~zK48rx`4OCqe%1 jAUQA*VG9}iPxE+B-VyZZf5!Xef2()Y`oG|Pnt^`<>x;#3 literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/Issue697.dll b/cecil-master/Test/Resources/assemblies/Issue697.dll new file mode 100644 index 0000000000000000000000000000000000000000..6310d6c2df2ac9c33d1e2bb3398495c9606df840 GIT binary patch literal 6656 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 I|FHu90<5!B_5c6? literal 0 HcmV?d00001 diff --git a/cecil-master/Test/Resources/assemblies/Issue697.dll.mdb b/cecil-master/Test/Resources/assemblies/Issue697.dll.mdb new file mode 100644 index 0000000000000000000000000000000000000000..862bd59a9353d4908bf53114ce38c20fafb588a8 GIT binary patch literal 1233 zcmZ{kT}TvB7>2*^oSD(hCfi-t|A;bIvy55`NsGc&it4H;yx1tU4T>$p(dZ^p>4zZb z#|q54Dt{0vx~a5o%B!Gq?H3}mf=CU@te}Y6-ZMMk-gMZP=RNOy=ghaWb2hE((4Rd2 zXjOpXlYr_lFxon`-v#i-b!; z!AOl|Em>4&ZSUH