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)); }
private static void WriteFakeILWithBranches(BlobBuilder builder, ControlFlowBuilder branchBuilder, int size) { Assert.Equal(0, builder.Count); const byte filling = 0x01; int ilOffset = 0; foreach (var branch in branchBuilder.Branches) { builder.WriteBytes(filling, branch.ILOffset - ilOffset); Assert.Equal(branch.ILOffset, builder.Count); builder.WriteByte((byte)branch.OpCode); int operandSize = branch.OpCode.GetBranchOperandSize(); if (operandSize == 1) { builder.WriteSByte(-1); } else { builder.WriteInt32(-1); } ilOffset = branch.ILOffset + sizeof(byte) + operandSize; } builder.WriteBytes(filling, size - ilOffset); Assert.Equal(size, builder.Count); }
internal static ExceptionRegionEncoder SerializeTableHeader(BlobBuilder builder, int exceptionRegionCount, bool hasSmallRegions) { Debug.Assert(exceptionRegionCount > 0); const byte EHTableFlag = 0x01; const byte FatFormatFlag = 0x40; bool hasSmallFormat = hasSmallRegions && IsSmallRegionCount(exceptionRegionCount); int dataSize = GetExceptionTableSize(exceptionRegionCount, hasSmallFormat); builder.Align(4); if (hasSmallFormat) { builder.WriteByte(EHTableFlag); builder.WriteByte(unchecked((byte)dataSize)); builder.WriteInt16(0); } else { Debug.Assert(dataSize <= 0x00ffffff); builder.WriteByte(EHTableFlag | FatFormatFlag); builder.WriteByte(unchecked((byte)dataSize)); builder.WriteUInt16(unchecked((ushort)(dataSize >> 8))); } return new ExceptionRegionEncoder(builder, hasSmallFormat); }
/// <summary> /// Serialized the metadata root content into the given <see cref="BlobBuilder"/>. /// </summary> /// <param name="builder">Builder to write to.</param> /// <param name="methodBodyStreamRva"> /// The relative virtual address of the start of the method body stream. /// Used to calculate the final value of RVA fields of MethodDef table. /// </param> /// <param name="mappedFieldDataStreamRva"> /// The relative virtual address of the start of the field init data stream. /// Used to calculate the final value of RVA fields of FieldRVA table. /// </param> /// <exception cref="ArgumentNullException"><paramref name="builder"/> is null.</exception> /// <exception cref="ArgumentOutOfRangeException"><paramref name="methodBodyStreamRva"/> or <paramref name="mappedFieldDataStreamRva"/> is negative.</exception> public void Serialize(BlobBuilder builder, int methodBodyStreamRva, int mappedFieldDataStreamRva) { if (builder == null) { Throw.ArgumentNull(nameof(builder)); } if (methodBodyStreamRva < 0) { Throw.ArgumentOutOfRange(nameof(methodBodyStreamRva)); } if (mappedFieldDataStreamRva < 0) { Throw.ArgumentOutOfRange(nameof(mappedFieldDataStreamRva)); } // header: MetadataBuilder.SerializeMetadataHeader(builder, MetadataVersion, _serializedMetadata.Sizes); // #~ or #- stream: _tablesAndHeaps.SerializeMetadataTables(builder, _serializedMetadata.Sizes, _serializedMetadata.StringMap, methodBodyStreamRva, mappedFieldDataStreamRva); // #Strings, #US, #Guid and #Blob streams: _tablesAndHeaps.WriteHeapsTo(builder, _serializedMetadata.StringHeap); }
private string ReadVersion(BlobBuilder metadata) { using (var provider = MetadataReaderProvider.FromMetadataImage(metadata.ToImmutableArray())) { return provider.GetMetadataReader().MetadataVersion; } }
public void WriteData(BlobBuilder resourceWriter) { if (_fileReference == null) { try { using (Stream stream = _streamProvider()) { if (stream == null) { throw new InvalidOperationException(CodeAnalysisResources.ResourceStreamProviderShouldReturnNonNullStream); } var count = (int)(stream.Length - stream.Position); resourceWriter.WriteInt32(count); int bytesWritten = resourceWriter.TryWriteBytes(stream, count); if (bytesWritten != count) { throw new EndOfStreamException( string.Format(CultureInfo.CurrentUICulture, CodeAnalysisResources.ResourceStreamEndedUnexpectedly, bytesWritten, count)); } resourceWriter.Align(8); } } catch (Exception e) { throw new ResourceException(_name, e); } } }
public void Baseline() { var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var rootBuilder = new MetadataRootBuilder(mdBuilder); var mdBlob = new BlobBuilder(); rootBuilder.Serialize(mdBlob, 0, 0); // validate sizes table rows that reference guids: using (var mdProvider = MetadataReaderProvider.FromMetadataImage(mdBlob.ToImmutableArray())) { var mdReader = mdProvider.GetMetadataReader(); Assert.Equal(2 + 3 * 2 + 2, mdReader.ModuleTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.TypeRefTable.RowSize); Assert.Equal(4 + 2 + 2 + 2 + 2 + 2, mdReader.TypeDefTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.FieldTable.RowSize); Assert.Equal(8 + 2 + 2 + 2, mdReader.MethodDefTable.RowSize); Assert.Equal(4 + 2, mdReader.ParamTable.RowSize); Assert.Equal(2 + 2, mdReader.InterfaceImplTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.MemberRefTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.ConstantTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.CustomAttributeTable.RowSize); Assert.Equal(2 + 2, mdReader.FieldMarshalTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.DeclSecurityTable.RowSize); Assert.Equal(6 + 2, mdReader.ClassLayoutTable.RowSize); Assert.Equal(4 + 2, mdReader.FieldLayoutTable.RowSize); Assert.Equal(2, mdReader.StandAloneSigTable.RowSize); Assert.Equal(2 + 2, mdReader.EventMapTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.EventTable.RowSize); Assert.Equal(2 + 2, mdReader.PropertyMapTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.PropertyTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.MethodSemanticsTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.MethodImplTable.RowSize); Assert.Equal(2, mdReader.ModuleRefTable.RowSize); Assert.Equal(2, mdReader.TypeSpecTable.RowSize); Assert.Equal(2 + 2 + 2 + 2, mdReader.ImplMapTable.RowSize); Assert.Equal(4 + 2, mdReader.FieldRvaTable.RowSize); Assert.Equal(16 + 2 + 2 + 2, mdReader.AssemblyTable.RowSize); Assert.Equal(12 + 2 + 2 + 2 + 2, mdReader.AssemblyRefTable.RowSize); Assert.Equal(4 + 2 + 2, mdReader.FileTable.RowSize); Assert.Equal(8 + 2 + 2 + 2, mdReader.ExportedTypeTable.RowSize); Assert.Equal(8 + 2 + 2, mdReader.ManifestResourceTable.RowSize); Assert.Equal(2 + 2, mdReader.NestedClassTable.RowSize); Assert.Equal(4 + 2 + 2, mdReader.GenericParamTable.RowSize); Assert.Equal(2 + 2, mdReader.MethodSpecTable.RowSize); Assert.Equal(2 + 2, mdReader.GenericParamConstraintTable.RowSize); Assert.Equal(2 + 2 + 2 + 2, mdReader.DocumentTable.RowSize); Assert.Equal(2 + 2, mdReader.MethodDebugInformationTable.RowSize); Assert.Equal(2 + 2 + 2 + 2 + 4 + 4, mdReader.LocalScopeTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.LocalVariableTable.RowSize); Assert.Equal(2 + 2, mdReader.LocalConstantTable.RowSize); Assert.Equal(2 + 2, mdReader.ImportScopeTable.RowSize); Assert.Equal(2 + 2, mdReader.StateMachineMethodTable.RowSize); Assert.Equal(2 + 2 + 2, mdReader.CustomDebugInformationTable.RowSize); } }
public void Serialize_Errors() { var mdBuilder = new MetadataBuilder(); var pdbBuilder = new PortablePdbBuilder(mdBuilder, MetadataRootBuilder.EmptyRowCounts, default(MethodDefinitionHandle)); var builder = new BlobBuilder(); Assert.Throws<ArgumentNullException>(() => pdbBuilder.Serialize(null)); }
public void BlobEncoder_FieldSignature() { var b = new BlobBuilder(); var e = new BlobEncoder(b); var s = e.FieldSignature(); AssertEx.Equal(new byte[] { 0x06 }, b.ToArray()); Assert.Same(b, s.Builder); }
public BlobEncoder(BlobBuilder builder) { if (builder == null) { Throw.BuilderArgumentNull(); } Builder = builder; }
public SerializedMetadata( MetadataSizes sizes, BlobBuilder stringHeap, ImmutableArray<int> stringMap) { Sizes = sizes; StringHeap = stringHeap; StringMap = stringMap; }
public SerializedSection(BlobBuilder builder, string name, SectionCharacteristics characteristics, int relativeVirtualAddress, int sizeOfRawData, int pointerToRawData) { Name = name; Characteristics = characteristics; Builder = builder; RelativeVirtualAddress = relativeVirtualAddress; SizeOfRawData = sizeOfRawData; PointerToRawData = pointerToRawData; }
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 Ctor() { var code = new BlobBuilder(); var flow = new ControlFlowBuilder(); var ie = new InstructionEncoder(code, flow); Assert.Same(ie.CodeBuilder, code); Assert.Same(ie.ControlFlowBuilder, flow); Assert.Throws<ArgumentNullException>(() => new InstructionEncoder(null)); }
public void Serialize_Errors() { var mdBuilder = new MetadataBuilder(); var rootBuilder = new MetadataRootBuilder(mdBuilder); var builder = new BlobBuilder(); Assert.Throws<ArgumentNullException>(() => rootBuilder.Serialize(null, 0, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, -1, 0)); Assert.Throws<ArgumentOutOfRangeException>(() => rootBuilder.Serialize(builder, 0, -1)); }
/// <summary> /// Creates an encoder backed by code and control-flow builders. /// </summary> /// <param name="codeBuilder">Builder to write encoded instructions to.</param> /// <param name="controlFlowBuilder"> /// Builder tracking labels, branches and exception handlers. /// Must be specified to be able to use some of the control-flow factory methods of <see cref="InstructionEncoder"/>, /// such as <see cref="Branch(ILOpCode, LabelHandle)"/>, <see cref="DefineLabel"/>, <see cref="MarkLabel(LabelHandle)"/> etc. /// </param> public InstructionEncoder(BlobBuilder codeBuilder, ControlFlowBuilder controlFlowBuilder = null) { if (codeBuilder == null) { Throw.BuilderArgumentNull(); } CodeBuilder = codeBuilder; ControlFlowBuilder = controlFlowBuilder; }
private void TestContentEquals(byte[] left, byte[] right) { var builder1 = new BlobBuilder(0); builder1.WriteBytes(left); var builder2 = new BlobBuilder(0); builder2.WriteBytes(right); bool expected = ByteSequenceComparer.Equals(left, right); Assert.Equal(expected, builder1.ContentEquals(builder2)); }
public void Ctor() { var builder = new BlobBuilder(); Assert.Equal(BlobBuilder.DefaultChunkSize, builder.ChunkCapacity); builder = new BlobBuilder(0); Assert.Equal(BlobBuilder.MinChunkSize, builder.ChunkCapacity); builder = new BlobBuilder(10001); Assert.Equal(10001, builder.ChunkCapacity); }
private static BlobBuilder BuildMetadataImage() { var mdBuilder = new MetadataBuilder(); mdBuilder.AddModule(0, default(StringHandle), default(GuidHandle), default(GuidHandle), default(GuidHandle)); var rootBuilder = new MetadataRootBuilder(mdBuilder, "v9.9.9.9"); var builder = new BlobBuilder(); rootBuilder.Serialize(builder, 0, 0); return builder; }
public void SerializeMetadata(BlobBuilder builder, Func<BlobBuilder, ContentId> idProvider, out ContentId contentId) { SerializeMetadataImpl(builder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0); contentId = idProvider(builder); // fill in the id: var idWriter = new BlobWriter(_pdbIdBlob); idWriter.WriteBytes(contentId.Guid); idWriter.WriteBytes(contentId.Stamp); Debug.Assert(idWriter.RemainingBytes == 0); }
internal MethodBodyEncoder( BlobBuilder builder, ushort maxStack, int exceptionRegionCount, StandaloneSignatureHandle localVariablesSignature, MethodBodyAttributes attributes) { Builder = builder; _maxStack = maxStack; _localVariablesSignature = localVariablesSignature; _attributes = (byte)attributes; _exceptionRegionCount = exceptionRegionCount; }
public void ContentEquals() { var builder = new BlobBuilder(); Assert.True(builder.ContentEquals(builder)); Assert.False(builder.ContentEquals(null)); TestContentEquals(new byte[] { }, new byte[] { }); TestContentEquals(new byte[] { 1 }, new byte[] { }); TestContentEquals(new byte[] { }, new byte[] { 1 }); TestContentEquals(new byte[] { 1 }, new byte[] { 1 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }); TestContentEquals( new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }, new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 }); }
internal void SerializeMetadataTables(BlobBuilder writer) { var sizes = new Sizes(_blobHeapSize, _guidWriter.Count); SerializeHeader(writer, sizes); // tables: SerializeDocumentTable(writer, sizes); SerializeMethodTable(writer, sizes); // heaps: writer.LinkSuffix(_guidWriter); WriteBlobHeap(writer); }
public void TokenInstructions() { var builder = new BlobBuilder(); var il = new InstructionEncoder(builder); Assert.Equal(0, il.Offset); il.Token(MetadataTokens.TypeDefinitionHandle(0x123456)); Assert.Equal(4, il.Offset); il.Token(0x7F7E7D7C); Assert.Equal(8, il.Offset); il.LoadString(MetadataTokens.UserStringHandle(0x010203)); Assert.Equal(13, il.Offset); il.Call(MetadataTokens.MethodDefinitionHandle(0xA0A1A2)); Assert.Equal(18, il.Offset); il.Call(MetadataTokens.MethodSpecificationHandle(0xB0B1B2)); Assert.Equal(23, il.Offset); il.Call(MetadataTokens.MemberReferenceHandle(0xC0C1C2)); Assert.Equal(28, il.Offset); il.Call((EntityHandle)MetadataTokens.MethodDefinitionHandle(0xD0D1D2)); Assert.Equal(33, il.Offset); il.Call((EntityHandle)MetadataTokens.MethodSpecificationHandle(0xE0E1E2)); Assert.Equal(38, il.Offset); il.Call((EntityHandle)MetadataTokens.MemberReferenceHandle(0xF0F1F2)); Assert.Equal(43, il.Offset); il.CallIndirect(MetadataTokens.StandaloneSignatureHandle(0x001122)); Assert.Equal(48, il.Offset); AssertEx.Equal(new byte[] { 0x56, 0x34, 0x12, 0x02, 0x7C, 0x7D, 0x7E, 0x7F, (byte)ILOpCode.Ldstr, 0x03, 0x02, 0x01, 0x70, (byte)ILOpCode.Call, 0xA2, 0xA1, 0xA0, 0x06, (byte)ILOpCode.Call, 0xB2, 0xB1, 0xB0, 0x2B, (byte)ILOpCode.Call, 0xC2, 0xC1, 0xC0, 0x0A, (byte)ILOpCode.Call, 0xD2, 0xD1, 0xD0, 0x06, (byte)ILOpCode.Call, 0xE2, 0xE1, 0xE0, 0x2B, (byte)ILOpCode.Call, 0xF2, 0xF1, 0xF0, 0x0A, (byte)ILOpCode.Calli, 0x22, 0x11, 0x00, 0x11 }, builder.ToArray()); }
public void Complex() { using (var peStream = new MemoryStream()) { var ilBuilder = new BlobBuilder(); var metadataBuilder = new MetadataBuilder(); var entryPoint = ComplexEmit(metadataBuilder, ilBuilder); WritePEImage(peStream, metadataBuilder, ilBuilder, entryPoint); // peStream.Position = 0; // File.WriteAllBytes(@"c:\temp\test.dll", peStream.ToArray()); } }
/// <summary> /// Serialized #Pdb stream. /// </summary> protected override void SerializeStandalonePdbStream(BlobBuilder builder) { int startPosition = builder.Count; // the id will be filled in later _pdbIdBlob = builder.ReserveBytes(MetadataSizes.PdbIdSize); builder.WriteInt32(_entryPoint.IsNil ? 0 : MetadataTokens.GetToken(_entryPoint)); builder.WriteUInt64(MetadataSizes.ExternalTablesMask); MetadataWriterUtilities.SerializeRowCounts(builder, MetadataSizes.ExternalRowCounts); int endPosition = builder.Count; Debug.Assert(MetadataSizes.CalculateStandalonePdbStreamSize() == endPosition - startPosition); }
public void BasicValidation() { using (var peStream = new MemoryStream()) { var ilBuilder = new BlobBuilder(); var metadataBuilder = new MetadataBuilder(); var entryPoint = BasicValidationEmit(metadataBuilder, ilBuilder); WritePEImage(peStream, metadataBuilder, ilBuilder, entryPoint); peStream.Position = 0; var r = new PEReader(peStream); var h = r.PEHeaders; var mdReader = r.GetMetadataReader(); } }
public void AddMethodBody_Errors() { var streamBuilder = new BlobBuilder(); var il = new InstructionEncoder(new BlobBuilder()); Assert.Throws<ArgumentNullException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(default(InstructionEncoder))); Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(il, -1)); Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(il, ushort.MaxValue + 1)); Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: -1)); Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: 1, maxStack: -1)); Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: 1, maxStack: ushort.MaxValue + 1)); Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: 1, exceptionRegionCount: -1)); Assert.Throws<ArgumentOutOfRangeException>(() => new MethodBodyStreamEncoder(streamBuilder).AddMethodBody(codeSize: 1, exceptionRegionCount: 699051)); }
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 BlobBuilder(int size = DefaultChunkSize) { if (size < 0) { throw new ArgumentOutOfRangeException(nameof(size)); } // the writer assumes little-endian architecture: if (!BitConverter.IsLittleEndian) { throw new PlatformNotSupportedException(); } _nextOrPrevious = this; _buffer = new byte[Math.Max(MinChunkSize, size)]; }
public CustomAttributeArrayTypeEncoder(BlobBuilder builder) { Builder = builder; }
public FixedArgumentsEncoder(BlobBuilder builder) { Builder = builder; }
public GenericTypeArgumentsEncoder(BlobBuilder builder) { Builder = builder; }
/// <summary> /// Serialize the export symbol table into the export section. /// </summary> /// <param name="location">RVA and file location of the .edata section</param> private BlobBuilder SerializeExportSection(SectionLocation sectionLocation) { _exportSymbols.MergeSort((es1, es2) => StringComparer.Ordinal.Compare(es1.Name, es2.Name)); BlobBuilder builder = new BlobBuilder(); int minOrdinal = int.MaxValue; int maxOrdinal = int.MinValue; // First, emit the name table and store the name RVA's for the individual export symbols // Also, record the ordinal range. foreach (ExportSymbol symbol in _exportSymbols) { symbol.NameRVAWhenPlaced = sectionLocation.RelativeVirtualAddress + builder.Count; builder.WriteUTF8(symbol.Name); builder.WriteByte(0); if (symbol.Ordinal < minOrdinal) { minOrdinal = symbol.Ordinal; } if (symbol.Ordinal > maxOrdinal) { maxOrdinal = symbol.Ordinal; } } // Emit the DLL name int dllNameRVA = sectionLocation.RelativeVirtualAddress + builder.Count; builder.WriteUTF8(_dllNameForExportDirectoryTable); builder.WriteByte(0); int[] addressTable = new int[maxOrdinal - minOrdinal + 1]; // Emit the name pointer table; it should be alphabetically sorted. // Also, we can now fill in the export address table as we've detected its size // in the previous pass. builder.Align(4); int namePointerTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; foreach (ExportSymbol symbol in _exportSymbols) { builder.WriteInt32(symbol.NameRVAWhenPlaced); SymbolTarget symbolTarget = _symbolMap[symbol.Symbol]; Section symbolSection = _sections[symbolTarget.SectionIndex]; Debug.Assert(symbolSection.RVAWhenPlaced != 0); addressTable[symbol.Ordinal - minOrdinal] = symbolSection.RVAWhenPlaced + symbolTarget.Offset; } // Emit the ordinal table int ordinalTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; foreach (ExportSymbol symbol in _exportSymbols) { builder.WriteUInt16((ushort)(symbol.Ordinal - minOrdinal)); } // Emit the address table builder.Align(4); int addressTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; foreach (int addressTableEntry in addressTable) { builder.WriteInt32(addressTableEntry); } // Emit the export directory table builder.Align(4); int exportDirectoryTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; // +0x00: reserved builder.WriteInt32(0); // +0x04: TODO: time/date stamp builder.WriteInt32(0); // +0x08: major version builder.WriteInt16(0); // +0x0A: minor version builder.WriteInt16(0); // +0x0C: DLL name RVA builder.WriteInt32(dllNameRVA); // +0x10: ordinal base builder.WriteInt32(minOrdinal); // +0x14: number of entries in the address table builder.WriteInt32(addressTable.Length); // +0x18: number of name pointers builder.WriteInt32(_exportSymbols.Count); // +0x1C: export address table RVA builder.WriteInt32(addressTableRVA); // +0x20: name pointer RVV builder.WriteInt32(namePointerTableRVA); // +0x24: ordinal table RVA builder.WriteInt32(ordinalTableRVA); int exportDirectorySize = sectionLocation.RelativeVirtualAddress + builder.Count - exportDirectoryTableRVA; _exportDirectoryEntry = new DirectoryEntry(relativeVirtualAddress: exportDirectoryTableRVA, size: exportDirectorySize); return(builder); }
/// <summary> /// Emit the .reloc section based on file relocation information in the individual blocks. /// We rely on the fact that the .reloc section is emitted last so that, by the time /// it's getting serialized, all other sections that may contain relocations have already /// been laid out. /// </summary> private BlobBuilder SerializeRelocationSection(SectionLocation sectionLocation) { // There are 12 bits for the relative offset const int RelocationTypeShift = 12; const int MaxRelativeOffsetInBlock = (1 << RelocationTypeShift) - 1; // Even though the format doesn't dictate it, it seems customary // to align the base RVA's on 4K boundaries. const int BaseRVAAlignment = 1 << RelocationTypeShift; BlobBuilder builder = new BlobBuilder(); int baseRVA = 0; List <ushort> offsetsAndTypes = null; Section relocSection = FindSection(R2RPEBuilder.RelocSectionName); if (relocSection != null) { relocSection.FilePosWhenPlaced = sectionLocation.PointerToRawData; relocSection.RVAWhenPlaced = sectionLocation.RelativeVirtualAddress; builder = relocSection.Content; } // Traverse relocations in all sections in their RVA order // By now, all "normal" sections with relocations should already have been laid out foreach (Section section in _sections.OrderBy((sec) => sec.RVAWhenPlaced)) { foreach (PlacedObjectData placedObjectData in section.PlacedObjectDataToRelocate) { for (int relocIndex = 0; relocIndex < placedObjectData.Relocs.Length; relocIndex++) { RelocType relocType = placedObjectData.Relocs[relocIndex].RelocType; RelocType fileRelocType = Relocation.GetFileRelocationType(relocType); if (fileRelocType != RelocType.IMAGE_REL_BASED_ABSOLUTE) { int relocationRVA = section.RVAWhenPlaced + placedObjectData.Offset + placedObjectData.Relocs[relocIndex].Offset; if (offsetsAndTypes != null && relocationRVA - baseRVA > MaxRelativeOffsetInBlock) { // Need to flush relocation block as the current RVA is too far from base RVA FlushRelocationBlock(builder, baseRVA, offsetsAndTypes); offsetsAndTypes = null; } if (offsetsAndTypes == null) { // Create new relocation block baseRVA = relocationRVA & -BaseRVAAlignment; offsetsAndTypes = new List <ushort>(); } ushort offsetAndType = (ushort)(((ushort)fileRelocType << RelocationTypeShift) | (relocationRVA - baseRVA)); offsetsAndTypes.Add(offsetAndType); } } } } if (offsetsAndTypes != null) { FlushRelocationBlock(builder, baseRVA, offsetsAndTypes); } if (builder.Count != 0) { _relocationDirectoryEntry = new DirectoryEntry(sectionLocation.RelativeVirtualAddress, builder.Count); } return(builder); }
protected override void Build(ref EntityMoveNode data, BlobBuilder _, ITreeNode <INodeDataBuilder>[] __) { data.Velocity = Velocity; }
private static MethodDefinitionHandle ComplexEmit(MetadataBuilder metadata, BlobBuilder ilBuilder, out Blob mvidFixup) { var mvid = metadata.ReserveGuid(); mvidFixup = mvid.Content; metadata.AddModule( 0, metadata.GetOrAddString("ConsoleApplication.exe"), mvid.Handle, 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(genericType: dictionaryTypeRef, genericArgumentCount: 2, isValueType: false); 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().Type(type: baseClassTypeDef, isValueType: false)))); var methodBodyStream = new MethodBodyStreamEncoder(ilBuilder); var buffer = new BlobBuilder(); var il = new InstructionEncoder(buffer); // // Foo // il.LoadString(metadata.GetOrAddUserString("asdsad")); il.OpCode(ILOpCode.Newobj); il.Token(invalidOperationExceptionTypeRef); il.OpCode(ILOpCode.Throw); int fooBodyOffset = methodBodyStream.AddMethodBody(il); // 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)); }
private static FieldDefinitionHandle FieldRVAValidationEmit(MetadataBuilder metadata, BlobBuilder mappedRVAData, double doubleToWriteAsData) { 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: metadata.GetOrAddBlob(ImmutableArray.Create(Misc.KeyPair_PublicKey)), flags: AssemblyFlags.PublicKey, 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")); mappedRVAData.WriteDouble(doubleToWriteAsData); var rvaFieldSignature = new BlobBuilder(); new BlobEncoder(rvaFieldSignature). FieldSignature().Double(); var fieldRVADef = metadata.AddFieldDefinition( FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.HasFieldRVA, metadata.GetOrAddString("RvaField"), metadata.GetOrAddBlob(rvaFieldSignature)); metadata.AddFieldRelativeVirtualAddress(fieldRVADef, 0); metadata.AddTypeDefinition( TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit, metadata.GetOrAddString("ConsoleApplication"), metadata.GetOrAddString("Program"), systemObjectTypeRef, fieldList: fieldRVADef, methodList: MetadataTokens.MethodDefinitionHandle(1)); return(fieldRVADef); }
public ParametersEncoder(BlobBuilder builder, bool hasVarArgs) { Builder = builder; HasVarArgs = hasVarArgs; }
public NamedArgumentTypeEncoder(BlobBuilder builder) { Builder = builder; }
public CustomAttributeNamedArgumentsEncoder(BlobBuilder builder) { Builder = builder; }
public NameEncoder(BlobBuilder builder) { Builder = builder; }
public VectorEncoder(BlobBuilder builder) { Builder = builder; }
public ScalarEncoder(BlobBuilder builder) { Builder = builder; }
public MethodSignatureEncoder(BlobBuilder builder, bool hasVarArgs) { Builder = builder; HasVarArgs = hasVarArgs; }
public CustomAttributeElementTypeEncoder(BlobBuilder builder) { Builder = builder; }
//[MethodImpl(MethodImplOptions.NoInlining)] void GenerateLoop(int brushNodeIndex0, int brushNodeIndex1, ref BlobArray <SurfaceInfo> surfaceInfos, ref BrushTreeSpacePlanes brushTreeSpacePlanes, NativeArray <PlaneVertexIndexPair> foundIndices0, ref int foundIndices0Length, //ref HashedVertices hashedVertices, NativeList <BlobAssetReference <BrushIntersectionLoops> > .ParallelWriter outputSurfaces) { // Why is the unity NativeSort slower than bubble sort? for (int i = 0; i < foundIndices0Length - 1; i++) { for (int j = i + 1; j < foundIndices0Length; j++) { var x = foundIndices0[i]; var y = foundIndices0[j]; if (x.planeIndex > y.planeIndex) { continue; } if (x.planeIndex == y.planeIndex) { if (x.vertexIndex <= y.vertexIndex) { continue; } } var t = x; foundIndices0[i] = foundIndices0[j]; foundIndices0[j] = t; } } var planeIndexOffsetsLength = 0; var planeIndexOffsets = stackalloc PlaneIndexOffsetLength[foundIndices0Length]; var uniqueIndicesLength = 0; var uniqueIndices = stackalloc ushort[foundIndices0Length]; // Now that our indices are sorted by planeIndex, we can segment them by start/end offset var previousPlaneIndex = foundIndices0[0].planeIndex; var previousVertexIndex = foundIndices0[0].vertexIndex; uniqueIndices[uniqueIndicesLength] = previousVertexIndex; uniqueIndicesLength++; var loopStart = 0; for (int i = 1; i < foundIndices0Length; i++) { var indices = foundIndices0[i]; var planeIndex = indices.planeIndex; var vertexIndex = indices.vertexIndex; // TODO: why do we have soooo many duplicates sometimes? if (planeIndex == previousPlaneIndex && vertexIndex == previousVertexIndex) { continue; } if (planeIndex != previousPlaneIndex) { var currLength = (uniqueIndicesLength - loopStart); if (currLength > 2) { planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength { length = (ushort)currLength, offset = (ushort)loopStart, planeIndex = previousPlaneIndex }; planeIndexOffsetsLength++; } loopStart = uniqueIndicesLength; } uniqueIndices[uniqueIndicesLength] = vertexIndex; uniqueIndicesLength++; previousVertexIndex = vertexIndex; previousPlaneIndex = planeIndex; } { var currLength = (uniqueIndicesLength - loopStart); if (currLength > 2) { planeIndexOffsets[planeIndexOffsetsLength] = new PlaneIndexOffsetLength { length = (ushort)currLength, offset = (ushort)loopStart, planeIndex = previousPlaneIndex }; planeIndexOffsetsLength++; } } var maxLength = 0; for (int i = 0; i < planeIndexOffsetsLength; i++) { maxLength = math.max(maxLength, planeIndexOffsets[i].length); } // For each segment, we now sort our vertices within each segment, // making the assumption that they are convex var sortedStack = stackalloc int2[maxLength * 2]; var vertices = hashedVertices.GetUnsafeReadOnlyPtr(); for (int n = planeIndexOffsetsLength - 1; n >= 0; n--) { var planeIndexOffset = planeIndexOffsets[n]; var length = planeIndexOffset.length; var offset = planeIndexOffset.offset; var planeIndex = planeIndexOffset.planeIndex; // TODO: use plane information instead SortIndices(vertices, sortedStack, uniqueIndices, offset, length, brushTreeSpacePlanes.treeSpacePlanes[planeIndex].xyz); } var totalLoopsSize = 16 + (planeIndexOffsetsLength * UnsafeUtility.SizeOf <BrushIntersectionLoop>()); var totalSize = totalLoopsSize; for (int j = 0; j < planeIndexOffsetsLength; j++) { var planeIndexLength = planeIndexOffsets[j]; var loopLength = planeIndexLength.length; totalSize += (loopLength * UnsafeUtility.SizeOf <float3>()); } var builder = new BlobBuilder(Allocator.Temp, totalSize); ref var root = ref builder.ConstructRoot <BrushIntersectionLoops>();
public ParameterTypeEncoder(BlobBuilder builder) { Builder = builder; }
protected override unsafe void Build(ref SetTransformRotationNode data, BlobBuilder builder, ITreeNode <INodeDataBuilder>[] tree) { RotationReader.Allocate(ref builder, ref data.RotationProperty, this, tree); }
public override ObjectData GetData(NodeFactory factory, bool relocsOnly = false) { if (relocsOnly) { return(new ObjectData(Array.Empty <byte>(), null, 1, null)); } if (!_emissionCompleted) { foreach (ISignatureEmitter emitter in _signatureEmitters) { emitter.MaterializeSignature(); } _emissionCompleted = true; } MetadataBuilder metadataBuilder = new MetadataBuilder(); AssemblyHashAlgorithm hashAlgorithm = AssemblyHashAlgorithm.None; BlobHandle publicKeyBlob = default(BlobHandle); AssemblyFlags manifestAssemblyFlags = default(AssemblyFlags); Version manifestAssemblyVersion = new Version(0, 0, 0, 0); if ((factory.CompositeImageSettings != null) && factory.CompilationModuleGroup.IsCompositeBuildMode) { if (factory.CompositeImageSettings.PublicKey != null) { hashAlgorithm = AssemblyHashAlgorithm.Sha1; publicKeyBlob = metadataBuilder.GetOrAddBlob(factory.CompositeImageSettings.PublicKey); manifestAssemblyFlags |= AssemblyFlags.PublicKey; } if (factory.CompositeImageSettings.AssemblyVersion != null) { manifestAssemblyVersion = factory.CompositeImageSettings.AssemblyVersion; } } string manifestMetadataAssemblyName = "ManifestMetadata"; metadataBuilder.AddAssembly( metadataBuilder.GetOrAddString(manifestMetadataAssemblyName), manifestAssemblyVersion, culture: default(StringHandle), publicKey: publicKeyBlob, flags: manifestAssemblyFlags, hashAlgorithm: hashAlgorithm); metadataBuilder.AddModule( 0, metadataBuilder.GetOrAddString(manifestMetadataAssemblyName), default(GuidHandle), default(GuidHandle), default(GuidHandle)); // Module type metadataBuilder.AddTypeDefinition( default(TypeAttributes), default(StringHandle), metadataBuilder.GetOrAddString("<Module>"), baseType: default(EntityHandle), fieldList: MetadataTokens.FieldDefinitionHandle(1), methodList: MetadataTokens.MethodDefinitionHandle(1)); foreach (var idAndAssemblyName in _moduleIdToAssemblyNameMap.OrderBy(x => x.Key)) { AssemblyName assemblyName = idAndAssemblyName.Value; AssemblyFlags assemblyFlags = 0; byte[] publicKeyOrToken; if ((assemblyName.Flags & AssemblyNameFlags.PublicKey) != 0) { assemblyFlags |= AssemblyFlags.PublicKey; publicKeyOrToken = assemblyName.GetPublicKey(); } else { publicKeyOrToken = assemblyName.GetPublicKeyToken(); } if ((assemblyName.Flags & AssemblyNameFlags.Retargetable) != 0) { assemblyFlags |= AssemblyFlags.Retargetable; } AssemblyReferenceHandle newHandle = metadataBuilder.AddAssemblyReference( name: metadataBuilder.GetOrAddString(assemblyName.Name), version: assemblyName.Version, culture: metadataBuilder.GetOrAddString(assemblyName.CultureName), publicKeyOrToken: metadataBuilder.GetOrAddBlob(publicKeyOrToken), flags: assemblyFlags, hashValue: default(BlobHandle) /* TODO */); } MetadataRootBuilder metadataRootBuilder = new MetadataRootBuilder(metadataBuilder); BlobBuilder metadataBlobBuilder = new BlobBuilder(); metadataRootBuilder.Serialize(metadataBlobBuilder, methodBodyStreamRva: 0, mappedFieldDataStreamRva: 0); return(new ObjectData( data: metadataBlobBuilder.ToArray(), relocs: Array.Empty <Relocation>(), alignment: 1, definedSymbols: new ISymbolDefinitionNode[] { this })); }
private static MethodDefinitionHandle BasicValidationEmit(MetadataBuilder metadata, BlobBuilder ilBuilder) { 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: metadata.GetOrAddBlob(ImmutableArray.Create(Misc.KeyPair_PublicKey)), flags: AssemblyFlags.PublicKey, 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 methodBodyStream = new MethodBodyStreamEncoder(ilBuilder); var codeBuilder = new BlobBuilder(); InstructionEncoder il; // // 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(); // // Program::Main // var flowBuilder = new ControlFlowBuilder(); il = new InstructionEncoder(codeBuilder, flowBuilder); var tryStart = il.DefineLabel(); var tryEnd = il.DefineLabel(); var finallyStart = il.DefineLabel(); var finallyEnd = il.DefineLabel(); flowBuilder.AddFinallyRegion(tryStart, tryEnd, finallyStart, finallyEnd); // .try il.MarkLabel(tryStart); // ldstr "hello" il.LoadString(metadata.GetOrAddUserString("hello")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // leave.s END il.Branch(ILOpCode.Leave_s, finallyEnd); il.MarkLabel(tryEnd); // .finally il.MarkLabel(finallyStart); // ldstr "world" il.LoadString(metadata.GetOrAddUserString("world")); // call void [mscorlib]System.Console::WriteLine(string) il.Call(consoleWriteLineMemberRef); // .endfinally il.OpCode(ILOpCode.Endfinally); il.MarkLabel(finallyEnd); // ret il.OpCode(ILOpCode.Ret); int mainBodyOffset = methodBodyStream.AddMethodBody(il); codeBuilder.Clear(); flowBuilder.Clear(); var mainMethodDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.HideBySig, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString("Main"), metadata.GetOrAddBlob(mainSignature), mainBodyOffset, parameterList: default(ParameterHandle)); var ctorDef = metadata.AddMethodDefinition( MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, MethodImplAttributes.IL | MethodImplAttributes.Managed, metadata.GetOrAddString(".ctor"), parameterlessCtorBlobIndex, ctorBodyOffset, parameterList: 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 LocalVariableTypeEncoder(BlobBuilder builder) { Builder = builder; }
/// <summary> /// Serializes .text section data into a specified <paramref name="builder"/>. /// </summary> /// <param name="builder">An empty builder to serialize section data to.</param> /// <param name="relativeVirtualAddess">Relative virtual address of the section within the containing PE file.</param> /// <param name="entryPointTokenOrRelativeVirtualAddress">Entry point token or RVA (<see cref="CorHeader.EntryPointTokenOrRelativeVirtualAddress"/>)</param> /// <param name="corFlags">COR Flags (<see cref="CorHeader.Flags"/>).</param> /// <param name="baseAddress">Base address of the PE image.</param> /// <param name="metadataBuilder"><see cref="BlobBuilder"/> containing metadata. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param> /// <param name="ilBuilder"><see cref="BlobBuilder"/> containing IL stream. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param> /// <param name="mappedFieldDataBuilderOpt"><see cref="BlobBuilder"/> containing mapped field data. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param> /// <param name="resourceBuilderOpt"><see cref="BlobBuilder"/> containing managed resource data. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param> /// <param name="debugDataBuilderOpt"><see cref="BlobBuilder"/> containing PE debug table and data. Must be populated with data. Linked into the <paramref name="builder"/> and can't be expanded afterwards.</param> /// <param name="strongNameSignature">Blob reserved in the <paramref name="builder"/> for strong name signature.</param> public void Serialize( BlobBuilder builder, int relativeVirtualAddess, int entryPointTokenOrRelativeVirtualAddress, CorFlags corFlags, ulong baseAddress, BlobBuilder metadataBuilder, BlobBuilder ilBuilder, BlobBuilder?mappedFieldDataBuilderOpt, BlobBuilder?resourceBuilderOpt, BlobBuilder?debugDataBuilderOpt, out Blob strongNameSignature) { Debug.Assert(builder.Count == 0); Debug.Assert(metadataBuilder.Count == MetadataSize); Debug.Assert(metadataBuilder.Count % 4 == 0); Debug.Assert(ilBuilder.Count == ILStreamSize); Debug.Assert((mappedFieldDataBuilderOpt?.Count ?? 0) == MappedFieldDataSize); Debug.Assert((resourceBuilderOpt?.Count ?? 0) == ResourceDataSize); Debug.Assert((resourceBuilderOpt?.Count ?? 0) % 4 == 0); // TODO: avoid recalculation int importTableRva = GetImportTableDirectoryEntry(relativeVirtualAddess).RelativeVirtualAddress; int importAddressTableRva = GetImportAddressTableDirectoryEntry(relativeVirtualAddess).RelativeVirtualAddress; if (RequiresStartupStub) { WriteImportAddressTable(builder, importTableRva); } WriteCorHeader(builder, relativeVirtualAddess, entryPointTokenOrRelativeVirtualAddress, corFlags); // IL: ilBuilder.Align(4); builder.LinkSuffix(ilBuilder); // metadata: builder.LinkSuffix(metadataBuilder); // managed resources: if (resourceBuilderOpt != null) { builder.LinkSuffix(resourceBuilderOpt); } // strong name signature: strongNameSignature = builder.ReserveBytes(StrongNameSignatureSize); // The bytes are required to be 0 for the purpose of calculating hash of the PE content // when strong name signing. new BlobWriter(strongNameSignature).WriteBytes(0, StrongNameSignatureSize); // debug directory and data: if (debugDataBuilderOpt != null) { builder.LinkSuffix(debugDataBuilderOpt); } if (RequiresStartupStub) { WriteImportTable(builder, importTableRva, importAddressTableRva); WriteNameTable(builder); WriteRuntimeStartupStub(builder, importAddressTableRva, baseAddress); } // mapped field data: if (mappedFieldDataBuilderOpt != null) { builder.LinkSuffix(mappedFieldDataBuilderOpt); } Debug.Assert(builder.Count == ComputeSizeOfTextSection()); }
protected internal override void Serialize(BlobBuilder builder, SectionLocation location) { throw new NotImplementedException(); }
protected override void Build(ref NodeA data, BlobBuilder _, ITreeNode <INodeDataBuilder>[] __) => data.A = A;
protected internal override void Serialize(BlobBuilder builder, SectionLocation location) { builder.WriteInt32(0x12345678); builder.WriteInt32(location.PointerToRawData); builder.WriteInt32(location.RelativeVirtualAddress); }
protected override void AllocateData(ref BlobBuilder builder, ref BlobVariable <T> blobVariable) { builder.Allocate(ref blobVariable, CustomValue); }
public PermissionSetEncoder(BlobBuilder builder) { Builder = builder; }
public LiteralsEncoder(BlobBuilder builder) { Builder = builder; }
/// <exception cref="InvalidOperationException" /> internal void CopyCodeAndFixupBranches(BlobBuilder srcBuilder, BlobBuilder dstBuilder) { var branch = _branches[0]; int branchIndex = 0; // offset within the source builder int srcOffset = 0; // current offset within the current source blob int srcBlobOffset = 0; foreach (Blob srcBlob in srcBuilder.GetBlobs()) { Debug.Assert( srcBlobOffset == 0 || srcBlobOffset == 1 && srcBlob.Buffer[0] == 0xff || srcBlobOffset == 4 && srcBlob.Buffer[0] == 0xff && srcBlob.Buffer[1] == 0xff && srcBlob.Buffer[2] == 0xff && srcBlob.Buffer[3] == 0xff); while (true) { // copy bytes preceding the next branch, or till the end of the blob: int chunkSize = Math.Min(branch.ILOffset - srcOffset, srcBlob.Length - srcBlobOffset); dstBuilder.WriteBytes(srcBlob.Buffer, srcBlobOffset, chunkSize); srcOffset += chunkSize; srcBlobOffset += chunkSize; // there is no branch left in the blob: if (srcBlobOffset == srcBlob.Length) { srcBlobOffset = 0; break; } Debug.Assert(srcBlob.Buffer[srcBlobOffset] == (byte)branch.OpCode); int operandSize = branch.OpCode.GetBranchOperandSize(); bool isShortInstruction = operandSize == 1; // Note: the 4B operand is contiguous since we wrote it via BlobBuilder.WriteInt32() Debug.Assert( srcBlobOffset + 1 == srcBlob.Length || (isShortInstruction ? srcBlob.Buffer[srcBlobOffset + 1] == 0xff : BitConverter.ToUInt32(srcBlob.Buffer, srcBlobOffset + 1) == 0xffffffff)); // write branch opcode: dstBuilder.WriteByte(srcBlob.Buffer[srcBlobOffset]); // write branch operand: int branchDistance; bool isShortDistance = branch.IsShortBranchDistance(_labels, out branchDistance); if (isShortInstruction && !isShortDistance) { // We could potentially implement algortihm that automatically fixes up the branch instructions as well to accomodate bigger distances, // however an optimal algorithm would be rather complex (something like: calculate topological ordering of crossing branch instructions // and then use fixed point to eliminate cycles). If the caller doesn't care about optimal IL size they can use long branches whenever the // distance is unknown upfront. If they do they probably already implement more sophisticad algorithm for IL layout optimization already. throw new InvalidOperationException(SR.Format(SR.DistanceBetweenInstructionAndLabelTooBig, branch.OpCode, srcOffset, branchDistance)); } if (isShortInstruction) { dstBuilder.WriteSByte((sbyte)branchDistance); } else { dstBuilder.WriteInt32(branchDistance); } srcOffset += sizeof(byte) + operandSize; // next branch: branchIndex++; if (branchIndex == _branches.Count) { branch = new BranchInfo(int.MaxValue, default(LabelHandle), 0); } else { branch = _branches[branchIndex]; } // the branch starts at the very end and its operand is in the next blob: if (srcBlobOffset == srcBlob.Length - 1) { srcBlobOffset = operandSize; break; } // skip fake branch instruction: srcBlobOffset += sizeof(byte) + operandSize; } } }