public void BlobEncoder_MethodSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.MethodSignature(); AssertEx.Equal(new byte[] { 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); Assert.False(s.HasVarArgs); b.Clear(); s = e.MethodSignature( convention: SignatureCallingConvention.StdCall, genericParameterCount: 1234, isInstanceMethod: true); AssertEx.Equal(new byte[] { 0x32, 0x84, 0xD2 }, b.ToArray()); Assert.False(s.HasVarArgs); b.Clear(); s = e.MethodSignature( convention: SignatureCallingConvention.VarArgs, genericParameterCount: 1, isInstanceMethod: false); AssertEx.Equal(new byte[] { 0x15, 0x01 }, b.ToArray()); Assert.True(s.HasVarArgs); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSignature(genericParameterCount: -1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSignature(genericParameterCount: ushort.MaxValue + 1)); }
public void BlobEncoder_MethodSpecificationSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.MethodSpecificationSignature(genericArgumentCount: 0); AssertEx.Equal(new byte[] { 0x0A, 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); e.MethodSpecificationSignature(genericArgumentCount: 1234); AssertEx.Equal(new byte[] { 0x0A, 0x84, 0xD2 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSpecificationSignature(genericArgumentCount: -1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.MethodSpecificationSignature(genericArgumentCount: ushort.MaxValue + 1)); }
public void Add_Small() { var builder = new BlobBuilder(); var encoder = new ExceptionRegionEncoder(builder, hasSmallFormat: true); encoder.Add(ExceptionRegionKind.Catch, 1, 2, 4, 5, catchType: MetadataTokens.TypeDefinitionHandle(1)); AssertEx.Equal(new byte[] { 0x00, 0x00, // kind 0x01, 0x00, // try offset 0x02, // try length 0x04, 0x00, // handler offset 0x05, // handler length 0x01, 0x00, 0x00, 0x02 // catch type }, builder.ToArray()); builder.Clear(); encoder.Add(ExceptionRegionKind.Filter, 0xffff, 0xff, 0xffff, 0xff, filterOffset: int.MaxValue); AssertEx.Equal(new byte[] { 0x01, 0x00, // kind 0xff, 0xff, // try offset 0xff, // try length 0xff, 0xff, // handler offset 0xff, // handler length 0xff, 0xff, 0xff, 0x7f // filter offset }, builder.ToArray()); builder.Clear(); encoder.Add(ExceptionRegionKind.Fault, 0xffff, 0xff, 0xffff, 0xff); AssertEx.Equal(new byte[] { 0x04, 0x00, // kind 0xff, 0xff, // try offset 0xff, // try length 0xff, 0xff, // handler offset 0xff, // handler length 0x00, 0x00, 0x00, 0x00 }, builder.ToArray()); builder.Clear(); encoder.Add(ExceptionRegionKind.Finally, 0, 0, 0, 0); AssertEx.Equal(new byte[] { 0x02, 0x00, // kind 0x00, 0x00, // try offset 0x00, // try length 0x00, 0x00, // handler offset 0x00, // handler length 0x00, 0x00, 0x00, 0x00 }, builder.ToArray()); builder.Clear(); }
public void CountClear() { var builder = new BlobBuilder(); Assert.Equal(0, builder.Count); builder.WriteByte(1); Assert.Equal(1, builder.Count); builder.WriteInt32(4); Assert.Equal(5, builder.Count); builder.Clear(); Assert.Equal(0, builder.Count); builder.WriteInt64(1); Assert.Equal(8, builder.Count); AssertEx.Equal(new byte[] { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, builder.ToArray()); }
public void LiteralEncoder_TaggedScalar() { var b = new BlobBuilder(); var e = new LiteralEncoder(b); Assert.Same(b, e.Builder); CustomAttributeElementTypeEncoder elementType; ScalarEncoder scalar; e.TaggedScalar(out elementType, out scalar); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, elementType.Builder); Assert.Same(b, scalar.Builder); b.Clear(); e.TaggedScalar( et => Assert.Same(b, et.Builder), s => Assert.Same(b, s.Builder)); Assert.Throws <ArgumentNullException>(() => e.TaggedScalar(null, s => { })); Assert.Throws <ArgumentNullException>(() => e.TaggedScalar(et => { }, null)); }
public void SerializeTableHeader() { var builder = new BlobBuilder(); builder.WriteByte(0xff); ExceptionRegionEncoder.SerializeTableHeader(builder, ExceptionRegionEncoder.MaxSmallExceptionRegions, hasSmallRegions: true); AssertEx.Equal(new byte[] { 0xff, 0x00, 0x00, 0x00, // padding 0x01, // flags 0xf4, // size 0x00, 0x00 }, builder.ToArray()); builder.Clear(); builder.WriteByte(0xff); ExceptionRegionEncoder.SerializeTableHeader(builder, ExceptionRegionEncoder.MaxExceptionRegions, hasSmallRegions: false); AssertEx.Equal(new byte[] { 0xff, 0x00, 0x00, 0x00, // padding 0x41, // flags 0xf4, 0xff, 0xff, // size }, builder.ToArray()); }
public void LiteralEncoder_TaggedVector() { var b = new BlobBuilder(); var e = new LiteralEncoder(b); Assert.Same(b, e.Builder); CustomAttributeArrayTypeEncoder arrayType; VectorEncoder vector; e.TaggedVector(out arrayType, out vector); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, arrayType.Builder); Assert.Same(b, vector.Builder); b.Clear(); e.TaggedVector( at => Assert.Same(b, at.Builder), v => Assert.Same(b, v.Builder)); Assert.Throws <ArgumentNullException>(() => e.TaggedVector(null, v => { })); Assert.Throws <ArgumentNullException>(() => e.TaggedVector(at => { }, null)); }
public void WriteUTF8_Substring() { var writer = new BlobBuilder(4); writer.WriteUTF8("abc", 0, 0, allowUnpairedSurrogates: true, prependSize: false); AssertEx.Equal(new byte[0], writer.ToArray()); writer.Clear(); writer.WriteUTF8("abc", 0, 1, allowUnpairedSurrogates: true, prependSize: false); AssertEx.Equal(new[] { (byte)'a' }, writer.ToArray()); writer.Clear(); writer.WriteUTF8("abc", 0, 2, allowUnpairedSurrogates: true, prependSize: false); AssertEx.Equal(new[] { (byte)'a', (byte)'b' }, writer.ToArray()); writer.Clear(); writer.WriteUTF8("abc", 0, 3, allowUnpairedSurrogates: true, prependSize: false); AssertEx.Equal(new[] { (byte)'a', (byte)'b', (byte)'c' }, writer.ToArray()); writer.Clear(); writer.WriteUTF8("abc", 1, 0, allowUnpairedSurrogates: true, prependSize: false); AssertEx.Equal(new byte[0], writer.ToArray()); writer.Clear(); writer.WriteUTF8("abc", 1, 1, allowUnpairedSurrogates: true, prependSize: false); AssertEx.Equal(new[] { (byte)'b' }, writer.ToArray()); writer.Clear(); writer.WriteUTF8("abc", 1, 2, allowUnpairedSurrogates: true, prependSize: false); AssertEx.Equal(new[] { (byte)'b', (byte)'c' }, writer.ToArray()); writer.Clear(); writer.WriteUTF8("abc", 2, 1, allowUnpairedSurrogates: true, prependSize: false); AssertEx.Equal(new[] { (byte)'c' }, writer.ToArray()); writer.Clear(); }
public void CustomAttributeNamedArgumentsEncoder_Count() { var b = new BlobBuilder(); var e = new CustomAttributeNamedArgumentsEncoder(b); Assert.Same(b, e.Builder); e.Count(0); AssertEx.Equal(new byte[] { 0x00, 0x00 }, b.ToArray()); b.Clear(); e.Count(ushort.MaxValue); AssertEx.Equal(new byte[] { 0xff, 0xff }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.Count(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Count(ushort.MaxValue + 1)); }
private static void EmitHelperLibraryMetadata(string assemblyName, string rootNamespace, MetadataBuilder metadata, BlobBuilder ilBuilder) { // Dynamically get mscorlib assembly information for executing runtime var mscorlibName = typeof(object).GetTypeInfo().Assembly.GetName(); // Create module version identifier var mvid = Guid.NewGuid(); metadata.AddModule( 0, metadata.GetOrAddString($"{assemblyName}.dll"), metadata.GetOrAddGuid(mvid), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString(assemblyName), new Version(1, 0, 0, 0), default(StringHandle), default(BlobHandle), default(AssemblyFlags), AssemblyHashAlgorithm.Sha1); // Add mscorlib assembly reference and related type references var mscorlibRef = metadata.AddAssemblyReference( metadata.GetOrAddString("mscorlib"), mscorlibName.Version, default(StringHandle), metadata.GetOrAddBlob(mscorlibName.GetPublicKeyToken()), default(AssemblyFlags), default(BlobHandle)); var objectTypeRef = metadata.AddTypeReference( mscorlibRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); var consoleTypeRef = metadata.AddTypeReference( mscorlibRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Console")); // Create method signature of System.Console.WriteLine reference var consoleWriteLineSignature = new BlobBuilder(); new BlobEncoder(consoleWriteLineSignature).MethodSignature().Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().String()); var consoleWriteLineMemberRef = metadata.AddMemberReference( consoleTypeRef, metadata.GetOrAddString("WriteLine"), metadata.GetOrAddBlob(consoleWriteLineSignature)); // Create constructor signature for TestClass var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature).MethodSignature(isInstanceMethod: true) .Parameters(0, returnType => returnType.Void(), parameters => { }); var parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); // Create constructor of TestClass var objectCtorMemberRef = metadata.AddMemberReference( objectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); // Create TestClass.TestMethod signature var testMethodSignature = new BlobBuilder(); new BlobEncoder(testMethodSignature).MethodSignature(isInstanceMethod: true) .Parameters(0, returnType => returnType.Void(), parameters => { }); // Create an IL stream and serialize each methods var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); InstructionEncoder il; // Create constructor body by composing IL codes // TestClass::.ctor il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); var ctorBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Create TestClass.TestMethod body by composing IL codes // TestClass::TestMethod il = new InstructionEncoder(codeBuilder); // ldstr "hello" il.LoadString(metadata.GetOrAddUserString("Hello world from serialized assembly!")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // ret il.OpCode(ILOpCode.Ret); var testMethodBodyOffset = methodBodyStream.AddMethodBody(il); // Create TestClass.TestMethod method definition var testMethodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString("TestMethod"), metadata.GetOrAddBlob(testMethodSignature), testMethodBodyOffset, default(ParameterHandle)); // Create TestClass constructor definition var ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, default(ParameterHandle)); metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), default(EntityHandle), MetadataTokens.FieldDefinitionHandle(1), MetadataTokens.MethodDefinitionHandle(1)); metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString(rootNamespace), metadata.GetOrAddString("TestClass"), objectTypeRef, MetadataTokens.FieldDefinitionHandle(1), testMethodDef); }
public void GetBlobs() { var builder = new BlobBuilder(16); builder.WriteBytes(1, 100); var blobs = builder.GetBlobs().ToArray(); Assert.Equal(2, blobs.Length); Assert.Equal(16, blobs[0].Length); Assert.Equal(100 - 16, blobs[1].Length); builder.WriteByte(1); blobs = builder.GetBlobs().ToArray(); Assert.Equal(3, blobs.Length); Assert.Equal(16, blobs[0].Length); Assert.Equal(16, blobs[0].GetBytes().Array.Length); Assert.Equal(100 - 16, blobs[1].Length); Assert.Equal(100 - 16, blobs[1].GetBytes().Array.Length); Assert.Equal(1, blobs[2].Length); Assert.Equal(100 - 16, blobs[2].GetBytes().Array.Length); builder.Clear(); blobs = builder.GetBlobs().ToArray(); Assert.Equal(1, blobs.Length); Assert.Equal(0, blobs[0].Length); // Clear uses the first buffer: Assert.Equal(16, blobs[0].GetBytes().Array.Length); }
public void PermissionSetEncoder_AddPermission() { var b = new BlobBuilder(); var e = new PermissionSetEncoder(b); var s = e.AddPermission("ABCD", ImmutableArray.Create<byte>(1, 2, 3)); Assert.Same(b, s.Builder); AssertEx.Equal(new byte[] { 0x04, 0x41, 0x42, 0x43, 0x44, 0x03, 0x01, 0x02, 0x03 }, b.ToArray()); b.Clear(); var args = new BlobBuilder(); args.WriteBytes(new byte[] { 1, 2, 3 }); s = e.AddPermission("ABCD", args); Assert.Same(b, s.Builder); AssertEx.Equal(new byte[] { 0x04, 0x41, 0x42, 0x43, 0x44, 0x03, 0x01, 0x02, 0x03 }, b.ToArray()); b.Clear(); s = e.AddPermission("", ImmutableArray.Create<byte>()); AssertEx.Equal(new byte[] { 0x00, 0x00 }, b.ToArray()); b.Clear(); s = e.AddPermission("", new BlobBuilder()); AssertEx.Equal(new byte[] { 0x00, 0x00 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.AddPermission(null, ImmutableArray.Create<byte>(1))); Assert.Throws<ArgumentNullException>(() => e.AddPermission(null, args)); Assert.Throws<ArgumentNullException>(() => e.AddPermission("A", default(ImmutableArray<byte>))); Assert.Throws<ArgumentNullException>(() => e.AddPermission("A", null)); }
public void NamedArgumentTypeEncoder_SZArray() { var b = new BlobBuilder(); var e = new NamedArgumentTypeEncoder(b); Assert.Same(b, e.Builder); e.SZArray(); AssertEx.Equal(new byte[0], b.ToArray()); b.Clear(); }
public void SignatureTypeEncoder_Primitives() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.Boolean(); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.Char(); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.SByte(); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.Byte(); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.Int16(); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.UInt16(); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.Int32(); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.UInt32(); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.Int64(); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.UInt64(); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.Single(); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.Double(); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.String(); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); e.IntPtr(); AssertEx.Equal(new byte[] { 0x18 }, b.ToArray()); b.Clear(); e.UIntPtr(); AssertEx.Equal(new byte[] { 0x19 }, b.ToArray()); b.Clear(); e.Object(); AssertEx.Equal(new byte[] { 0x1C }, b.ToArray()); b.Clear(); }
public static void Convert(Stream peStream, Stream sourcePdbStream, Stream targetPdbStream) { using (var peReader = new PEReader(peStream)) using (var pdbReaderProvider = MetadataReaderProvider.FromPortablePdbStream(sourcePdbStream)) using (var pdbWriter = new PdbWriter(peReader.GetMetadataReader())) { var metadataReader = peReader.GetMetadataReader(); var metadataModel = new MetadataModel(metadataReader); var pdbReader = pdbReaderProvider.GetMetadataReader(); var documentWriters = new ArrayBuilder <ISymUnmanagedDocumentWriter>(pdbReader.Documents.Count); var symSequencePointBuilder = new SequencePointsBuilder(capacity: 64); var declaredExternAliases = new HashSet <string>(); var importStringsBuilder = new List <string>(); var importCountsPerScope = new List <int>(); var cdiBuilder = new BlobBuilder(); var dynamicLocals = new List <(string LocalName, byte[] Flags, int Count, int SlotIndex)>(); // state for calculating import string forwarding: var lastImportScopeHandle = default(ImportScopeHandle); var lastImportScopeMethodDefHandle = default(MethodDefinitionHandle); var importStringsMap = new Dictionary <ImmutableArray <string>, MethodDefinitionHandle>(); var aliasedAssemblyRefs = GetAliasedAssemblyRefs(pdbReader); var kickOffMethodToMoveNextMethodMap = GetStateMachineMethodMap(pdbReader); string vbDefaultNamespace = MetadataUtilities.GetVisualBasicDefaultNamespace(metadataReader); bool vbSemantics = vbDefaultNamespace != null; string vbDefaultNamespaceImportString = vbSemantics ? "*" + vbDefaultNamespace : null; foreach (var documentHandle in pdbReader.Documents) { var document = pdbReader.GetDocument(documentHandle); var languageGuid = pdbReader.GetGuid(document.Language); documentWriters.Add(pdbWriter.DefineDocument( name: pdbReader.GetString(document.Name), language: languageGuid, type: s_documentTypeText, vendor: GetLanguageVendorGuid(languageGuid), algorithmId: pdbReader.GetGuid(document.HashAlgorithm), checksum: pdbReader.GetBlobBytes(document.Hash))); } var localScopeEnumerator = pdbReader.LocalScopes.GetEnumerator(); LocalScope currentLocalScope = NextLocalScope(); LocalScope NextLocalScope() => localScopeEnumerator.MoveNext() ? pdbReader.GetLocalScope(localScopeEnumerator.Current) : default(LocalScope); var firstMethodDefHandle = default(MethodDefinitionHandle); foreach (var methodDebugInfoHandle in pdbReader.MethodDebugInformation) { var methodDebugInfo = pdbReader.GetMethodDebugInformation(methodDebugInfoHandle); var methodDefHandle = methodDebugInfoHandle.ToDefinitionHandle(); int methodToken = MetadataTokens.GetToken(methodDefHandle); var methodDef = metadataReader.GetMethodDefinition(methodDefHandle); // methods without debug info: if (methodDebugInfo.Document.IsNil && methodDebugInfo.SequencePointsBlob.IsNil) { continue; } // methods without method body don't currently have any debug information: if (methodDef.RelativeVirtualAddress == 0) { continue; } var methodBody = peReader.GetMethodBody(methodDef.RelativeVirtualAddress); pdbWriter.OpenMethod(methodToken); var forwardImportScopesToMethodDef = default(MethodDefinitionHandle); Debug.Assert(dynamicLocals.Count == 0); bool isFirstMethodScope = true; while (currentLocalScope.Method == methodDefHandle) { if (isFirstMethodScope) { if (lastImportScopeHandle == currentLocalScope.ImportScope) { // forward to a method that has the same imports: forwardImportScopesToMethodDef = lastImportScopeMethodDefHandle; } else { Debug.Assert(importStringsBuilder.Count == 0); Debug.Assert(declaredExternAliases.Count == 0); Debug.Assert(importCountsPerScope.Count == 0); AddImportStrings(importStringsBuilder, importCountsPerScope, declaredExternAliases, pdbReader, metadataModel, currentLocalScope.ImportScope, aliasedAssemblyRefs, vbDefaultNamespaceImportString); var importStrings = importStringsBuilder.ToImmutableArray(); importStringsBuilder.Clear(); if (importStringsMap.TryGetValue(importStrings, out forwardImportScopesToMethodDef)) { // forward to a method that has the same imports: lastImportScopeMethodDefHandle = forwardImportScopesToMethodDef; } else { // attach import strings to the current method: WriteImports(pdbWriter, importStrings); lastImportScopeMethodDefHandle = methodDefHandle; } lastImportScopeHandle = currentLocalScope.ImportScope; } if (vbSemantics && !forwardImportScopesToMethodDef.IsNil) { pdbWriter.UsingNamespace("@" + MetadataTokens.GetToken(forwardImportScopesToMethodDef)); } } else { pdbWriter.OpenScope(currentLocalScope.StartOffset); } foreach (var localConstantHandle in currentLocalScope.GetLocalConstants()) { var constant = pdbReader.GetLocalConstant(localConstantHandle); string name = pdbReader.GetString(constant.Name); if (name.Length > MaxEntityNameLength) { // TODO: report warning continue; } var(value, signature) = PortableConstantSignature.GetConstantValueAndSignature(pdbReader, localConstantHandle, pdbWriter.MetadataImport); if (!metadataModel.TryGetStandaloneSignatureHandle(signature, out var constantSignatureHandle)) { // TODO: report warning // TODO: // Currently the EEs require signature to match exactly the type of the value. // We could relax that and use the type of the value regardless of the signature for primitive types. // Then we could use any signature here. continue; } pdbWriter.DefineLocalConstant(name, value, MetadataTokens.GetToken(constantSignatureHandle)); var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localConstantHandle); if (TryGetDynamicLocal(name, 0, dynamicFlags, out var dynamicLocal)) { dynamicLocals.Add(dynamicLocal); } } foreach (var localVariableHandle in currentLocalScope.GetLocalVariables()) { var variable = pdbReader.GetLocalVariable(localVariableHandle); string name = pdbReader.GetString(variable.Name); if (name.Length > MaxEntityNameLength) { // TODO: report warning continue; } int localSignatureToken = methodBody.LocalSignature.IsNil ? 0 : MetadataTokens.GetToken(methodBody.LocalSignature); pdbWriter.DefineLocalVariable(variable.Index, name, variable.Attributes, localSignatureToken); var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localVariableHandle); if (TryGetDynamicLocal(name, variable.Index, dynamicFlags, out var dynamicLocal)) { dynamicLocals.Add(dynamicLocal); } } if (!isFirstMethodScope) { pdbWriter.CloseScope(currentLocalScope.EndOffset - (vbSemantics ? 1 : 0)); } currentLocalScope = NextLocalScope(); isFirstMethodScope = false; } WriteSequencePoints(pdbWriter, documentWriters, symSequencePointBuilder, methodDebugInfo.GetSequencePoints()); // async method data: var asyncData = MetadataUtilities.ReadAsyncMethodData(pdbReader, methodDebugInfoHandle); if (!asyncData.IsNone) { pdbWriter.SetAsyncInfo( moveNextMethodToken: methodToken, kickoffMethodToken: MetadataTokens.GetToken(asyncData.KickoffMethod), catchHandlerOffset: asyncData.CatchHandlerOffset, yieldOffsets: asyncData.YieldOffsets, resumeOffsets: asyncData.ResumeOffsets); } // custom debug information: var cdiEncoder = new CustomDebugInfoEncoder(cdiBuilder); if (kickOffMethodToMoveNextMethodMap.TryGetValue(methodDefHandle, out var moveNextHandle)) { cdiEncoder.AddReferenceToIteratorClass(GetIteratorTypeName(metadataReader, moveNextHandle)); } else { if (!vbSemantics) { if (forwardImportScopesToMethodDef.IsNil) { // record the number of import strings in each scope: cdiEncoder.AddUsingInfo(importCountsPerScope); if (!firstMethodDefHandle.IsNil) { // forward assembly ref aliases to the first method: cdiEncoder.AddReferenceToMethodWithModuleInfo(firstMethodDefHandle); } } else { // forward all imports to another method: cdiEncoder.AddReferenceToPreviousMethodWithUsingInfo(forwardImportScopesToMethodDef); } } var hoistedLocalScopes = GetStateMachineHoistedLocalScopes(pdbReader, methodDefHandle); if (!hoistedLocalScopes.IsDefault) { cdiEncoder.AddStateMachineLocalScopes(hoistedLocalScopes); } } if (dynamicLocals.Count > 0) { cdiEncoder.AddDynamicLocals(dynamicLocals); dynamicLocals.Clear(); } // the following blobs map 1:1 CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.TupleElementNames, CustomDebugInfoKind.TupleElementNames); CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLocalSlotMap, CustomDebugInfoKind.EditAndContinueLocalSlotMap); CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLambdaAndClosureMap, CustomDebugInfoKind.EditAndContinueLambdaMap); cdiBuilder.Clear(); if (firstMethodDefHandle.IsNil) { firstMethodDefHandle = methodDefHandle; foreach (var(assemblyRefHandle, alias) in aliasedAssemblyRefs) { var assemblyRef = metadataReader.GetAssemblyReference(assemblyRefHandle); pdbWriter.UsingNamespace("Z" + alias + " " + MetadataHelpers.GetAssemblyDisplayName(metadataReader, assemblyRef)); } } pdbWriter.CloseMethod(methodBody.GetILReader().Length); } pdbWriter.WriteTo(targetPdbStream); } }
public void CustomAttributeElementTypeEncoder_PrimitiveType() { var b = new BlobBuilder(); var e = new CustomAttributeElementTypeEncoder(b); Assert.Same(b, e.Builder); e.PrimitiveType(PrimitiveSerializationTypeCode.Boolean); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Char); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.SByte); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Byte); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Int16); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.UInt16); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Int32); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.UInt32); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Int64); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.UInt64); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Single); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Double); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.String); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveSerializationTypeCode)255)); }
public void CustomAttributeElementTypeEncoder_Enum() { var b = new BlobBuilder(); var e = new CustomAttributeElementTypeEncoder(b); Assert.Same(b, e.Builder); e.Enum("abc"); AssertEx.Equal(new byte[] { 0x55, 0x03, 0x61, 0x62, 0x63 }, b.ToArray()); b.Clear(); e.Enum("\ud800"); // unpaired surrogate AssertEx.Equal(new byte[] { 0x55, 0x03, 0xED, 0xA0, 0x80 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.Enum(null)); Assert.Throws<ArgumentException>(() => e.Enum("")); }
public void CustomAttributeElementTypeEncoder_Primitives() { var b = new BlobBuilder(); var e = new CustomAttributeElementTypeEncoder(b); Assert.Same(b, e.Builder); e.Boolean(); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.Char(); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.SByte(); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.Byte(); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.Int16(); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.UInt16(); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.Int32(); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.UInt32(); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.Int64(); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.UInt64(); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.Single(); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.Double(); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.String(); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); }
public void CustomAttributeArrayTypeEncoder_ElementType() { var b = new BlobBuilder(); var e = new CustomAttributeArrayTypeEncoder(b); Assert.Same(b, e.Builder); var s = e.ElementType(); AssertEx.Equal(new byte[] { 0x1D }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); }
public void CustomAttributeArrayTypeEncoder_ObjectArray() { var b = new BlobBuilder(); var e = new CustomAttributeArrayTypeEncoder(b); Assert.Same(b, e.Builder); e.ObjectArray(); AssertEx.Equal(new byte[] { 0x1D, 0x51 }, b.ToArray()); b.Clear(); }
public void VectorEncoder_Count() { var b = new BlobBuilder(); var e = new VectorEncoder(b); Assert.Same(b, e.Builder); var s = e.Count(0); AssertEx.Equal(new byte[] { 0x00, 0x00, 0x00, 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.Count(int.MaxValue); AssertEx.Equal(new byte[] { 0xFF, 0xFF, 0xFF, 0x7F }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.Count(-1)); }
public void SignatureTypeEncoder_PrimitiveType() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.PrimitiveType(PrimitiveTypeCode.Boolean); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Char); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.SByte); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Byte); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int16); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt16); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int32); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt32); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int64); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt64); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Single); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Double); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.String); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.IntPtr); AssertEx.Equal(new byte[] { 0x18 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UIntPtr); AssertEx.Equal(new byte[] { 0x19 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Object); AssertEx.Equal(new byte[] { 0x1C }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.Void)); Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.TypedReference)); Assert.Throws<ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveTypeCode)255)); }
private static MethodDefinitionHandle BasicValidationEmit(MetadataBuilder metadata, BlobBuilder ilBuilder) { metadata.AddModule( 0, metadata.GetOrAddString("ConsoleApplication.exe"), metadata.GetOrAddGuid(Guid.NewGuid()), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString("ConsoleApplication"), version: new Version(0, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: default(AssemblyFlags), hashAlgorithm: AssemblyHashAlgorithm.Sha1); var mscorlibAssemblyRef = metadata.AddAssemblyReference( name: metadata.GetOrAddString("mscorlib"), version: new Version(4, 0, 0, 0), culture: default(StringHandle), publicKeyOrToken: metadata.GetOrAddBlob(ImmutableArray.Create <byte>(0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89)), flags: default(AssemblyFlags), hashValue: default(BlobHandle)); var systemObjectTypeRef = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); var systemConsoleTypeRefHandle = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Console")); var consoleWriteLineSignature = new BlobBuilder(); new BlobEncoder(consoleWriteLineSignature). MethodSignature(). Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().String()); var consoleWriteLineMemberRef = metadata.AddMemberReference( systemConsoleTypeRefHandle, metadata.GetOrAddString("WriteLine"), metadata.GetOrAddBlob(consoleWriteLineSignature)); var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature). MethodSignature(isInstanceMethod: true). Parameters(0, returnType => returnType.Void(), parameters => { }); var parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); var objectCtorMemberRef = metadata.AddMemberReference( systemObjectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); var mainSignature = new BlobBuilder(); new BlobEncoder(mainSignature). MethodSignature(). Parameters(0, returnType => returnType.Void(), parameters => { }); var methodBodies = new MethodBodiesEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); var branchBuilder = new BranchBuilder(); InstructionEncoder il; // // Program::.ctor // int ctorBodyOffset; il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); methodBodies.AddMethodBody().WriteInstructions(codeBuilder, out ctorBodyOffset); codeBuilder.Clear(); // // Program::Main // int mainBodyOffset; il = new InstructionEncoder(codeBuilder, branchBuilder); var endLabel = il.DefineLabel(); // .try int tryOffset = il.Offset; // ldstr "hello" il.LoadString(metadata.GetOrAddUserString("hello")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // leave.s END il.Branch(ILOpCode.Leave, endLabel); // .finally int handlerOffset = il.Offset; // ldstr "world" il.LoadString(metadata.GetOrAddUserString("world")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // .endfinally il.OpCode(ILOpCode.Endfinally); int handlerEnd = il.Offset; // END: il.MarkLabel(endLabel); // ret il.OpCode(ILOpCode.Ret); var body = methodBodies.AddMethodBody(exceptionRegionCount: 1); var eh = body.WriteInstructions(codeBuilder, branchBuilder, out mainBodyOffset); eh.StartRegions(); eh.AddFinally(tryOffset, handlerOffset - tryOffset, handlerOffset, handlerEnd - handlerOffset); eh.EndRegions(); codeBuilder.Clear(); branchBuilder.Clear(); var mainMethodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString("Main"), metadata.GetOrAddBlob(mainSignature), mainBodyOffset, paramList: default(ParameterHandle)); var ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, paramList: default(ParameterHandle)); metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString("ConsoleApplication"), metadata.GetOrAddString("Program"), systemObjectTypeRef, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); return(mainMethodDef); }
public void BlobEncoder_PropertySignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.PropertySignature(); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); Assert.Same(b, s.Builder); Assert.False(s.HasVarArgs); b.Clear(); s = e.PropertySignature(isInstanceProperty: true); AssertEx.Equal(new byte[] { 0x28 }, b.ToArray()); Assert.False(s.HasVarArgs); b.Clear(); }
public void ScalarEncoder_Constant() { var b = new BlobBuilder(); var e = new ScalarEncoder(b); Assert.Same(b, e.Builder); e.Constant(null); AssertEx.Equal(new byte[] { 0xff }, b.ToArray()); b.Clear(); e.Constant(""); AssertEx.Equal(new byte[] { 0x00 }, b.ToArray()); b.Clear(); e.Constant("abc"); AssertEx.Equal(new byte[] { 0x03, 0x61, 0x62, 0x63 }, b.ToArray()); b.Clear(); e.Constant("\ud800"); // unpaired surrogate AssertEx.Equal(new byte[] { 0x03, 0xED, 0xA0, 0x80 }, b.ToArray()); b.Clear(); e.Constant(true); AssertEx.Equal(new byte[] { 0x01 }, b.ToArray()); b.Clear(); e.Constant(HandleKind.UserString); AssertEx.Equal(new byte[] { 0x70 }, b.ToArray()); b.Clear(); e.Constant((byte)0xAB); AssertEx.Equal(new byte[] { 0xAB }, b.ToArray()); b.Clear(); e.Constant((sbyte)0x12); AssertEx.Equal(new byte[] { 0x12 }, b.ToArray()); b.Clear(); e.Constant((ushort)0xABCD); AssertEx.Equal(new byte[] { 0xCD, 0xAB }, b.ToArray()); b.Clear(); e.Constant((short)0x1234); AssertEx.Equal(new byte[] { 0x34, 0x12 }, b.ToArray()); b.Clear(); e.Constant((char)0xABCD); AssertEx.Equal(new byte[] { 0xCD, 0xAB }, b.ToArray()); b.Clear(); e.Constant(0xABCD); AssertEx.Equal(new byte[] { 0xCD, 0xAB, 0x00, 0x00 }, b.ToArray()); b.Clear(); e.Constant((uint)0xABCD); AssertEx.Equal(new byte[] { 0xCD, 0xAB, 0x00, 0x00 }, b.ToArray()); b.Clear(); e.Constant(0x1122334455667788); AssertEx.Equal(new byte[] { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11 }, b.ToArray()); b.Clear(); e.Constant(0xAABBCCDDEEFF1122); AssertEx.Equal(new byte[] { 0x22, 0x11, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA }, b.ToArray()); b.Clear(); e.Constant(0.1f); AssertEx.Equal(new byte[] { 0xCD, 0xCC, 0xCC, 0x3D }, b.ToArray()); b.Clear(); e.Constant(0.1); AssertEx.Equal(new byte[] { 0x9A, 0x99, 0x99, 0x99, 0x99, 0x99, 0xB9, 0x3F }, b.ToArray()); b.Clear(); }
private static MethodDefinitionHandle EmitHelloWorld(MetadataBuilder metadata, BlobBuilder ilBuilder) { // Create module and assembly for a console application. metadata.AddModule( 0, metadata.GetOrAddString("ConsoleApplication.exe"), metadata.GetOrAddGuid(s_guid), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString("ConsoleApplication"), version: new Version(1, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: 0, hashAlgorithm: AssemblyHashAlgorithm.None); // Create references to System.Object and System.Console types. AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference( name: metadata.GetOrAddString("mscorlib"), version: new Version(4, 0, 0, 0), culture: default(StringHandle), publicKeyOrToken: metadata.GetOrAddBlob( new byte[] { 0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89 } ), flags: default(AssemblyFlags), hashValue: default(BlobHandle)); TypeReferenceHandle systemObjectTypeRef = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); TypeReferenceHandle systemConsoleTypeRefHandle = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Console")); // Get reference to Console.WriteLine(string) method. var consoleWriteLineSignature = new BlobBuilder(); new BlobEncoder(consoleWriteLineSignature). MethodSignature(). Parameters(1, returnType => returnType.Void(), parameters => parameters.AddParameter().Type().String()); MemberReferenceHandle consoleWriteLineMemberRef = metadata.AddMemberReference( systemConsoleTypeRefHandle, metadata.GetOrAddString("WriteLine"), metadata.GetOrAddBlob(consoleWriteLineSignature)); // Get reference to Object's constructor. var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature). MethodSignature(isInstanceMethod: true). Parameters(0, returnType => returnType.Void(), parameters => { }); BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); MemberReferenceHandle objectCtorMemberRef = metadata.AddMemberReference( systemObjectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); // Create signature for "void Main()" method. var mainSignature = new BlobBuilder(); new BlobEncoder(mainSignature). MethodSignature(). Parameters(0, returnType => returnType.Void(), parameters => { }); var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); InstructionEncoder il; // Emit IL for Program::.ctor il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); int ctorBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Emit IL for Program::Main var flowBuilder = new ControlFlowBuilder(); il = new InstructionEncoder(codeBuilder, flowBuilder); // ldstr "hello" il.LoadString(metadata.GetOrAddUserString("Hello, world")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // ret il.OpCode(ILOpCode.Ret); int mainBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Create method definition for Program::Main MethodDefinitionHandle mainMethodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, MethodImplAttributes.IL, metadata.GetOrAddString("Main"), metadata.GetOrAddBlob(mainSignature), mainBodyOffset, parameterList: default(ParameterHandle)); // Create method definition for Program::.ctor MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, parameterList: default(ParameterHandle)); // Create type definition for the special <Module> type that holds global functions metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); // Create type definition for ConsoleApplication.Program metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString("ConsoleApplication"), metadata.GetOrAddString("Program"), baseType: systemObjectTypeRef, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: mainMethodDef); return(mainMethodDef); }
public void LiteralEncoder_TaggedScalar() { var b = new BlobBuilder(); var e = new LiteralEncoder(b); Assert.Same(b, e.Builder); CustomAttributeElementTypeEncoder elementType; ScalarEncoder scalar; e.TaggedScalar(out elementType, out scalar); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, elementType.Builder); Assert.Same(b, scalar.Builder); b.Clear(); e.TaggedScalar( et => Assert.Same(b, et.Builder), s => Assert.Same(b, s.Builder)); Assert.Throws<ArgumentNullException>(() => e.TaggedScalar(null, s => { })); Assert.Throws<ArgumentNullException>(() => e.TaggedScalar(et => { }, null)); }
public void NamedArgumentsEncoder_AddArgument() { var b = new BlobBuilder(); var e = new NamedArgumentsEncoder(b); Assert.Same(b, e.Builder); NamedArgumentTypeEncoder type; NameEncoder name; LiteralEncoder literal; e.AddArgument(true, out type, out name, out literal); AssertEx.Equal(new byte[] { 0x53 }, b.ToArray()); Assert.Same(b, type.Builder); Assert.Same(b, name.Builder); Assert.Same(b, literal.Builder); b.Clear(); e.AddArgument(false, t => Assert.Same(b, t.Builder), n => Assert.Same(b, n.Builder), l => Assert.Same(b, l.Builder)); AssertEx.Equal(new byte[] { 0x54 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.AddArgument(true, null, _ => { }, _ => { })); Assert.Throws<ArgumentNullException>(() => e.AddArgument(true, _ => { }, null, _ => { })); Assert.Throws<ArgumentNullException>(() => e.AddArgument(true, _ => { }, _ => { }, null)); }
// returns the DEBUG_S_TYPE_MDTOKEN_MAP subsection as a byte array // DEBUG_S_TYPE_MDTOKEN_MAP subsection contains type-index to mdToken mapping // // contents of subsection: // offset 0, 4 bytes: count of entries in the map // offset 4, 8*N bytes: 4 byte type-index + 4 byte 'offset' relative to the start of 'type data' // offset 4+8*N, * bytes: ECMA formatted type signature packed sequentially with no padding // // 'offset' optimization: for type signatures with size<= 4-bytes // we can store the signature in offset field such that // offset = (1 << 31) | (sig[0] << 24 | sig[1] << 16 | sig[2] << 8 | sig[3]) // We chose this bit encoding because sig[0] holds the CorElementType whose // highest bit is always 0 and the highest bit of offset can be used as a flag // to indicate that it is not an offset but the signature itself. // // all entries are sorted by 'offset' field and so offset-based entries are arranged before other // (raw-signature) entries (since raw-signature entries are of the form 0x80000000 | signature, and will always be // numerically bigger than the offset) // private DebugInfoBlob GetDebugTypeIndexToTokenMap(ManagedBinaryEmitter pseudoAssembly, ICollection <KeyValuePair <TypeDesc, uint> > completeKnownTypes) { DebugInfoBlob typeDataBlob = new DebugInfoBlob(); DebugInfoBlob typeIndexToTokenMapBlob = new DebugInfoBlob(); List <KeyValuePair <uint, uint> > sigInOffsetEntries = new List <KeyValuePair <uint, uint> >(); typeIndexToTokenMapBlob.WriteDWORD(checked ((uint)completeKnownTypes.Count)); BlobBuilder blobBuilder = new BlobBuilder(); foreach (var entry in completeKnownTypes) { uint typeIndex = entry.Value; blobBuilder.Clear(); pseudoAssembly.EncodeSignatureForType(entry.Key, blobBuilder); // if signature fits in 4-bytes, store it in sigInOffsetEntries // otherwise store it in the type-data blob if (blobBuilder.Count <= 4) { uint sigInOffset = 0x80000000; int i = 0; // This is a slightly confusing approach, but this is how one iterates through the bytes in a blobBuilder without flattening it to a byte[] foreach (Blob blob in blobBuilder.GetBlobs()) { foreach (byte b in blob.GetBytes()) { sigInOffset |= ((uint)b) << (8 * (3 - i)); i++; } } // sigInOffsetEntries will be later sorted and appended to typeIndexToTokenMapBlob sigInOffsetEntries.Add(new KeyValuePair <uint, uint>(typeIndex, sigInOffset)); } else { typeIndexToTokenMapBlob.WriteDWORD(typeIndex); typeIndexToTokenMapBlob.WriteDWORD(typeDataBlob.Size()); typeDataBlob.WriteBuffer(blobBuilder); } } // sort sigInOffsetEntries based on sigInOffset sigInOffsetEntries.Sort((KeyValuePair <uint, uint> left, KeyValuePair <uint, uint> right) => { if (left.Value < right.Value) { return(-1); } if (left.Value == right.Value) { return(0); } return(1); }); // write the sorted sigInOffsetEntries foreach (KeyValuePair <uint, uint> sigInOffsetEntry in sigInOffsetEntries) { typeIndexToTokenMapBlob.WriteDWORD(sigInOffsetEntry.Key); typeIndexToTokenMapBlob.WriteDWORD(sigInOffsetEntry.Value); } // add typeDataBlob to the end of m_typeIndexToTokenMapBlob typeIndexToTokenMapBlob.WriteBuffer(typeDataBlob.ToArray()); return(typeIndexToTokenMapBlob); }
private static MethodDefinitionHandle EmitMethod(string assemblyName, MetadataBuilder metadata, BlobBuilder ilBuilder, string name, Func <MetadataBuilder, BlobBuilder> signatureCallback, string[] paramNames) { BlobBuilder methodSignature = signatureCallback(metadata); // Create module and assembly metadata.AddModule( 0, metadata.GetOrAddString(assemblyName + ".dll"), metadata.GetOrAddGuid(s_guid), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString(assemblyName), version: new Version(1, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: 0, hashAlgorithm: AssemblyHashAlgorithm.None); // Create references to System.Object and System.Console types. AssemblyReferenceHandle mscorlibAssemblyRef = metadata.AddAssemblyReference( name: metadata.GetOrAddString("System.Runtime"), version: new Version(4, 0, 0, 0), culture: default(StringHandle), publicKeyOrToken: default(BlobHandle), flags: default(AssemblyFlags), hashValue: default(BlobHandle)); TypeReferenceHandle systemObjectTypeRef = metadata.AddTypeReference( mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); // Get reference to Object's constructor. var parameterlessCtorSignature = new BlobBuilder(); new BlobEncoder(parameterlessCtorSignature). MethodSignature(isInstanceMethod: true). Parameters(0, returnType => returnType.Void(), parameters => { }); BlobHandle parameterlessCtorBlobIndex = metadata.GetOrAddBlob(parameterlessCtorSignature); MemberReferenceHandle objectCtorMemberRef = metadata.AddMemberReference( systemObjectTypeRef, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex); var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); InstructionEncoder il; // Emit IL for Program::.ctor il = new InstructionEncoder(codeBuilder); // ldarg.0 il.LoadArgument(0); // call instance void [mscorlib]System.Object::.ctor() il.Call(objectCtorMemberRef); // ret il.OpCode(ILOpCode.Ret); int ctorBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Emit IL for a method il = new InstructionEncoder(codeBuilder); il.OpCode(ILOpCode.Ldnull); il.OpCode(ILOpCode.Throw); int methodBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); // Create parameters for a method definition int nextParameterIndex = 1; ParameterHandle pFirst = default(ParameterHandle); for (int i = 0; i < paramNames.Length; i++) { ParameterHandle p = metadata.AddParameter( ParameterAttributes.None, metadata.GetOrAddString(paramNames[i]), i + 1); nextParameterIndex++; if (i == 0) { pFirst = p; } } // Create method definition MethodDefinitionHandle methodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, MethodImplAttributes.IL, metadata.GetOrAddString(name), metadata.GetOrAddBlob(methodSignature), methodBodyOffset, parameterList: pFirst); // Create method definition for Program::.ctor MethodDefinitionHandle ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, parameterList: MetadataTokens.ParameterHandle(nextParameterIndex)); // Create type definition for the special <Module> type that holds global functions metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); // Create type definition for ConsoleApplication.Program metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString(assemblyName), metadata.GetOrAddString("Program"), baseType: systemObjectTypeRef, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: methodDef); return(methodDef); }
internal void Convert(PEReader peReader, MetadataReader pdbReader, PdbWriter <TDocumentWriter> pdbWriter, PdbConversionOptions options) { if (!SymReaderHelpers.TryReadPdbId(peReader, out var pePdbId, out int peAge)) { throw new InvalidDataException(ConverterResources.SpecifiedPEFileHasNoAssociatedPdb); } if (!new BlobContentId(pdbReader.DebugMetadataHeader.Id).Equals(pePdbId)) { throw new InvalidDataException(ConverterResources.PdbNotMatchingDebugDirectory); } string vbDefaultNamespace = MetadataUtilities.GetVisualBasicDefaultNamespace(pdbReader); bool vbSemantics = vbDefaultNamespace != null; string vbDefaultNamespaceImportString = string.IsNullOrEmpty(vbDefaultNamespace) ? null : "*" + vbDefaultNamespace; var metadataReader = peReader.GetMetadataReader(); var metadataModel = new MetadataModel(metadataReader, vbSemantics); var documentWriters = new ArrayBuilder <TDocumentWriter>(pdbReader.Documents.Count); var documentNames = new ArrayBuilder <string>(pdbReader.Documents.Count); var symSequencePointBuilder = new SequencePointsBuilder(capacity: 64); var declaredExternAliases = new HashSet <string>(); var importStringsBuilder = new List <string>(); var importGroups = new List <int>(); var cdiBuilder = new BlobBuilder(); var dynamicLocals = new List <(string LocalName, byte[] Flags, int Count, int SlotIndex)>(); var tupleLocals = new List <(string LocalName, int SlotIndex, int ScopeStart, int ScopeEnd, ImmutableArray <string> Names)>(); var openScopeEndOffsets = new Stack <int>(); // state for calculating import string forwarding: var lastImportScopeHandle = default(ImportScopeHandle); var vbLastImportScopeNamespace = default(string); var lastImportScopeMethodDefHandle = default(MethodDefinitionHandle); var importStringsMap = new Dictionary <ImmutableArray <string>, MethodDefinitionHandle>(SequenceComparer <string> .Instance); var aliasedAssemblyRefs = GetAliasedAssemblyRefs(pdbReader); foreach (var documentHandle in pdbReader.Documents) { var document = pdbReader.GetDocument(documentHandle); var languageGuid = pdbReader.GetGuid(document.Language); var name = pdbReader.GetString(document.Name); documentNames.Add(name); documentWriters.Add(pdbWriter.DefineDocument( name: name, language: languageGuid, type: s_documentTypeText, vendor: GetLanguageVendorGuid(languageGuid), algorithmId: pdbReader.GetGuid(document.HashAlgorithm), checksum: pdbReader.GetBlobBytes(document.Hash))); } var localScopeEnumerator = pdbReader.LocalScopes.GetEnumerator(); LocalScope?currentLocalScope = NextLocalScope(); LocalScope?NextLocalScope() => localScopeEnumerator.MoveNext() ? pdbReader.GetLocalScope(localScopeEnumerator.Current) : default(LocalScope?); // Handle of the method that is gonna contain list of AssemblyRef aliases. // Other methods will forward to it. var methodDefHandleWithAssemblyRefAliases = default(MethodDefinitionHandle); foreach (var methodDebugInfoHandle in pdbReader.MethodDebugInformation) { var methodDebugInfo = pdbReader.GetMethodDebugInformation(methodDebugInfoHandle); var methodDefHandle = methodDebugInfoHandle.ToDefinitionHandle(); int methodToken = MetadataTokens.GetToken(methodDefHandle); var methodDef = metadataReader.GetMethodDefinition(methodDefHandle); #if DEBUG var declaringTypeDef = metadataReader.GetTypeDefinition(methodDef.GetDeclaringType()); var typeName = metadataReader.GetString(declaringTypeDef.Name); var methodName = metadataReader.GetString(methodDef.Name); #endif bool methodOpened = false; var methodBodyOpt = (methodDef.RelativeVirtualAddress != 0 && (methodDef.ImplAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Managed) ? peReader.GetMethodBody(methodDef.RelativeVirtualAddress) : null; var vbCurrentMethodNamespace = vbSemantics ? GetMethodNamespace(metadataReader, methodDef) : null; var moveNextHandle = metadataModel.FindStateMachineMoveNextMethod(methodDefHandle, vbSemantics); bool isKickOffMethod = !moveNextHandle.IsNil; var forwardImportScopesToMethodDef = default(MethodDefinitionHandle); Debug.Assert(dynamicLocals.Count == 0); Debug.Assert(tupleLocals.Count == 0); Debug.Assert(openScopeEndOffsets.Count == 0); void LazyOpenMethod() { if (!methodOpened) { #if DEBUG Debug.WriteLine($"Open Method '{typeName}::{methodName}' {methodToken:X8}"); #endif pdbWriter.OpenMethod(methodToken); methodOpened = true; } } void CloseOpenScopes(int currentScopeStartOffset) { // close all open scopes that end before this scope starts: while (openScopeEndOffsets.Count > 0 && currentScopeStartOffset >= openScopeEndOffsets.Peek()) { int scopeEnd = openScopeEndOffsets.Pop(); Debug.WriteLine($"Close Scope [.., {scopeEnd})"); // Note that the root scope end is not end-inclusive in VB: pdbWriter.CloseScope(AdjustEndScopeOffset(scopeEnd, isEndInclusive: vbSemantics && openScopeEndOffsets.Count > 0)); } } bool isFirstMethodScope = true; while (currentLocalScope.HasValue && currentLocalScope.Value.Method == methodDefHandle) { // kickoff methods don't have any scopes emitted to Windows PDBs if (methodBodyOpt == null) { ReportDiagnostic(PdbDiagnosticId.MethodAssociatedWithLocalScopeHasNoBody, MetadataTokens.GetToken(localScopeEnumerator.Current)); } else if (!isKickOffMethod) { LazyOpenMethod(); var localScope = currentLocalScope.Value; CloseOpenScopes(localScope.StartOffset); Debug.WriteLine($"Open Scope [{localScope.StartOffset}, {localScope.EndOffset})"); pdbWriter.OpenScope(localScope.StartOffset); openScopeEndOffsets.Push(localScope.EndOffset); if (isFirstMethodScope) { if (lastImportScopeHandle == localScope.ImportScope && vbLastImportScopeNamespace == vbCurrentMethodNamespace) { // forward to a method that has the same imports: forwardImportScopesToMethodDef = lastImportScopeMethodDefHandle; } else { Debug.Assert(importStringsBuilder.Count == 0); Debug.Assert(declaredExternAliases.Count == 0); Debug.Assert(importGroups.Count == 0); AddImportStrings(importStringsBuilder, importGroups, declaredExternAliases, pdbReader, metadataModel, localScope.ImportScope, aliasedAssemblyRefs, vbDefaultNamespaceImportString, vbCurrentMethodNamespace, vbSemantics); var importStrings = importStringsBuilder.ToImmutableArray(); importStringsBuilder.Clear(); if (importStringsMap.TryGetValue(importStrings, out forwardImportScopesToMethodDef)) { // forward to a method that has the same imports: lastImportScopeMethodDefHandle = forwardImportScopesToMethodDef; } else { // attach import strings to the current method: WriteImports(pdbWriter, importStrings); lastImportScopeMethodDefHandle = methodDefHandle; importStringsMap[importStrings] = methodDefHandle; } lastImportScopeHandle = localScope.ImportScope; vbLastImportScopeNamespace = vbCurrentMethodNamespace; } if (vbSemantics && !forwardImportScopesToMethodDef.IsNil) { pdbWriter.UsingNamespace("@" + MetadataTokens.GetToken(forwardImportScopesToMethodDef)); } // This is the method that's gonna have AssemblyRef aliases attached: if (methodDefHandleWithAssemblyRefAliases.IsNil) { foreach (var(assemblyRefHandle, alias) in aliasedAssemblyRefs) { var assemblyRef = metadataReader.GetAssemblyReference(assemblyRefHandle); pdbWriter.UsingNamespace("Z" + alias + " " + AssemblyDisplayNameBuilder.GetAssemblyDisplayName(metadataReader, assemblyRef)); } } } foreach (var localVariableHandle in localScope.GetLocalVariables()) { var variable = pdbReader.GetLocalVariable(localVariableHandle); string name = pdbReader.GetString(variable.Name); if (name.Length > MaxEntityNameLength) { ReportDiagnostic(PdbDiagnosticId.LocalConstantNameTooLong, MetadataTokens.GetToken(localVariableHandle)); continue; } if (methodBodyOpt.LocalSignature.IsNil) { ReportDiagnostic(PdbDiagnosticId.MethodContainingLocalVariablesHasNoLocalSignature, methodToken); continue; } // TODO: translate hoisted variable scopes to dummy VB hoisted state machine locals (https://github.com/dotnet/roslyn/issues/8473) pdbWriter.DefineLocalVariable(variable.Index, name, variable.Attributes, MetadataTokens.GetToken(methodBodyOpt.LocalSignature)); var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localVariableHandle); if (TryGetDynamicLocal(name, variable.Index, dynamicFlags, out var dynamicLocal)) { dynamicLocals.Add(dynamicLocal); } var tupleElementNames = MetadataUtilities.ReadTupleCustomDebugInformation(pdbReader, localVariableHandle); if (!tupleElementNames.IsDefaultOrEmpty) { tupleLocals.Add((name, SlotIndex: variable.Index, ScopeStart: 0, ScopeEnd: 0, Names: tupleElementNames)); } } foreach (var localConstantHandle in localScope.GetLocalConstants()) { var constant = pdbReader.GetLocalConstant(localConstantHandle); string name = pdbReader.GetString(constant.Name); if (name.Length > MaxEntityNameLength) { ReportDiagnostic(PdbDiagnosticId.LocalConstantNameTooLong, MetadataTokens.GetToken(localConstantHandle)); continue; } var(value, signature) = PortableConstantSignature.GetConstantValueAndSignature(pdbReader, localConstantHandle, metadataReader.GetQualifiedTypeName); if (!metadataModel.TryGetStandaloneSignatureHandle(signature, out var constantSignatureHandle)) { // Signature will be unspecified. At least we store the name and the value. constantSignatureHandle = default(StandaloneSignatureHandle); } pdbWriter.DefineLocalConstant(name, value, MetadataTokens.GetToken(constantSignatureHandle)); var dynamicFlags = MetadataUtilities.ReadDynamicCustomDebugInformation(pdbReader, localConstantHandle); if (TryGetDynamicLocal(name, 0, dynamicFlags, out var dynamicLocal)) { dynamicLocals.Add(dynamicLocal); } var tupleElementNames = MetadataUtilities.ReadTupleCustomDebugInformation(pdbReader, localConstantHandle); if (!tupleElementNames.IsDefaultOrEmpty) { // Note that the end offset of tuple locals is always end-exclusive, regardless of whether the PDB uses VB semantics or not. tupleLocals.Add((name, SlotIndex: -1, ScopeStart: localScope.StartOffset, ScopeEnd: localScope.EndOffset, Names: tupleElementNames)); } } } currentLocalScope = NextLocalScope(); isFirstMethodScope = false; } bool hasAnyScopes = !isFirstMethodScope; CloseOpenScopes(int.MaxValue); if (openScopeEndOffsets.Count > 0) { ReportDiagnostic(PdbDiagnosticId.LocalScopeRangesNestingIsInvalid, methodToken); openScopeEndOffsets.Clear(); } if (!methodDebugInfo.SequencePointsBlob.IsNil) { LazyOpenMethod(); WriteSequencePoints(pdbWriter, documentWriters, symSequencePointBuilder, methodDebugInfo.GetSequencePoints(), methodToken); } // async method data: var asyncData = MetadataUtilities.ReadAsyncMethodData(pdbReader, methodDebugInfoHandle); if (!asyncData.IsNone) { LazyOpenMethod(); pdbWriter.SetAsyncInfo( moveNextMethodToken: methodToken, kickoffMethodToken: MetadataTokens.GetToken(asyncData.KickoffMethod), catchHandlerOffset: asyncData.CatchHandlerOffset, yieldOffsets: asyncData.YieldOffsets.ToArray(), resumeOffsets: asyncData.ResumeOffsets.ToArray()); } // custom debug information: var cdiEncoder = new CustomDebugInfoEncoder(cdiBuilder); if (isKickOffMethod) { cdiEncoder.AddStateMachineTypeName(GetIteratorTypeName(metadataReader, moveNextHandle)); } else { if (!vbSemantics && hasAnyScopes) { if (forwardImportScopesToMethodDef.IsNil) { // record the number of import strings in each scope: cdiEncoder.AddUsingGroups(importGroups); if (!methodDefHandleWithAssemblyRefAliases.IsNil) { // forward assembly ref aliases to the first method: cdiEncoder.AddForwardModuleInfo(methodDefHandleWithAssemblyRefAliases); } } else { // forward all imports to another method: cdiEncoder.AddForwardMethodInfo(forwardImportScopesToMethodDef); } } var hoistedLocalScopes = GetStateMachineHoistedLocalScopes(pdbReader, methodDefHandle); if (!hoistedLocalScopes.IsDefault) { cdiEncoder.AddStateMachineHoistedLocalScopes(hoistedLocalScopes); } if (dynamicLocals.Count > 0) { cdiEncoder.AddDynamicLocals(dynamicLocals); dynamicLocals.Clear(); } if (tupleLocals.Count > 0) { cdiEncoder.AddTupleElementNames(tupleLocals); tupleLocals.Clear(); } } importGroups.Clear(); // the following blobs map 1:1 CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLocalSlotMap, CustomDebugInfoKind.EditAndContinueLocalSlotMap); CopyCustomDebugInfoRecord(ref cdiEncoder, pdbReader, methodDefHandle, PortableCustomDebugInfoKinds.EncLambdaAndClosureMap, CustomDebugInfoKind.EditAndContinueLambdaMap); if (cdiEncoder.RecordCount > 0) { LazyOpenMethod(); pdbWriter.DefineCustomMetadata(cdiEncoder.ToArray()); } cdiBuilder.Clear(); if (methodOpened && aliasedAssemblyRefs.Length > 0 && !isKickOffMethod && methodDefHandleWithAssemblyRefAliases.IsNil) { methodDefHandleWithAssemblyRefAliases = methodDefHandle; } if (methodOpened) { Debug.WriteLine($"Close Method {methodToken:X8}"); pdbWriter.CloseMethod(); } } if (!pdbReader.DebugMetadataHeader.EntryPoint.IsNil) { pdbWriter.SetEntryPoint(MetadataTokens.GetToken(pdbReader.DebugMetadataHeader.EntryPoint)); } var sourceLinkHandle = pdbReader.GetCustomDebugInformation(EntityHandle.ModuleDefinition, PortableCustomDebugInfoKinds.SourceLink); if (!sourceLinkHandle.IsNil) { if ((options & PdbConversionOptions.SuppressSourceLinkConversion) == 0) { ConvertSourceServerData(pdbReader.GetStringUTF8(sourceLinkHandle), pdbWriter, documentNames); } else { pdbWriter.SetSourceLinkData(pdbReader.GetBlobBytes(sourceLinkHandle)); } } SymReaderHelpers.GetWindowsPdbSignature(pdbReader.DebugMetadataHeader.Id, out var guid, out var stamp, out var age); pdbWriter.UpdateSignature(guid, stamp, age); }
public void ArrayShapeEncoder_Shape() { var b = new BlobBuilder(); var e = new ArrayShapeEncoder(b); Assert.Same(b, e.Builder); e.Shape(ushort.MaxValue, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty); AssertEx.Equal(new byte[] { 0xC0, 0x00, 0xFF, 0xFF, 0x00, 0x00 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(0x0A), ImmutableArray <int> .Empty); AssertEx.Equal(new byte[] { 0x03, 0x01, 0x0A, 0x00 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(0x0A, 0x0B), ImmutableArray.Create(0x02, 0x03)); AssertEx.Equal(new byte[] { 0x03, 0x02, 0x0A, 0x0B, 0x02, 0x04, 0x06 }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray <int> .Empty, ImmutableArray.Create(-2, -1)); AssertEx.Equal(new byte[] { 0x03, 0x00, 0x02, 0x7D, 0x7F }, b.ToArray()); b.Clear(); e.Shape(3, ImmutableArray.Create(BlobWriterImpl.MaxCompressedIntegerValue), ImmutableArray.Create(BlobWriterImpl.MinSignedCompressedIntegerValue, BlobWriterImpl.MaxSignedCompressedIntegerValue)); AssertEx.Equal(new byte[] { 0x03, 0x01, 0xDF, 0xFF, 0xFF, 0xFF, 0x02, 0xC0, 0x00, 0x00, 0x01, 0xDF, 0xFF, 0xFF, 0xFE }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentNullException>(() => e.Shape(1, default(ImmutableArray <int>), ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(0, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(-1, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(ushort.MaxValue + 1, ImmutableArray <int> .Empty, ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(1, 2, 3), ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(1, 2, 3))); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(-1), ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray.Create(BlobWriterImpl.MaxCompressedIntegerValue + 1), ImmutableArray <int> .Empty)); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(BlobWriterImpl.MinSignedCompressedIntegerValue - 1))); Assert.Throws <ArgumentOutOfRangeException>(() => e.Shape(1, ImmutableArray <int> .Empty, ImmutableArray.Create(BlobWriterImpl.MaxSignedCompressedIntegerValue + 1))); }
public void Free() { _builder.Clear(); // frees all but first chunk s_pool.Free(this); // return first chunk to pool }
public void LiteralEncoder_TaggedVector() { var b = new BlobBuilder(); var e = new LiteralEncoder(b); Assert.Same(b, e.Builder); CustomAttributeArrayTypeEncoder arrayType; VectorEncoder vector; e.TaggedVector(out arrayType, out vector); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, arrayType.Builder); Assert.Same(b, vector.Builder); b.Clear(); e.TaggedVector( at => Assert.Same(b, at.Builder), v => Assert.Same(b, v.Builder)); Assert.Throws<ArgumentNullException>(() => e.TaggedVector(null, v => { })); Assert.Throws<ArgumentNullException>(() => e.TaggedVector(at => { }, null)); }
// // returns the DEBUG_S_FUNC_MDTOKEN_MAP subsection as a byte array // DEBUG_S_FUNC_MDTOKEN_MAP subsection contains method RVA to mdToken mapping // // contents of subsection: // offset 0, 4 bytes: count of entries in the map // offset 4, 8*N bytes: 4 byte RVA + 4 byte 'offset' relative to the start of 'method data' // offset 4+8*N, * bytes: all method data packed sequentially with no padding. method data consists of // 1 byte 'count' of generic parameters, 3 bytes of method's rid and 'count' // variable sized ECMA formatted TypeSpec signatures for each generic parameter // // Compiler places the CTLToken (for a method) or the lexical funclet order (if a method has 1 or more funclets), // which binder uses to compute the RVA. // // all entries are sorted by 'offset' field. // // 'offset' optimization: if the method has no generic parameters, we don't need to pass in a signature // and can encode the mdToken of method in 'offset' // We do this by setting the high bit of 'offset' and then storing rid part of // token in last 3 bytes of 'offset' // internal DebugInfoBlob GetDebugMethodRVAToTokenMap(ManagedBinaryEmitter pseudoAssembly, IEnumerable <IMethodBodyNode> emittedMethods, out List <Relocation> debugRelocations) { DebugInfoBlob methodRVAToTokenMap = new DebugInfoBlob(); DebugInfoBlob methodDataBlob = new DebugInfoBlob(); debugRelocations = new List <Relocation>(); BlobBuilder blobBuilder = new BlobBuilder(); uint entryCount = 0; methodRVAToTokenMap.WriteDWORD(0); // Placeholder for count of entries in map. Will be udpated later. List <EmittedMethodWithILToken> tokenInOffsetEntries = new List <EmittedMethodWithILToken>(); foreach (IMethodBodyNode emitted in emittedMethods) { if (!(emitted.Method.GetTypicalMethodDefinition() is Internal.TypeSystem.Ecma.EcmaMethod)) { continue; } EntityHandle methodHandle = pseudoAssembly.EmitMetadataHandleForTypeSystemEntity(emitted.Method.GetTypicalMethodDefinition()); Debug.Assert(methodHandle.Kind == HandleKind.MemberReference); uint methodToken = (uint)MetadataTokens.GetToken(methodHandle); uint methodTokenRid = methodToken & 0xFFFFFF; if (!(emitted.Method.HasInstantiation || emitted.Method.OwningType.HasInstantiation)) { tokenInOffsetEntries.Add(new EmittedMethodWithILToken(emitted, methodTokenRid)); continue; } uint cGenericArguments = checked ((uint)emitted.Method.Instantiation.Length + (uint)emitted.Method.OwningType.Instantiation.Length); // Debugger format does not allow the debugging of methods that have more than 255 generic parameters (spread between the type and method instantiation) if (cGenericArguments > 0xFF) { continue; } blobBuilder.Clear(); // write the signature for each generic parameter of class foreach (TypeDesc instantiationType in emitted.Method.OwningType.Instantiation) { pseudoAssembly.EncodeSignatureForType(instantiationType, blobBuilder); } // write the signature for each generic parameter of the method foreach (TypeDesc instantiationType in emitted.Method.Instantiation) { pseudoAssembly.EncodeSignatureForType(instantiationType, blobBuilder); } Add_DEBUG_S_FUNC_MDTOKEN_MAP_Entry(methodRVAToTokenMap, debugRelocations, emitted, methodDataBlob.Size(), ref entryCount); methodDataBlob.WriteDWORD(cGenericArguments << 24 | methodTokenRid); methodDataBlob.WriteBuffer(blobBuilder); } // sort tokenInOffsetEntries based on tokenInOffset tokenInOffsetEntries.Sort(); foreach (EmittedMethodWithILToken emitted in tokenInOffsetEntries) { Add_DEBUG_S_FUNC_MDTOKEN_MAP_Entry(methodRVAToTokenMap, debugRelocations, emitted.EmittedMethod, emitted.IlTokenRid | 0x80000000, ref entryCount); } methodRVAToTokenMap.SetDWORDAtBlobIndex(0, entryCount); // // Update placeholder for count of entries in map methodRVAToTokenMap.WriteBuffer(methodDataBlob); return(methodRVAToTokenMap); }
public void NameEncoder_Name() { var b = new BlobBuilder(); var e = new NameEncoder(b); Assert.Same(b, e.Builder); e.Name("abc"); AssertEx.Equal(new byte[] { 0x03, 0x61, 0x62, 0x63 }, b.ToArray()); b.Clear(); e.Name("\ud800"); // unpaired surrogate AssertEx.Equal(new byte[] { 0x03, 0xED, 0xA0, 0x80 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.Name(null)); Assert.Throws<ArgumentException>(() => e.Name("")); }
public void SignatureTypeEncoder_PrimitiveType() { var b = new BlobBuilder(); var e = new SignatureTypeEncoder(b); Assert.Same(b, e.Builder); e.PrimitiveType(PrimitiveTypeCode.Boolean); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Char); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.SByte); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Byte); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int16); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt16); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int32); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt32); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Int64); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UInt64); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Single); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Double); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.String); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.IntPtr); AssertEx.Equal(new byte[] { 0x18 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.UIntPtr); AssertEx.Equal(new byte[] { 0x19 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveTypeCode.Object); AssertEx.Equal(new byte[] { 0x1C }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.Void)); Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType(PrimitiveTypeCode.TypedReference)); Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveTypeCode)255)); }
public void BlobEncoder_CustomAttributeSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); FixedArgumentsEncoder fixedArgs; CustomAttributeNamedArgumentsEncoder namedArgs; e.CustomAttributeSignature(out fixedArgs, out namedArgs); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); Assert.Same(b, fixedArgs.Builder); Assert.Same(b, namedArgs.Builder); b.Clear(); e.CustomAttributeSignature( f => Assert.Same(b, f.Builder), n => Assert.Same(b, namedArgs.Builder)); AssertEx.Equal(new byte[] { 0x01, 0x00 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentNullException>(() => e.CustomAttributeSignature(null, n => { })); Assert.Throws<ArgumentNullException>(() => e.CustomAttributeSignature(f => { }, null)); }
public void BlobEncoder_LocalVariableSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.LocalVariableSignature(variableCount: 0); AssertEx.Equal(new byte[] { 0x07, 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.LocalVariableSignature(variableCount: 1000000); AssertEx.Equal(new byte[] { 0x07, 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.LocalVariableSignature(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.LocalVariableSignature(BlobWriterImpl.MaxCompressedIntegerValue + 1)); }
public void CustomAttributeElementTypeEncoder_PrimitiveType() { var b = new BlobBuilder(); var e = new CustomAttributeElementTypeEncoder(b); Assert.Same(b, e.Builder); e.PrimitiveType(PrimitiveSerializationTypeCode.Boolean); AssertEx.Equal(new byte[] { 0x02 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Char); AssertEx.Equal(new byte[] { 0x03 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.SByte); AssertEx.Equal(new byte[] { 0x04 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Byte); AssertEx.Equal(new byte[] { 0x05 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Int16); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.UInt16); AssertEx.Equal(new byte[] { 0x07 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Int32); AssertEx.Equal(new byte[] { 0x08 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.UInt32); AssertEx.Equal(new byte[] { 0x09 }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Int64); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.UInt64); AssertEx.Equal(new byte[] { 0x0B }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Single); AssertEx.Equal(new byte[] { 0x0C }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.Double); AssertEx.Equal(new byte[] { 0x0D }, b.ToArray()); b.Clear(); e.PrimitiveType(PrimitiveSerializationTypeCode.String); AssertEx.Equal(new byte[] { 0x0E }, b.ToArray()); b.Clear(); Assert.Throws <ArgumentOutOfRangeException>(() => e.PrimitiveType((PrimitiveSerializationTypeCode)255)); }
public void BlobEncoder_PermissionSetArguments() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.PermissionSetArguments(argumentCount: 0); AssertEx.Equal(new byte[] { 0x00 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.PermissionSetArguments(argumentCount: 1000000); AssertEx.Equal(new byte[] { 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.PermissionSetArguments(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => e.PermissionSetArguments(BlobWriterImpl.MaxCompressedIntegerValue + 1)); }
public void MethodSignatureEncoder_Parameters() { var b = new BlobBuilder(); var e = new MethodSignatureEncoder(b, hasVarArgs: false); ReturnTypeEncoder returnType; ParametersEncoder parameters; e.Parameters(0, out returnType, out parameters); AssertEx.Equal(new byte[] { 0x00 }, b.ToArray()); Assert.Same(b, parameters.Builder); Assert.Same(b, returnType.Builder); b.Clear(); e.Parameters(1000000, out returnType, out parameters); AssertEx.Equal(new byte[] { 0xC0, 0x0F, 0x42, 0x40 }, b.ToArray()); b.Clear(); e.Parameters(10, rt => Assert.Same(b, rt.Builder), ps => Assert.Same(b, ps.Builder)); AssertEx.Equal(new byte[] { 0x0A }, b.ToArray()); b.Clear(); Assert.Throws<ArgumentOutOfRangeException>(() => e.Parameters(-1, out returnType, out parameters)); Assert.Throws<ArgumentOutOfRangeException>(() => e.Parameters(BlobWriterImpl.MaxCompressedIntegerValue + 1, out returnType, out parameters)); Assert.Throws<ArgumentNullException>(() => e.Parameters(0, null, ps => { })); Assert.Throws<ArgumentNullException>(() => e.Parameters(0, rt => { }, null)); }
public void LocalVariableTypeEncoder_Type() { var b = new BlobBuilder(); var e = new LocalVariableTypeEncoder(b); var s = e.Type(); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.Type(isByRef: true); AssertEx.Equal(new byte[] { 0x10 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.Type(isPinned: true); AssertEx.Equal(new byte[] { 0x45 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.Type(isByRef: true, isPinned: true); AssertEx.Equal(new byte[] { 0x45, 0x10 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); }
private static MethodDefinitionHandle ComplexEmit(MetadataBuilder metadata, BlobBuilder ilBuilder) { metadata.AddModule( 0, metadata.GetOrAddString("ConsoleApplication.exe"), metadata.GetOrAddGuid(Guid.NewGuid()), default(GuidHandle), default(GuidHandle)); metadata.AddAssembly( metadata.GetOrAddString("ConsoleApplication"), version: new Version(0, 0, 0, 0), culture: default(StringHandle), publicKey: default(BlobHandle), flags: default(AssemblyFlags), hashAlgorithm: AssemblyHashAlgorithm.Sha1); var mscorlibAssemblyRef = metadata.AddAssemblyReference( name: metadata.GetOrAddString("mscorlib"), version: new Version(4, 0, 0, 0), culture: default(StringHandle), publicKeyOrToken: metadata.GetOrAddBlob(ImmutableArray.Create <byte>(0xB7, 0x7A, 0x5C, 0x56, 0x19, 0x34, 0xE0, 0x89)), flags: default(AssemblyFlags), hashValue: default(BlobHandle)); // TypeRefs: var systemObjectTypeRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Object")); var dictionaryTypeRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System.Collections.Generic"), metadata.GetOrAddString("Dictionary`2")); var strignBuilderTypeRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System.Text"), metadata.GetOrAddString("StringBuilder")); var typeTypeRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Type")); var int32TypeRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("Int32")); var runtimeTypeHandleRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("RuntimeTypeHandle")); var invalidOperationExceptionTypeRef = metadata.AddTypeReference(mscorlibAssemblyRef, metadata.GetOrAddString("System"), metadata.GetOrAddString("InvalidOperationException")); // TypeDefs: metadata.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadata.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); var baseClassTypeDef = metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit | TypeAttributes.Abstract, metadata.GetOrAddString("Lib"), metadata.GetOrAddString("BaseClass"), systemObjectTypeRef, fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); var derivedClassTypeDef = metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString("Lib"), metadata.GetOrAddString("DerivedClass"), baseClassTypeDef, fieldList: MetadataTokens.FieldDefinitionHandle(4), methodList: MetadataTokens.MethodDefinitionHandle(1)); // FieldDefs: // Field1 var baseClassNumberFieldDef = metadata.AddFieldDefinition( FieldAttributes.Private, metadata.GetOrAddString("_number"), metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().Int32()))); // Field2 var baseClassNegativeFieldDef = metadata.AddFieldDefinition( FieldAttributes.Assembly, metadata.GetOrAddString("negative"), metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().Boolean()))); // Field3 var derivedClassSumCacheFieldDef = metadata.AddFieldDefinition( FieldAttributes.Assembly, metadata.GetOrAddString("_sumCache"), metadata.GetOrAddBlob(BuildSignature(e => { var inst = e.FieldSignature().GenericInstantiation(isValueType: false, typeRefDefSpec: dictionaryTypeRef, genericArgumentCount: 2); inst.AddArgument().Int32(); inst.AddArgument().Object(); }))); // Field4 var derivedClassCountFieldDef = metadata.AddFieldDefinition( FieldAttributes.Assembly, metadata.GetOrAddString("_count"), metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().SZArray().Int32()))); // Field5 var derivedClassBCFieldDef = metadata.AddFieldDefinition( FieldAttributes.Assembly, metadata.GetOrAddString("_bc"), metadata.GetOrAddBlob(BuildSignature(e => e.FieldSignature().TypeDefOrRefOrSpec(isValueType: false, typeRefDefSpec: baseClassTypeDef)))); var methodBodies = new MethodBodiesEncoder(ilBuilder); var buffer = new BlobBuilder(); InstructionEncoder il; // // Foo // int fooBodyOffset; il = new InstructionEncoder(buffer); il.LoadString(metadata.GetOrAddUserString("asdsad")); il.OpCode(ILOpCode.Newobj); il.Token(invalidOperationExceptionTypeRef); il.OpCode(ILOpCode.Throw); methodBodies.AddMethodBody().WriteInstructions(buffer, out fooBodyOffset); buffer.Clear(); // Method1 var derivedClassFooMethodDef = metadata.AddMethodDefinition( MethodAttributes.PrivateScope | MethodAttributes.Private | MethodAttributes.HideBySig, MethodImplAttributes.IL, metadata.GetOrAddString("Foo"), metadata.GetOrAddBlob(BuildSignature(e => e.MethodSignature(isInstanceMethod: true).Parameters(0, returnType => returnType.Void(), parameters => { }))), fooBodyOffset, default(ParameterHandle)); return(default(MethodDefinitionHandle)); }
public void ParameterTypeEncoder_Type() { var b = new BlobBuilder(); var e = new ParameterTypeEncoder(b); var s = e.Type(); AssertEx.Equal(new byte[0], b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); s = e.Type(isByRef: true); AssertEx.Equal(new byte[] { 0x10 }, b.ToArray()); Assert.Same(b, s.Builder); b.Clear(); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { // This node does not trigger generation of other nodes. if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), Array.Empty <Relocation>(), 1, new ISymbolDefinitionNode[] { this })); } ObjectDataBuilder objDataBuilder = new ObjectDataBuilder(factory, relocsOnly); // Emit number of dictionaries in table objDataBuilder.AddSymbol(this); IReadOnlyCollection <GenericDictionaryNode> dictionariesEmitted = factory.MetadataManager.GetCompiledGenericDictionaries(); objDataBuilder.EmitInt(dictionariesEmitted.Count); DebugInfoBlob signatureData = new DebugInfoBlob(); BlobBuilder signatureBlobBuilder = new BlobBuilder(); BlobBuilder signatureLenBuilder = new BlobBuilder(); ManagedBinaryEmitter pseudoAssembly = factory.WindowsDebugData.DebugPseudoAssemblySection.PseudoAssembly; foreach (GenericDictionaryNode dictionary in dictionariesEmitted) { objDataBuilder.EmitReloc(dictionary, RelocType.IMAGE_REL_BASED_ADDR32NB); objDataBuilder.EmitUInt(signatureData.Size()); signatureBlobBuilder.Clear(); int typeDictLen = dictionary.TypeInstantiation.IsNull ? 0 : dictionary.TypeInstantiation.Length; int methodDictLen = dictionary.MethodInstantiation.IsNull ? 0 : dictionary.MethodInstantiation.Length; signatureBlobBuilder.WriteCompressedInteger(typeDictLen + methodDictLen); if (typeDictLen != 0) { foreach (TypeDesc type in dictionary.TypeInstantiation) { pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder); } } if (methodDictLen != 0) { foreach (TypeDesc type in dictionary.MethodInstantiation) { pseudoAssembly.EncodeSignatureForType(type, signatureBlobBuilder); } } int blobSize = signatureBlobBuilder.Count; signatureLenBuilder.Clear(); signatureLenBuilder.WriteCompressedInteger(blobSize); // Prepend the signature data with a length signatureData.WriteBuffer(signatureLenBuilder); // And then attach the actual signature data signatureData.WriteBuffer(signatureBlobBuilder); } // Attach signature information to end after all of the rva/offset pairs objDataBuilder.EmitBytes(signatureData.ToArray()); return(objDataBuilder.ToObjectData()); }
public void Free() { _builder.Clear(); }