public void Serialize(BlobBuilder writer) { switch (this.Discriminator) { case ConstantValueTypeDiscriminator.Boolean: writer.WriteBoolean(this.BooleanValue); break; case ConstantValueTypeDiscriminator.SByte: writer.WriteSByte(this.SByteValue); break; case ConstantValueTypeDiscriminator.Byte: writer.WriteByte(this.ByteValue); break; case ConstantValueTypeDiscriminator.Char: case ConstantValueTypeDiscriminator.Int16: writer.WriteInt16(this.Int16Value); break; case ConstantValueTypeDiscriminator.UInt16: writer.WriteUInt16(this.UInt16Value); break; case ConstantValueTypeDiscriminator.Single: writer.WriteSingle(this.SingleValue); break; case ConstantValueTypeDiscriminator.Int32: writer.WriteInt32(this.Int32Value); break; case ConstantValueTypeDiscriminator.UInt32: writer.WriteUInt32(this.UInt32Value); break; case ConstantValueTypeDiscriminator.Double: writer.WriteDouble(this.DoubleValue); break; case ConstantValueTypeDiscriminator.Int64: writer.WriteInt64(this.Int64Value); break; case ConstantValueTypeDiscriminator.UInt64: writer.WriteUInt64(this.UInt64Value); break; default: throw ExceptionUtilities.UnexpectedValue(this.Discriminator); } }
private BlobHandle SerializeSpans( ImmutableArray <SourceSpan> spans, Dictionary <DebugSourceDocument, int> documentIndex) { if (spans.Length == 0) { return(default(BlobHandle)); } // 4 bytes per span plus a header, the builder expands by the same amount. var writer = new BlobBuilder(4 + spans.Length * 4); int previousStartLine = -1; int previousStartColumn = -1; DebugSourceDocument previousDocument = spans[0].Document; // header: writer.WriteCompressedInteger(GetOrAddDocument(previousDocument, documentIndex)); for (int i = 0; i < spans.Length; i++) { var currentDocument = spans[i].Document; if (previousDocument != currentDocument) { writer.WriteInt16(0); writer.WriteCompressedInteger(GetOrAddDocument(currentDocument, documentIndex)); previousDocument = currentDocument; } // Delta Lines & Columns: SerializeDeltaLinesAndColumns(writer, spans[i]); // delta Start Lines & Columns: if (previousStartLine < 0) { Debug.Assert(previousStartColumn < 0); writer.WriteCompressedInteger(spans[i].StartLine); writer.WriteCompressedInteger(spans[i].StartColumn); } else { writer.WriteCompressedSignedInteger(spans[i].StartLine - previousStartLine); writer.WriteCompressedSignedInteger(spans[i].StartColumn - previousStartColumn); } previousStartLine = spans[i].StartLine; previousStartColumn = spans[i].StartColumn; } return(GetOrAddBlob(writer)); }
public CustomDebugInfoEncoder(BlobBuilder builder) { Debug.Assert(builder.Count == 0); Builder = builder; _recordCount = 0; // header: builder.WriteByte(CustomDebugInfoConstants.Version); // reserve byte for record count: _recordCountFixup = builder.ReserveBytes(1); // alignment: builder.WriteInt16(0); }
public void WritePrimitive() { var writer = new BlobBuilder(17); writer.WriteUInt32(0x11223344); writer.WriteUInt16(0x5566); writer.WriteByte(0x77); writer.WriteUInt64(0x8899aabbccddeeff); writer.WriteInt32(-1); writer.WriteInt16(-2); writer.WriteSByte(-3); writer.WriteBoolean(true); writer.WriteBoolean(false); writer.WriteInt64(unchecked ((long)0xfedcba0987654321)); writer.WriteDateTime(new DateTime(0x1112223334445556)); writer.WriteDecimal(102030405060.70m); writer.WriteDouble(double.NaN); writer.WriteSingle(float.NegativeInfinity); var guid = new Guid("01020304-0506-0708-090A-0B0C0D0E0F10"); writer.WriteBytes(guid.ToByteArray()); writer.WriteGuid(guid); AssertEx.Equal(new byte[] { 0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x77, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0x01, 0x00, 0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE, 0x56, 0x55, 0x44, 0x34, 0x33, 0x22, 0x12, 0x11, 0x02, 0xD6, 0xE0, 0x9A, 0x94, 0x47, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x04, 0x03, 0x02, 0x01, 0x06, 0x05, 0x08, 0x07, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x04, 0x03, 0x02, 0x01, 0x06, 0x05, 0x08, 0x07, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }, writer.ToArray()); }
/// <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. 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 int addressTableRVA = sectionLocation.RelativeVirtualAddress + builder.Count; foreach (int addressTableEntry in addressTable) { builder.WriteInt32(addressTableEntry); } // Emit the export directory table 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); }
private static BlobHandle SerializeSequencePoints( MetadataBuilder metadataBuilder, int localSignatureRowId, ImmutableArray <SymUnmanagedSequencePoint> sequencePoints, Dictionary <string, DocumentHandle> documentIndex, out DocumentHandle singleDocumentHandle) { if (sequencePoints.Length == 0) { singleDocumentHandle = default(DocumentHandle); return(default(BlobHandle)); } var writer = new BlobBuilder(); int previousNonHiddenStartLine = -1; int previousNonHiddenStartColumn = -1; // header: writer.WriteCompressedInteger(localSignatureRowId); DocumentHandle previousDocument = TryGetSingleDocument(sequencePoints, documentIndex); singleDocumentHandle = previousDocument; for (int i = 0; i < sequencePoints.Length; i++) { var currentDocument = documentIndex[sequencePoints[i].Document.GetName()]; if (previousDocument != currentDocument) { // optional document in header or document record: if (!previousDocument.IsNil) { writer.WriteCompressedInteger(0); } writer.WriteCompressedInteger(MetadataTokens.GetHeapOffset(currentDocument)); previousDocument = currentDocument; } // delta IL offset: if (i > 0) { writer.WriteCompressedInteger((sequencePoints[i].Offset - sequencePoints[i - 1].Offset)); } else { writer.WriteCompressedInteger(sequencePoints[i].Offset); } if (sequencePoints[i].IsHidden) { writer.WriteInt16(0); continue; } // Delta Lines & Columns: SerializeDeltaLinesAndColumns(writer, sequencePoints[i]); // delta Start Lines & Columns: if (previousNonHiddenStartLine < 0) { Debug.Assert(previousNonHiddenStartColumn < 0); writer.WriteCompressedInteger(sequencePoints[i].StartLine); writer.WriteCompressedInteger(sequencePoints[i].StartColumn); } else { writer.WriteCompressedSignedInteger(sequencePoints[i].StartLine - previousNonHiddenStartLine); writer.WriteCompressedSignedInteger(sequencePoints[i].StartColumn - previousNonHiddenStartColumn); } previousNonHiddenStartLine = sequencePoints[i].StartLine; previousNonHiddenStartColumn = sequencePoints[i].StartColumn; } return(metadataBuilder.GetOrAddBlob(writer)); }
private BlobHandle SerializeSpans( ImmutableArray<SourceSpan> spans, Dictionary<DebugSourceDocument, int> documentIndex) { if (spans.Length == 0) { return default(BlobHandle); } // 4 bytes per span plus a header, the builder expands by the same amount. var writer = new BlobBuilder(4 + spans.Length * 4); int previousStartLine = -1; int previousStartColumn = -1; DebugSourceDocument previousDocument = spans[0].Document; // header: writer.WriteCompressedInteger(GetOrAddDocument(previousDocument, documentIndex)); for (int i = 0; i < spans.Length; i++) { var currentDocument = spans[i].Document; if (previousDocument != currentDocument) { writer.WriteInt16(0); writer.WriteCompressedInteger(GetOrAddDocument(currentDocument, documentIndex)); previousDocument = currentDocument; } // Delta Lines & Columns: SerializeDeltaLinesAndColumns(writer, spans[i]); // delta Start Lines & Columns: if (previousStartLine < 0) { Debug.Assert(previousStartColumn < 0); writer.WriteCompressedInteger(spans[i].StartLine); writer.WriteCompressedInteger(spans[i].StartColumn); } else { writer.WriteCompressedSignedInteger(spans[i].StartLine - previousStartLine); writer.WriteCompressedSignedInteger(spans[i].StartColumn - previousStartColumn); } previousStartLine = spans[i].StartLine; previousStartColumn = spans[i].StartColumn; } return GetOrAddBlob(writer); }
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); }
public void WritePrimitive() { var writer = new BlobBuilder(17); writer.WriteUInt32(0x11223344); writer.WriteUInt16(0x5566); writer.WriteByte(0x77); writer.WriteUInt64(0x8899aabbccddeeff); writer.WriteInt32(-1); writer.WriteInt16(-2); writer.WriteSByte(-3); writer.WriteBoolean(true); writer.WriteBoolean(false); writer.WriteInt64(unchecked((long)0xfedcba0987654321)); writer.WriteDateTime(new DateTime(0x1112223334445556)); writer.WriteDecimal(102030405060.70m); writer.WriteDouble(double.NaN); writer.WriteSingle(float.NegativeInfinity); var guid = new Guid("01020304-0506-0708-090A-0B0C0D0E0F10"); writer.WriteBytes(guid.ToByteArray()); writer.WriteGuid(guid); AssertEx.Equal(new byte[] { 0x44, 0x33, 0x22, 0x11, 0x66, 0x55, 0x77, 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfd, 0x01, 0x00, 0x21, 0x43, 0x65, 0x87, 0x09, 0xBA, 0xDC, 0xFE, 0x56, 0x55, 0x44, 0x34, 0x33, 0x22, 0x12, 0x11, 0x02, 0xD6, 0xE0, 0x9A, 0x94, 0x47, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x04, 0x03, 0x02, 0x01, 0x06, 0x05, 0x08, 0x07, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x04, 0x03, 0x02, 0x01, 0x06, 0x05, 0x08, 0x07, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 }, writer.ToArray()); }
internal static void WriteConstant(BlobBuilder writer, object value) { if (value == null) { // The encoding of Type for the nullref value for FieldInit is ELEMENT_TYPE_CLASS with a Value of a 32-bit. writer.WriteUInt32(0); return; } var type = value.GetType(); if (type.GetTypeInfo().IsEnum) { type = Enum.GetUnderlyingType(type); } if (type == typeof(bool)) { writer.WriteBoolean((bool)value); } else if (type == typeof(int)) { writer.WriteInt32((int)value); } else if (type == typeof(string)) { writer.WriteUTF16((string)value); } else if (type == typeof(byte)) { writer.WriteByte((byte)value); } else if (type == typeof(char)) { writer.WriteUInt16((char)value); } else if (type == typeof(double)) { writer.WriteDouble((double)value); } else if (type == typeof(short)) { writer.WriteInt16((short)value); } else if (type == typeof(long)) { writer.WriteInt64((long)value); } else if (type == typeof(sbyte)) { writer.WriteSByte((sbyte)value); } else if (type == typeof(float)) { writer.WriteSingle((float)value); } else if (type == typeof(ushort)) { writer.WriteUInt16((ushort)value); } else if (type == typeof(uint)) { writer.WriteUInt32((uint)value); } else if (type == typeof(ulong)) { writer.WriteUInt64((ulong)value); } else { // TODO: message throw new ArgumentException(); } }
private BlobHandle SerializeSequencePoints( StandaloneSignatureHandle localSignatureHandleOpt, ImmutableArray <SequencePoint> sequencePoints, Dictionary <DebugSourceDocument, DocumentHandle> documentIndex, out DocumentHandle singleDocumentHandle) { if (sequencePoints.Length == 0) { singleDocumentHandle = default(DocumentHandle); return(default(BlobHandle)); } var writer = new BlobBuilder(); int previousNonHiddenStartLine = -1; int previousNonHiddenStartColumn = -1; // header: writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(localSignatureHandleOpt)); var previousDocument = TryGetSingleDocument(sequencePoints); singleDocumentHandle = (previousDocument != null) ? GetOrAddDocument(previousDocument, documentIndex) : default(DocumentHandle); for (int i = 0; i < sequencePoints.Length; i++) { var currentDocument = sequencePoints[i].Document; if (previousDocument != currentDocument) { var documentHandle = GetOrAddDocument(currentDocument, documentIndex); // optional document in header or document record: if (previousDocument != null) { writer.WriteCompressedInteger(0); } writer.WriteCompressedInteger(MetadataTokens.GetRowNumber(documentHandle)); previousDocument = currentDocument; } // delta IL offset: if (i > 0) { writer.WriteCompressedInteger(sequencePoints[i].Offset - sequencePoints[i - 1].Offset); } else { writer.WriteCompressedInteger(sequencePoints[i].Offset); } if (sequencePoints[i].IsHidden) { writer.WriteInt16(0); continue; } // Delta Lines & Columns: SerializeDeltaLinesAndColumns(writer, sequencePoints[i]); // delta Start Lines & Columns: if (previousNonHiddenStartLine < 0) { Debug.Assert(previousNonHiddenStartColumn < 0); writer.WriteCompressedInteger(sequencePoints[i].StartLine); writer.WriteCompressedInteger(sequencePoints[i].StartColumn); } else { writer.WriteCompressedSignedInteger(sequencePoints[i].StartLine - previousNonHiddenStartLine); writer.WriteCompressedSignedInteger(sequencePoints[i].StartColumn - previousNonHiddenStartColumn); } previousNonHiddenStartLine = sequencePoints[i].StartLine; previousNonHiddenStartColumn = sequencePoints[i].StartColumn; } return(_debugMetadataOpt.GetOrAddBlob(writer)); }